The customer lifecycle in Paygentic involves creating customer relationships, establishing subscriptions, and tracking usage. This guide covers the programmatic approach to managing customers through the API.
Overview
Paygentic supports two distinct types of consumer accounts, each with different capabilities and use cases:
Managed Consumers Created via API by merchants for quick onboarding. Customers only access Paygentic in relation to this one merchant.
These customer do not have Paygentic users and only use Paygentic through the merchant integration.
Full Consumer Accounts When the customer interacts with multiple merchants they can choose to keep everything in one account and sign in to Paygentic to manage their usage.
Normally customers will start off as a managed customer and only transition to a full account when needed.
The key point for merchants is that in managed accounts the account funds are exclusively available to that merchant.
Creating customers via API
Prerequisites
Valid merchant API key
Merchant account ID
Customer email and preferable address
When creating a new customer with consumer data, you’re establishing a managed consumer account: const axios = require ( 'axios' );
async function createManagedCustomer () {
try {
const response = await axios . post (
'https://api.paygentic.io/v0/customers' ,
{
merchantId: 'org_YS8jkP59V71TdUvj' ,
consumer: {
name: 'John Doe' ,
email: 'john.doe@example.com' ,
phone: '+1-555-0100' ,
address: {
line1: '123 Main St' ,
city: 'San Francisco' ,
state: 'CA' ,
country: 'US' ,
zipCode: '94105'
}
}
},
{
headers: {
'Authorization' : 'Bearer sk_live_YOUR_API_KEY' ,
'Content-Type' : 'application/json'
}
}
);
console . log ( 'Customer created:' , response . data . customerId );
return response . data . customerId ;
} catch ( error ) {
console . error ( 'Error creating customer:' , error . response ?. data );
throw error ;
}
}
curl -X POST https://api.paygentic.io/v0/customers \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"merchantId": "org_YS8jkP59V71TdUvj",
"consumer": {
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "+1-555-0100",
"address": {
"line1": "123 Main St",
"city": "San Francisco",
"state": "CA",
"country": "US",
"zipCode": "94105"
}
}
}'
import requests
def create_managed_customer ():
url = "https://api.paygentic.io/v0/customers"
headers = {
"Authorization" : "Bearer sk_live_YOUR_API_KEY" ,
"Content-Type" : "application/json"
}
payload = {
"merchantId" : "org_YS8jkP59V71TdUvj" ,
"consumer" : {
"name" : "John Doe" ,
"email" : "john.doe@example.com" ,
"phone" : "+1-555-0100" ,
"address" : {
"line1" : "123 Main St" ,
"city" : "San Francisco" ,
"state" : "CA" ,
"country" : "US" ,
"zipCode" : "94105"
}
}
}
try :
response = requests.post(url, json = payload, headers = headers)
response.raise_for_status()
customer_id = response.json()[ "customerId" ]
print ( f "Customer created: { customer_id } " )
return customer_id
except requests.exceptions.RequestException as e:
print ( f "Error creating customer: { e } " )
raise
If you’ve already created a managed consumer, you can reuse it: async function createCustomerWithExistingConsumer () {
try {
const response = await axios . post (
'https://api.paygentic.io/v0/customers' ,
{
merchantId: 'org_YS8jkP59V71TdUvj' ,
consumerId: 'org_EXISTING_CONSUMER_ID' // Must be managed consumer
},
{
headers: {
'Authorization' : 'Bearer sk_live_YOUR_API_KEY' ,
'Content-Type' : 'application/json'
}
}
);
return response . data . customerId ;
} catch ( error ) {
// Error code 403: Attempting to use unauthorized consumerId
if ( error . response ?. status === 403 ) {
console . error ( 'Cannot use this consumerId - not a managed consumer' );
}
throw error ;
}
}
curl -X POST https://api.paygentic.io/v0/customers \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"merchantId": "org_YS8jkP59V71TdUvj",
"consumerId": "org_EXISTING_CONSUMER_ID"
}'
def create_customer_with_existing_consumer ():
url = "https://api.paygentic.io/v0/customers"
headers = {
"Authorization" : "Bearer sk_live_YOUR_API_KEY" ,
"Content-Type" : "application/json"
}
payload = {
"merchantId" : "org_YS8jkP59V71TdUvj" ,
"consumerId" : "org_EXISTING_CONSUMER_ID" # Must be managed consumer
}
try :
response = requests.post(url, json = payload, headers = headers)
response.raise_for_status()
return response.json()[ "customerId" ]
except requests.exceptions.HTTPError as e:
if e.response.status_code == 403 :
print ( "Cannot use this consumerId - not a managed consumer" )
raise
Idempotency : If a customer already exists for the consumer-merchant pair, the API returns 200 with the existing customer ID instead of creating a duplicate.
Creating subscriptions
Once you have a customer, you can create subscriptions. The plan you choose determines which fees and usage-based prices apply.
Prepaid fees need to be paid before the subscription starts. In the subscription response there will be a payment link where the customer can pay for this charge. The payment link is also present if the subscription has a “prefundAmount”, this should be used to add funds for pay-as-you-go (instantly priced usage billable metrics).
async function createPostpaidSubscription ( customerId , planId ) {
try {
const response = await axios . post (
'https://api.paygentic.io/v0/subscriptions' ,
{
customerId: customerId ,
planId: planId ,
name: 'Monthly API Service' ,
startedAt: new Date (). toISOString (),
prefundAmount: "25"
},
{
headers: {
'Authorization' : 'Bearer sk_live_YOUR_API_KEY' ,
'Content-Type' : 'application/json'
}
}
);
const subscription = response . data ;
console . log ( 'Subscription created:' , subscription . id );
console . log ( 'Payment link (if payment is required):' , subscription . payment ?. checkoutUrl );
return subscription ;
} catch ( error ) {
console . error ( 'Error creating subscription:' , error . response ?. data );
throw error ;
}
}
from datetime import datetime
def create_postpaid_subscription ( customer_id , plan_id ):
url = "https://api.paygentic.io/v0/subscriptions"
headers = {
"Authorization" : "Bearer sk_live_YOUR_API_KEY" ,
"Content-Type" : "application/json"
}
payload = {
"customerId" : customer_id,
"planId" : plan_id, # Must be a postpaid plan
"name" : "Monthly API Service" ,
"startedAt" : datetime.utcnow().isoformat() + "Z" ,
"prefundAmount" : "25"
}
try :
response = requests.post(url, json = payload, headers = headers)
response.raise_for_status()
subscription = response.json()
print ( f "Subscription created: { subscription[ 'id' ] } " )
print ( f "Payment details (if payment is required): { subscription.get( 'payment' ) } " )
return subscription
except requests.exceptions.RequestException as e:
print ( f "Error creating subscription: { e } " )
raise
Customer portal
The customer portal allows your customers to view their subscription details, usage metrics, invoices, and manage payment sources - all within a secure, hosted interface.
Generating portal links
Managed Consumer Portal
Full Platform Access
For managed consumers, generate portal links via the subscription endpoint: async function generatePortalLink ( subscriptionId ) {
try {
const response = await axios . post (
`https://api.paygentic.io/v0/subscriptions/ ${ subscriptionId } /portal` ,
{},
{
headers: {
'Authorization' : 'Bearer sk_live_YOUR_API_KEY' ,
'Content-Type' : 'application/json'
}
}
);
const portalUrl = response . data . url ;
console . log ( 'Portal URL:' , portalUrl );
return portalUrl ;
} catch ( error ) {
console . error ( 'Error generating portal link:' , error . response ?. data );
throw error ;
}
}
curl -X POST https://api.paygentic.io/v0/subscriptions/{subscriptionId}/portal \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
import requests
def generate_portal_link ( subscription_id ):
url = f "https://api.paygentic.io/v0/subscriptions/ { subscription_id } /portal"
headers = {
"Authorization" : "Bearer sk_live_YOUR_API_KEY" ,
"Content-Type" : "application/json"
}
try :
response = requests.post(url, json = {}, headers = headers)
response.raise_for_status()
portal_url = response.json()[ "url" ]
print ( f "Portal URL: { portal_url } " )
return portal_url
except requests.exceptions.RequestException as e:
print ( f "Error generating portal link: { e } " )
raise
This provides read-only access to subscription data, source management, and usage tracking. Full consumer accounts have complete platform access at platform.paygentic.io with:
Account management
Payment method management
Full subscription control
Usage history and invoices
Embedding the portal
You can embed the customer portal directly into your application, providing a seamless experience without redirecting users away.
Setup requirements
Before embedding:
Domain Whitelisting : Contact support@paygentic.io to whitelist your domain(s)
CSP Configuration : Add platform.paygentic.io to your CSP frame-src directive:
Content-Security-Policy: frame-src 'self' https://platform.paygentic.io;
Implementation
<! DOCTYPE html >
< html >
< body >
< iframe
src = "https://platform.paygentic.io/portal/access/PORTAL_ACCESS_TOKEN"
width = "100%"
height = "800px"
sandbox = "allow-scripts allow-same-origin allow-forms allow-popups"
style = "border: none; border-radius: 8px;"
></ iframe >
</ body >
</ html >
export function CustomerPortal ({ portalUrl }) {
return (
< iframe
src = { portalUrl }
width = "100%"
height = "800px"
sandbox = "allow-scripts allow-same-origin allow-forms allow-popups"
style = { { border: 'none' , borderRadius: '8px' } }
/>
);
}
Important:
Portal URLs are single-use - generate a fresh URL for each session or page reload
The sandbox attribute is required for security
Understanding sandbox attributes
The sandbox attribute is required for security:
allow-scripts - Portal functionality
allow-same-origin - Communication with your site
allow-forms - Form submission
allow-popups - 3D Secure authentication
Payment Checkout : To collect one-off payments or embed a payment form in your application, see Payment Portal .
Next steps