Quickstart
Create a crypto payment intent from your backend and retrieve it by its Relay transaction ID.
Before you begin#
You need:
- an active Relay organization;
- an organization API key;
- an approved settlement destination for the asset, or an external destination address supplied in the request; and
- a network and token returned by the active-assets endpoint.
Use the production base URL below. Relay may give you a different URL for a controlled test environment.
https://bridge.relayfinance.io1. List active payment assets#
Do not hard-code asset availability. Query Relay when you build or refresh your checkout configuration.
curl --request GET \
--url https://bridge.relayfinance.io/payment/get-active-payment-intents-currency \
--header 'accesskey: YOUR_ORGANIZATION_API_KEY'{
"success": true,
"data": [
{
"name": "Tether USD",
"network": "tron",
"token": "USDT"
}
],
"meta": {
"requestId": "60739e1b-997e-4bce-bdfd-15ad9fafc3bb"
}
}2. Create a payment intent#
This example asks the customer to fund a temporary TRON address, then sends the confirmed proceeds to an external address.
The path is currently case-sensitive: use
/payment/create-crypto-Payment-Intentexactly as shown.
curl --request POST \
--url https://bridge.relayfinance.io/payment/create-crypto-Payment-Intent \
--header 'Content-Type: application/json' \
--header 'accesskey: YOUR_ORGANIZATION_API_KEY' \
--data '{
"amount": 125.50,
"txRef": "order-1042",
"type": "crypto",
"direction": "deposit",
"cryptonetwork": "tron",
"cryptotoken": "USDT",
"metadata": { "orderId": "1042" },
"useremail": "buyer@example.com",
"postTransactionType": "external_wallet",
"postTransactionAddress": "TQ9ExampleDestinationAddress"
}'Relay returns HTTP 201 Created. Use data.tempWallet[0].address as the deposit address and data.expectedAmount as the exact amount the customer must send.
{
"success": true,
"data": {
"txRef": "order-1042",
"type": "crypto",
"direction": "deposit",
"cryptonetwork": "tron",
"cryptotoken": "USDT",
"expectedAmount": "126.75",
"originalAmount": "126.75",
"confirmedAmount": "0",
"outstandingAmount": "126.75",
"status": "pending",
"txId": "RLY-01J9Y7Y9F4M6",
"tempWallet": [
{
"address": "TX1ExampleDepositAddress",
"network": "tron",
"id": "wallet_example"
}
]
},
"meta": {
"requestId": "72328264-aa68-4c0d-8553-811a1d25ca62"
}
}The quoted expectedAmount can be greater than the requested amount because it includes the fee calculated for the organization and asset. Treat Relay's returned decimal string as authoritative.
3. Retrieve the intent#
Store txId, not the temporary wallet address, as your Relay resource identifier.
const response = await fetch(
"https://bridge.relayfinance.io/payment/get-payment-intent/RLY-01J9Y7Y9F4M6",
{
headers: { accesskey: process.env.RELAY_ACCESS_KEY },
},
);
const body = await response.json();
if (!response.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
console.log(body.data.status, body.data.confirmedAmount);The retrieval response uses the same payment object as creation. A successful HTTP response only means the lookup succeeded; inspect data.status, data.confirmedAmount, and data.settlementStatus for the business state.
4. Add webhooks#
Configure a public HTTPS endpoint in the Relay dashboard. Verify Relay-Signature against the exact raw request body, acknowledge with any 2xx response, and deduplicate by Relay-Event-Id.
Continue with webhook verification before using events in production.