Skip to main content

Create Ramp Intent

Create a standalone ramp intent for on-ramp (buy crypto) or off-ramp (sell crypto). A ramp intent represents a merchant-initiated ramp session that tracks the full lifecycle of a transaction — from creation through to completion or expiry.

POSThttps://api.zenpayz.com/payment/api/v1/ramp-intents
Bearer · API key

Request

Headers

HeaderDescription
Content-Type
REQUIRED
application/json
Authorization
REQUIRED
Bearer {api_key}
x-merchant-id
REQUIRED
Your merchant ID
x-request-id
REQUIRED
Unique request ID for tracing
Authenticated Endpoint

This endpoint requires API key authentication. Include your API key in the Authorization header and your merchant ID in x-merchant-id.

Body Parameters

ParameterTypeDescription
userId
REQUIRED
stringUnique user identifier from your system. Used as the KYC record key.
kycVerified
REQUIRED
booleanWhether you have already verified this user's identity. When true, ZenPays KYC verification is skipped in the widget.
type
REQUIRED
stringbuy (on-ramp) or sell (off-ramp)
wallets
REQUIRED
arrayArray of { network, address } objects (min 1)
fiatCurrency
REQUIRED
stringFiat currency code (e.g. USD, EUR)
cryptoCurrency
OPTIONAL
stringCrypto identifier (e.g. btc_bitcoin, usdt_tron)
amount
OPTIONAL
numberDefault amount (must be positive)
successUrl
OPTIONAL
stringURL to redirect on success
cancelUrl
OPTIONAL
stringURL to redirect on cancel
customerEmail
OPTIONAL
stringCustomer's email address
metadata
OPTIONAL
objectCustom key-value pairs for your reference
KYC Behavior

When kycVerified: true, the checkout widget skips ZenPays KYC verification entirely — use this when your platform has already verified the user's identity.

When kycVerified: false (default), the widget checks the user's KYC status. If unverified, the customer is prompted to complete identity verification before proceeding.

Wallet Object

ParameterTypeDescription
network
REQUIRED
stringBlockchain network (e.g. ethereum, tron, solana)
address
REQUIRED
stringWallet address on the network

Sample Request Body

{
"userId": "usr_abc123",
"kycVerified": false,
"type": "buy",
"wallets": [
{
"network": "ethereum",
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD28"
}
],
"fiatCurrency": "USD",
"cryptoCurrency": "eth_ethereum",
"amount": 100,
"successUrl": "https://yourapp.com/success",
"cancelUrl": "https://yourapp.com/cancel",
"customerEmail": "customer@example.com",
"metadata": {
"orderId": "order_123"
}
}

Response

Success (201 Created)

{
"success": true,
"data": {
"intentId": "ri_1710345678000_a1b2c3d4e5f6g7h8",
"redirectUrl": "https://checkout.zenpayz.com/payments/ramping/widget/ri_1710345678000_a1b2c3d4e5f6g7h8",
"expiresAt": "2026-03-15T10:00:00.000Z"
},
"message": "Ramp intent created"
}

Response Fields

ParameterTypeDescription
intentId
OPTIONAL
stringUnique intent identifier (format: ri_{timestamp}_{hex})
redirectUrl
OPTIONAL
stringURL to redirect the customer to the ramp widget
expiresAt
OPTIONAL
stringISO 8601 expiry timestamp (1 hour from creation)
Intent Expiry

Ramp intents automatically expire 1 hour after creation. Once expired, the intent cannot be used and a new one must be created.

Error Responses

CodeHTTPMessage
VALIDATION_ERROR400Invalid request body or missing required fields
RAMP_INTENT_CREATION_FAILED500Failed to create the ramp intent

Examples

curl -X POST https://api.zenpayz.com/payment/api/v1/ramp-intents \
-H "Content-Type: application/json" \
-H "Authorization: Bearer zp_test_your_api_key" \
-H "x-merchant-id: merch_abc123" \
-H "x-request-id: req_$(date +%s)" \
-d '{
"userId": "usr_abc123",
"kycVerified": false,
"type": "buy",
"wallets": [
{ "network": "ethereum", "address": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD28" }
],
"fiatCurrency": "USD",
"cryptoCurrency": "eth_ethereum",
"amount": 100,
"customerEmail": "customer@example.com",
"successUrl": "https://yourapp.com/success",
"cancelUrl": "https://yourapp.com/cancel"
}'

Intent Status Lifecycle

                    ┌──────────┐
│ created │ ← Initial state
└────┬─────┘

First GET request

┌────▼─────┐
┌────│ active │────┐
│ └────┬─────┘ │
│ │ │
┌────▼────┐ ┌──▼───────┐ ┌▼──────────┐
│cancelled│ │completed │ │ expired │
└─────────┘ └──────────┘ └────────────┘
(terminal states)

Webhook Events

When a ramp intent reaches a terminal state, ZenPay delivers a webhook to your configured endpoint. Configure webhooks in the merchant dashboard under Developer Tools → Webhooks.

Events

EventWhenDescription
ramp.completedBuy: crypto sent to wallet. Sell: fiat payout submitted.The ramp flow finished successfully.
ramp.failedCrypto send or payout submission failed.The ramp flow encountered an error.

Buy Ramp Completed (ramp.completed)

Delivered when crypto has been sent to the customer's wallet address.

{
"event_type": "ramp.completed",
"payment_data": {
"merchant_id": "m_abc123",
"intentId": "ri_1710345678000_a1b2c3d4e5f6g7h8",
"type": "buy",
"status": "completed",
"fiatCurrency": "USD",
"cryptoCurrency": "eth_ethereum",
"amount": 100,
"chain": "ethereum",
"destinationAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD28",
"fireblocksTxId": "fb_tx_9a8b7c6d5e4f",
"completedAt": "2026-03-16T14:30:00.000Z"
}
}

Sell Ramp Completed (ramp.completed)

Delivered when the fiat payout has been submitted to the customer's bank account.

{
"event_type": "ramp.completed",
"payment_data": {
"merchant_id": "m_abc123",
"intentId": "ri_1710345678000_a1b2c3d4e5f6g7h8",
"type": "sell",
"status": "completed",
"fiatCurrency": "USD",
"cryptoCurrency": "usdt_tron",
"amount": 20,
"payoutId": "po_xyz789",
"payoutAmount": 19.50,
"payoutCurrency": "USD",
"completedAt": "2026-03-16T14:30:00.000Z"
}
}

Ramp Failed (ramp.failed)

Delivered when the crypto send (buy) or payout submission (sell) fails.

{
"event_type": "ramp.failed",
"payment_data": {
"merchant_id": "m_abc123",
"intentId": "ri_1710345678000_a1b2c3d4e5f6g7h8",
"type": "buy",
"status": "failed",
"fiatCurrency": "USD",
"cryptoCurrency": "eth_ethereum",
"amount": 100,
"reason": "Crypto send failed",
"failedAt": "2026-03-16T14:30:00.000Z"
}
}

Webhook Payload Fields

ParameterTypeDescription
merchant_id
OPTIONAL
stringYour merchant ID
intentId
OPTIONAL
stringRamp intent ID (ri_...)
type
OPTIONAL
string"buy" or "sell"
status
OPTIONAL
string"completed" or "failed"
fiatCurrency
OPTIONAL
stringISO currency code (e.g. USD, EUR)
cryptoCurrency
OPTIONAL
stringCrypto identifier (e.g. eth_ethereum, usdt_tron)
amount
OPTIONAL
numberOriginal intent amount
completedAt
OPTIONAL
stringISO 8601 completion timestamp
failedAt
OPTIONAL
stringISO 8601 failure timestamp
reason
OPTIONAL
stringHuman-readable failure reason
chain
OPTIONAL
stringBlockchain network (e.g. ethereum, tron)
destinationAddress
OPTIONAL
stringWallet address crypto was sent to
cryptoTxId
OPTIONAL
stringCrypto transaction reference
payoutId
OPTIONAL
stringPayout reference ID
payoutAmount
OPTIONAL
numberFiat amount paid out (after fees)
payoutCurrency
OPTIONAL
stringFiat currency of payout

Webhook Headers

HeaderDescription
X-ZenPay-SignatureHMAC-SHA256 signature of the request body
X-Zenpay-EventEvent type (e.g. ramp.completed)
X-Zenpay-Event-IdUnique delivery ID for deduplication
X-Zenpay-TimestampISO 8601 timestamp of delivery
X-Zenpay-AttemptDelivery attempt number (1, 2, or 3)

See the Webhooks guide for signature verification, retry behavior, and best practices.

Next Steps