Skip to main content
Sending a cross-border payment with RemitFlex takes four steps: confirm the corridor is open, get a live conversion quote, submit the payment, then monitor its progress until fiat lands in your recipient’s account. This guide walks you through each step with working code examples.

Prerequisites

  • A RemitFlex account with an active API key
  • Your recipient’s bank details (IBAN or local account number, BIC/SWIFT or local routing code)
  • Sufficient stablecoin balance in your RemitFlex wallet

1
Step 1: Check corridor availability
2
Before creating a payment, verify that RemitFlex supports the source-to-destination corridor. Pass source and destination as ISO 3166-1 alpha-2 country codes.
3
curl
curl -G https://api.remitflex.com/v1/corridors \
  -d source=US \
  -d destination=MX \
  -H "Authorization: Bearer YOUR_API_KEY"
JavaScript
const response = await fetch(
  'https://api.remitflex.com/v1/corridors?source=US&destination=MX',
  {
    headers: {
      Authorization: 'Bearer YOUR_API_KEY',
    },
  }
);

const data = await response.json();
console.log(data);
4
Expected response
5
{
  "source_country": "US",
  "destination_country": "MX",
  "available": true,
  "supported_currencies": ["USDC", "USDT"],
  "destination_currencies": ["MXN"],
  "estimated_delivery_hours": 24
}
6
If available is false, the corridor may be temporarily suspended for compliance reasons or scheduled maintenance. Check the RemitFlex status page for updates.
7
8
Step 2: Get a conversion quote
9
Request a live exchange rate for your payment. The quote locks the rate for 30 seconds — execute your payment before it expires or you will need to request a new one.
10
curl
curl -X POST https://api.remitflex.com/v1/conversions/quote \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from_currency": "USDC",
    "to_currency": "MXN",
    "amount": 500
  }'
JavaScript
const response = await fetch(
  'https://api.remitflex.com/v1/conversions/quote',
  {
    method: 'POST',
    headers: {
      Authorization: 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      from_currency: 'USDC',
      to_currency: 'MXN',
      amount: 500,
    }),
  }
);

const quote = await response.json();
console.log(quote);
11
Expected response
12
{
  "quote_id": "qt_01HX9M2P4KZBN8VXQR7YWT3CD",
  "from_currency": "USDC",
  "to_currency": "MXN",
  "amount": 500,
  "converted_amount": 8537.50,
  "exchange_rate": 17.075,
  "fee": 1.25,
  "fee_currency": "USDC",
  "expires_at": "2024-01-15T10:30:30Z",
  "created_at": "2024-01-15T10:30:00Z"
}
13
Save the quote_id — you’ll reference it when creating the payment.
14
15
Step 3: Create the payment
16
Submit the payment using the quote_id from the previous step alongside your recipient details. The rate is locked at the quoted price as long as you submit within the 30-second window.
17
curl
curl -X POST https://api.remitflex.com/v1/payments \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "quote_id": "qt_01HX9M2P4KZBN8VXQR7YWT3CD",
    "amount": 500,
    "currency": "USDC",
    "destination_currency": "MXN",
    "reference": "invoice-2024-0042",
    "recipient": {
      "name": "Maria García López",
      "account_number": "002180700951485075",
      "bank_code": "BNMXMXMM",
      "bank_country": "MX"
    }
  }'
JavaScript
const response = await fetch('https://api.remitflex.com/v1/payments', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    quote_id: 'qt_01HX9M2P4KZBN8VXQR7YWT3CD',
    amount: 500,
    currency: 'USDC',
    destination_currency: 'MXN',
    reference: 'invoice-2024-0042',
    recipient: {
      name: 'Maria García López',
      account_number: '002180700951485075',
      bank_code: 'BNMXMXMM',
      bank_country: 'MX',
    },
  }),
});

const payment = await response.json();
console.log(payment);
18
Expected response
19
{
  "id": "pmt_01HX4N3RKVZWP9QJDB6CTYMX8",
  "status": "pending",
  "amount": 500,
  "currency": "USDC",
  "destination_currency": "MXN",
  "converted_amount": 8537.50,
  "exchange_rate": 17.075,
  "fee": 1.25,
  "recipient": {
    "name": "Maria García López",
    "account_number": "002180700951485075",
    "bank_code": "BNMXMXMM",
    "bank_country": "MX"
  },
  "reference": "invoice-2024-0042",
  "estimated_delivery": "2024-01-16T10:30:00Z",
  "created_at": "2024-01-15T10:30:05Z",
  "updated_at": "2024-01-15T10:30:05Z"
}
20
Store the payment id (prefixed pmt_) to poll for status updates or correlate incoming webhook events.
21
22
Step 4: Monitor payment status
23
Poll the payment endpoint or listen for webhook events to track progress from pending through to delivered.
24
curl
curl https://api.remitflex.com/v1/payments/pmt_01HX4N3RKVZWP9QJDB6CTYMX8 \
  -H "Authorization: Bearer YOUR_API_KEY"
JavaScript
const response = await fetch(
  'https://api.remitflex.com/v1/payments/pmt_01HX4N3RKVZWP9QJDB6CTYMX8',
  {
    headers: {
      Authorization: 'Bearer YOUR_API_KEY',
    },
  }
);

const payment = await response.json();
console.log(payment.status);

Required recipient fields

The recipient object must include these fields for fiat delivery:
FieldTypeRequiredDescription
namestring✅ YesRecipient’s full legal name
account_numberstring✅ YesIBAN (Europe) or local account number
bank_codestring✅ YesBIC/SWIFT code or local routing number
bank_countrystring✅ YesISO 3166-1 alpha-2 country code (e.g., MX, DE)
addressobjectNoPostal address — required by some corridors for compliance

Payment object reference

Every payment response contains these fields:
FieldTypeDescription
idstringUnique payment ID, prefixed pmt_
statusstringCurrent lifecycle status (see below)
amountnumberSource amount sent
currencystringSource currency (e.g., USDC)
destination_currencystringDestination fiat or stablecoin
converted_amountnumberAmount delivered to the recipient
exchange_ratenumberFX rate applied at execution
feenumberRemitFlex fee charged in currency
recipientobjectRecipient bank details
referencestringYour reference string, echoed back
estimated_deliverystringISO 8601 timestamp for expected delivery
created_atstringISO 8601 creation timestamp
updated_atstringISO 8601 timestamp of last status change

Payment status descriptions

StatusMeaning
pendingPayment received and queued for processing
processingFunds are being moved and FX conversion is in progress
settledStablecoin leg has settled on-chain
deliveredFiat has been deposited into the recipient’s bank account
failedPayment could not be completed (see failure_reason)
cancelledPayment was cancelled before processing began

Handling payment failures

If a payment reaches failed status, the response includes a failure_reason field explaining the cause. Common reasons include quote expiry, insufficient balance, and recipient bank rejection. If the quote has expired:
{
  "id": "pmt_01HX4N3RKVZWP9QJDB6CTYMX8",
  "status": "failed",
  "failure_reason": "QUOTE_EXPIRED",
  "failure_message": "The quote qt_01HX9M2P... expired before the payment was submitted."
}
Request a fresh quote and resubmit the payment:
JavaScript
async function sendPaymentWithRetry(paymentDetails, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    // Get a fresh quote
    const quoteRes = await fetch('https://api.remitflex.com/v1/conversions/quote', {
      method: 'POST',
      headers: {
        Authorization: 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        from_currency: paymentDetails.currency,
        to_currency: paymentDetails.destination_currency,
        amount: paymentDetails.amount,
      }),
    });
    const quote = await quoteRes.json();

    // Submit payment immediately with the new quote
    const paymentRes = await fetch('https://api.remitflex.com/v1/payments', {
      method: 'POST',
      headers: {
        Authorization: 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ ...paymentDetails, quote_id: quote.quote_id }),
    });
    const payment = await paymentRes.json();

    if (payment.status !== 'failed' || payment.failure_reason !== 'QUOTE_EXPIRED') {
      return payment;
    }
  }
  throw new Error('Payment failed after maximum retries');
}
Always fetch a new quote immediately before retrying — do not reuse an expired quote_id. Each quote is valid for 30 seconds from created_at.
For production workloads, consider listening to webhook events instead of polling. Webhooks deliver real-time status updates to your server without additional API calls.