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:
- Get payment methods: Use List Payment Methods to get valid
payment_methodIDs - Get currencies: Use List Supported Currencies to get valid currency codes
- Optional - Get rails: Use
GET /api/v1/payments/rails?payment_method=X¤cy=Yto get validpayment_railoptions
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_idbecomes 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¤cy=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:
- Create quotes at different times
- Rates may vary slightly to simulate real conditions
- 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.
Related Endpoints
- Create Checkout - Standard hosted checkout
- Create Whitelabel Checkout - Use quotes for custom checkout
- List Payment Methods - Get valid payment method IDs
- List Supported Currencies - Get valid currency codes
Next Steps
After getting a quote:
- Display pricing to your customer
- Create a checkout using Create Checkout
- Or build custom flow using Whitelabel Checkout
- Monitor payment with Get Charge Status