Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.centryos.xyz/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Create a payment link for collecting payments from customers. The link can be one-time (default) or recurring. For POST /v1/ext/collections/payment-link, itemDeliveryAddress and cartItems are required, and each cart item must include at least name and description. Endpoint: POST /v1/ext/collections/payment-link Auth: Bearer token with scope external.apis (authorizer: walletos-account-service-{stage}-authorizer).

Default vs recurring

ModeHow to requestResult
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).
RecurringSend checkoutType: "recurring" and a valid recurringCharge object.Payment link that creates a subscription (fixed, consumption, or seating) after the customer completes checkout.
Recurring compatibility: Existing callers that do not send checkoutType or recurringCharge still get one-time payment links.

Request

URL

POST {{LIQUIDITY_URL}}/v1/ext/collections/payment-link

Headers

HeaderRequiredDescription
AuthorizationYesBearer <token> with scope external.apis.
Content-TypeYesapplication/json.

Body (JSON) – common fields

FieldTypeRequiredDescription
currencystringYesCurrency code. Supported: USD, NGN, CAD, GBP, EUR.
namestringNoDisplay name for the link (default: "page").
amountnumberYes*Amount per payment. *For one-time: min 0.5. For recurring subscription: required (min 0.5). For consumption/seating: optional (min 0).
customUrlPathstringNoSlug for the URL (default: "page").
redirectTostringNoURI to redirect after payment (default: "https://www.centryos.xyz").
expiredAtstringNoISO date when the link expires (default: one year from now).
checkoutTypestringNo"generic" (default), "ecommerce", or "recurring". Use "recurring" for recurring payment links.
recurringChargeobjectNo**Required when checkoutType === "recurring". Forbidden otherwise. See Recurring body.
isOpenLinkbooleanNoIf true, link can be used multiple times (default: true).
customerPaysbooleanNoIf true, customer pays fees (default: true).
orderIdstringNoYour order/reference id.
dataCollectionsarrayNoExtra data to collect (e.g. ["Phone number"]). Base set always includes Email, First name, Last name, Phone number.
customFieldsarrayNoCustom field names.
acceptedPaymentOptionsarrayNoe.g. ["card"] (default).
notifyPayeebooleanNoNotify payee (default: false).
agentobjectNoAgent details (type, email, name, etc.) for notifications.
brandingConfigobjectNoLogo, colors, etc.
advancedConfigobjectNowebsiteUrl, webhookPath, webhookSecret for external webhook registration when using /ext path.
customDataobjectNoKey-value metadata (string values only).
itemDeliveryAddressstringYesMerchant-supplied delivery address saved with the payment link and copied into transaction metadata when the customer pays.
cartItemsarrayYesCart items for the payment link. Send at least one item, and each item must include name and description.
externalIdstringNoYour external reference.

Cart items

Each cartItems[] entry must include:
FieldTypeRequiredDescription
namestringYesItem name shown for the order.
descriptionstringYesItem description shown for the order.
qtynumberNoQuantity of the item.
pricenumberNoItem price.
currencystringNoItem currency code.
productIdstringNoYour product identifier.
imageUrlstringNoPublic image URL for the item.

Recurring body

When checkoutType is "recurring", you must send recurringCharge with this shape:
FieldTypeRequiredDescription
typestringYes"subscription", "consumption", or "seating".
startDatestringYesISO date when billing starts (trial end). Must be before expiredAt.
intervalobjectYesBilling interval.
interval.typestringYes"day", "week", "month", or "year".
interval.countnumberYese.g. 1 for monthly.
productIdstringNoProduct ID for recurring billing (optional).
consumptionDetailsobjectYes if type is consumptionSee below.
seatDetailsobjectYes if type is seatingSee below.
When type === "consumption":
FieldTypeRequiredDescription
unitstringYese.g. "API call", "GB".
costPerUnitnumberYesPrice per unit.
minimumUnitsnumberNoIncluded units before charges apply.
baseFeenumberConditionalRequired if minimumUnits is set.
When type === "seating":
FieldTypeRequiredDescription
baseFeenumberYesFixed fee per period.
costPerSeatnumberYesPrice per seat.
newSeatBillingTypestringYes"prorate", "next_cycle", or "immediate".

Examples

All POST /v1/ext/collections/payment-link examples below include the required itemDeliveryAddress and cartItems fields.
curl -X POST "{{LIQUIDITY_URL}}/v1/ext/collections/payment-link" \
  -H "Authorization: Bearer {{accessToken}}" \
  -H "Content-Type: application/json" \
  -d '{
    "currency": "USD",
    "name": "One-time donation",
    "amount": 25.00,
    "customUrlPath": "donate",
    "redirectTo": "https://example.com/thanks",
    "itemDeliveryAddress": "123 Main St, Austin, TX, 78701, US",
    "cartItems": [
      {
        "name": "Hourly service",
        "description": "One hour of service",
        "price": 25.00,
        "currency": "USD"
      }
    ]
  }'
Omit checkoutType and recurringCharge to get the existing one-time behavior.

Recurring – fixed subscription

{
  "currency": "USD",
  "name": "Monthly plan",
  "amount": 29.99,
  "customUrlPath": "monthly-plan",
  "redirectTo": "https://example.com/thanks",
  "itemDeliveryAddress": "123 Main St, Austin, TX, 78701, US",
  "cartItems": [
    {
      "name": "Monthly plan seat",
      "description": "Monthly subscription access",
      "price": 29.99,
      "currency": "USD"
    }
  ],
  "checkoutType": "recurring",
  "recurringCharge": {
    "type": "subscription",
    "startDate": "2026-02-01",
    "interval": { "type": "month", "count": 1 }
  }
}

Recurring – consumption (usage-based)

{
  "currency": "USD",
  "name": "API usage",
  "amount": 0,
  "customUrlPath": "api-usage",
  "redirectTo": "https://example.com/thanks",
  "itemDeliveryAddress": "123 Main St, Austin, TX, 78701, US",
  "cartItems": [
    {
      "name": "API usage plan",
      "description": "Usage-based billing plan",
      "price": 0,
      "currency": "USD"
    }
  ],
  "checkoutType": "recurring",
  "recurringCharge": {
    "type": "consumption",
    "startDate": "2026-02-01",
    "interval": { "type": "month", "count": 1 },
    "consumptionDetails": {
      "unit": "API call",
      "costPerUnit": 0.10,
      "minimumUnits": 1000,
      "baseFee": 20
    }
  }
}

Recurring – seating (per-seat)

{
  "currency": "USD",
  "name": "Team plan",
  "amount": 0,
  "customUrlPath": "team-plan",
  "redirectTo": "https://example.com/thanks",
  "itemDeliveryAddress": "123 Main St, Austin, TX, 78701, US",
  "cartItems": [
    {
      "name": "Team plan base seat",
      "description": "Seat-based team subscription",
      "price": 0,
      "currency": "USD"
    }
  ],
  "checkoutType": "recurring",
  "recurringCharge": {
    "type": "seating",
    "startDate": "2026-02-01",
    "interval": { "type": "month", "count": 1 },
    "seatDetails": {
      "baseFee": 20,
      "costPerSeat": 5,
      "newSeatBillingType": "prorate"
    }
  }
}

Response

Success (200)

{
  "success": true,
  "data": {
    "url": "<checkout-widget-url>",
    "application": {
      "id": "<payment-link-uuid>",
      "token": "<token>",
      "tokenType": "<type>",
      "expiredAt": "<ISO-date>",
      "valid": true
    }
  }
}
  • data.url is 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)

{
  "success": false,
  "message": "<error detail or validation errors>",
  "fatal": true
}
SituationHTTPNotes
Unauthorized401Invalid or expired token, or missing external.apis scope.
Validation error400Missing/invalid fields (e.g. amount, currency, itemDeliveryAddress, cartItems, or recurringCharge when checkoutType is recurring).
recurringCharge when not recurring400recurringCharge is only allowed when checkoutType is "recurring".
Missing recurringCharge400When checkoutType is "recurring", recurringCharge is required with valid type, startDate, interval, and type-specific details.
Collection account not found400No collection account for the business/currency.
Server error500e.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 for consumption/seating (min 0).
  • itemDeliveryAddress – Required on POST /v1/ext/collections/payment-link.
  • cartItems – Required on POST /v1/ext/collections/payment-link; send at least one item, and each item must include name and description.
  • checkoutType – Optional. Default: "generic". Use "recurring" for recurring payment links.
  • recurringCharge – Allowed only when checkoutType === "recurring". Required then, with type, startDate, interval; plus consumptionDetails or seatDetails depending on type.
  • 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

  • External API request fields: itemDeliveryAddress and cartItems are required on POST /v1/ext/collections/payment-link. Each cart item must include at least name and description.
  • Recurring via External API: Create payment link supports checkoutType: "recurring" and recurringCharge on POST /v1/ext/collections/payment-link. Default remains one-time when these fields are omitted (no breaking changes).