Payment methods
Local currency
A buyer abroad can pay your US-dollar price in their own currency. The checkout shows both amounts side by side (for example AED 74.93 or US$20.00) with the exchange rate, and the buyer's own currency is selected for them. They can switch to US dollars with one tap.
You are still paid in US dollars, at your usual fees. What you receive is what the same sale paid in US dollars on the same card pays you: a card from another country carries the international card fee, as it always does. The buyer's rate is the day's exchange rate with a currency conversion markup in it, which the buyer pays, and the checkout shows that markup as a percentage.
1. Where it shows
Every Vezmo checkout shows it on its own: payment links, product pages, invoices, subscription checkouts (section 7), and the Secure Payments hosted page and embed. You don't need to write any code for these. If you build your own payment page with vezmo-elements.js or the Elements API, see sections 4 and 5.
A buyer is offered their own currency when all of these hold:
- the price is in
USD; - the buyer's country uses a currency Vezmo offers (the
choiceslist below); - the converted amount is above that currency's minimum charge;
- you haven't switched it off (section 2).
A buyer can also pick another offered currency from the checkout's currency menu. Paying in a local currency is by card or wallet, and in Indian rupees also by UPI, in Brazilian reais by Pix, when you offer it (localOffer.methods lists it); methods that are US-dollar only (ACH, Cash App Pay, Klarna, Affirm, Afterpay, Amazon Pay) stay with the US-dollar option.
2. Turn it off for your business
Go to VezmoPay → Settings → Pay in their own currency. Switching it off removes the option from all of your checkouts at once. Buyers then see your US-dollar price only.
3. The price and the rate
The amount in the buyer's currency is your price converted at the rate the checkout shows. That rate is held until expiresAt. A promo code or a new quantity is priced at the same rate, so the total the buyer sees is the total they pay. If the buyer pays after the rate has expired, they get a fresh price and choose again.
amountInTheirCurrency = ceil(priceInUsd × (1 / usdPerUnit) × (1 + markupPercent / 100)) // to the cent
rate (shown) = amountInTheirCurrency ÷ priceInUsd // 5 decimals4. Your own page: the Elements API
POST /secure-payments/:token/checkout returns a localOffer object when the buyer may pay in their own currency, and null otherwise.
"localOffer": {
"currency": "AED",
"amount": 74.93, // what the buyer pays in AED
"amountMinor": 7493,
"price": { "amount": 20.00, "currency": "USD" },
"rate": 3.7465, // AED per US dollar, markup included
"markupPercent": 2,
"usdPerUnit": 0.272287, // the day's rate, US dollars per AED
"expiresAt": "2026-10-14T05:30:00.000Z",
"country": "AE", // the buyer's country, when known
"choices": ["AED", "AUD", "CAD", "EUR", "GBP", "…"],
"methods": [], // ways to pay made for this currency you offer (["upi"] for INR, ["pix"] for BRL)
"token": "…" // send it back with the buyer's choice
}- Another currency. Add
?currency=EUR(any code inchoices) to the checkout call to get the offer in that currency. - Pay in it. Send the token in the body of
POST /secure-payments/:token/intent. Without it the payment is made in the price's currency.
POST /secure-payments/:token/intent
Content-Type: application/json
{ "localOffer": "<localOffer.token>" }409 with errors[0].code = "local_price_changed" means the held rate has expired. Load the checkout again, show the buyer the new amount, and let them choose again.
5. Your own page: vezmo-elements.js
The session reads the offer for you. Show both amounts, wait for the buyer to choose, then pass the choice before confirm().
var lp = session.localPrice();
// { currency, amount, amountMinor, rate, markupPercent, expiresAt, choices } | null
if (lp) {
showCurrencyChoice(lp, function (pick) { // your UI: two equal options
session.chooseCurrency(pick); // 'local' | 'price' | a code from lp.choices
});
}
session.confirm().catch(function (err) {
if (err.code === 'currency_choice_required') {
// the buyer hasn't chosen a currency yet
}
});chooseCurrency('EUR') fetches the offer in that currency and resolves with the new localPrice(). When the held rate expires, the session gets a fresh offer for you: show localPrice() again before the buyer pays.
If you build the choice yourself:
- show both amounts; you may select the buyer's currency for them, as Vezmo's hosted checkouts do, with
chooseCurrency('local'); - show the rate (
1 USD = 3.74650 AED) while their currency is selected; - the session pays nothing until a currency is chosen; the buyer's receipt names the rate and its markup.
6. After the sale
- Webhooks and the Payments API report your price in
amountandcurrency. What the buyer was charged is incharged. Thechargedfield appears only on sales paid in the buyer's currency.
"amount": 20.00,
"currency": "USD",
"charged": { "amount": 74.93, "currency": "AED" }- Refunds over the API take
amountin your price's currency (10.00refunds half of aUSD 20.00price). The buyer gets back the matching share of what they paid, in their currency, at the sale's own rate (the card networks require it). The refund response reports the money returned in the currency the buyer paid. - What a refund costs you. The refund is paid from your balance at the day's exchange rate, so a full refund can cost a little more or less in US dollars than the sale brought in, as the rate moves. Fees are not returned, as on any refund.
- The buyer's receipt shows the amount in their currency, your price, the rate with its markup, and that they chose to pay in that currency.
- Your dashboard shows both amounts on the transaction, and its fee and net in US dollars: the fee is your price less what you received, the same as the sale paid in US dollars would show. The buyer's markup is not your fee.
7. Subscriptions
A buyer can subscribe in their own currency too. The first payment is at the rate the checkout shows. Each renewal is charged in the same currency at that billing day's rate, so the amount in their currency can change a little from one renewal to the next; the checkout and the buyer's consent say so.
- Your plan, invoices, payouts and fees stay in US dollars at your plan price, on every renewal.
- Indian rupees are not offered for subscriptions. Bank debit stays with the US-dollar option.
- If a renewal can't be priced in the buyer's currency (for example, you switched the feature off), it is charged in US dollars.