Skip to content

Create a payment

POST
/payments/create
curl --request POST \
--url https://hub.stablezact.com/api/v1/payments/create \
--header 'Content-Type: application/json' \
--header 'X-Public-Key: <X-Public-Key>' \
--data '{ "amount": 1, "currency": "USDT", "network": "ethereum", "customerEmail": "hello@example.com", "callbackUrl": "https://example.com", "orderId": "example", "metadata": { "additionalProperty": "example" }, "agentId": "example", "agentOwner": "example" }'

Idempotent. The server recognises a repeat using the first of these it finds: an Idempotency-Key header, an orderId in the body, or a fingerprint of the whole body. The versioned and unversioned paths share a key, so retrying against either does not create a second payment.

Idempotency-Key
string
<= 200 characters

Preferred way to make a retry safe.

Media typeapplication/json
object
amount
required
One of:
number
currency

Validation accepts four values, but only USDC and USDT are configured on any network. DAI and BUSD pass validation and then fail with “Currency DAI is not supported on the base network”.

string
default: USDT
Allowed values: USDT USDC DAI BUSD
network

Case-insensitive. You must have a settlement wallet configured for the network, or the request is rejected naming it.

string
default: ethereum
Allowed values: ethereum bsc polygon optimism arbitrum avalanche base celo solana tron algorand monad linea scroll unichain zksync
customerEmail

Optional. Normalised before storage.

string format: email
callbackUrl

Where webhooks for this payment are delivered.

string format: uri
orderId

Your own reference. Also used to recognise a retry when no Idempotency-Key header is sent, so keep it at the top level rather than inside metadata, which is ignored for that purpose.

string
<= 100 characters
metadata

Arbitrary key/value data returned on reads and included in webhooks. Must be an object, not an array. Values may be strings, numbers, booleans or null.

object
key
additional properties
string | number | boolean | null
agentId

For agent-initiated payments. Must be sent with agentOwner.

string
<= 100 characters /^[a-zA-Z0-9_-]+$/
agentOwner

Must be sent with agentId. Sending one without the other is rejected.

string
<= 100 characters

Payment created.

Media typeapplication/json
object
success
boolean
requestId
string
amount
number
payment

Includes a contractCall block with everything needed to submit the payment on chain: contract address, function name, parameters and whether an approval is required.

object
Examplegenerated
{
"success": true,
"requestId": "example",
"amount": 1,
"payment": {}
}

The request was rejected. Read error and message.

Media typeapplication/json
object
success
boolean
error
required

Short machine-ish reason.

string
message

Longer explanation, when there is one.

string
Example
{
"success": false,
"error": "Validation failed",
"message": "Unsupported currency: GBP"
}

Missing or invalid credentials.

Media typeapplication/json
object
success
boolean
error
required

Short machine-ish reason.

string
message

Longer explanation, when there is one.

string
Example
{
"error": "API credentials required. Use x-public-key header or x-api-key and x-api-secret headers."
}