Create Quote

Overview

Generate a price quote for a payment before creating a checkout. This endpoint provides real-time exchange rates, payment method details, and the exact amount your customer will pay.

Use quotes to:

  • Show accurate pricing to customers before they commit
  • Display exchange rates and fees transparently
  • Build custom checkout flows with upfront pricing
  • Lock in rates for a short period (quotes are valid for 30 seconds)

When to use: When you want to show customers the exact amount they'll pay in their chosen currency before starting the checkout process.


Authentication

Type: API Key (required)

Required Headers

Header Required Description
Authorization Yes Format: Bearer sk_test_... or Bearer sk_live_...
Content-Type Yes Must be application/json

Request

Method & Path

POST /api/v1/payments/quotes

Request Body

{
  "pricing": {
    "base_currency": "USD",
    "amount": "50.00"
  },
  "payment_method": "bank_transfer",
  "to_currency": "NGN",
  "payment_rail": "kora",
  "customer_email": "customer@example.com",
  "customer_name": "John Doe"
}

Request Fields

Field Type Required Description
pricing object Yes Pricing configuration (same format as checkout)
pricing.base_currency string Yes Your base currency (e.g., USD)
pricing.amount string Yes Amount in base currency
pricing.local_pricing object No Currency overrides (only when base is USD)
payment_method string Yes Payment method ID (e.g., bank_transfer, mobile_money)
to_currency string Yes Currency customer wants to pay in
payment_rail string No Specific payment rail identifier
customer_email string No Customer email (for context)
customer_name string No Customer name (for context)

Dependencies & Prerequisites

Before using this endpoint:

  1. Get payment methods: Use List Payment Methods to get valid payment_method IDs
  2. Get currencies: Use List Supported Currencies to get valid currency codes
  3. Optional - Get rails: Use GET /api/v1/payments/rails?payment_method=X&currency=Y to get valid payment_rail options

Example Use Case

Scenario: Your e-commerce platform needs to display accurate pricing to customers before checkout. A customer in Nigeria wants to purchase a $50 USD product and prefers to pay via bank transfer in NGN. You need to show them the exact amount they'll pay in their local currency, including all fees, before they commit to the purchase.

Implementation:

// Step 1: Customer selects "Bank Transfer" and "NGN"
const quoteResponse = await fetch('https://api.usesyncpay.com/api/v1/payments/quotes', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer sk_live_abc123xyz...',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    pricing: {
      base_currency: 'USD',
      amount: '50.00'
    },
    payment_method: 'bank_transfer',
    to_currency: 'NGN',
    customer_email: 'customer@example.com'
  })
});

const quote = await quoteResponse.json();

// Step 2: Display quote to customer
console.log(`
  Amount to pay: ₦${quote.amount} NGN
  Exchange rate: 1 USD = ${quote.exchange_rate} NGN
  Expires in: ${Math.floor((new Date(quote.expires_at) - new Date()) / 1000)} seconds
`);

// Step 3: Customer confirms, use quote.quote_id in checkout or whitelabel flow

Response

200 – Success

Returns a detailed quote with pricing, exchange rates, and payment details.

{
  "quote_id": "quote_1a2b3c4d5e6f",
  "currency": "NGN",
  "amount": "75000.00",
  "payment_method": "bank_transfer",
  "payment_rail": "rail_123",
  "exchange_rate": "1500.00",
  "base_currency": "USD",
  "base_amount": "50.00",
  "fees": {
    "total_fee": "750.00",
    "fee_breakdown": {
      "platform_fee": "500.00",
      "gateway_fee": "250.00"
    }
  },
  "expires_at": "2026-01-24T14:40:00.000Z",
  "created_at": "2026-01-24T14:30:00.000Z"
}

Response Fields

Field Type Description
quote_id string Unique identifier for this quote (valid for 30 seconds)
currency string Currency customer will pay in
amount string Exact amount customer will pay
payment_method string Payment method used
payment_rail string Payment rail identifier used
exchange_rate string Exchange rate applied (1 base_currency = X to_currency)
base_currency string Your original currency
base_amount string Your original amount
fees object Fee breakdown
fees.total_fee string Total fees in payment currency
fees.fee_breakdown object Detailed fee breakdown
expires_at string ISO 8601 timestamp when quote expires (30 seconds)
created_at string ISO 8601 timestamp when quote was created

400 – Bad Request

Invalid request parameters or unsupported combination.

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Unsupported payment method for currency",
    "details": {
      "payment_method": "mobile_money is not supported for USD"
    }
  }
}

Common causes:

  • Invalid payment_method (not in supported list)
  • Invalid currency combination (payment method doesn't support that currency)
  • Invalid amount format (must be string, not number)
  • Missing required fields

401 – Unauthorized

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid API key"
  }
}

Using Quotes in Checkout Flows

Option 1: Display Quote, Then Create Checkout

// 1. Get quote
const quote = await getQuote({ ... });

// 2. Show quote to customer
showQuoteModal({
  amount: quote.amount,
  currency: quote.currency,
  exchangeRate: quote.exchange_rate
});

// 3. Customer confirms, create checkout
const checkout = await createCheckout({ ... });

// 4. Redirect to checkout
window.location.href = checkout.checkout_url;

Option 2: Use Quote in Whitelabel Checkout

For more control, use the quote in a Whitelabel Checkout:

// 1. Get quote
const quote = await getQuote({ ... });

// 2. Create whitelabel checkout with quote_id
const payment = await fetch('https://api.usesyncpay.com/api/v1/payments/whitelabel', {
  method: 'POST',
  headers: { ... },
  body: JSON.stringify({
    quote_id: quote.quote_id,
    payment_method: quote.payment_method,
    payment_rail: quote.payment_rail,
    // ... other fields
  })
});

// 3. Handle payment instructions directly

Important Notes

Quote Expiration

Quotes are valid for 30 seconds from creation. After expiration:

  • The quote_id becomes invalid
  • Exchange rates may have changed
  • You must generate a new quote

Why? Exchange rates and fees can change rapidly. Short expiration ensures customers see accurate, up-to-date pricing.

Exchange Rates

Exchange rates are fetched from multiple sources and updated frequently. The rate in a quote is:

  • Locked for the quote's lifetime (30 seconds)
  • Inclusive of all fees and margins
  • Final - the amount shown is what the customer pays

Fees

Fees are transparently shown in the quote:

  • Platform fee: SyncPay's fee for processing
  • Gateway fee: Processing fee
  • Total fee: Sum of all fees

Note: Fees are already included in the amount field. The customer pays only the amount, not amount + fees.

Payment Rails

If you don't specify a payment_rail, SyncPay automatically selects the best available option based on:

  • Currency and payment method combination
  • Availability and reliability
  • Cost optimization
  • Success rates

To see available rails for a payment method + currency:

curl "https://api.usesyncpay.com/api/v1/payments/rails?payment_method=bank_transfer&currency=NGN" \
  -H "Authorization: Bearer sk_test_..."

Quote vs Direct Checkout

When to Use Quotes

Use quotes when:

  • You need to display accurate pricing before checkout
  • Building a custom, multi-step checkout flow
  • Displaying exchange rates transparently to customers
  • Customers choose currency/method before committing
  • Using whitelabel checkout

When to Skip Quotes

Skip quotes when:

  • Using standard hosted checkout (it handles quotes internally)
  • One-click payment flows
  • Customers don't need to see rates upfront
  • Simplicity is priority

Testing

Test Mode Quotes

In test mode (sk_test_...):

  • Quotes use simulated exchange rates
  • Fees are calculated but not charged
  • All payment methods and currencies are available
  • Quotes still expire after 30 seconds

Testing Different Rates

To test different exchange rate scenarios:

  1. Create quotes at different times
  2. Rates may vary slightly to simulate real conditions
  3. Test quote expiration by waiting 10 minutes

Common Questions

Can I extend quote expiration?

No, quotes always expire after 30 seconds. This ensures pricing accuracy. If a customer needs more time, generate a new quote.

Do quotes cost anything?

No, generating quotes is free. You're only charged when a payment is completed.

Can I get a quote without a customer email?

Yes, customer_email and customer_name are optional. They're only used for context and future features.

What happens if exchange rates change during checkout?

If using a quote in a whitelabel checkout, the rate is locked for the quote's lifetime (30 seconds). If the quote expires, the payment will fail and you'll need a new quote.

Can I quote multiple currencies at once?

No, each quote is for a single payment method + currency combination. To show multiple options, make multiple quote requests.



Next Steps

After getting a quote:

  1. Display pricing to your customer
  2. Create a checkout using Create Checkout
  3. Or build custom flow using Whitelabel Checkout
  4. Monitor payment with Get Charge Status