Building your frontend integration with Catch's JavaScript SDK.

πŸ‘

Interested In Integrating With Catch?

To make use of the tools described in this documentation, you will need a merchant account with Catch. Please reach out to Jack Stewart ([email protected]) for inquiries.

Overview

Catch.js provides components for developing applications that integrate with Catch on merchant storefront websites. It's designed to be used in tandem with Catch's Transaction APIs to implement the frontend portion of the overall integration.

Catch.js provides the following main categories of functionality:

  • UI widgets: various prefabricated elements which applications can display and control in the user interface (UI). All Catch widgets are HTML custom elements and can be manipulated using standard DOM APIs (e.g. HTML attributes, event listeners, CSS) in combination with Catch-widget-specific attributes and events.
  • Checkout flow control: an interface for applications to open Catch checkouts. Catch.js supports two types of checkout flows: a "redirect" flow wherein Catch.js redirects to Catch's hosted checkout UI, and an "inline" flow wherein Catch.js renders Catch's hosted checkout UI in an IFrame which is overlaid on the current page.
  • Page type tracking: an interface for applications to tell Catch the type of page on which Catch.js is currently running. Catch.js currently uses the page type only for internal telemetry, but in the future it's possible that page types will affect other functionality as well.

Live Demo

The Live Demo provides a showcase of Catch.js's UI widgets and other features in isolation. This may be used as a reference companion alongside this documentation.

Compatibility

Catch.js supports the following browsers versions:

BrowserVersion
Chrome94+
Firefox92+
Edge94+
Safari14+
iOS Safari14+
Android Browser93+

Catch.js does not support Internet Explorer.

JavaScript must be enabled in the browser for Catch.js to work. Applications may use a <noscript> tag to display relevant messaging if JavaScript is disabled. For example:

<body>
  <noscript>
    <p>Please enable JavaScript to pay with Catch!</p>
  </noscript>
</body>

Catch.js is designed to be used within any modern Javascript framework, or may be used independent of a framework as well.

πŸ“˜

TypeScript

It's possible to use Catch.js in TypeScript projects. If you wish to do so, we recommend using our Catch.js package, which is discussed below under Asynchronous Loading. This package includes type declarations for the SDK.

Loading

Catch.js is hosted on Catch's servers and designed to be loaded via a <script> tag directly from Catch's CDN:

<body>
  <script src="<Live or Sandbox Catch.js URL>"></script>
</body>

There are two distinct modes of Catch.js: live and sandbox. Each mode of Catch.js is published under its own URL:

Applications should use the live Catch.js in their production environment, and sandbox in their non-production environments (development, testing, etc). Both modes of Catch.js generally provide the same functionality, but, in sandbox mode, checkouts are opened in Catch's sandbox environment, and some additional environment-specific details may vary (for example, in sandbox mode Catch.js may log messages to the JavaScript console, whereas in live mode it will not). Applications should also ensure that the mode of Catch.js they use lines up with the environments being used for Catch's Transaction APIs. For example, to open a given checkout with Catch.js in live mode, the checkout must have been created using Catch's Live Transaction API endpoint (and, for sandbox, the environments must be aligned as well).

Note that Catch.js should be loaded synchronously when using this method of loading via a <script> tag. In other words, applications should not set a defer or async attribute on the Catch.js <script> tag. To avoid blocking critical parts of the document from rendering, we recommend including this <script> tag towards the end of the <body> element.

Asynchronous Loading

Catch publishes an NPM package which provides an ES module for loading Catch.js asynchronously, as an alternative to using a <script> tag. Refer to the documentation for information on loading the SDK using this method.

Initialization

When Catch.js first loads and executes, a single object named catchjs is placed in the global namespace. Once Catch.js has been loaded, the SDK must be initialized for a specific merchant by calling the function catchjs.init() (this function should be invoked exactly once during the lifecycle of the application).

<body>
  <script src="<Live or Sandbox Catch.js URL>"></script>
  <script>
    catchjs.init("<merchant public key value>", {
        // Optional configuration settings
    });
  </script>
</body>

catchjs.init accepts two parameters: publicKey and options. The publicKey is required and should be a string representing the merchant's public API key. options is an object which specifies optional configuration settings to control global behavior of the SDK.

Catch.js's initialization routine is asynchronous. catchjs.init() returns a Promise which resolves once the SDK has successfully initialized, and rejects if there was an error that prevented initialization from completing.

If the provided publicKey is invalid, initialization will not succeed. Applications may handle this scenario by catching the Promise returned by catchjs.init():

catchjs.init("invalid publicKey").catch(function (error) {
  // Initialization failed :(
});
try {
  await catchjs.init("invalid publicKey");
} catch (error) {
  // Initialization failed :(
}

When initialization succeeds, the Promise returned by catchjs.init() is resolved with a reference to a Catch handle object. The handle object exposes an interface for all SDK functions that may only be invoked post initialization. Applications must obtain a reference to the handle in cases where further interaction with Catch.js is needed after initialization (for instance, to open a checkout).

catchjs.init("<merchant public key value>").then(function (catchHandle) {
  // The handle object is available here as `catchHandle`
  // (the parameter name "catchHandle" is arbitrary in this example)
});
const catchHandle = await catchjs.init("<merchant public key value>");

πŸ“˜

Viewing the Live Demo With Your Public Key

By default, the Live Demo initializes Catch.js for a test merchant (Merch by Catch). Alternatively, you may view the demo using a different merchant's valid public key, by loading the live demo page with the ?publicKey=<merchant public key value> querystring parameter.

Initialization options

The options object passed as the second argument to catchjs.init() may provide the following key/values. If an option key is not defined, or options is omitted entirely, Catch.js will fallback to a default value for the option.

Key nameTypeDefault valueDescription
pageTypestring which is one of the following values: "unknown", "home", "product", "mini-cart", "cart", "checkout""unknown"Specifies the type of page in which Catch.js is currently running. This should be set to the most applicable value if the page type fits with one of the available page type choices. The "unknown" page type may be used when there isn't a more specific page type that fits.
themestring which is one of the following values: "light-color", "light-mono", "dark-color", "dark-mono"."light-color"Specifies the default theme which determines the look and feel of widgets, from a set of available predesigned options. The "light-color" theme is intended for widgets which are displayed over a light background, and features Catch's branding color scheme. The "light-mono" theme is also intended for light backgrounds, but renders a monochromatic foreground color. The "dark-color" and "dark-mono" themes are analogous to the light themes, but intended for widgets which are displayed over a dark background. Widgets will render using the default theme by default, but a theme may also be designated for an individual widget via a theme attribute.

Catch Handle API

The handle object that's returned when catchjs.init() resolves provides the following functions:

Function signatureDescription
setPageType(pageType: string): voidChanges the current value of the page type. The pageType parameter accepts the same enumeration of values that can be used for the pageType option when initializing the SDK. Applications should call this function if the page type changes at any point after the SDK has been initialized (for example, when navigating to another page without triggering a full page reload).
setTheme(theme: string): voidChanges the current value of the default theme. The theme parameter accepts the same enumeration of values that can be used for the theme option when initializing the SDK.
trackPaymentMethodSelected(): voidDispatches an event to Catch's internal analytics denoting that Catch has been selected as the customer's payment method. This function is built into the Payment Method widget and as such should only be used as a standalone function when the customer will not proceed through the "normal" checkout flow (e.g. if the customer will check out via an express checkout flow)
openCheckout(checkoutId: string, options?: object): voidOpen a Catch checkout using either a redirect flow or an inline flow. Usage of this function is discussed under Checkout Flow Control.
closeConfirmedCheckout(): voidManually remove Catch's checkout UI if the checkout has been successfully confirmed. Calling this function before the checkout has been confirmed has no effect. This function is only for use with inline checkouts that are configured to not automatically close on confirm. Usage is discussed under Checkout Flow Control.

πŸ“˜

Custom Themes

Some merchants may have a "custom" theme associated with their account. When Catch.js is used for a merchant with a custom theme, it will automatically use the settings specified by the custom theme to determine the look and feel of all widgets. In this case, setting one of the built-in themes (via the theme initialization option or the catchHandle.setTheme() function as described above) will have no effect.

UI Widgets

Overview

The HTML tags for all UI widgets may be used anywhere in the HTML document where flow content is accepted (i.e. anywhere where it would be acceptable to use a <div>, for example). It is possible to include the HTML for a Catch.js widget before the SDK has actually been initialized. For example, the following HTML markup demonstrates a Callout widget (whose tag is <catch-callout>) being used in the document ahead of loading and initializing the SDK (in this hypothetical example, we imagine the Callout widget being used on a product detail page):

<body>
  <div class="product-details">
    <h1>T-shirt</h1>
    <h2>$50</h2>
    <catch-callout price="5000" />
  </div>
  
  <script src="<Live or Sandbox Catch.js URL>"></script>
  <script>
    catchjs.init("<merchant public key value>", {
        pageType: "product"
    });
  </script>
</body>

Styling widgets pre and post initialization

Prior to complete initialization of Catch.js, the custom element (in this example, <catch-callout>) will be rendered by the browser in an undefined state, and not display any Catch.js-specific content or CSS (in effect, appearing essentially as if the element were an empty <div>). Applications may choose to provide their own styling for these elements while they are still undefined (or not display widgets at all until after initializing the SDK). In the following example CSS, styling is applied to Callout widgets which are undefined in order to have them appear as a gray box while Catch.js is still loading:

catch-callout:not(:defined) {
  display: block;
  height: 28px;
  background: gray;
}

After Catch.js initialization has completed, all custom elements defined by the SDK are switched into a defined state, and provide the full content, styling, and behaviors implemented by the SDK. As desired, applications may choose to apply their own CSS to defined custom elements as well (for example, to control things like margins around the widgets).

catch-callout:defined {
  margin: 10px 0;
}

Callout (<catch-callout>)

<catch-callout
  price="23000"
  border-style="pill"
  or-prefix
  page-type="mini-cart"
  theme="light-mono"
  items='[{"name": "test-item", "price": 10000, "quantity": 1, "sku": "test-sku", "image-url": "https://assets.merchant.com/test-sku"}]'
  userCohorts='["platinum", "diamond"]'
/>

The Callout widget shows consumers how much Catch credit they could earn or redeem based on the price of the item(s) they're considering (e.g. when viewing a product detail page or their cart). The widget also includes a trigger that, when clicked, opens a modal which displays more detailed informational content about paying with Catch and earning rewards on the merchant's site. The widget automatically recognizes consumers who are currently signed in to Catch, and tailors the messaging to them if they have rewards that are available to redeem with the merchant.

The Callout widget also makes use of its price, items, and userCohorts attributes to calculate rewards the user will earn on the current item (if implemented on product detail page) or on the current order (if implemented in the cart or during the checkout flow).

Attributes

The following attributes are used to customize the behavior of an instance of <catch-callout>:

Attribute nameTypeRequired?Default valueDescription
pricenumberNoThe cost in cents that a consumer would pay for the item(s) without redeeming Catch credit. If not set, the widgets will display the rewards rate (e.g. β€œEarn 10% credit”) rather than a specific rewards value (e.g., "Earn $24.00 credit"). If provided, the price must be a positive number. A negative price will be treated as if the price is not set at all.
border-stylestring which is one of the following values: "default", "pill", "square", "none", "none-no-padding"No"default"The style of border the widget renders. Defaults to default, a rectangular (slightly rounded) border around the widget. pill renders a rounded border around the widget. square renders a border without rounded corners. none renders the widget without a border. none-no-padding renders the widget without a border, and also removes the padding around the widget text (whereas the none border style keeps the padding).
or-prefixbooleanNofalseIf or-prefix is set, the word "or" is prepended into the displayed messaging (e.g. "or earn $23.00 credit" instead of "Earn $23.00 credit".
page-typestring which is one of the supported pageType values that can be passed when initializing the SDK or invoking the catchHandle.setPageType() function.NoA widget-specific "page type". Normally, the current page type in Catch.js is set globally through the pageType option when initializing the SDK, or by calling the setPageType() function on a Catch handle object. Optionally, the page-type attribute may be used to override the global page type at the individual widget level. This is intended for Callout widgets that are displayed in a modal/overlay where the context they're displayed in can be described with a more specific page type than the current global one. For example, on a merchant's PDP, it is expected the application will set the global page type to "product". If, however, that page also displays a Callout widget in a cart that's opened on the page as an overlay, the application should set a page-type on that specific widget to "mini-cart".
themestring which is one of the supported theme values that can be passed when initializing the SDK or invoking the catchHandle.setTheme() function.NoA "theme" to be used for displaying this Callout instance. If this attribute is not set, the widget will render using the default theme. This attribute is ignored if the merchant is using a custom theme.
itemsJSON.stringified Array of items included in the order, used to calculate SKU based reward rules.

Items are objects with the following shape:
{ image_url?: string; name?: string; price?: number; quantity?: number; sku?: string; }
NoA list of items included in the order (i.e. on PDP, this would be the single item displayed on the page. On the cart/checkout pages, this would be a list of all items included in the order). If this attribute is not set, Catch.js will be unable to calculate any SKU based rewards for display on upfunnel messaging.
userCohortsJSON.stringified Array of strings to describe which user cohorts the currently logged in user is a part of. Used to calculate cohort based reward rules. See more details on user cohorts here.NoA list of user cohorts that the signed in user qualifies for. On the cart/checkout pages, this would be a list of all items included in the order). If this attribute is not set, Catch.js will be unable to calculate any user cohort based rewards for display on upfunnel messaging.

πŸ“˜

Attributes and reactivity

All custom attributes for all Catch widget elements are reactive. If a given widget's attribute's value is changed after the the widget is already rendered, the widget will automatically detect this and update its display accordingly.

With Callout widgets, for example, applications may dynamically set the value of the price attribute should the relevant price change. One scenario where we anticipate this may be applicable is when a Callout is displayed in a cart, and the total price reflected by the cart changes as the consumer adds/removes items.

πŸ“˜

Currency support

Catch.js currently displays all money amounts (based on attribute values such as price) in US dollars. Future versions of the SDK may be extended to support additional currencies.

🚧

Prices are specified in cents, not dollars

Please note that all price values in Catch.js are specified in cents. Widgets will not behave correctly if their price attributes are based on dollars. For example, if the price of a product is 100 dollars, than the value set in the price attribute for a corresponding Callout widget should be "10000", not "100".

Express Checkout Callout (<catch-express-checkout-callout>)

<catch-express-checkout-callout
  price="23000"
  border-style="square"
  items='[{"name": "test-item", "price": 10000, "quantity": 1, "sku": "test-sku", "image-url": "https://assets.merchant.com/test-sku"}]'
  userCohorts='["platinum", "diamond"]'
/>

The Express Checkout Callout widget displays similar informational content as the Callout with additional messaging on where to find Catch in the checkout flow. It is intended to be displayed in merchant checkout flows in which an express checkout option is present--since Catch can only be selected on the final step of checkout, this messaging is meant to reduce confusion if the consumer intends to pay with Catch but does not see it displayed as an express checkout option. The widget also includes a button to open an informational modal with more detailed literature about paying with Catch and with links to visit Catch's marketing website.

The Express Checkout Callout widget also makes use of its price, items, and userCohorts attributes to calculate rewards the user will earn on the current purchase.

Attributes

The following attributes are used to customize the behavior of an instance of <catch-express-checkout-callout>

Attribute nameTypeRequired?Default valueDescription
pricenumberNoProvides the same behavior as the price attribute on the Callout widget.
border-stylestring which is one of the following values: "default", "pill", "square", "none", "none-no-padding"No"default"The style of border the widget renders. Defaults to default, a rectangular (slightly rounded) border around the widget. pill renders a rounded border around the widget. square renders a border without rounded corners. none renders the widget without a border. none-no-padding renders the widget without a border, and also removes the padding around the widget text (whereas the none border style keeps the padding).
themestring which is one of the supported theme values that can be passed when initializing the SDK or invoking the catchHandle.setTheme() function.NoA "theme" to be used for displaying this Express Checkout Callout instance. If this attribute is not set, the widget will render using the default theme. This attribute is ignored if the merchant is using a custom theme.
itemsJSON.stringified Array of items included in the order, used to calculate SKU based reward rules.

Items are objects with the following shape:
{ image_url?: string; name?: string; price?: number; quantity?: number; sku?: string; }
NoA list of items included in the order (i.e. on PDP, this would be the single item displayed on the page. On the cart/checkout pages, this would be a list of all items included in the order). If this attribute is not set, Catch.js will be unable to calculate any SKU based rewards for display on upfunnel messaging.
userCohortsJSON.stringified Array of strings to describe which user cohorts the currently logged in user is a part of. Used to calculate cohort based reward rules.NoA list of user cohorts that the signed in user qualifies for. On the cart/checkout pages, this would be a list of all items included in the order). If this attribute is not set, Catch.js will be unable to calculate any user cohort based rewards for display on upfunnel messaging.

Payment Method (<catch-payment-method>)

<catch-payment-method
  price="23000"
  controlled
  selected
  disabled
  theme="dark-color"
  items='[{"name": "test-item", "price": 10000, "quantity": 1, "sku": "test-sku", "image-url": "https://assets.merchant.com/test-sku"}]'
  userCohorts='["platinum", "diamond"]'
/>

The Payment Method widget displays similar messaging and informational content as the Callout, but is designed specifically to be displayed in merchant checkout UI's where a consumer may select Catch as their payment method (typically choosing between Catch and other payment options). The widget may be placed in a "selected" state (either programmatically, or automatically in response to the consumer clicking on it), and dispatches events when its selected state is changed. The widget may also be placed in a "disabled" state, when the application wants to disable Catch as a payment method while still showing the widget greyed-out.

The Payment Method widget also makes use of its price, items, and userCohorts attributes to calculate rewards the user will earn on the current purchase.

Attributes

The following attributes are used to customize the behavior of an instance of <catch-payment-method>:

Attribute nameTypeRequired?Default valueDescription
pricenumberNoProvides the same behavior as the price attribute on the Callout widget.
controlledbooleanNofalseDetermines whether the widget's selected state is externally controlled by the application, or internally managed by the widget. If controlled is not set (the default behavior), then the widget will automatically update its selected state when it's clicked on. If controlled is set, the widget will never update its selected state automatically, and expect any updates to selected to be controlled externally by the application.
selectedbooleanNofalseWhether or not the widget is in a selected state. When the widget is "controlled", applications are responsible for manually setting the selected attribute when the widget should be selected or deselected. selected is also an IDL attribute. Applications may access it as a property on the widget HTML element, to both read and set its value.
disabledbooleanNofalseWhether or not the widget is in a disabled state. Disabled payment method widgets are displayed slightly greyed out and, even if they are not "controlled" will not automatically become selected when clicked on. Like selected, disabled is also an IDL attribute and may be manipulated as such as a property on the widget HTML element.
themestring which is one of the supported theme values that can be passed when initializing the SDK or invoking the catchHandle.setTheme() function. This attribute is ignored if the merchant is using a custom theme.NoA "theme" to be used for displaying this Payment Method instance. If this attribute is not set, the widget will render using the default theme. This attribute is ignored if the merchant is using a custom theme.
variantstring which is either "default", "compact", or "logo-compact"No"default"The "compact" variant of the payment method will not render the Catch logo. The "logo-compact" variant will render the Catch logo and reward text.
itemsStrigified Array of items included in the order, used to calculate SKU based reward rules.

Items are objects with the following shape:
{ image_url?: string; name?: string; price?: number; quantity?: number; sku?: string; }
NoA list of items included in the order (i.e. on PDP, this would be the single item displayed on the page. On the cart/checkout pages, this would be a list of all items included in the order). If this attribute is not set, Catch.js will be unable to calculate any SKU based rewards for display on upfunnel messaging.
userCohortsStringified Array of strings to describe which user cohorts the currently logged in user is a part of. Used to calculate cohort based reward rules.NoA list of user cohorts that the signed in user qualifies for. On the cart/checkout pages, this would be a list of all items included in the order). If this attribute is not set, Catch.js will be unable to calculate any user cohort based rewards for display on upfunnel messaging.

Events

Payment Method widgets dispatch the following events (in addition to standard DOM events such as "click") as they are interacted with. None of these events bubble, so applications that wish to handle any of these events must add the relevant listener(s) to the widget element itself (e.g. using the DOM's addEventListener() function).

Event nameDescription
selectDispatched when the widget's selected state changes from false to true.
changeDispatched when the widget's selected state changes (either from false to true or true to false).
inputIdentical behavior to the change event. Provided for consistency with standard form element APIs.

🚧

The "select", "change", and "input" events are not dispatched if the widget is disabled.

In the following example code, a "change" event listener is setup for a Payment Method widget instance ("select" and "input" events can be handled similarly):

<catch-payment-method id="catch-payment-method-1" />

<script>
  const paymentMethodWidget = document.getElementById("catch-payment-method-1");

  paymentMethodWidget.addEventListener("change", function (event) {
    if (event.currentTarget.selected) {
      console.log("Catch payment method was selected");
    } else {
      console.log("Catch payment method was deselected");
    }
  });
</script>

When to use "controlled" payment method widgets

In some applications, the selected state of a Payment Method might be determined by user interaction with application-specific elements outside of the widget itself. For example, if the widget is rendered inside of a set of radio fields in a <form>, clicking on the radio <input> or its <label> should likely cause the widget to become selected. In these scenarios, the widget needs to know that it should not deal with changing its selected state on its own, but rather expect the application to set it as necessary.

In the following example code, we show a <form> with radio fields for selecting between two different payment options: credit/debit card, and Catch. When the radio field corresponding to the Catch Payment Method is changed by being selected or deselected, we manually update the selected state of the widget accordingly:

<form>
  <h1>Choose a payment method</h1>
  
  <label>
    <input type="radio" name="payment-options" id="credit-or-debit-radio" />
    Credit or debit card
  </label>
  
  <label>
    <input type="radio" name="payment-options" id="catch-radio" />
    <catch-payment-method id="catch-payment-method-2" controlled />
  </label>
</form>

<script>
  const creditOrDebitRadio = document.getElementById("credit-or-debit-radio");
  const catchRadio = document.getElementById("catch-radio");
  const paymentMethodWidget = document.getElementById("catch-payment-method-2");

  creditOrDebitRadio.addEventListener("change", function () {
    if (creditOrDebitRadio.checked) {
      paymentMethodWidget.selected = false;
    }
  });
  
  catchRadio.addEventListener("change", function () {
    if (catchRadio.checked) {
      paymentMethodWidget.selected = true;
    }
  });
</script>

Purchase Confirmation (<catch-purchase-confirmation>)

<catch-purchase-confirmation
  earned="1000"
  anchor-target="_blank"
  theme="light-color"
/>

The Purchase Confirmation widget displays a confirmation message to consumers after they've completed a checkout with Catch. It is designed to be used on the merchant's order confirmation page if Catch was used as a payment method, after the application has successfully created a Purchase object (using Catch's Transaction APIs Create Purchase endpoint). The confirmation message displayed by the widget includes information about how much credit the consumer just earned through their purchase, based on the value of its earned attribute. The widget also acts as a hyperlink, which directs the consumer to their account page on Catch's website.

Some merchants have enabled functionality that gives consumers the option to donate a portion of their earned rewards when making a purchase using Catch. If a consumer has chosen to donate, the Create Purchase information will include a field indicating the donation amount. The Purchase Confirmation widget can be used to display an additional confirmation message about the donation, based on the value of its donation attribute.

Attributes

The following attributes are used to customize the behavior of an instance of <catch-purchase-confirmation>:

Attribute nameTypeRequired?Default valueDescription
earnednumberYesThe amount in cents that that the consumer earned in credit based on their purchase.
anchor-targetstring which is a valid value for the target attribute of a standard <a> element, such as "_self" or "_blank".No"_blank"The value to use for the target attribute on the <a> element the widget displays to link consumers to their account page on Catch. For example, this attribute may be set to "_self" to open the link in the same tab.
themestring which is one of the supported theme values that can be passed when initializing the SDK or invoking the catchHandle.setTheme() function. This attribute is ignored if the merchant is using a custom theme.NoA "theme" to be used for displaying this Purchase Confirmation instance. If this attribute is not set, the widget will render using the default theme. This attribute is ignored if the merchant is using a custom theme.
donationnumberNoThe amount of cents that the consumer is donating. Not used if the merchant doesn't have donations enabled.

Campaign Link (<catch-campaign-link>)

<catch-campaign-link
  campaign-name="POST-CHECKOUT"
  anchor-target="_blank"
  theme="light-color"
/>

The Campaign Link widget fetches an active Catch campaign corresponding to campaign-name. The widget is designed to be used on your order confirmation page if Catch was not used as a payment method to offer credits the next time the consumer pays with Catch.

The widget includes information about how much Catch credit the consumer can claim based on the reward campaign’s metadata and acts as a hyperlink, directing consumers who interact with it to a page on which they can claim their credits.

Attributes

The following attributes are used to customize the behavior of an instance of <catch-campaign-link>:

Attribute nameTypeRequired?Default valueDescription
campaign-namestring which is the name of a valid campaign configured through Catch.YesThe name of a valid and active Catch campaign.
anchor-targetstring which is a valid value for the target attribute of a standard <a> element, such as "_self" or "_blank".No"_blank"The value to use for the target attribute on the <a> element the widget displays to link consumers to their account page on Catch. For example, this attribute may be set to "_self" to open the link in the same tab.
themestring which is one of the supported theme values that can be passed when initializing the SDK or invoking the catchHandle.setTheme() function. This attribute is ignored if you are using a custom theme.NoA "theme" to be used for displaying this Purchase Confirmation instance. If this attribute is not set, the widget will render using the default theme. This attribute is ignored if the merchant is using a custom theme.

Catch Logo (<catch-logo>)

<catch-logo
  size="sm"
/>

The Catch Logo widget displays Catch's logo. To control the size of the widget, you can use the size property for two pre-determined dimensions. To control the size of the logo on a more granular level, omit the size property from the widget entirely and style its dimensions as necessary.

Attributes

The following attributes are used to customize the appearance of an instance of <catch-logo>:

Attribute nameTypeRequired?Default valueDescription
sizestring which is one of the following values: sm or mdNoThe size of the rendered Catch logo. sm will render an 18px x 57px logo, md will render a 40px x 116px logo, and leaving the attribute undefined will allow the logo to fill its containing element
themestring which is one of the supported theme values that can be passed when initializing the SDK or invoking the catchHandle.setTheme() function. This attribute is ignored if the merchant is using a custom theme.NoA "theme" to be used for displaying this Catch Logo instance. If this attribute is not set, the widget will render using the default theme. This attribute is ignored if the merchant is using a custom theme.

Checkout Flow Control

Overview

To open a Catch checkout flow, applications obtain a reference to the Catch handle object and invoke its openCheckout() function.

catchjs.init("<merchant public key value>").then(function (catchHandle) {
  catchHandle.openCheckout("<checkout ID value>", {
    // Checkout flow configuration options
  });
});

openCheckout accepts two parameters: checkoutId and options. The checkoutId is required and should be a string representing the ID of the Checkout being opened. options is an object which specifies configuration options that customize certain aspects of the checkout flow.

🚧

Ahead of using the openCheckout() function, applications are responsible for creating a Checkout object using Catch's Transaction APIs. A successful call to Catch's POST Checkout endpoint will return a checkout ID in the body of its response, which should subsequently be supplied as the first argument to openCheckout().

openCheckout() does not return any value or expect to throw any exceptions. checkoutIds passed to openCheckout() are not validated ahead of opening the checkout flow. If a given checkoutId turns out not to be valid, Catch's checkout UI will display error messaging to the consumer indicating that their checkout could not be loaded. If the consumer encounters an error during the checkout flow (e.g. they're unable to link a bank account successfully, etc), Catch's checkout UI will be responsible for handling such errors and displaying relevant information to the consumer. The call to openCheckout(), in other words, is essentially a full handoff from the merchant application to Catch's checkout application.

Handling terminations

🚧

Enforce defined progression from Checkout to Purchase

Your application should not attempt to create a new Purchase until the consumer has confirmed their Checkout and triggered a successful termination of the Catch checkout flow.

There are two circumstances in which a Catch checkout flow is terminated and control is handed back to the merchant application: (1) a consumer successfully completes the checkout flow, or (2) a consumer explicitly cancels their checkout flow. After (1), the application is responsible for creating a Purchase with Catch using the Transaction APIs POST Purchase endpoint and subsequently displaying a confirmation page. After (2), the application may display content as seen fit (for example, it might show the consumer the page they were on before they opened the Catch checkout flow). The method by which control is handed back to the application when a checkout flow is terminated is different depending on whether the checkout was opened using a redirect flow or an inline flow.

Redirect flow

In a redirect flow, Catch's checkout application will redirect the consumer to the redirect_confirm_url or redirect_cancel_url associated with the Checkout object, depending on whether the consumer completed or canceled their checkout (the values of these fields are determined by the application when creating the Checkout object). When redirecting to either of these URLs, the query string ?checkoutId=<checkout ID value> is added to the URL.

Inline flow

In an inline flow, callback functions may be passed in to openCheckout() via the options argument (detailed below). Catch.js internally manages showing/hiding the checkout IFrame. When an inline checkout flow is terminated, by default the application does not hide Catch's checkout UI that's rendered in an IFrame. This is to allow integrations to do additional processing once the checkout has been confirmed, and that processing should happen while the checkout IFrame remains visible to the user. Once the confirm callback has fired, the integration may then call the closeConfirmedCheckout() to manually hide the checkout IFrame. The IFrame modal will stay on the page until closeConfirmedCheckout() is called or a redirect occurs. In some applications, however, an integration may choose to have Catch.js automatically hide the checkout IFrame when the checkout has been confirmed. To do this, the autoCloseOnConfirm option should be passed as true when calling openCheckout(). With this configuration, Catch.js closes the IFrame quickly as checkout confirmations are usually a quick process.

Pre-filling consumer info

Within Catch's checkout flow, consumers are asked to input their phone number, name, and email address. Because it's often the case that the consumer would have already filled out this info on the merchant's site (for example, when filling out their shipping info), Catch checkouts allow the applications to specify these values ahead of opening the checkout flow, so that they are pre-filled in Catch's UI and the consumer doesn't have to re-enter them. The openCheckout() function provides an option to specify values to pre-fill these fields (detailed below).

πŸ“˜

When pre-filling a consumer's phone number, the provided phone number value should be stripped of any formatting. Catch's checkout UI will automatically format numbers. For example, applications should provide a phone number pre-fill value that looks like "4155550132" rather than "(415) 555-0132".

Catch only supports pre-filling 10-digit US phone numbers at this time.

🚧

Note that, in preliminary versions of Catch's Transaction APIs, pre-fill values could be set when creating a Checkout object using the POST Checkout endpoint endpoint. These fields are now deprecated on this endpoint and should instead be provided exclusively when opening a checkout flow via Catch.js (rather than when creating the Checkout).

openCheckout options

The options object passed as the second argument to openCheckout() may provide the following key/values.

Key nameTypeDefault valueDescription
inlinebooleanfalseWhether or not to use an inline checkout flow. If inline is true, the checkout is opened in an IFrame on the current page. If false, the checkout is opened using a redirect flow (the consumer will be redirected to checkout on a separate Catch-hosted URL).
onCancelfunctionIf provided, this function is called when the consumer cancels a checkout flow. This option is only used if the inline option is true.
onConfirmfunctionIf provided, this function is called when the consumer successfully completes a checkout flow. This option is only used if the inline option is true.
prefillobjectSpecifies pre-fill values to use in the checkout flow. If provided, the prefill object should contain string values for the keys userPhone, userName, and userEmail. Applications should always try to provide as much pre-fill data as possible. However, all prefill entries are individually optional (for example, it's technically valid to specify only prefill.userPhone and not prefill.userName).
autoCloseOnConfirmbooleanfalseFor an inline checkout opened with this option set to false, Catch.js will fire the onConfirm callback, but not close the checkout modal. In this scenario, the merchant integration may manually close the checkout modal by calling the catchHandle.closeConfirmedCheckout() function after the onConfirm callback has fired. When autoCloseOnConfirm is true, Catch.js will manage closing the inline checkout modal automatically when the Catch checkout is confirmed, right before invoking the onConfirm callback. This option is only used if the inline option is true.
hideHeaderbooleanfalseThis flag toggles the visibility of the header in the cart at checkout. The header contains a logo image and a back button. When the header is gone, the consumer can still use the browser back button to navigate away from checkout. This flag is intended to be used when your site is embedded in a web view in a mobile application that already has a static header with your logo.

In the following example code, we demonstrate opening an inline checkout flow with cancel and confirm callbacks, and pre-filled consumer info:

// Assumes a reference to catchHandle, which was obtained from calling catchjs.init()
catchHandle.openCheckout({
  inline: true,
  autoCloseOnConfirm: true,
  onCancel () {
    console.log("Checkout flow was canceled");
  },
  onConfirm () {
    console.log("Checkout flow was completed successfully"); 
  },
  prefill: {
    userPhone: "4155550132",
    userName: "Jane Smith",
    userEmail: "[email protected]"
  }
});

Additional Code Examples

Checkout flow

The following example code sketches out a basic flow using Catch.js on a checkout page. A Catch Payment Method Widget is rendered in a form along along with another payment option, and input fields for the consumer's phone number, name, and email. If the widget is in a selected state when the form is submitted, we call an imaginary service in the application (exposed by the application backend at the endpoint /create-catch-checkout/) to create a Checkout and obtain a checkout ID, and then open a redirect checkout flow with our pre-fill fields.

<form id="checkout-form">
  <h2>Enter your shipping info</h2>
  
  <label>
    Phone Number
    <input type="text" name="phone" />
  </label>
  
  <label>
    Name
    <input type="text" name="name" />
  </label>
  
  <label>
    Email
    <input type="text" name="email" />
  </label>
  
  <h2>Choose a payment method</h2>
  
  <label>
    <input type="radio" name="payment-options" id="credit-or-debit-radio" />
    Credit or debit card
  </label>
  
  <label>
    <input type="radio" name="payment-options" id="catch-radio" />
    <catch-payment-method id="catch-payment-method-1" controlled />
  </label>
  
  <input type="submit" value="Complete Order" />
</form>

<script src="<Live or Sandbox Catch.js URL>"></script>
<script>
  function initCheckout (catchHandle) {
    const checkoutForm = document.getElementById("checkout-form");
    const creditOrDebitRadio = document.getElementById("credit-or-debit-radio");
    const catchRadio = document.getElementById("catch-radio");
    const paymentMethodWidget = document.getElementById("catch-payment-method-1");

    creditOrDebitRadio.addEventListener("change", function () {
      if (creditOrDebitRadio.checked) {
        paymentMethodWidget.selected = false;
      }
    });

    catchRadio.addEventListener("change", function () {
      if (catchRadio.checked) {
        paymentMethodWidget.selected = true;
      }
    });
    
    checkoutForm.addEventListener("submit", function (event) {
      if (paymentMethodWidget.selected) {
        event.preventDefault();
        openCatchCheckout(catchHandle, checkoutForm);
      }
    });
  }
  
  async function openCatchCheckout (catchHandle, checkoutForm) {
    // First, the application must create a Catch Checkout
    // using Catch's endpoint from their backend application,
    // and acquire a corresponding checkout_id.
    const response = await fetch("/create-catch-checkout/", {
      method: "POST",
      body: { /* checkout data */ },
    });
    const { checkoutId } = await response.json();

    catchHandle.openCheckout(checkoutId, {
      prefill: {
        userPhone: checkoutForm.querySelector("[name=phone]").value,
        userName: checkoutForm.querySelector("[name=name]").value,
        userEmail: checkoutForm.querySelector("[name=email]").value
      }
    });
  }
  
  async function init () {
    try {
      const catchHandle = await catchjs.init("<merchant public key value>", {
        pageType: "checkout"
      });
      initCheckout(catchHandle);
    } catch (error) {
      // TODO handle initialization error
    }
  }
  
  init();
</script>

Experimentation

These docs describe the default appearance of Catch widgets. To improve our product, Catch may run experiments that alter the appearance of some widgets, and some variants may not use some of the variables that a merchant has set.