Skip to content

API Checkout Integration Guide

Overview

API Checkout gives you complete control over the payment UI. Instead of redirecting customers to a PSC-hosted page, you build your own checkout experience. PSC handles the on-chain payment infrastructure — generating deposit addresses, monitoring blockchain confirmations, and notifying you when payment is complete.

Best for:

  • Merchants who need a fully branded, seamless checkout experience
  • Native mobile apps or single-page applications where browser redirects are disruptive
  • Accepting on-chain stablecoin transfers (USDC, USDT, USD1) directly

PERMISSION REQUIRED

API Checkout is a separate product that must be explicitly enabled. Contact technical support to activate it. Requests will return error code 50010 (API_PERMISSION_DISABLED) until activated.


How It Works

Merchant UI          Merchant Server              PSC API
      |                    |                          |
      |                    |--- GET payment methods -->|
      |                    |<-- methods list ----------|
      |<-- render picker --|                           |
      |-- user selects --->|                           |
      |                    |--- POST /checkout/orders ->|
      |                    |<-- depositAddress ---------|
      |<-- show address + --|                           |
      |   amount + timer   |                           |
      |                    |                           |
      |   (user sends crypto on-chain)                 |
      |                    |                           |
      |                    |<--- POST webhook ----------|
      |                    |--- {"code":"00000"} ------>|
      |<-- update status --|                           |

Step 1: Fetch Available Payment Methods

Before rendering your payment UI, fetch the methods available for your merchant account. This must be called at runtime — do not hardcode currency/network combinations.

bash
curl -X GET "https://api.paystablecoin.global/api/v1/merchants/MCH_20240101_ABC123/checkout/payment-methods" \
  -H "X-Timestamp: 1640000000000" \
  -H "X-Signature: <calculated-signature>"

Useful fields from the response:

FieldUse
cryptoCurrencyCurrency to display (USDC / USDT / USD1)
networkNetwork code to pass when creating the order
networkDisplayNameHuman-readable name for display (e.g. "TRON Network")
minAmount / maxAmountValidate the order amount before creation
estimatedConfirmationTimeSecShow confirmation time estimate to the customer
displayOrderSort your UI by this field (ascending)

Step 2: Build Your Payment Method Selector

Render the available options in your checkout UI. At minimum show:

  • The cryptocurrency (USDC / USDT / USD1)
  • The network name (networkDisplayName)
  • The estimated confirmation time

Only show combinations returned by Get Payment Methods — availability depends on your merchant configuration and can change.


Step 3: Create a Checkout Order

Once the customer selects a currency and network, create the order immediately:

bash
curl -X POST https://api.paystablecoin.global/api/v1/merchants/MCH_20240101_ABC123/checkout/orders \
  -H "X-Timestamp: 1640000000000" \
  -H "X-Signature: <calculated-signature>" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantOrderId": "ORDER_2024010112345678",
    "orderAmount": { "value": "100.50", "currency": "USDC" },
    "paymentMethodType": "ON_CHAIN_TRANSFER",
    "network": "tron",
    "expiresAt": "2024-01-01T13:00:00Z",
    "callbackUrl": "https://your-server.com/webhook/checkout"
  }'

Key parameters:

ParameterNotes
merchantOrderIdMust be unique per merchant. Same ID = returns existing order (idempotency)
orderAmount.currencyMust be a stablecoin: USDC, USDT, or USD1 — fiat currencies are not supported
networkMust match the customer's selected method and form a valid combination with orderAmount.currency
expiresAtRecommended: 30 minutes from now. Maximum: 24 hours
callbackUrlStrongly recommended — your webhook endpoint for payment notifications

Step 4: Display the Deposit Screen

Use the response to build the payment screen the customer sees:

Response fieldHow to display
data.depositAddressShow as both text and a QR code
data.cryptoPaymentAmount.valueThe exact amount the customer must send
data.cryptoPaymentAmount.currencyShow alongside the amount
data.networkDisplayNameShow prominently — sending on the wrong network results in lost funds
data.expiresAtDrive a live countdown timer

WARNING

Always display cryptoPaymentAmount, not orderAmount. They may differ due to fees. The customer must send at least cryptoPaymentAmount.value — sending less causes the order to fail.


Step 5: Receive and Verify the Webhook

When PSC detects and confirms the on-chain transaction, it calls your callbackUrl.

Signature verification — before processing any business logic:

  1. Extract X-Timestamp and X-Signature from the request headers
  2. Read the raw request body as a string
  3. Compute: Base64(HMAC-SHA256(timestamp + "\n" + requestBody, apiSecret))
  4. Compare the computed value with X-Signature
  5. Verify X-Timestamp is within 5 minutes of the current time

Response requirement — for API Checkout webhooks, the response body is required:

json
{
  "code": "00000"
}

Your endpoint must respond with HTTP 200 and this body within 5 seconds. Any other response or timeout triggers a retry. See API Checkout Reference for the full retry schedule.

Use acquiringOrderId or merchantOrderId to deduplicate — the same event may be delivered more than once.


Step 6: Handle Order Expiry

If expiresAt passes without a detected payment, the order status becomes CLOSED. You should:

  • Stop the countdown timer and update your UI when it reaches zero
  • Stop displaying the deposit address
  • Let the customer start a new order if they still want to pay

Polling as a Fallback

If your server does not receive a webhook (network issues, misconfigured callbackUrl), poll the order status every 5–10 seconds:

bash
curl -X GET "https://api.paystablecoin.global/api/v1/merchants/MCH_20240101_ABC123/checkout/orders/ORDER_2024010112345678" \
  -H "X-Timestamp: 1640000000000" \
  -H "X-Signature: <calculated-signature>"

Stop polling when status reaches a final state: SUCCEEDED, FAILED, or CLOSED.


Key Checklist

  • [ ] Call Get Payment Methods at runtime — never hardcode currency/network combinations
  • [ ] Display cryptoPaymentAmount (not orderAmount) to the customer
  • [ ] Show networkDisplayName prominently to avoid wrong-network transfers
  • [ ] Implement a countdown timer driven by expiresAt
  • [ ] Verify X-Signature on every incoming webhook before processing
  • [ ] Respond to webhooks with HTTP 200 + {"code":"00000"} within 5 seconds
  • [ ] Handle duplicate webhook delivery using acquiringOrderId or merchantOrderId
  • [ ] Implement polling as a fallback in case webhooks are not received

Released under the MIT License.