Skip to content

Troubleshooting ​

Русская версия

First, collect the basic facts: the engine phase, the provider, the payment (intent) id, the kind of step (action) and the error code. Then look at the matching request to your server.

Never write card fields, tokens, client secrets or raw SDK responses to logs.

Setup ​

ProblemWhat to check and how to fix
npm cannot download a checkout-kit dependencyUse the full @checkout-kit/* name and public registry. Remove an old @checkout-kit:registry setting pointing to GitHub Packages from your project/user npm config. Check npm view @checkout-kit/core version --registry=https://registry.npmjs.org. See installation.
The UI has no stylesImport @checkout-kit/ui/styles.css and wrap the checkout in CheckoutRoot (or an element with the .ck-root class).
window is not defined during SSRCreate the runtime and the bridge only in the browser. React and UI components can be imported and rendered on the server.
Unknown providerImport its config type and register it with its real id and module.
No cookie / the API call failsCheck baseUrl, origin, credentials, the host name and that the buyer has a session.

Extra steps (actions) ​

ProblemWhat to check and how to fix
A step is waiting, but nothing is shownRender PaymentActionHost, or call runPendingAction yourself.
No place to show the step (no mount)For iframe and inline steps, use createMount(element) and keep that element visible.
No SDK adapterThe adapter's sdk name must match action.sdk. See the provider setup.
The SDK returns too earlyReturn the result from the SDK's "finished" or "additional details" callback, not when the component appears.
Integrity conflictUse one script address and one hash per session. Reload the page before changing them.
The iframe's answer is ignoredCheck the exact origin, the sender, the message type and the step id. Do not allow "any origin" (*).
Unsupported stepTurn on only payment methods you support, or implement the step type the provider returned.
A QR payment never finishesCheck the status on your server, the notifications and the status polling. Scanning a code does not prove payment.

Recovery and status ​

ProblemWhat to check and how to fix
The return page shows 404Your app must open at exactly the return address on the deployed site.
The saved payment is not foundPass runtime.storage to the engine. Stay in the same tab. Do not call reset() before hydrate().
The server is down during recoveryKeep the parameters and call hydrate again when the server is back.
Processing never endsCheck the same payment before allowing a new charge.
Stripe capture_requiredCapture the money on your server. The example uses automatic capture.
PayPal capture_unverifiedReturn the checked capture status, amount and currency — not only the order status.
Adyen Pending / ReceivedCheck the webhook signature (HMAC), the account, the event order and what is stored on the server.
Data from another order / invalid dataUse the saved step of this order.
HTTP 409 on a repeated requestThe data changed, but the operation key stayed the same. Look at the first result for that key.
The retry button stays disabledisLocked is also true in final states. Add your own condition for recovery.

Mobile apps (native bridge) ​

  • Use the session from the PAYMENT_READY message, and give every command a unique id.
  • Build injected commands with createBridgeCommand / createCommandScript. They escape the data safely.
  • Old and duplicate commands are ignored. A ping gets an answer with the matching ready data.
  • In onMessage, accept messages only from your checkout page address.
  • Even if the WebView is allowed to open the bank's page, that page cannot give orders to your app.
  • When the app receives a return link with its own scheme, send its data as PAYMENT_RESUME instead of loading that address in the WebView.

The mobile app example stores return links that arrive before the handshake, and shows how to handle navigation. Browser tests do not replace a real iOS or Android build.

Find where it fails ​

Run npm run dev:integration to compare your setup with the local simulator.

  • If the simulator works, the problem is in your sandbox settings, your server or the SDK setup.
  • If the simulator also fails, run the tests of the affected package and the contract tests.

Apache-2.0 · Headless engine, provider adapters and runnable examples.