Overview
Create a payment link for collecting payments from customers. The link can be one-time (default) or recurring. Same handler and validation as the internal create payment link; default behavior is one-time with no breaking changes. Endpoint:POST /v1/ext/collections/payment-link
Auth: Bearer token with scope external.apis (authorizer: walletos-account-service-{stage}-authorizer).
Default vs recurring
| Mode | How to request | Result |
|---|---|---|
| One-time (default) | Omit checkoutType and recurringCharge, or send checkoutType: "generic". | Single-use or multi-use payment link; customer pays once (or multiple times if isOpenLink is true). |
| Recurring | Send checkoutType: "recurring" and a valid recurringCharge object. | Payment link that creates a subscription (fixed, consumption, or seating) after the customer completes checkout. |
checkoutType or recurringCharge continue to get one-time payment links.
Request
URL
Headers
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer <token> with scope external.apis. |
Content-Type | Yes | application/json. |
Body (JSON) – common fields
| Field | Type | Required | Description |
|---|---|---|---|
currency | string | Yes | Currency code. Supported: USD, NGN, CAD, GBP, EUR. |
name | string | No | Display name for the link (default: "page"). |
amount | number | Yes* | Amount per payment. *For one-time: min 0.5. For recurring subscription: required (min 0.5). For consumption/seating: optional (min 0). |
customUrlPath | string | No | Slug for the URL (default: "page"). |
redirectTo | string | No | URI to redirect after payment (default: "https://www.centryos.xyz"). |
expiredAt | string | No | ISO date when the link expires (default: one year from now). |
checkoutType | string | No | "generic" (default), "ecommerce", or "recurring". Use "recurring" for recurring payment links. |
recurringCharge | object | No** | Required when checkoutType === "recurring". Forbidden otherwise. See Recurring body. |
isOpenLink | boolean | No | If true, link can be used multiple times (default: true). |
customerPays | boolean | No | If true, customer pays fees (default: true). |
orderId | string | No | Your order/reference id. |
dataCollections | array | No | Extra data to collect (e.g. ["Phone number"]). Base set always includes Email, First name, Last name, Phone number. |
customFields | array | No | Custom field names. |
acceptedPaymentOptions | array | No | e.g. ["card"] (default). |
notifyPayee | boolean | No | Notify payee (default: false). |
agent | object | No | Agent details (type, email, name, etc.) for notifications. |
brandingConfig | object | No | Logo, colors, etc. |
advancedConfig | object | No | websiteUrl, webhookPath, webhookSecret for external webhook registration when using /ext path. |
customData | object | No | Key-value metadata (string values only). |
cartItems | array | No | Cart items; if present, total amount is derived from cart and amount can be omitted per validation. |
externalId | string | No | Your external reference. |
Recurring body
WhencheckoutType is "recurring", you must send recurringCharge with this shape:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | "subscription", "consumption", or "seating". |
startDate | string | Yes | ISO date when billing starts (trial end). Must be before expiredAt. |
interval | object | Yes | Billing interval. |
interval.type | string | Yes | "day", "week", "month", or "year". |
interval.count | number | Yes | e.g. 1 for monthly. |
productId | string | No | Product ID for recurring billing (optional). |
consumptionDetails | object | Yes if type is consumption | See below. |
seatDetails | object | Yes if type is seating | See below. |
type === "consumption":
| Field | Type | Required | Description |
|---|---|---|---|
unit | string | Yes | e.g. "API call", "GB". |
costPerUnit | number | Yes | Price per unit. |
minimumUnits | number | No | Included units before charges apply. |
baseFee | number | Conditional | Required if minimumUnits is set. |
type === "seating":
| Field | Type | Required | Description |
|---|---|---|---|
baseFee | number | Yes | Fixed fee per period. |
costPerSeat | number | Yes | Price per seat. |
newSeatBillingType | string | Yes | "prorate", "next_cycle", or "immediate". |
Examples
One-time payment link (default)
checkoutType and recurringCharge to get the existing one-time behavior.
Recurring – fixed subscription
Recurring – consumption (usage-based)
Recurring – seating (per-seat)
Response
Success (200)
data.urlis the payment link URL to share with customers.- For recurring links, after the customer completes checkout (payment method saved), a subscription is created and billing follows the configured interval and type.
Error (4xx / 5xx)
| Situation | HTTP | Notes |
|---|---|---|
| Unauthorized | 401 | Invalid or expired token, or missing external.apis scope. |
| Validation error | 400 | Missing/invalid fields (e.g. amount, currency, or recurringCharge when checkoutType is recurring). |
| recurringCharge when not recurring | 400 | recurringCharge is only allowed when checkoutType is "recurring". |
| Missing recurringCharge | 400 | When checkoutType is "recurring", recurringCharge is required with valid type, startDate, interval, and type-specific details. |
| Collection account not found | 400 | No collection account for the business/currency. |
| Server error | 500 | e.g. database or downstream failure. |
Validation summary
- currency – Required, one of supported types.
- amount – Required for one-time and for recurring
subscription(min 0.5). Optional forconsumption/seating(min 0). - checkoutType – Optional. Default:
"generic". Use"recurring"for recurring payment links. - recurringCharge – Allowed only when
checkoutType === "recurring". Required then, withtype,startDate,interval; plusconsumptionDetailsorseatDetailsdepending ontype. - startDate – Must be before
expiredAt.
Recurring billing behavior
For recurring links, the customer is first asked to save a payment method (no charge at link use). When the setup succeeds, a subscription is created and charges follow the configured model (subscription, consumption, or seating). Billing cycles, seat changes, and usage reporting follow the platform’s recurring payments behavior.Changelog
- Recurring via External API: Create payment link supports
checkoutType: "recurring"andrecurringChargeonPOST /v1/ext/collections/payment-link. Default remains one-time when these fields are omitted (no breaking changes).