{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Integrating the Cashier","siteUrl":"https://docs.omno.com"},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"integrating-the-cashier","__idx":0},"children":["Integrating the Cashier"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The SDK and the backend API are ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["not"]}," two separate flows. Every Cashier integration has two parts: your ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["backend"]}," creates a session, and your ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["frontend"]}," opens it."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"part-1--backend-create-a-session","__idx":1},"children":["Part 1 — Backend: create a session"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Call ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /public/cashier/session"]}," from your backend to create a session and get back a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sessionId"]}," (and hosted URLs). Full field tables, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentTypes"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fee"]},", deposit/withdrawal-only and the response are documented on the API page — see ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["APIs → ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://docs.omno.com/apis"},"children":["Cashier Session"]}]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -X POST \"https://api.omno.com/public/cashier/session\" \\\n  -H \"Authorization: Bearer <access_token>\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"currency\": \"EUR\",\n    \"paymentTypes\": [\"CARD\", \"APM\", \"CRYPTO\"],\n    \"customer\": { \"externalUserId\": \"3183818381183\" }\n  }'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The response contains ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sessionId"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["token"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["checkoutUrl"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["depositUrl"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["withdrawalUrl"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"the-checkout-token","__idx":2},"children":["The checkout token"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["token"]}," is a short-lived, signed credential (a JWT) that authorizes opening this specific session:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["It is ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["bound to your merchant account"]}," and ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["expires with the session"]}," (default ~2 hours)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Pass it from your backend to your frontend together with the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sessionId"]},", and forward it to the SDK — see Part 2. The SDK attaches it to the cashier URL automatically."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["It is ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["required once checkout token verification is enabled for your account"]},". Without it, opening the session is rejected. We enable verification per merchant, so upgrade your integration to forward the token before it is turned on for you — otherwise the cashier will fail to open."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["OMNO verifies the token's signature against its published keys (",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["JWKS"]},"). You do ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["not"]}," verify or decode it yourself — treat it as an opaque credential, pass it through, and never log it."]}]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["ℹ️ Make sure you are on a Web SDK version that supports the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["token"]}," parameter (see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/cashier/web-sdk-reference"},"children":["Web SDK Reference"]},")."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"part-2--frontend-open-the-session-with-the-web-sdk-recommended","__idx":3},"children":["Part 2 — Frontend: open the session with the Web SDK (recommended)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Open the session on your frontend with ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://www.npmjs.com/package/@omno-payment/checkout-js"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["@omno-payment/checkout-js"]}]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"import CashierSDK, { CashierEmitEvent } from \"@omno-payment/checkout-js\";\n\nconst cashier = new CashierSDK({ baseUrl: \"https://checkout.omno.com\" });\n\ncashier.on(CashierEmitEvent.PAYMENT_SUCCESS, (data) => {\n  // UI reaction only — see the warning below\n  console.log(\"Payment success\", data);\n});\n\ncashier.open({ sessionId, token }); // sessionId and token from your backend\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Then handle the outcome in your ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["webhook handler"]}," (and/or ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://docs.omno.com/apis"},"children":["Get Transaction Info"]},") — see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/getting-started/webhooks"},"children":["Webhooks"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"why-the-sdk-is-recommended","__idx":4},"children":["Why the SDK is recommended"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Opening the raw hosted URL works, but you lose these SDK functions:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Return URL handling after redirects (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["returnUrlAfterRedirection"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Close handling: close-button and overlay events (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["IFRAME_CLOSE_REQUESTED"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["IFRAME_CLOSED"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["OVERLAY_CLICKED"]},") and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["close()"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Language selection at runtime (dynamic language via ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["postMessage"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Payment lifecycle events: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PAYMENT_SUCCESS"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PAYMENT_FAILED"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PAYMENT_PENDING"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PAYMENT_CANCELED"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["KYC error events (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["KYC_REQUIRED_FIELD_ERRORS"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["KYC_REQUIRED_LEVEL_ERRORS"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Deduplicated analytics event (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ANALYTICS_EVENT"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Automatic device detection, and a mobile bottom sheet with configurable height"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Opening directly into Deposit or Withdraw (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentAction"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Opening as a modal or inside your own container (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["containerId"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Styling (modal and mobile)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Live chat event (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["LIVE_CHAT_CLICKED"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["reload()"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["destroy()"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isOpen()"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["getSessionId()"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["getDeviceType()"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Built-in origin validation"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Full method, event and configuration detail: ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/cashier/web-sdk-reference"},"children":["Web SDK Reference"]},". If you cannot use the SDK, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/cashier/using-hosted-url"},"children":["Using the Hosted URL without the SDK"]},"."]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["⚠️ ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Warning:"]}," SDK events are for UI updates only. Credit or debit balances only after a ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/getting-started/webhooks"},"children":["webhook"]}," or ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://docs.omno.com/apis"},"children":["Get Transaction Info"]}," confirms the result. Browser events can be lost (closed tab) or spoofed."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"payouts-with-manual-approval","__idx":5},"children":["Payouts with manual approval"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If a withdrawal requires manual approval, the payout enters ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["WAITING_FOR_CONFIRMATION"]},"; confirm or reject it via the API — see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://docs.omno.com/apis"},"children":["APIs → Confirm / Reject Payout"]},"."]}]},"headings":[{"value":"Integrating the Cashier","id":"integrating-the-cashier","depth":1},{"value":"Part 1 — Backend: create a session","id":"part-1--backend-create-a-session","depth":2},{"value":"The checkout token","id":"the-checkout-token","depth":3},{"value":"Part 2 — Frontend: open the session with the Web SDK (recommended)","id":"part-2--frontend-open-the-session-with-the-web-sdk-recommended","depth":2},{"value":"Why the SDK is recommended","id":"why-the-sdk-is-recommended","depth":3},{"value":"Payouts with manual approval","id":"payouts-with-manual-approval","depth":2}],"frontmatter":{"seo":{"title":"Integrating the Cashier"}},"lastModified":"2026-10-12T06:54:23.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/cashier/integrating-the-cashier","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}