Ozow Hub
On this page18 sections
Build with AI 1 package

A build package is every page for one task, with the API operations they use. Copy the prompt into a coding assistant, or hand it the package itself: slim links to each page, full inlines all of them in one document.

  • Embed checkout in your own pageEverything needed to keep the customer on your site while they pay, as an iframe, a modal, or the Wallet SDK for Apple Pay and Google Pay, with the notification that actually confirms the payment.
    View package

Limited availability

Embedded wallets are available to approved merchants only. Contact your account manager or support@ozow.com to enquire about eligibility and onboarding.

This guide is a Payments API integration. You create the payment request with POST /postpaymentrequest, authenticate with your API key, and sign the hash with your private key: the One API Client ID and Client Secret are not used here. Prerequisites and onboarding says which credential belongs to which API.

What is an embedded wallet?

The embedded wallet lets you offer digital wallets, Apple Pay and Google Pay, and optionally card payments, directly on your checkout page. The payment UI renders inside a secure Ozow iframe on your domain. Your customers never leave your site and sensitive payment data never touches your page.

This is the only way to offer Apple Pay and Google Pay as standalone payment options.

Digital wallets cannot be triggered via the standalone button method used for other payment methods. If you want to offer Apple Pay or Google Pay at checkout, you must use the Wallet SDK.

Not sure which embedded option is right for you? See Overview: how to choose.

Before you start

Before integrating, confirm the following with Ozow:

  • Wallet enablement: Apple Pay, Google Pay, and/or card must be enabled on your merchant profile by Ozow before they will appear
  • Origin allowlist: every checkout origin (scheme + host + port) where you will load the SDK must be registered with Ozow. Requests from unlisted origins will receive 403 Forbidden
  • Apple Pay domain verification: if you are offering Apple Pay, each top-level checkout domain must be verified (see Apple Pay setup below)
  • SettlementSettlement Ozow paying the money you have collected into your bank account. Payins arrive at Ozow first and are settled to you on a schedule, so what a customer paid you today and what has been settled to you today are different amounts. currency: the amount and currency in your payment request must match your Ozow settlement configuration

You will also need:

  • An active Ozow merchant account with the relevant payment methods enabled
  • A server-side integration to create payment requests
  • HTTPS on your checkout domain with a valid TLSTLS The encryption behind https. Every call to Ozow uses it, which is what keeps a request unreadable in transit.Wikipedia certificate

How the Wallet SDK works

Environments

Environment API base URL iframe origin Dashboard
Production https://pay.ozow.com https://pay.ozow.com dash.ozow.com
Staging https://stagingpay.ozow.com https://stagingpay.ozow.com stagingdash.ozow.com

Core integration

Step 1: Create a payment request (server-side)

Your server creates the payment request with POST /postpaymentrequest. The response returns paymentRequestId, a GUIDUUID A 128-bit identifier written as 36 characters, such as 497f6eca-6276-4993-bfeb-53cbbbba6f08. Generated rather than assigned in sequence, so two systems can create identifiers without coordinating.Wikipedia, which you pass to the SDK as its requestId option.

Important

The payment request must be created server-side. Never build the hash, expose your private key, or call the payment request endpoint from browser code.

Pass the requestId to your checkout page, typically embedded in the page HTML, returned from your own API, or passed as a query parameter.

One request per checkout attempt

pass a fresh requestId for each new payment session. If a payment fails and the customer retries, call destroy() and create a new payment request server-side before reinitialising the SDK.


Step 2: Load the SDK script

Load the SDK from Ozow's CDN. Contact Ozow for the current recommended version and matching SRI hash for your environment.

<script
  src="https://cdn.ozow.com/sdk/v1/1.7.0/ozow.js"
  integrity="sha384-YOUR_SRI_HASH"
  crossorigin="anonymous"
></script>

Pinned version

the SDK URL includes a specific version number. There is no latest channel, version bumps are an explicit change on your side. This ensures predictable behaviour and no silent CDN drift.

Single script tag only

include the SDK script once per page. It exposes a global window.Ozow object.


Step 3: Add the mount container

Add a container element where the SDK will render the wallet buttons:

<div id="ozow-payment"></div>

No additional markup is required. The SDK injects the iframe automatically.


Step 4: Initialise and mount the SDK

const requestId = "YOUR_REQUEST_ID"; // From your server

const ozow = Ozow.init({
  requestId: requestId,
  environment: "production", // 'test' | 'production'
  apiBaseUrl: "https://pay.ozow.com",
  iframeBaseUrl: "https://pay.ozow.com",
});

// Listen for events before mounting
ozow.on("ready", (payload) => {
  console.log("SDK ready", payload.availableWallets);
  if (payload.availableWallets.length === 0) {
    // No wallets available on this device - show fallback payment methods
    showFallbackPaymentMethods();
  }
});

ozow.on("authorizationResult", (payload) => {
  switch (payload.status) {
    case "approved":
      // Payment authorised - fulfil order using payload.transactionId
      completeOrder(payload.transactionId);
      break;
    case "cancelled":
      // Customer cancelled - re-enable checkout
      unlockCheckout();
      break;
    case "declined":
    case "error":
    default:
      // Payment failed - show message and allow retry
      showPaymentFailed(payload.reason);
      break;
  }
});

ozow.on("error", (payload) => {
  console.error(payload.error.code, payload.error.message);
  showPaymentFailed(payload.error.message);
});

// Mount the SDK
ozow.mount("#ozow-payment", {
  wallets: ["applePay", "googlePay"],
  // To include card when enabled on your merchant profile:
  // paymentMethods: ['card', 'applePay', 'googlePay'],
});

Amount lock

once the customer opens a wallet sheet, the payment amount must not change. Listen for the walletSheetOpened event and lock your cart at that point.


Step 5: Handle lifecycle events

Subscribe to events using ozow.on(eventName, handler) and unsubscribe using ozow.off.

Event catalogue

Event When it fires Recommended action
ready iframe loaded and wallet availability known Enable checkout UI; check availableWallets
availability Per-provider availability resolved Telemetry; explain why a button is hidden
walletSheetOpened Customer tapped a wallet button Lock cart amount
walletTokenIssued Wallet authorised; token submitted internally Show "Processing..." indicator
authorizationResult Terminal payment outcome Show the outcome. Fulfil on the notification, not on this
walletSheetClosed Wallet sheet dismissed Re-enable UI if not a terminal outcome
error Recoverable or fatal SDK error Show error message; check error.code

Late subscribers

the SDK replays ready and terminal error events to handlers registered after mount. You can safely attach listeners immediately after init or defer until your SPA hydrates.

authorizationResult is not the confirmation.

The SDK reaches that outcome by polling from the browser, and it gives up after 60 seconds. It tells you what the customer's browser saw, which is not the same as what the bank did, and a customer who closes the tab produces no event at all.

The payment is confirmed the same way every other Ozow payinPayin A payment made by a consumer to a merchant. The direction most of this site is about: money coming in. Its counterpart is a payout, which sends money out and is not tied to any payment anyone made you. is: by the notification Ozow sends to your server. Because this guide creates the payment with POST /postpaymentrequest, that is the Payments API transaction notification, posted to the NotifyUrl on the request and verified by its Hash. Handle it exactly as Step 4: Handle the notification response describes: same format, same hash check.

Important

Update the order from the notification. Use authorizationResult to move the customer's screen on, and nothing else.

Recommended event handler pattern

ozow.on("walletSheetOpened", () => {
  lockCartAmount();
});

ozow.on("walletTokenIssued", () => {
  showProcessingOverlay();
});

ozow.on("authorizationResult", ({ status, transactionId, reason }) => {
  hideProcessingOverlay();
  switch (status) {
    case "approved":
      return completeOrder(transactionId);
    case "cancelled":
      return unlockCheckout();
    default:
      return showPaymentFailed(reason);
  }
});

ozow.on("error", ({ error }) => {
  hideProcessingOverlay();
  showPaymentFailed(error.message);
});

Step 6: Handle retries and cleanup

Call destroy() whenever the customer leaves checkout or retries a failed payment. Always create a new payment request server-side before reinitialising the SDK with a new requestId.

// Tear down listeners, iframe, and in-flight work
ozow.destroy();

// For a retry - create a new payment request server-side first
const retry = Ozow.init({
  requestId: newRequestId,
  apiBaseUrl: "https://pay.ozow.com",
  iframeBaseUrl: "https://pay.ozow.com",
});
retry.mount("#ozow-payment", { wallets: ["applePay", "googlePay"] });
Scenario Action
Payment failed / customer retry destroy(), create new payment request server-side, reinitialise with new requestId
SPA route change away from checkout Call destroy() in your route teardown
Remounting on same page Call destroy() before remounting, only one active instance per page

Apple Pay setup

Apple Pay in the Wallet SDK validates your top-level checkout domain, not the Ozow iframe origin. Ozow handles certificates and server-side merchant validation. You are responsible for domain verification.

What you must do

Step Detail
Register each checkout domain with Ozow Include production, staging, and localhost origins
Host the domain association file Ozow supplies the file. Serve it at exactly: https://YOUR_DOMAIN/.well-known/apple-developer-merchantid-domain-association
No redirects on the well-known path Apple must fetch the file directly, no 301/302 redirects
HTTPS only Valid TLS certificate required on your checkout domain
Update your CSPContent Security Policy A response header listing the origins a page is allowed to load scripts, frames and other resources from. A policy that does not name Ozow's origin blocks an embedded checkout, and the browser reports it in the console rather than on the page.MDN Add https://applepay.cdn-apple.com to script-src and connect-src
Do not load Apple Pay JS yourself The SDK lazy-loads Apple's script: do not add a duplicate script tag
Do not mock window.ApplePaySession Test doubles that replace the constructor break the payment sheet in all browsers

Cross-browser behaviour

Browser Behaviour
Safari (macOS / iOS) Native Apple Pay sheet
Chrome, Edge, Firefox (including Windows) Apple Pay button opens a QR code sheet; customer completes on an iOS 18+ device
Unsupported browsers Button hidden after availability check

Common Apple Pay failures

Symptom Likely cause
Apple Pay button never appears Domain not verified, merchant not Apple-enabled, or device unavailable
apple_pay_validation_failed Domain not on Ozow allowlist, or association file missing or misconfigured
wallet_sheet_failed Another script overwrote window.ApplePaySession before Apple's SDK loaded

Google Pay setup

No Google-side merchant onboarding is required per checkout domain. Google validates the Ozow iframe origin (pay.ozow.com), which is already approved by Google.

You only need to:

  • Enable Google Pay on your Ozow merchant profile
  • Ensure your CSP allows the Ozow iframe origin (see Security and CSP below)

Card payments

When card is enabled on your merchant profile, the Wallet SDK can show a card payment form alongside wallet buttons. Card fields render only inside the Ozow iframe; card data never enters your DOM, keeping your checkout page out of PCI cardholder data scope. 3DS is handled entirely inside the Ozow iframe.

To include card, pass it in paymentMethods when mounting:

ozow.mount("#ozow-payment", {
  paymentMethods: ["card", "applePay", "googlePay"],
});

Security and CSP

Add these directives to your checkout page Content Security Policy:

Content-Security-Policy: script-src 'self' https://cdn.ozow.com https://applepay.cdn-apple.com; frame-src 'self' https://pay.ozow.com;

Adjust the hostnames for staging (stagingpay.ozow.com).

iframe attributes

the SDK creates <iframe allow="payment"> automatically. Do not strip payment permissions on the mount container.


Error codes

Code Typical cause
request_invalid Missing or malformed requestId
request_load_failed Payment request not found or API unreachable
mount_failed Mount operation failed
invalid_mount_target Container selector not found
not_initialized mount called before init
invalid_config Unsupported configuration
apple_pay_unavailable Device or browser cannot offer Apple Pay
apple_pay_validation_failed Domain verification or merchant validation failed
apple_pay_submit_failed Apple Pay token submission failed
google_pay_unavailable Google Pay not ready on device
google_pay_submit_failed Google Pay submission failed
transaction_initiate_failed Could not create transaction
polling_failed Polling timed out or errored
authorization_failed Backend declined or errored
three_ds_failed 3DS step-up failed
wallet_sheet_failed Wallet sheet could not open
network_error Network request failed
destroyed Operation called after destroy()
internal_error Unexpected SDK error

Go-live checklist

Use this checklist before going live.

Backend

Frontend

Apple Pay

Security

Card (if applicable)


Next steps

In the API reference

2 entries

Last updated