Create Checkout
POST/checkoutsDescription
Create a new checkout session for a one-time stablecoin payment. Returns a checkout object containing a checkout_url where you should redirect your customer to complete the payment.
For direct payments, a signatures array is required in the request body (see Signed Requests for SDK setup). For two-step payments, no signature is needed at creation time.
Expiry depends on the payment method. For direct checkouts the expiry is the deadline you
signed into each signatures entry (the SDK defaults it to one hour), so expires_at is derived
from the signed deploy deadline and passing it in the body is rejected. For two-step checkouts
you may set expires_at to an ISO 8601 timestamp; it defaults to 24 hours.
Headers
| Header | Description | Required |
|---|---|---|
| Authorization | Bearer token with your API key | yes |
| Content-Type | application/json | yes |
Request Body
| Name | Type | Description | Required |
|---|---|---|---|
| amount | number | Payment amount in the smallest currency unit (e.g., cents for USD). | yes |
| currency | string | Three-letter ISO currency code for pricing (e.g., "USD", "EUR"). The customer will pay the equivalent in their chosen stablecoin. | yes |
| description | string | Description of the payment shown to the customer. | no |
| success_url | string | URL to redirect the customer after successful payment. | yes |
| cancel_url | string | URL to redirect the customer if they cancel the checkout. | no |
| customer_email | string | Customer email for payment receipt. | no |
| metadata | object | Custom key-value pairs to attach to the checkout. | no |
| expires_at | string | ISO 8601 timestamp for when the checkout should expire. Accepted for `two_step` only (defaults to 24 hours); rejected for `direct`, where the expiry is derived from the signed deploy `deadline`. | no |
| payment_method | string | Payment method: "direct" (funds sent directly to your settlement address, requires signed request) or "two_step" (funds held in escrow for capture or refund via signed requests). | yes |
| signatures | array | Array of per-chain deploy signatures, one entry per chain family, e.g. [{ "chain_family": "evm", "on_chain_id": "0x…", "signature": "0x…", "deadline": 1700000000 }]. The per-entry `deadline` sets the resulting `expires_at`. Required for direct payments; must be omitted for two-step. | direct only |
Example: Direct Payment
import { CheckoutSigner } from '@exodus/checkout-signer'
const signer = new CheckoutSigner()
// Your PaymentFactory address, from GET /settings. Sign a deploy per chain you accept.
const factoryAddress = '0xfaceb00cfaceb00cfaceb00cfaceb00cfaceb00c'
const signatures = signer.createDirectPayment({
factory_addresses: { evm: factoryAddress },
})
// signatures = { evm: { on_chain_id, signature, deadline }, solana: { on_chain_id, signature, deadline } }
const response = await fetch('https://checkout-api.exodus-int.com/checkouts', {
method: 'POST',
headers: {
Authorization: 'Bearer sk_live_xxxxxxxxxxxxxxxx',
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: 5000,
currency: 'USD',
description: 'Order #12345',
payment_method: 'direct',
signatures: [
{
chain_family: 'evm',
on_chain_id: signatures.evm.on_chain_id,
signature: signatures.evm.signature,
deadline: signatures.evm.deadline,
},
],
success_url: 'https://yoursite.com/success',
cancel_url: 'https://yoursite.com/cancel',
}),
})Example: Two-Step Payment
const response = await fetch('https://checkout-api.exodus-int.com/checkouts', {
method: 'POST',
headers: {
Authorization: 'Bearer sk_live_xxxxxxxxxxxxxxxx',
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: 5000,
currency: 'USD',
description: 'Order #12345',
payment_method: 'two_step',
success_url: 'https://yoursite.com/success',
cancel_url: 'https://yoursite.com/cancel',
customer_email: '[email protected]',
metadata: {
order_id: '12345',
product_name: 'Widget',
},
}),
});Response
{
"id": "chk_1234567890abcdef",
"object": "checkout",
"amount": 5000,
"currency": "USD",
"description": "Order #12345",
"payment_method": "two_step",
"status": "pending",
"checkout_url": "https://checkout.exodus-int.com/pay/chk_1234567890abcdef",
"success_url": "https://yoursite.com/success",
"cancel_url": "https://yoursite.com/cancel",
"customer_email": "[email protected]",
"metadata": {
"order_id": "12345",
"product_name": "Widget"
},
"expires_at": "2024-01-16T12:00:00Z",
"created_at": "2024-01-15T12:00:00Z"
}Error Responses
{
"error": {
"type": "validation_error",
"message": "Amount must be greater than 0",
"param": "amount"
}
}