@healnow/payments-ui
v1.3.0
Published
Browser SDK for embedding a Tabz checkout into your own page. It mounts the hosted checkout in an `<iframe>` and exposes a small JavaScript object, `PaymentsUI.checkout`, that you drive and subscribe to from the parent page.
Readme
Tabz Payments UI
Browser SDK for embedding a Tabz checkout into your own page. It mounts the
hosted checkout in an <iframe> and exposes a small JavaScript object,
PaymentsUI.checkout, that you drive and subscribe to from the parent page.
Installation
Via npm:
npm install @healnow/payments-uiimport PaymentsUI from '@healnow/payments-ui';Or drop the pre-built bundle onto the page — it exposes a global PaymentsUI:
<script src="https://.../payments-ui.js"></script>Quick start
// 1 · Your backend creates a cart (server-side, with your secret key).
// The response includes a checkout_url for that cart.
// POST /v1/carts → { "id", "checkout_url", "status": "open", ... }
// 2 · Mount the checkout into an element on your page.
const checkout = PaymentsUI.checkout(cart.checkout_url);
await checkout.mount('#payment-form');
// 3 · Render your own pay button. Submitting the order returns a promise that
// resolves with the confirmed order or rejects with an error message.
const payButton = document.querySelector('#pay');
payButton.onclick = () =>
checkout.submit()
.then(order => showConfirmation(order))
.catch(message => showError(message));
// 4 · Surface any errors raised from inside the checkout.
checkout.on('error', message => showError(message));The checkout renders card entry and, when available, the Apple Pay / Google Pay
buttons. Both card and wallet payments are completed by calling submit() — for
wallets, call it once the wallet token has been captured (after an
'applepay:ready' / 'googlepay:ready' event).
PaymentsUI.checkout(checkoutUrl, options)
Creates a checkout instance.
| Argument | Type | Description |
| --- | --- | --- |
| checkoutUrl | string | The checkout_url returned when your backend created the cart. |
| options | object | Optional configuration (see below). |
Methods
| Method | Returns | Description |
| --- | --- | --- |
| mount(target) | Promise<void> | Inserts the checkout iframe into target (a CSS selector string or an HTMLElement) and resolves once it has connected and initialized. Throws if already mounted or the target is invalid. |
| unmount() | Promise<void> | Removes the checkout iframe. Throws if not currently mounted. |
| submit() | Promise<order> | Submits the current payment — a card payment, or a wallet payment whose token was already captured (after 'applepay:ready' / 'googlepay:ready'). Resolves with the confirmed order, or rejects with an error message (e.g. no payment method selected, checkout still loading, or the payment was declined). Throws synchronously if a submit is already in flight. |
| on(event, handler) | this | Subscribes handler to a checkout event, or to several at once when event is an array of names (see Events). You may register more than one handler for the same event; all are called, in registration order. Returns the checkout, so calls can be chained. |
Events
Subscribe with checkout.on(event, handler). event is a single event name or
an array of names sharing one handler. Register handlers before the customer
starts interacting with the checkout — typically right after mount(). You may
register multiple handlers for the same event; each is called in the order it
was registered. on() returns the checkout instance, so calls can be chained.
An unrecognized event name is ignored with a console warning.
checkout.on(['applepay:ready', 'googlepay:ready'], () => checkout.submit());Order lifecycle
| Event | Fires when | Handler argument |
| --- | --- | --- |
| 'order:paid' | The order has been created and confirmed. This is the success signal. | order — the confirmed order object |
| 'order:declined' | A submit attempt fails (declined or errored). | message — an error string |
submit()already resolves with the order and rejects with the error, so you can drive success/failure straight from the returned promise. The'order:paid'/'order:declined'events are broadcast for the same outcomes — handy for observability or for wallet flows wheresubmit()is triggered from a':ready'handler rather than a direct button click.
Notices
| Event | Fires when | Handler argument |
| --- | --- | --- |
| 'info' | A non-error, informational message is raised (e.g. a verification code was sent, a card was removed). | message — an informational string |
| 'error' | An error occurred, typically triggered by a user action. | message — an error string |
Apple Pay
| Event | Fires when | Handler argument |
| --- | --- | --- |
| 'applepay:start' | The Apple Pay button is tapped. | — |
| 'applepay:ready' | The customer authorizes the Apple Pay sheet and the token is captured. The charge has not run yet — call submit() to complete it. | — |
| 'applepay:cancel' | The Apple Pay flow ends without a captured token — the customer dismisses the sheet, or merchant validation / authorization fails. | — |
Google Pay
| Event | Fires when | Handler argument |
| --- | --- | --- |
| 'googlepay:start' | The Google Pay button is tapped. | — |
| 'googlepay:ready' | The customer authorizes the Google Pay sheet and the token is captured. The charge has not run yet — call submit() to complete it. | — |
| 'googlepay:cancel' | The Google Pay flow ends without a captured token — the customer dismisses the sheet, or the request fails. | — |
Full lifecycle example
const checkout = PaymentsUI.checkout(cart.checkout_url);
await checkout.mount('#payment-form');
// Card payments: submit from your own pay button and handle the outcome.
const payButton = document.querySelector('#pay');
payButton.onclick = () =>
checkout.submit()
.then(order => showConfirmation(order))
.catch(message => showError(message));
// Wallet payments: once the wallet token is captured, complete the charge.
checkout.on(['applepay:ready', 'googlepay:ready'], () =>
checkout.submit()
.then(order => showConfirmation(order))
.catch(message => showError(message))
);
// Order outcome (broadcast alongside the submit() promise).
checkout.on('order:paid', order => showConfirmation(order));
checkout.on('order:declined', message => showError(message));
// Notices
checkout.on('info', message => showToast(message));
checkout.on('error', message => showError(message));
// Analytics
checkout.on('applepay:start', () => track('apple_pay_selected'));
checkout.on('applepay:cancel', () => track('apple_pay_cancelled'));
checkout.on('googlepay:start', () => track('google_pay_selected'));
checkout.on('googlepay:cancel', () => track('google_pay_cancelled'));
// Later, when navigating away
await checkout.unmount();