# BNPL messaging integration guide

> Follow the steps below to add BNPL Messaging to a page:

Follow the steps below to add [BNPL Messaging](/platforms/embedded-payments/bnpl-messaging/) to a page:

1. (clientside) Load `shuttle.js` with your shared key and the merchant's instance key in the URL
2. (clientside) Add an element for each message
3. (clientside) Call `Shuttle.credit_message` for each element

There is nothing to do on your server: the messages advertise, and the payment itself goes through [Checkout](/platforms/embedded-payments/checkout/).

## Loading shuttle.js

BNPL Messaging needs the copy of shuttle.js that Shuttle builds for the merchant. Put your shared key and the merchant's instance key in the URL:

```html
<script src="https://app.shuttleglobal.com/${shared_key}/${instance_key}/shuttle-1.4.7.js" type="text/javascript"></script>
```

* `shared_key`: the shared key of your application environment, shown next to its secret key on your application's **Developer** tab (see [Applications](/platforms/embedded-payments/applications/)). Use the sandbox shared key for sandbox instances and the live one for live instances. Never put a secret key in a page.
* `instance_key`: the merchant's instance key (see [Multi-tenancy / instances](/platforms/embedded-payments/instances/)).

This is the same script [Express Checkout](/platforms/embedded-payments/express-checkout/) uses, and it also runs [Checkout](/platforms/embedded-payments/checkout/) and the other components, so a page needs only one shuttle.js script tag.

:::note[No SRI checksum on this URL]
The content at this URL is different for each merchant and changes when they change payment providers, so an `integrity` checksum cannot match it: leave `integrity` out. Still pin the version (`shuttle-1.4.7.js`). See [shuttle.js](/platforms/embedded-payments/shuttlejs/) for the available versions.
:::

Shuttle includes each payment provider the merchant has connected and set up to take payments, where that provider supports BNPL Messaging. The script is cached, so a provider the merchant has only just connected may not show a message straight away.

## Adding a message

Add an empty element where the message should appear, then call `Shuttle.credit_message` once the element is in the page:

```html
<div id="product-123-bnpl"></div>

<script src="https://app.shuttleglobal.com/${shared_key}/${instance_key}/shuttle-1.4.7.js" type="text/javascript"></script>
<script>
  Shuttle.credit_message({
    element: "product-123-bnpl",
    currency: "USD",
    amount: "149.99"
  });
</script>
```

For several messages on one page, give each element its own `id` and call `Shuttle.credit_message` once for each:

```javascript
Shuttle.credit_message({ element: "product-123-bnpl", currency: "USD", amount: "100.00" });
Shuttle.credit_message({ element: "product-456-bnpl", currency: "USD", amount: "149.99" });
```

In a single page app, call it after the element has been rendered: once the page has loaded, a call for an element that is not in the page renders nothing. When the amount changes, for example when the customer changes the quantity, call it again for the same element with the new amount. shuttle.js empties the element and renders the message again.

Alternatively, set `window.shuttle_credit_message_options` to an array of options before the shuttle.js script tag, and shuttle.js renders each one as soon as the page has loaded:

```html
<script>
  window.shuttle_credit_message_options = [
    { element: "product-123-bnpl", currency: "USD", amount: "100.00" },
    { element: "product-456-bnpl", currency: "USD", amount: "149.99" }
  ];
</script>
<script src="https://app.shuttleglobal.com/${shared_key}/${instance_key}/shuttle-1.4.7.js" type="text/javascript"></script>
```

## Options

| Option | Description |
| --- | --- |
| `element` | Required. The `id` of the element to render the message in (a leading `#` is accepted). It must be unique on the page. shuttle.js empties the element before rendering. |
| `amount` | Required. The price the message is for, as a decimal string such as `"149.99"`. |
| `currency` | Required. The currency of the price, as an ISO code such as `USD`. Not every provider offers every currency: Affirm and PayTomorrow work in USD. |
| `type` | Optional. `INLINE` asks PayPal to show its logo inline with the text. Other providers ignore it. |
| `debug` | Optional. `true` to log what shuttle.js is doing to the browser console while you build. |

## Checking availability (optional)

`Shuttle.credit_message` returns a Promise that resolves to `{ is_available: true }` when at least one provider's message was placed in the element, and `{ is_available: false }` when none was. Whether a provider then shows a message for that amount is up to the provider.

```javascript
Shuttle.credit_message({ element: "basket-bnpl", currency: "USD", amount: "249.00" })
  .then(function (result) {
    document.getElementById("basket-bnpl").hidden = !result.is_available;
  });
```

If you would rather know before the page is built, list the merchant's gateways with the [List gateways API](/platforms/reference/operations/listgateways/) and look for `CREDIT_MESSAGE` in a gateway's `features`:

```bash
curl -u "$SHUTTLE_SECRET_KEY:" \
  "https://app.shuttleglobal.com/c/api/instances/M12345/gateways?criteria=status%3DACTIVE%3BLINKED"
```

Do this when the merchant's configuration changes and store the result, rather than on every page view. A gateway can report `CREDIT_MESSAGE` and still show nothing, for example PayTomorrow without its price estimator set up, so treat the list as a guide. Because nothing is rendered when no provider supports it, you can also include the element on every page and skip the check.