Creating Payments

Create a payment and redirect your customer to the hosted checkout.

Endpoint

POST/v1/payment

Rate limit: 60 requests per minute. Requires authentication.

Request

curl -X POST https://api.cloakd.ai/v1/payment \
  -H "X-API-Key: sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-2026-001-1735905600" \
  -d '{
    "pay_amount": "100.00",
    "order_id": "ORDER-2026-001",
    "order_description": "Premium Subscription",
    "success_url": "https://yoursite.com/success",
    "cancel_url": "https://yoursite.com/cancel",
    "expiration_minutes": 60
  }'
FieldRequiredDescription
pay_amountYesAmount in your settlement currency (string, e.g. "100.00")
order_idYesYour internal order or invoice ID (max 255 chars)
order_descriptionNoHuman-readable description shown on the checkout (max 1000 chars)
callback_urlNoWebhook URL for this payment (overrides your default)
success_urlNoRedirect URL after successful payment
cancel_urlNoRedirect URL if the customer cancels
expiration_minutesNoExpiration time in minutes (5–1440, default: 60)
customer_emailNoCustomer email for receipts

Response

{
  "id": "cm9x8y7z6a5b4c3d2e1f0g1h",
  "token_id": "abc123def456",
  "order_id": "ORDER-2026-001",
  "checkout_url": "https://pay.cloakd.ai/checkout/abc123def456",
  "status": "WAITING",
  "pay_amount": "100.00",
  "pay_currency": "USDT",
  "pay_network": "ethereum",
  "actually_paid": null,
  "actually_paid_currency": null,
  "created_at": "2026-01-03T10:00:00.000Z",
  "expires_at": "2026-01-03T11:00:00.000Z",
  "settled_at": null
}

Redirect your customer to the checkout_url to complete payment.

Store the id in your database alongside your order. You will need it to check status and match webhook events.

Payment lifecycle

StatusMeaningWhat to do
WAITINGPayment created, waiting for customerShow the checkout_url to the customer
PENDINGCustomer initiated payment, awaiting blockchain confirmationMonitor via webhook
CONFIRMINGTransaction detected, waiting for confirmationsWait — do not fulfill yet
SETTLEDPayment fully confirmed and settledDeliver goods or services
EXPIREDPayment expired before completionCreate a new payment if needed
FAILEDTechnical failureContact support or retry

Idempotency

Always include an Idempotency-Key header when creating payments. If a network timeout causes you to retry the same request, the key prevents duplicate payments being created.

// Node.js example
const idempotencyKey = `order-${orderId}-${Date.now()}`;

await fetch('https://api.cloakd.ai/v1/payment', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.CLOAKD_API_KEY,
    'Content-Type': 'application/json',
    'Idempotency-Key': idempotencyKey,
  },
  body: JSON.stringify(paymentData),
});

Checking payment status

Use GET /v1/payment/:id to query a specific payment. For ongoing status updates, prefer webhooks over polling.

curl -X GET https://api.cloakd.ai/v1/payment/cm9x8y7z6a5b4c3d2e1f0g1h \
  -H "X-API-Key: sk_live_your_api_key"

Best practices

  • Store the payment id in your database alongside your order ID as soon as you create it.
  • Never calculate the amount client-side — always compute it on your server before calling the API.
  • Use webhooks for settlement detection instead of polling GET /v1/payment/:id repeatedly.
  • Set expiration_minutes based on your use case: 15–30 minutes for digital goods, 60+ for physical items.
  • Implement exponential backoff and respect the Retry-After header when you receive a 429 response.