Common API Errors
”Invalid Vault API Key”
The Problem: The Vault rejected the key in yourX-API-KEY header (401).
The Fix:
- Find your Vault API Key under Developers → Vault Key
- Copy the key exactly (no extra spaces)
- Make sure it’s in the
X-API-KEYheader (notX-OZURA-API-KEY)
“Too many requests: the Vault API key could not be checked” (429, VAULT_RATE_LIMITED)
The Problem: Too many requests checked your Vault API Key in a short time, usually because you sent many Create Session or Create Payment Link requests at once. Your key is fine.
The Fix: Wait for the number of seconds in the Retry-After header, then send the same request again. When you create sessions or links in bulk, space the requests out. See Retry Logic for API Calls.
”The Vault API key could not be checked right now” (503, VAULT_UNAVAILABLE)
The Problem: The key check couldn’t be completed. This is temporary and doesn’t mean anything is wrong with your key.
The Fix: Retry with backoff. If it keeps happening, contact support.
”Invalid Merchant API Key”
The Problem: YourX-OZURA-API-KEY header doesn’t match.
The Fix:
- Go to Developers → API Keys
- Copy your Merchant API Key exactly
- Paste it in the
X-OZURA-API-KEYheader (notX-API-KEY)
“merchantId is required”
The Fix: Add it to your request body:“successUrl is required”
The Fix: Include all three required URLs:“Payment processing is not available for this merchant.”
This error appears on the checkout page after the customer clicks Pay Now. What it means: The Merchant API Key (X-OZURA-API-KEY) used to create the session does not have sale permission for the merchantId in the request. The card was never charged.
The Fix:
- Verify your
merchantIdexactly matches what’s in your Ozura Dashboard - Verify the
X-OZURA-API-KEYyou are using is authorized for thatmerchantId - Create a new checkout session with the corrected credentials
”Authentication failed. Please start a new checkout session.”
This error appears on the checkout page after the customer fills in their card details and clicks Pay Now. What it means: The session’s tokenization credential (issued at session creation) was rejected by the vault. This is not a card number issue — the error happens before any card data is processed. Most likely causes:- Session is older than 30 minutes. The credential expires 30 minutes from when the session was created. If the customer (or developer) took longer than that to fill in the form and submit, the credential will be expired. Create a new session and redirect the customer to the new checkout URL.
-
Merchant API key lacks sale permission for the
merchantId. TheX-OZURA-API-KEYused to create the session does not have sale permission for themerchantIdin the request. This surfaces as a “Payment processing is not available for this merchant” error on the checkout page (not a card issue — the error occurs before the card is charged). Verify that the Merchant API Key you are using is authorized for themerchantIdyou are passing in the session body. -
Vault key environment mismatch. The
X-API-KEYused to create the session is a staging vault key, but the Checkout deployment is configured for the production vault (or vice versa). Keys and the checkout environment must match. - Vault key lacks tokenize permission. The vault API key does not have tokenization rights. Verify your key has the correct permissions in the Ozura Dashboard.
merchantId matches the Merchant API Key, then create a new checkout session and send the customer to the new URL.
”Session not found”
The Fix:- Sessions expire after 30 minutes – create a new one
- Check you’re using the correct
sessionId - Make sure you’re hitting the right environment (test vs production)
“Session has expired”
The Fix: Create a new session. Sessions expire after 30 minutes for security.”Session already completed”
The Fix: Check your records – the payment went through! If customer needs to pay again, create a new session.CORS Errors
”Access-Control-Allow-Origin” error in browser
The Fix: SetparentOrigin to your exact website URL:
- Include
https://(not justyoursite.com) - No trailing slash
- Exact match required
Popup/New Tab Issues
Popup blocked
The Fix:- Popup must open from a user click (not automatically)
- Ask user to allow popups for your site
- Consider using redirect mode as fallback:
“EMBED DOWNGRADE” warning, or checkout won’t load in an iframe
Why: iframe embedding is in progress and not available yet. Until it is, a session created withembedMode: "iframe" runs as a full-page redirect, and the response says so in warnings (with "embedMode": "redirect" in data). Changing your own Content Security Policy won’t help.
The Fix (for now): Use embedMode: "popup" or "new_tab" with parentOrigin. See Integration Modes.
Not receiving postMessage events
Check:- The origin you accept matches the environment. Events come from the checkout domain you created the session on:
https://checkout.ozura.comin production,https://sandbox-checkout.ozura.comin sandbox. A listener that only accepts the production origin silently ignores every sandbox event. parentOriginexactly matches the page that opened checkout, includinghttps://and any port, with no path or trailing slash. Events are sent only to that origin.- New tab mode: the session needs
parentOrigin, and the tab must not be opened withnoopener.
Cart/Itemization Issues
”Cannot use both amount and items”
The Fix: Choose one:“Mixed taxExempt values in items”
The Fix: All items must have the sametaxExempt value:
“price has X decimal places but Y only allows Z”
The Fix: Match the currency’s decimal precision:Recurring Issues
”recurringConfig.initialAmount must be a valid amount string with at most 2 decimal places”
The Cause:initialAmount or setupFee has more than 2 decimal places (for example "10.123"). The same rule applies to both fields, and the error names the one that failed.
The Fix: Send a decimal string with at most 2 decimal places:
“recurringConfig.maxCycles must be an integer of at least 2”
The Cause:maxCycles is 1. A recurring plan needs at least two charges: the one at signup and one more.
The Fix: Set maxCycles to 2 or more, or omit it for an ongoing plan. For a single charge, use a standard payment session.
”recurringConfig.endDate must be at least one billing period after today, so the plan has a charge after signup”
The Cause:endDate comes before the plan’s first charge after signup (one billing period after the customer pays), so the plan would have nothing to bill after signup. endDate is read as the start of that day in UTC.
The Fix: Set endDate later than one billing period from today, or omit it for an ongoing plan. A payment link whose end date gets this close shows This subscription has ended and can no longer be started; create a new link.
The customer sees a different start date than my startDate
The Cause: startDate is deprecated and ignored. Billing always starts when the customer pays: the first charge is at signup, and the next one is one billing period later.
The Fix: Nothing is broken; checkout shows the customer the real Next charge date. You can stop sending startDate. See Billing Schedule.
Sales Tax Issues
The order summary says “Check your billing address”
The Cause: Sales tax couldn’t be calculated for the billing address the customer entered, for example a ZIP code that doesn’t exist. The Fix: The customer should correct the address. If they’re sure it’s right, they can click Continue to payment twice: the first click shows a warning, the second continues. Tax is calculated again before the payment page opens; if that fails too, they stay on checkout with an error and can correct the address. See If the address can’t be verified.The order summary says “We couldn’t preview your tax”
The Cause: The order summary couldn’t load the tax, usually because of a brief outage. The Fix: None needed: the customer can click Try again or just continue. Tax is still calculated before the payment page opens.”Please enter a 5-digit ZIP code”
The Cause: A US billing ZIP code must be 5 digits or ZIP+4 (9 digits). The Fix: The customer enters a valid ZIP code.”Sales tax isn’t available for your billing country yet”
The Cause: The billing country is one where tax isn’t available yet (Mexico, China, Paraguay, Costa Rica). Payments from these countries can’t be completed for now; nothing is charged. The Fix: None on your side. If the customer picked the wrong country, they can correct it. See Countries not supported yet.”Please enter your name using Latin letters (A-Z)”
The Cause: The name or address contains text in a non-Latin script (for example Japanese or Arabic). Card processors only accept Latin letters. The Fix: The customer writes it in Latin letters. Accented letters such as é or ü are fine. See Names and addresses in Latin letters.”Please enter a valid Canadian province” / “Please enter a valid postal code (e.g. M5V 3L9)”
The Cause: Canadian billing addresses need a real province (code or name, e.g.ON or Quebec) and a postal code in the A1A 1A1 format, because tax is calculated from them.
The Fix: The customer corrects the province or postal code.
Related Pages
- Error Handling — HTTP status codes, error response format, and retry patterns
- Handle the Payment Result — Verifying session status and processing outcomes
Still Stuck?
Contact Ozura support with:- Your Merchant ID
- Session ID (if applicable)
- The exact error message
- Steps to reproduce