How does a hosted checkout payment flow?
Seven steps, split between your backend and your frontend:
- Your backend gets an access token.
- Your backend calls
POST /public/cashier/session. - Omno returns a
sessionId, a short-livedtokenand the hosted URLs. - Your frontend opens the hosted checkout with the Web SDK.
- The customer pays, and the selected provider processes the payment.
- Omno sends a webhook with the outcome. This is the authoritative result.
- Optionally, your backend confirms it with
GET /public/payin/{id}orGET /public/payout/{id}.
How do I create a session?
Call the session endpoint from your backend with a Bearer token. The request names the currency, the payment types to offer and your customer:
{
"currency": "EUR",
"paymentTypes": ["CARD", "APM", "CRYPTO"],
"customer": {
"externalUserId": "customer-48213",
"customerGroups": ["vip"],
"kyc": { "kycLevels": ["level-2"] }
},
"kycVerified": true,
"previousTransactionCount": 14
}
This request is illustrative: currency, paymentTypes and customer.externalUserId are the core fields, and the routing signals are shown in the shape described in the routing guide. The response gives you everything the frontend needs:
{
"sessionId": "…",
"token": "…",
"checkoutUrl": "https://checkout.omno.com/…",
"depositUrl": "https://checkout.omno.com/…",
"withdrawalUrl": "https://checkout.omno.com/…"
}
Send as much customer context as you can. Customer groups, KYC levels (customer verification levels, sent as customer.kyc.kycLevels), kycVerified and previousTransactionCount drive routing and PSP eligibility, so they decide which providers the customer sees.
What is the checkout token?
The token is a signed JWT that authorises one session. It is bound to your merchant account and expires with the session, by default after about two hours. Pass token and sessionId from your backend to your frontend unchanged; Omno verifies the signature against its published keys.
Omno turns token verification on per merchant. Once it is on, the hosted checkout will not open without a token, so upgrade to a Web SDK version that accepts the token parameter before that happens.
How do I open the hosted checkout with the Web SDK?
Install @omno-payment/checkout-js, create the SDK with the checkout host as baseUrl, and open the session:
import CheckoutSDK, { CashierEmitEvent } from '@omno-payment/checkout-js';
const checkout = new CheckoutSDK({ baseUrl: 'https://checkout.omno.com' });
checkout.on(CashierEmitEvent.PAYMENT_SUCCESS, () => showPendingConfirmation());
checkout.on(CashierEmitEvent.IFRAME_CLOSED, () => refreshBalanceFromServer());
checkout.open({ sessionId, token });
The SDK also offers close(), reload(), destroy(), isOpen(), getSessionId() and getDeviceType(). Options include returnUrlAfterRedirection, paymentAction to open straight into the Deposit (payment) or Withdraw (payout) view, and containerId to choose between a modal and an embedded container. On phones the hosted checkout opens as a bottom sheet, and the language can be changed at runtime.
Which events does the SDK emit?
| Group | Events |
|---|---|
| Payment lifecycle | PAYMENT_SUCCESS, PAYMENT_FAILED, PAYMENT_PENDING, PAYMENT_CANCELED |
| Closing | IFRAME_CLOSE_REQUESTED, IFRAME_CLOSED, OVERLAY_CLICKED |
| KYC | KYC_REQUIRED_FIELD_ERRORS, KYC_REQUIRED_LEVEL_ERRORS |
| Other | ANALYTICS_EVENT, LIVE_CHAT_CLICKED |
Use them to update the interface. Balances move only on a webhook or a confirmed status.
How do payments and payouts differ?
Payouts are a separate capability that can use the same session. Open the payment view with depositUrl or paymentAction, and the payout view, used for payouts to the customer, with withdrawalUrl. Payouts follow the same eligibility rules as payments. A payout can stop in WAITING_FOR_CONFIRMATION when your account requires manual approval; confirm or reject it through the Confirm or Reject Payout endpoint.
Which statuses should I expect?
DECLINED means the provider declined the pay-in. FAILED means processing failed before or at the provider. TIMEOUT means no final answer arrived in time. PENDING and PENDING_3DS resolve later by webhook.