{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-product-guide/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["tabs","tab"]},"type":"markdown"},"seo":{"title":"GlomoPay Unified SDK (Web)","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"glomopay-unified-sdk-web","__idx":0},"children":["GlomoPay Unified SDK (Web)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Official JavaScript SDK for integrating GlomoPay payment checkout flows into your web applications. The Unified SDK supports standard payments, LRS (Liberalised Remittance Scheme) payments, subscriptions, and payment sessions — automatically detecting the correct flow based on your configuration."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"prerequisites","__idx":1},"children":["Prerequisites"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Before using this SDK, you need:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["API credentials (Public Key) from your GlomoPay ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://app.glomopay.com/api-keys-and-webhooks/api-keys"},"children":["dashboard"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A created order (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["order_id"]},"), subscription (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["subscription_id"]},"), or payment session (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentSessionId"]}," + ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentSessionToken"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A modern browser with ES module support"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"installation","__idx":2},"children":["Installation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Import the SDK directly from the hosted URL using an ES module import:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"html","header":{"controls":{"copy":{}}},"source":"<script type=\"module\">\n  import { GlomoCheckoutApi } from 'https://unified-sdk.glomopay.com/index.js';\n</script>\n","lang":"html"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"integration-guides","__idx":3},"children":["Integration Guides"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The SDK supports three integration journeys. Choose the one that matches your use case."]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"journey-1-payment-session-integrated-lrs--kyc","__idx":4},"children":["Journey 1: Payment Session (Integrated LRS & KYC)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use this when you have created a payment session via the GlomoPay API. Payment sessions bundle the LRS checkout flow with integrated KYC verification. When using a payment session, you do ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["not"]}," need a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["publicKey"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["orderId"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["What you need:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentSessionId"]}," — the payment session ID returned when you ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api-documentation/apis/openapi/payment_session/createpaymentsession"},"children":["create a payment session"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentSessionToken"]}," — the JWT token returned alongside the payment session ID"]}]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"HTML","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"html","header":{"controls":{"copy":{}}},"source":"<button id=\"pay-button\">Pay with Payment Session</button>\n<script type=\"module\">\n  import { GlomoCheckoutApi } from 'https://unified-sdk.glomopay.com/index.js';\n\n  const checkout = new GlomoCheckoutApi({\n    paymentSessionId: 'ps_679a16457aP6K',                  // Payment session ID from your server\n    paymentSessionToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI...',  // JWT token from your server\n  });\n\n  checkout.on('payment.success', function (response) {\n    console.log('Payment successful:', response);\n    // response contains: { paymentId, orderId, signature, status }\n  });\n\n  checkout.on('payment.failure', function (response) {\n    console.log('Payment failed:', response);\n  });\n\n  checkout.on('checkout.closed', function () {\n    console.log('Checkout closed by user');\n  });\n\n  document.getElementById('pay-button').addEventListener('click', () => {\n    checkout.open();\n  });\n</script>\n","lang":"html"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"React (TS)","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"tsx","header":{"controls":{"copy":{}}},"source":"import { FC, useEffect, useRef } from \"react\";\n\ninterface PaymentSessionButtonProps {\n  paymentSessionId: string;\n  paymentSessionToken: string;\n}\n\nconst PaymentSessionButton: FC<PaymentSessionButtonProps> = ({\n  paymentSessionId,\n  paymentSessionToken,\n}) => {\n  const buttonRef = useRef<HTMLButtonElement>(null);\n\n  useEffect(() => {\n    let checkout: any;\n\n    const loadCheckout = async () => {\n      try {\n        const { GlomoCheckoutApi } = await import(\n          'https://unified-checkout-sdk-prod.web.app/index.js'\n        );\n\n        checkout = new GlomoCheckoutApi({ paymentSessionId, paymentSessionToken });\n\n        checkout.on('payment.success', (response: unknown) => {\n          console.log('Payment successful:', response);\n        });\n\n        checkout.on('payment.failure', (response: unknown) => {\n          console.error('Payment failed:', response);\n        });\n\n        checkout.on('checkout.closed', () => {\n          console.log('Checkout closed by user');\n        });\n\n        if (buttonRef.current) {\n          buttonRef.current.addEventListener('click', () => checkout.open());\n        }\n      } catch (error) {\n        console.error('Error loading the checkout SDK:', error);\n      }\n    };\n\n    loadCheckout();\n  }, [paymentSessionId, paymentSessionToken]);\n\n  return <button ref={buttonRef}>Pay now</button>;\n};\n","lang":"tsx"},"children":[]}]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"journey-2-order-checkout-standard--lrs","__idx":5},"children":["Journey 2: Order Checkout (Standard & LRS)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use this when you have created an order via the GlomoPay API and have an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["orderId"]},". The SDK automatically detects whether the order is a standard payment or an LRS payment — no additional configuration is needed."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["What you need:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["publicKey"]}," — your public key from the GlomoPay ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://app.glomopay.com/api-keys-and-webhooks/api-keys"},"children":["dashboard"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["orderId"]}," — the order ID returned when you ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/product-guide/payin/order"},"children":["create an order"]}," on your server (starts with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["order_"]},")"]}]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"HTML","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"html","header":{"controls":{"copy":{}}},"source":"<button id=\"buy-button\">Buy Now</button>\n<script type=\"module\">\n  import { GlomoCheckoutApi } from 'https://unified-sdk.glomopay.com/index.js';\n\n  const checkout = new GlomoCheckoutApi({\n    publicKey: 'live_687b0151Bid24PAI', // Your public key from the dashboard\n    orderId: 'order_679a16457aP6K',     // Order ID from your server\n  });\n\n  // Called when the payment completes successfully.\n  // Send the response to your server for signature verification.\n  checkout.on('payment.success', function (response) {\n    console.log('Payment successful:', response);\n    // response contains: { paymentId, orderId, signature, status }\n  });\n\n  // Called when the payment fails.\n  checkout.on('payment.failure', function (response) {\n    console.log('Payment failed:', response);\n    // response contains: { paymentId, orderId, signature, status }\n  });\n\n  // Called when the user closes the checkout without completing payment.\n  checkout.on('checkout.closed', function () {\n    console.log('Checkout closed by user');\n  });\n\n  // For bank transfer payments only:\n  // Emitted when the user submits their bank transfer details.\n  // This does NOT mean the payment is complete — wait for a webhook to confirm.\n  checkout.on('payment.bank_transfer_submitted', function (response) {\n    console.log('Bank transfer submitted:', response);\n    // response contains: { orderId, senderAccountNumber, transactionReference }\n  });\n\n  document.getElementById('buy-button').addEventListener('click', () => {\n    checkout.open();\n  });\n</script>\n","lang":"html"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"React (TS)","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"tsx","header":{"controls":{"copy":{}}},"source":"import { FC, useEffect, useRef } from \"react\";\n\ninterface CheckoutButtonProps {\n  orderId: string;\n  publicKey: string;\n}\n\nconst CheckoutButton: FC<CheckoutButtonProps> = ({ orderId, publicKey }) => {\n  const buttonRef = useRef<HTMLButtonElement>(null);\n\n  useEffect(() => {\n    let checkout: any;\n\n    const loadCheckout = async () => {\n      try {\n        const { GlomoCheckoutApi } = await import(\n          'https://unified-checkout-sdk-prod.web.app/index.js'\n        );\n\n        checkout = new GlomoCheckoutApi({ orderId, publicKey });\n\n        checkout.on('payment.success', (response: unknown) => {\n          console.log('Payment successful:', response);\n        });\n\n        checkout.on('payment.failure', (response: unknown) => {\n          console.error('Payment failed:', response);\n        });\n\n        checkout.on('checkout.closed', () => {\n          console.log('Checkout closed by user');\n        });\n\n        if (buttonRef.current) {\n          buttonRef.current.addEventListener('click', () => checkout.open());\n        }\n      } catch (error) {\n        console.error('Error loading the checkout SDK:', error);\n      }\n    };\n\n    loadCheckout();\n  }, [orderId, publicKey]);\n\n  return <button ref={buttonRef}>Pay now</button>;\n};\n","lang":"tsx"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"order-checkout-with-callbackurl","__idx":6},"children":["Order Checkout with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["callbackUrl"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you prefer to handle the payment result server-side via a redirect instead of in JavaScript, pass ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["callbackUrl"]},". The SDK will redirect the user to your URL with the payment result as query parameters. Terminal ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".on()"]}," events (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.success"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.failure"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.bank_transfer_submitted"]},") will not fire."]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"HTML","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"html","header":{"controls":{"copy":{}}},"source":"<button id=\"buy-button\">Buy Now</button>\n<script type=\"module\">\n  import { GlomoCheckoutApi } from 'https://unified-sdk.glomopay.com/index.js';\n\n  const checkout = new GlomoCheckoutApi({\n    publicKey: 'live_687b0151Bid24PAI',                      // Your public key from the dashboard\n    orderId: 'order_679a16457aP6K',                          // Order ID from your server\n    callbackUrl: 'https://yourwebsite.com/payment-result',   // Redirect URL for payment result\n  });\n\n  // No payment.success or payment.failure listeners needed —\n  // when callbackUrl is set, the SDK redirects instead of emitting these events.\n\n  // checkout.closed still fires, so you can handle abandonment.\n  checkout.on('checkout.closed', function () {\n    console.log('Checkout closed by user');\n  });\n\n  document.getElementById('buy-button').addEventListener('click', () => {\n    checkout.open();\n  });\n</script>\n","lang":"html"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"React (TS)","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"tsx","header":{"controls":{"copy":{}}},"source":"import { FC, useEffect, useRef } from \"react\";\n\ninterface CheckoutButtonProps {\n  orderId: string;\n  publicKey: string;\n  callbackUrl: string;\n}\n\nconst CheckoutButton: FC<CheckoutButtonProps> = ({ orderId, publicKey, callbackUrl }) => {\n  const buttonRef = useRef<HTMLButtonElement>(null);\n\n  useEffect(() => {\n    let checkout: any;\n\n    const loadCheckout = async () => {\n      try {\n        const { GlomoCheckoutApi } = await import(\n          'https://unified-checkout-sdk-prod.web.app/index.js'\n        );\n\n        checkout = new GlomoCheckoutApi({ orderId, publicKey, callbackUrl });\n\n        // No payment.success or payment.failure listeners needed —\n        // when callbackUrl is set, the SDK redirects instead of emitting these events.\n\n        // checkout.closed still fires, so you can handle abandonment.\n        checkout.on('checkout.closed', () => {\n          console.log('Checkout closed by user');\n        });\n\n        if (buttonRef.current) {\n          buttonRef.current.addEventListener('click', () => checkout.open());\n        }\n      } catch (error) {\n        console.error('Error loading the checkout SDK:', error);\n      }\n    };\n\n    loadCheckout();\n  }, [orderId, publicKey, callbackUrl]);\n\n  return <button ref={buttonRef}>Pay now</button>;\n};\n","lang":"tsx"},"children":[]}]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"journey-3-subscription-checkout","__idx":7},"children":["Journey 3: Subscription Checkout"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use this when you have created a subscription and want to collect the first payment or set up recurring billing."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["What you need:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["publicKey"]}," — your public key from the GlomoPay ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://app.glomopay.com/api-keys-and-webhooks/api-keys"},"children":["dashboard"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["subscriptionId"]}," — the subscription ID returned when you ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/product-guide/payin/subscriptions"},"children":["create a subscription"]}," on your server"]}]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Important:"]}," You cannot pass both ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["orderId"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["subscriptionId"]}," — use one or the other."]}]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"HTML","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"html","header":{"controls":{"copy":{}}},"source":"<button id=\"subscribe-button\">Subscribe</button>\n<script type=\"module\">\n  import { GlomoCheckoutApi } from 'https://unified-sdk.glomopay.com/index.js';\n\n  const checkout = new GlomoCheckoutApi({\n    publicKey: 'live_687b0151Bid24PAI',    // Your public key from the dashboard\n    subscriptionId: 'sub_679a16457aP6K',   // Subscription ID from your server\n  });\n\n  checkout.on('payment.success', function (response) {\n    console.log('Subscription payment successful:', response);\n    // response contains: { paymentId, orderId, signature, status }\n  });\n\n  checkout.on('payment.failure', function (response) {\n    console.log('Subscription payment failed:', response);\n  });\n\n  checkout.on('checkout.closed', function () {\n    console.log('Checkout closed by user');\n  });\n\n  document.getElementById('subscribe-button').addEventListener('click', () => {\n    checkout.open();\n  });\n</script>\n","lang":"html"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"React (TS)","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"tsx","header":{"controls":{"copy":{}}},"source":"import { FC, useEffect, useRef } from \"react\";\n\ninterface SubscribeButtonProps {\n  subscriptionId: string;\n  publicKey: string;\n}\n\nconst SubscribeButton: FC<SubscribeButtonProps> = ({ subscriptionId, publicKey }) => {\n  const buttonRef = useRef<HTMLButtonElement>(null);\n\n  useEffect(() => {\n    let checkout: any;\n\n    const loadCheckout = async () => {\n      try {\n        const { GlomoCheckoutApi } = await import(\n          'https://unified-checkout-sdk-prod.web.app/index.js'\n        );\n\n        checkout = new GlomoCheckoutApi({ publicKey, subscriptionId });\n\n        checkout.on('payment.success', (response: unknown) => {\n          console.log('Subscription payment successful:', response);\n        });\n\n        checkout.on('payment.failure', (response: unknown) => {\n          console.error('Subscription payment failed:', response);\n        });\n\n        checkout.on('checkout.closed', () => {\n          console.log('Checkout closed by user');\n        });\n\n        if (buttonRef.current) {\n          buttonRef.current.addEventListener('click', () => checkout.open());\n        }\n      } catch (error) {\n        console.error('Error loading the checkout SDK:', error);\n      }\n    };\n\n    loadCheckout();\n  }, [subscriptionId, publicKey]);\n\n  return <button ref={buttonRef}>Subscribe</button>;\n};\n","lang":"tsx"},"children":[]}]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"configuration-reference","__idx":8},"children":["Configuration Reference"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GlomoCheckoutApi"]}," constructor accepts a configuration object. The required parameters depend on which journey you are using:"]},{"$$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":"Parameter"},"children":["Parameter"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Type"},"children":["Type"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Journey 1 (Payment Session)"},"children":["Journey 1 (Payment Session)"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Journey 2 (Order)"},"children":["Journey 2 (Order)"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Journey 3 (Subscription)"},"children":["Journey 3 (Subscription)"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentSessionId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["string"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Required"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Not used"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Not used"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Payment session identifier."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentSessionToken"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["string"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Required"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Not used"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Not used"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["JWT token for the payment session. Required when ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentSessionId"]}," is provided."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["publicKey"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["string"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Not used"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Required"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Required"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Your GlomoPay public key. If it starts with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["test_"]},", mock mode is enabled automatically."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["orderId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["string"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Not used"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Required"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Not used"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The order ID for this transaction. Must start with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["order_"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["subscriptionId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["string"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Not used"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Not used"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Required"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Subscription ID for subscription payments. Cannot be used together with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["orderId"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["callbackUrl"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["string"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Optional"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Optional"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Optional"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["URL to redirect the user after a terminal payment event (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.success"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.failure"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.bank_transfer_submitted"]},"). When set, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".on()"]}," listeners for these events are ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["not invoked"]}," — only the redirect fires. Must be an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["http:"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https:"]}," URL."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Validation rules:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Journey 1:"]}," Both ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentSessionId"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentSessionToken"]}," are required. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["publicKey"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["orderId"]}," are not needed"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Journey 2:"]}," Both ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["publicKey"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["orderId"]}," are required"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Journey 3:"]}," Both ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["publicKey"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["subscriptionId"]}," are required. Cannot be combined with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["orderId"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["callbackUrl (all journeys):"]}," When provided, the SDK navigates the parent window to this URL on payment completion, failure, or bank transfer submission. The event payload fields are appended as query string parameters. Terminal event listeners (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".on('payment.success', ...)"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".on('payment.failure', ...)"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".on('payment.bank_transfer_submitted', ...)"]},") are ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["not invoked"]}," — handle the result server-side via the redirect query parameters instead. Non-terminal events (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["checkout.closed"]},") still fire normally. Only ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["http:"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https:"]}," URLs are accepted."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"api-reference","__idx":9},"children":["API Reference"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"methods","__idx":10},"children":["Methods"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"open-promisevoid","__idx":11},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["open(): Promise<void>"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Opens the checkout in a modal overlay. Automatically detects the correct checkout flow (standard, LRS, or payment session) based on your configuration. A loading spinner is shown while initializing."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"await checkout.open();\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"close-void","__idx":12},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["close(): void"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Closes the checkout and cleans up all resources. Triggers the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["checkout.closed"]}," event."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"checkout.close();\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"onevent-callback---void","__idx":13},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["on(event, callback): () => void"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Registers an event listener. Returns an unsubscribe function to remove the listener."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"const unsubscribe = checkout.on('payment.success', (data) => {\n  console.log('Payment succeeded:', data);\n});\n\n// Later: remove the listener\nunsubscribe();\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"events","__idx":14},"children":["Events"]},{"$$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":"Event"},"children":["Event"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Payload"},"children":["Payload"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.success"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Payment completed successfully. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Not emitted when ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["callbackUrl"]}," is set."]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ paymentId, orderId, signature, status }"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.failure"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Payment failed. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Not emitted when ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["callbackUrl"]}," is set."]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ paymentId, orderId, signature, status }"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.bank_transfer_submitted"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["User submitted bank transfer details. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Does NOT confirm payment"]}," — await a webhook for confirmation. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Not emitted when ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["callbackUrl"]}," is set."]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ orderId, senderAccountNumber, transactionReference }"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["checkout.closed"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Checkout was closed by the user or programmatically"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{}"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"using-callbackurl-redirect-mode","__idx":15},"children":["Using ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["callbackUrl"]}," (Redirect Mode)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Instead of handling terminal payment events in JavaScript, you can pass a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["callbackUrl"]}," to redirect the user after payment completion. The SDK navigates the parent window to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["callbackUrl"]}," with the event payload fields appended as query string parameters. When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["callbackUrl"]}," is set:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".on()"]}," listeners for ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.success"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.failure"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.bank_transfer_submitted"]}," are ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["not invoked"]},". ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["callbackUrl"]}," and JS callbacks are mutually exclusive for terminal payment events — this prevents merchants from double-handling the same event."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Non-terminal events (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["checkout.closed"]},") continue to fire ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".on()"]}," listeners normally."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Only ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["http:"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https:"]}," callback URLs are accepted."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Query parameters by event:"]}]},{"$$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":"Event"},"children":["Event"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Query parameters appended"},"children":["Query parameters appended"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.success"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentId"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["orderId"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signature"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.failure"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentId"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["orderId"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signature"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["customerErrorMessage"]}," (when available)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.bank_transfer_submitted"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["orderId"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["senderAccountNumber"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionReference"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status"]}," reflects the payment lifecycle and varies by payment method (e.g. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["success"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pending"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bank_transfer_submitted"]},"). Treat it as an opaque string and rely on the event type for branching logic."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Example redirect after successful payment:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"https://yourwebsite.com/payment-result?paymentId=payment_abc123&orderId=order_abc123&status=success&signature=abc123def456\n"},"children":[]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Important:"]}," Verify the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signature"]}," query parameter on your server exactly as you would for the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".on()"]}," payload. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#signature-verification"},"children":["Signature Verification"]},"."]}]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Note:"]}," This differs from the checkout-sdk, which emits ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".on()"]}," events ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["and"]}," redirects when ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["callbackUrl"]}," is set. The Unified SDK only redirects — registering ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".on()"]}," listeners for terminal events alongside ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["callbackUrl"]}," has no effect."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"payload-types","__idx":16},"children":["Payload Types"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"interface PaymentPayload {\n  paymentId: string;   // Payment ID from GlomoPay\n  orderId: string;     // Order identifier (e.g., \"order_abc123\")\n  signature: string;   // Signature for server-side verification\n  status: string;      // Payment status\n}\n\ninterface BankTransferPayload {\n  orderId: string;                // The order ID\n  senderAccountNumber: string;    // Account number provided by the user\n  transactionReference: string;   // Reference number provided by the user\n}\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"signature-verification","__idx":17},"children":["Signature Verification"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After receiving a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.success"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment.failure"]}," event, verify the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["signature"]}," on your server using your secret key. Send the response payload to your server and generate the signature using:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"data = order_id + \"|\" + payment_id + \"|\" + status\nsignature = HMAC-SHA256(data, secret_key)\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For detailed instructions and sample code in PHP, Ruby, Go, JavaScript, and Python, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/product-guide/payin/checkout#steps-to-integrate-checkout"},"children":["Verify checkout response and signature"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"troubleshooting","__idx":18},"children":["Troubleshooting"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"mock-mode-testing","__idx":19},"children":["Mock Mode Testing"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Mock mode is automatically enabled based on your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["publicKey"]},":"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["If your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["publicKey"]}," starts with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["test_"]},", mock mode is enabled and the checkout URL will include ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["mode=mock"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Otherwise, live mode is used"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Example:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"// Mock mode (publicKey starts with \"test_\")\nconst checkout = new GlomoCheckoutApi({\n  publicKey: 'test_abc123',\n  orderId: 'order_xyz789',\n});\n\n// Live mode\nconst checkout = new GlomoCheckoutApi({\n  publicKey: 'live_abc123',\n  orderId: 'order_xyz789',\n});\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"checkout-popup-blocked","__idx":20},"children":["Checkout Popup Blocked"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the checkout fails to open in production, your website's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Cross-Origin-Opener-Policy"]}," header may be blocking popups. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/product-guide/payin/checkout#checkout-popup-blocked-in-production-environment"},"children":["Checkout Popup Blocked in Production Environment"]}," for solutions."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"cors-error-on-checkout-load","__idx":21},"children":["CORS Error on Checkout Load"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you see CORS errors in the browser console when the checkout loads, browser extensions may be interfering. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/product-guide/payin/checkout#cors-error-on-checkout-load-preferences-api-failure"},"children":["CORS Error on Checkout Load"]}," for troubleshooting steps."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"content-blocked-by-content-security-policy","__idx":22},"children":["Content Blocked by Content Security Policy"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the checkout iframe or SDK scripts fail to load due to CSP headers, you need to allow the Glomo domains in your CSP configuration. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/product-guide/payin/checkout#content-blocked-by-content-security-policy-csp"},"children":["Content Blocked by CSP"]}," for setup instructions."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"handling-abandoned-checkouts","__idx":23},"children":["Handling Abandoned Checkouts"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To detect when a user closes the checkout without completing payment, listen for the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["checkout.closed"]}," event:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"let paymentCompleted = false;\n\ncheckout.on('payment.success', () => {\n  paymentCompleted = true;\n});\n\ncheckout.on('payment.failure', () => {\n  paymentCompleted = true;\n});\n\ncheckout.on('checkout.closed', () => {\n  if (!paymentCompleted) {\n    console.log('User closed checkout without completing payment');\n    // Prompt the user to retry or log the abandonment\n  }\n});\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When using ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["callbackUrl"]},", the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["checkout.closed"]}," event still fires, so this pattern works regardless of whether you are using redirect mode or event-listener mode."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"using-the-web-checkout-in-a-native-mobile-app","__idx":24},"children":["Using the Web Checkout in a Native Mobile App"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you are embedding the checkout inside a native iOS/Android app via a WebView (rather than using this JavaScript SDK on a web page), see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/product-guide/sdk/web-checkout-in-mobile-app"},"children":["Web Checkout in a Mobile App (WebView)"]},". Note that the native ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/product-guide/sdk/flutter-sdk"},"children":["Flutter"]}," and ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/product-guide/sdk/react-native-sdk"},"children":["React Native"]}," SDKs are the recommended path."]}]},"headings":[{"value":"GlomoPay Unified SDK (Web)","id":"glomopay-unified-sdk-web","depth":1},{"value":"Prerequisites","id":"prerequisites","depth":2},{"value":"Installation","id":"installation","depth":2},{"value":"Integration Guides","id":"integration-guides","depth":2},{"value":"Journey 1: Payment Session (Integrated LRS & KYC)","id":"journey-1-payment-session-integrated-lrs--kyc","depth":3},{"value":"Journey 2: Order Checkout (Standard & LRS)","id":"journey-2-order-checkout-standard--lrs","depth":3},{"value":"Order Checkout with callbackUrl","id":"order-checkout-with-callbackurl","depth":4},{"value":"Journey 3: Subscription Checkout","id":"journey-3-subscription-checkout","depth":3},{"value":"Configuration Reference","id":"configuration-reference","depth":2},{"value":"API Reference","id":"api-reference","depth":2},{"value":"Methods","id":"methods","depth":3},{"value":"open(): Promise<void>","id":"open-promisevoid","depth":4},{"value":"close(): void","id":"close-void","depth":4},{"value":"on(event, callback): () => void","id":"onevent-callback---void","depth":4},{"value":"Events","id":"events","depth":3},{"value":"Using callbackUrl (Redirect Mode)","id":"using-callbackurl-redirect-mode","depth":3},{"value":"Payload Types","id":"payload-types","depth":3},{"value":"Signature Verification","id":"signature-verification","depth":2},{"value":"Troubleshooting","id":"troubleshooting","depth":2},{"value":"Mock Mode Testing","id":"mock-mode-testing","depth":3},{"value":"Checkout Popup Blocked","id":"checkout-popup-blocked","depth":3},{"value":"CORS Error on Checkout Load","id":"cors-error-on-checkout-load","depth":3},{"value":"Content Blocked by Content Security Policy","id":"content-blocked-by-content-security-policy","depth":3},{"value":"Handling Abandoned Checkouts","id":"handling-abandoned-checkouts","depth":3},{"value":"Using the Web Checkout in a Native Mobile App","id":"using-the-web-checkout-in-a-native-mobile-app","depth":3}],"frontmatter":{"title":"Unified SDK (Web)","seo":{"title":"GlomoPay Unified SDK (Web)"}},"lastModified":"2026-07-17T12:25:50.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/product-guide/sdk/unified-sdk","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}