{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-products/hosted-checkout/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Frequently Asked Questions","description":"Official Banxa API documentation – on-ramp and off-ramp transfers with identity verification and compliance.","llmstxt":{"title":"Banxa Developer Documentation","description":"Integrate crypto-fiat exchange with Banxa's licensed infrastructure: payments, KYC, compliance, and settlement handled. 150+ countries, 45 global licences.","details":{"content":"Two integration products: **Banxa Native API** for partners who manage their own KYC and want full UX control (headless, HMAC server-to-server, no Banxa-hosted screens); **Banxa Hosted Checkout** for partners who want Banxa to handle KYC and payments (three paths: Referral URL, API, or React Native SDK). Both use the same sandbox and production environments at `https://api.banxa-sandbox.com` and `https://api.banxa.com`.\n\n## When to use Banxa\n\nReach for Banxa when a product needs to let people **buy crypto with fiat or sell crypto for fiat** without the partner holding money-transmitter or VASP licences. Banxa is the licensed counterparty: it takes the payment, runs compliance, and delivers the asset. Typical fits are wallets, exchanges, dApps, gaming platforms and fintech apps adding an on-ramp or off-ramp.\n\nPick the product by who owns KYC:\n\n- **Banxa Native API** - the partner already runs its own KYC and wants no Banxa screens at all. Headless, HMAC-signed server-to-server, partner owns the entire interface. Needs a backend. Days to weeks to integrate.\n- **Banxa Hosted Checkout** - the partner does not want to run KYC. Banxa handles identity, payment and delivery in its own flow, reached by redirect, embedded iFrame, or React Native SDK. No backend required for the referral path. Hours to days to integrate.\n- **Legacy API** - existing integrations only. Do not start here.\n\nBanxa is not the right tool for crypto-to-crypto swaps, custody or wallet infrastructure, or for any flow where the partner wants to settle funds itself.\n\n## Constraints\n\n- **Authentication**: HMAC credentials must be stored server-side only, never expose in frontend, mobile, or client-side code. HMAC is required for all Native API calls and for KYC sharing in Hosted Checkout; `x-api-key` is used for all other Hosted Checkout endpoints.\n- **`externalCustomerId`**: Required on every buy and sell order. Use a stable opaque identifier, never PII.\n- **`identityReference`**: Must remain constant for the same user across all requests. Must not contain PII. If you attempt to create an identity for an email that already exists, you will receive a 422 / code 81, so retrieve the existing record rather than retrying creation. Use `GET /eapi/v0/identities/{identityReference}?email=user@example.com` to look up the real `identityReference` linked to an email.\n- **`quoteId`**: Only supported by `POST /eapi/v0/ramps` (bank transfer). The React Native SDK and Embedded Payment Button do not accept a `quoteId`, so use indicative pricing (`GET /eapi/v0/price`) for SDK and Embedded Payment Button flows.\n- **Quotes**: Indicative prices are not rate-locked, so refresh close to order creation to minimise rate drift. Locked quotes (`GET /eapi/v0/quote`) expire after approximately 3 minutes and are only valid for bank transfer ramp creation.\n- **Eligibility gate**: Never create a ramp or invoke the SDK when `paymentReady` is `false`. Always check eligibility and satisfy all requirements before payment execution.\n- **Webhooks**: Verify all inbound webhook signatures with HMAC-SHA256 before processing. Return HTTP 200 immediately and process asynchronously.\n- **Product selection**: Banxa Native is for partners who manage their own KYC. Banxa Hosted Checkout is for partners who do not do KYC. These are separate products with separate flows: do not mix endpoints across products.\n- **SDK scope**: The React Native SDK has no `banxa.customerIdentity` module. Identity and KYC are handled through the Native API only. `primerCallbacks` and `primerSettings` are Native context only and must not be referenced in Hosted Checkout integrations.\n- **Payment method naming**: Never use \"eAPI\" or \"EAPI\" as a product name. The correct name is \"Banxa Native API\". The URL path prefix `/eapi/` is correct and should not be changed.\n"}}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"frequently-asked-questions","__idx":0},"children":["Frequently Asked Questions"]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For the complete documentation index, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://docs.banxa.com/llms.txt"},"children":["llms.txt"]},". Append ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".md"]}," to any page URL for its markdown version."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The questions partners ask most often during integration, with links to the relevant guides."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"credentials-and-authentication","__idx":1},"children":["Credentials and authentication"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"which-api-key-do-i-use-for-which-endpoint","__idx":2},"children":["Which API key do I use for which endpoint?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Banxa has two credential types, and using the wrong one is the most common cause of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401 Unauthorized"]}," errors:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Credential"},"children":["Credential"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Used for"},"children":["Used for"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["v2 API key"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["x-api-key"]}," header)"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["All ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/v2"]}," endpoints: quotes, orders, payment methods, fiats, crypto, countries"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["HMAC key pair"]}," (API key + secret)"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /v2/identities/token/share"]}," (KYC sharing), and verifying incoming webhook signatures"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Both credential sets are visible in the merchant dashboard, per environment. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/hosted-checkout/docs/getting-started/authentication-and-environments"},"children":["Authentication & Environments"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"which-secret-verifies-webhook-signatures","__idx":3},"children":["Which secret verifies webhook signatures?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Webhook signatures are verified with your ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["HMAC secret"]},", not your v2 ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["x-api-key"]},". If you only have a v2 key, retrieve the HMAC credentials from the merchant dashboard or contact your account manager. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/hosted-checkout/docs/transaction-lifecycle/webhooks#securing-webhooks"},"children":["Webhooks"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"im-getting-401-errors-even-though-my-key-is-correct","__idx":4},"children":["I'm getting 401 errors even though my key is correct"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Check that you are calling the right environment. Sandbox keys only work against ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://api.banxa-sandbox.com"]},", production keys only against ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://api.banxa.com"]},". The base URL for each environment is shown in the merchant dashboard next to your API key."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"sandbox","__idx":5},"children":["Sandbox"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"why-is-my-sandbox-order-stuck-and-never-reaching-complete-","__idx":6},"children":["Why is my sandbox order stuck and never reaching ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["complete"]},"?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Sandbox orders do not settle automatically in all cases and may require manual fulfilment by Banxa. No crypto moves on-chain in sandbox. If your order is stuck, contact your integration manager to progress it. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/hosted-checkout/docs/testing/overview#sandbox-limitations"},"children":["Testing Overview"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"why-do-sandbox-prices-look-wrong","__idx":7},"children":["Why do sandbox prices look wrong?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Sandbox pricing is not refreshed at production frequency. Use sandbox to validate the integration flow, not pricing accuracy. Production rates are live."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"can-i-test-kyc-sharing-end-to-end-in-sandbox","__idx":8},"children":["Can I test KYC sharing end-to-end in sandbox?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The KYC sharing API accepts requests in sandbox, but the sandbox environment is not connected to Sumsub. Test user profiles are verified manually by Banxa; ask your integration manager to verify each test user profile you create."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"can-i-use-testnet-wallet-addresses","__idx":9},"children":["Can I use testnet wallet addresses?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["No. Sandbox validates mainnet address formats only. Use a valid mainnet-format address; no on-chain transaction occurs."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"why-am-i-getting-429-errors-in-sandbox","__idx":10},"children":["Why am I getting 429 errors in sandbox?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Sandbox is rate-limited to 120 requests per minute per merchant account. It is a shared testing environment, and the limit keeps it responsive for all merchants. If you hit 429s, reduce polling (use webhooks for order status instead) and add exponential backoff. Production has a higher limit; see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/hosted-checkout/docs/getting-started/authentication-and-environments"},"children":["Authentication & Environments"]},"."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"orders-and-settlement","__idx":11},"children":["Orders and settlement"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"when-is-an-order-final","__idx":12},"children":["When is an order final?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Only the terminal statuses are final: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["complete"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cancelled"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["declined"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["refunded"]},". In particular, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentReceived"]}," is ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["not"]}," final: an order can still be cancelled after payment if it is held for risk or compliance review. Do not credit your customer or trigger downstream fulfilment until you receive ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["complete"]},". See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/hosted-checkout/docs/transaction-lifecycle/order-statuses"},"children":["Order Statuses"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"what-is-the-difference-between-the-order-id-and-the-order-key","__idx":13},"children":["What is the difference between the order ID and the order key?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Orders have two identifiers: a short numeric ID shown to the customer in the checkout and in emails, and a long hash used in API responses and webhook payloads. Always reconcile using the hash. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/hosted-checkout/docs/transaction-lifecycle/order-lookup"},"children":["Order Lookup"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"why-does-the-merchant-dashboard-show-a-different-status-than-my-webhooks","__idx":14},"children":["Why does the merchant dashboard show a different status than my webhooks?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Webhooks are the real-time source of truth. The merchant dashboard order view can lag behind. Build your reconciliation on webhooks and the order lookup endpoint, not the dashboard."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"how-long-is-a-checkout-url-valid","__idx":15},"children":["How long is a checkout URL valid?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["checkoutUrl"]}," returned by ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /v2/buy"]}," is valid for 1 minute, starting from Banxa's response to the order creation request. Once the URL has been loaded there is no further expiry. Create the order at the moment the customer confirms, then open the URL immediately. Do not create orders in advance."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"pricing-and-fees","__idx":16},"children":["Pricing and fees"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"why-doesnt-the-quote-response-show-all-fees","__idx":17},"children":["Why doesn't the quote response show all fees?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The quote response shows ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["processingFee"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["networkFee"]}," explicitly. The Banxa spread is embedded in the exchange rate, so for some payment methods ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["processingFee"]}," can legitimately be ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0"]}," while the spread is applied via the rate. To calculate the effective all-in rate, divide the fiat amount by the crypto amount."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"is-a-quote-a-guaranteed-price","__idx":18},"children":["Is a quote a guaranteed price?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["No. Quotes are indicative and carry no quote ID; there is nothing to pass into order creation. The final price is confirmed at checkout. Re-quote whenever the customer changes amount, currency, or payment method. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/hosted-checkout/docs/api-integration/get-a-quote"},"children":["Get a Quote"]},"."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"customers-and-kyc","__idx":19},"children":["Customers and KYC"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"do-i-need-to-send-externalcustomerid-","__idx":20},"children":["Do I need to send ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["externalCustomerId"]},"?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Yes, it is required on buy and sell orders. Use one stable identifier ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["per customer"]},", not per order. Reusing the same ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["externalCustomerId"]}," is what lets returning verified customers skip repeat KYC. Generating a new ID per order breaks returning-customer recognition."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"do-i-call-the-kyc-sharing-endpoint-per-customer-or-per-order","__idx":21},"children":["Do I call the KYC sharing endpoint per customer or per order?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Once per customer. After sharing, pass the same ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["externalCustomerId"]}," on every order for that customer. Calling it again for the same customer is safe and will not error. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/hosted-checkout/docs/identity-compliance/kyc-sharing"},"children":["KYC Sharing"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"why-am-i-getting-the-feature-is-not-enabled-code-4005-on-the-identity-endpoint","__idx":22},"children":["Why am I getting \"The feature is not enabled\" (code 4005) on the identity endpoint?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["KYC sharing must be enabled on your account by Banxa, per environment, after a compliance review. If you see this error in sandbox or production, the feature has not yet been enabled for that environment. Contact your account manager. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/hosted-checkout/docs/reference/error-codes"},"children":["Error Codes"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"why-was-my-customers-order-delayed-even-though-payment-succeeded","__idx":23},"children":["Why was my customer's order delayed even though payment succeeded?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The most common cause is a name mismatch: the name on the payment instrument must match the name on the KYC profile. Mismatches route the order to manual review, which delays fulfilment."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"the-kyc-camera-step-fails-inside-my-iframe-or-webview","__idx":24},"children":["The KYC camera step fails inside my iframe or WebView"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Your embedding container must grant camera and microphone permissions. The fix depends on how you embed the checkout:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Web (iframe):"]}," include ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["allow=\"camera; microphone\""]}," on the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<iframe>"]}," element that loads the checkout. Without it, users see a \"Failed to acquire camera\" error during KYC. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/hosted-checkout/docs/checkout-experience/iframe/iframe-overview"},"children":["iFrame Overview"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Mobile app (WebView):"]}," camera permissions must be granted at the app level. On Android, declare ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CAMERA"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["RECORD_AUDIO"]}," in your manifest and grant permission requests in your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["WebChromeClient"]},". On iOS, implement ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["WKUIDelegate"]}," to grant media capture requests, and note that KYC liveness requires iOS 15+ in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["WKWebView"]},". Full configuration examples: ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/hosted-checkout/docs/checkout-experience/iframe/webview-mobile"},"children":["Embedded Checkout Mobile"]},"."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the desktop-to-phone QR handoff works but your in-app or in-page flow fails, missing container permissions are almost always the cause: the QR path opens the KYC step directly in the phone browser, outside your iframe or WebView."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"webhooks","__idx":25},"children":["Webhooks"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"how-many-webhook-urls-can-i-configure","__idx":26},"children":["How many webhook URLs can I configure?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["One webhook URL per environment (one for sandbox, one for production), configured in the merchant dashboard."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"are-order-webhooks-and-kyc-webhooks-the-same","__idx":27},"children":["Are order webhooks and KYC webhooks the same?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["They share the same configured URL but are separate notification types and may originate from different Banxa systems. Handle them independently by inspecting the payload. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/hosted-checkout/docs/transaction-lifecycle/webhooks"},"children":["Webhooks"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"i-received-paymentreceived-but-never-a-final-webhook","__idx":28},"children":["I received ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentReceived"]}," but never a final webhook"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Final settlement can take from minutes to hours depending on payment method, blockchain confirmation times, and whether the order is held for review. If an order remains non-terminal for an extended period, check it via ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/hosted-checkout/docs/transaction-lifecycle/order-lookup"},"children":["Order Lookup"]}," before escalating."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Still stuck? Contact your integration manager, or see the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/hosted-checkout/docs/reference/error-codes"},"children":["Error Codes"]}," reference."]}]},"headings":[{"value":"Frequently Asked Questions","id":"frequently-asked-questions","depth":1},{"value":"Credentials and authentication","id":"credentials-and-authentication","depth":2},{"value":"Which API key do I use for which endpoint?","id":"which-api-key-do-i-use-for-which-endpoint","depth":3},{"value":"Which secret verifies webhook signatures?","id":"which-secret-verifies-webhook-signatures","depth":3},{"value":"I'm getting 401 errors even though my key is correct","id":"im-getting-401-errors-even-though-my-key-is-correct","depth":3},{"value":"Sandbox","id":"sandbox","depth":2},{"value":"Why is my sandbox order stuck and never reaching complete ?","id":"why-is-my-sandbox-order-stuck-and-never-reaching-complete-","depth":3},{"value":"Why do sandbox prices look wrong?","id":"why-do-sandbox-prices-look-wrong","depth":3},{"value":"Can I test KYC sharing end-to-end in sandbox?","id":"can-i-test-kyc-sharing-end-to-end-in-sandbox","depth":3},{"value":"Can I use testnet wallet addresses?","id":"can-i-use-testnet-wallet-addresses","depth":3},{"value":"Why am I getting 429 errors in sandbox?","id":"why-am-i-getting-429-errors-in-sandbox","depth":3},{"value":"Orders and settlement","id":"orders-and-settlement","depth":2},{"value":"When is an order final?","id":"when-is-an-order-final","depth":3},{"value":"What is the difference between the order ID and the order key?","id":"what-is-the-difference-between-the-order-id-and-the-order-key","depth":3},{"value":"Why does the merchant dashboard show a different status than my webhooks?","id":"why-does-the-merchant-dashboard-show-a-different-status-than-my-webhooks","depth":3},{"value":"How long is a checkout URL valid?","id":"how-long-is-a-checkout-url-valid","depth":3},{"value":"Pricing and fees","id":"pricing-and-fees","depth":2},{"value":"Why doesn't the quote response show all fees?","id":"why-doesnt-the-quote-response-show-all-fees","depth":3},{"value":"Is a quote a guaranteed price?","id":"is-a-quote-a-guaranteed-price","depth":3},{"value":"Customers and KYC","id":"customers-and-kyc","depth":2},{"value":"Do I need to send externalCustomerId ?","id":"do-i-need-to-send-externalcustomerid-","depth":3},{"value":"Do I call the KYC sharing endpoint per customer or per order?","id":"do-i-call-the-kyc-sharing-endpoint-per-customer-or-per-order","depth":3},{"value":"Why am I getting \"The feature is not enabled\" (code 4005) on the identity endpoint?","id":"why-am-i-getting-the-feature-is-not-enabled-code-4005-on-the-identity-endpoint","depth":3},{"value":"Why was my customer's order delayed even though payment succeeded?","id":"why-was-my-customers-order-delayed-even-though-payment-succeeded","depth":3},{"value":"The KYC camera step fails inside my iframe or WebView","id":"the-kyc-camera-step-fails-inside-my-iframe-or-webview","depth":3},{"value":"Webhooks","id":"webhooks","depth":2},{"value":"How many webhook URLs can I configure?","id":"how-many-webhook-urls-can-i-configure","depth":3},{"value":"Are order webhooks and KYC webhooks the same?","id":"are-order-webhooks-and-kyc-webhooks-the-same","depth":3},{"value":"I received paymentReceived but never a final webhook","id":"i-received-paymentreceived-but-never-a-final-webhook","depth":3}],"frontmatter":{"title":"Frequently Asked Questions | Banxa Docs","description":"Answers to the most common Banxa Hosted Checkout integration questions: credentials, sandbox behaviour, order finality, fees, webhooks, and KYC sharing.","seo":{"title":"Frequently Asked Questions"}},"lastModified":"2026-08-20T06:59:29.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/products/hosted-checkout/docs/reference/faq","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}