@thenextgateway/cashier.sdk
Browser SDK for embedding and communicating with TNG Cashier.
Getting Started
Installation
npm install @thenextgateway/cashier.sdk @thenextgateway/core
Usage
To use Cashier, create a new instance of TNGCashier and pass the ID of the container element where the Cashier iframe should be rendered, Cashier params, and a configuration object.
Keep a reference to the created instance. Cashier still needs to be initialized manually, and the instance serves as the entry point for cross-frame communication.
import { TNGCashier } from "@thenextgateway/cashier.sdk";
import { TNG_TRANSACTION_TYPES, type CashierConfig } from "@thenextgateway/core";
const config: Partial<CashierConfig> = {
iframeOrigin: "https://cashier.example.com",
transactionType: TNG_TRANSACTION_TYPES.deposit,
transactionId: "example-transaction-id",
paymentMethodId: 1,
amount: "10",
currency: "EUR",
};
const cashier = new TNGCashier(
"iframe-container-id",
{
instance: "example-instance",
applicationId: "example-application-id",
},
config,
);
await cashier.initialize();
iframeOrigin is required when constructing TNGCashier. For params, instance is always required. Provide at least one of application or applicationId.
Cross-frame message types
The SDK communicates with Cashier through browser postMessage events. Message type values are prefixed with tng_ so they can be distinguished from other frame messages on the page.
If your application listens for Cashier messages directly or sends messages outside of TNGCashier, use the CASHIER_MESSAGE_TYPES and CROSSFRAME_MESSAGE_TYPES exports from @thenextgateway/core instead of hard-coded strings.
Setup
Cashier Params
| Field | Type | Description |
|---|---|---|
instance | string | Instance identifier. |
application | string (optional) | Application identifier. Required if applicationId is missing. |
applicationId | string (optional) | Application ID. Required if application is missing. |
Configuration Fields
The SDK constructor accepts Partial<CashierConfig>. iframeOrigin is checked immediately by the SDK. Other required fields are validated by Cashier during initialization and can be supplied either in the constructor config or later with updateConfig.
| Field | Type | Description |
|---|---|---|
iframeOrigin | string | URL of the iframe. Must match the deployed Cashier origin. |
transactionId | string | Transaction ID. Only needed if method step is turned off. |
paymentMethodId | number | Payment method ID. Only needed if method step is turned off. |
transactionType | TNGTransactionType (deposit / withdrawal) | Type of transaction. Use TNG_TRANSACTION_TYPES for provided values. |
amount | string | Transaction amount in string format, for example 10 or 9.99. Not required if optional amount step is configured, but can be used to set a default value. |
currency | string | Transaction currency, for example EUR. Not required if optional amount step is configured, but can be used to set a default value. |
redirectUrl | string (optional) | URL to redirect to after transaction is completed. When not provided, Cashier uses its own "process ended" static page. |
attributes | TransactionAttribute[] - array of objects with key/value, for example { key: "example", value: "example" } | Custom attributes to pass to server when processing. |
languageCode | string (optional) | Language code to use in Cashier. When not provided, Cashier uses English. |
optionalSteps | OptionalProgressStep[] - method, amount, and receipt | Which optional steps should be included in the flow. |
amountPresets | (string | number)[] (optional) | Presets for the amount optional step. These show as selectable options. Values that resolve to NaN are ignored. |
currencyOptions | string[] (optional if currency provided) | Currency options for the amount optional step. |
sessionId | string (required if method optional step is turned on) | Session ID needed to initialize the transaction when method selection happens on Cashier side. |
customerId | string (required if method optional step is turned on) | Customer ID needed to initialize the transaction when method selection happens on Cashier side. |
Initialization and communication methods
| Method | Argument(s) | Returns | Description |
|---|---|---|---|
initialize | - | Promise<TNGCashier> | Initializes Cashier, including loading the iframe. Returns promise that can either resolve successfully with a reference to Cashier object or reject with error message. |
dispose | - | - | Clears the listeners and removes the iframe. |
updateConfig | config: Partial<CashierConfig> | - | Updates Cashier config. |
onConfigMissing | callback: (result: HostEventData) => void | - | Registers a callback that will be called when Cashier did not initialize properly due to missing config values. Event sent back will include information which fields are missing exactly. |
onTransactionStart | callback: (result: HostEventData) => void | - | Registers a callback that will be called when Cashier starts transaction on the server side. Note that before that event triggers, it is still possible to change payment method by updating config. Sent Event will contain transaction and method objects. |
onTransactionComplete | callback: (result: HostEventData) => void | - | Registers a callback that will be called when Cashier completes transaction on the server side. Sent Event will contain transaction and method objects. |
onNavigate | callback: (result: HostEventData) => void | - | Registers a callback that will be called when current step of Cashier will change. Sent Event will contain information about current step. |
onClose | callback: (result: HostEventData) => void | - | Registers a callback that will be called when close action is requested by user. |
onError | callback: (result: HostEventData) => void | - | Registers a callback that will be called when transaction fails due to error thrown on client side. Note that this does not include errors on PSP side, as those will be handled in regular flow and returned as transaction result. Sent Event will contain information about error. |
on | newListeners: Partial<HostGlobalListeners> | - | A way to register multiple listeners with one method. Does not remove existing listeners, but replaces those specified if they exist. |
css | css (optional): string | - | Applies given CSS styles globally to the iframe. If called without parameter, clears all styles already set with this method. Note: If called multiple times, only last set of styles will be applied. |
cssVars | vars: TNGCssVars | - | Applies given CSS vars globally to the iframe. If called multiple times only the last set of vars will be applied. |
icons | iconSets: IconSet[], aliases (optional): Dictionary<string[]> | - | Registers icon sets and optionally aliases. Icons with names matching occurrences on cashier views will replace default ones. |
stylesheets | stylesheets: StylesheetParams[] | - | Stylesheets provided here will be loaded to be utilized in cashier iframe. |
Theming
Cashier allows for theming by providing custom CSS styles and CSS variables.
Ability to override CSS is unlimited (via css method described above), but it's recommended to try using the cssVars method for most needed overrides.
This method allows for setting CSS variables, altering global palettes and fonts, as well as overriding colors of specific elements outside of palettes.
For reference, below is an example TNGCssVars object that sets all currently possible variables. All fields are optional, and all values are CSS values.
For button overrides, color is the semantic button color and contrast is used for text/icons when that color is used as a filled background.
{
"color": {
"primary": {
"default": "#f00",
"light": "#222",
"dark": "#444",
"contrast": "#fff"
},
"danger": {
"default": "#ff8c00",
"light": "#ffa500",
"dark": "#ff4500",
"contrast": "#fff"
},
"success": {
"default": "#0000ff",
"light": "#add8e6",
"dark": "#00008b",
"contrast": "#fff"
},
"warning": {
"default": "#ee82ee",
"light": "#dda0dd",
"dark": "#9400d3",
"contrast": "#000"
},
"text": {
"default": "#000",
"light": "#222",
"dark": "#444",
"diffused": "#dadada"
},
"background": {
"default": "#e0ffff",
"light": "#fff",
"dark": "#87cefa",
"diffused": "#dadada"
},
"border": {
"default": "#000",
"light": "#222",
"dark": "#444",
"diffused": "#dadada"
}
},
"font": {
"base": "arial sans-serif",
"secondary": "roboto sans-serif",
"size": {
"base": "16px",
"2xs": "10px",
"xs": "12px",
"s": "14px",
"m": "16px",
"l": "18px",
"xl": "20px",
"2xl": "24px",
"3xl": "32px",
"4xl": "48px",
"5xl": "64px"
},
"weight": {
"light": "300",
"normal": "400",
"semiBold": "600",
"bold": "700"
}
},
"override": {
"field": {
"label": {
"color": "darkblue",
"size": "10px",
"weight": "900"
},
"content": {
"color": "red",
"size": "20px",
"weight": "700"
},
"placeholder": {
"color": "orange"
},
"background": {
"base": "yellow",
"hover": "lightyellow",
"active": "orange"
},
"validation": {
"color": "magenta",
"size": "15px",
"weight": "100"
},
"icon": {
"color": "darkgreen"
}
},
"button": {
"primary": {
"color": "blue",
"contrast": "yellow",
"opacity": "1",
"disabled": {
"color": "lightgray",
"contrast": "gray",
"opacity": "0.5"
},
"focus": {
"color": "darkblue",
"contrast": "darkred",
"opacity": "0.9"
},
"hover": {
"color": "lightblue",
"contrast": "orange",
"opacity": "0.7"
}
}
},
"table": {
"text": {
"color": "red",
"size": "30px",
"weight": "900"
},
"border": {
"color": "darkorange"
},
"background": {
"even": "lightyellow",
"odd": "lightgreen"
}
},
"scrollbar": {
"size": "10px",
"thumb": {
"color": {
"base": "blue",
"hover": "lightblue",
"active": "darkblue"
}
},
"track": {
"color": {
"base": "yellow",
"hover": "orange",
"active": "red"
}
}
},
"step": {
"method": {
"tile": {
"width": "400px"
}
}
}
}
}