Pay Monthly

See the component in action in the live demo, which runs two of them against a stage checkout configuration.

Advertise a FlexPay monthly payment offer on the pages that come before checkout — a product detail page, a category listing, or a cart. The <flexpay-pay-monthly> component renders a single line,

Pay Monthly from $83/mo ⓘ with flexpay

and its ⓘ button opens FlexPay's information modal, where the customer can see the terms and what their installments would look like.

It is the same offer line the Checkout component shows when FlexPay is enabled, and it reads the same checkout configuration, so what you advertise on a product page is what checkout goes on to offer. It cannot take a payment: there is no payment session behind it, and nothing the customer does in it charges them. Use it to make financing visible early, then let them pay through <checkout-session> as usual.

Step 1: Get your checkout configuration ID (Once)

Ask your account manager for the checkout configuration ID to use, and confirm FlexPay is enabled on it. It is the same kind of ID you already pass when creating a payment session, and the component resolves the FlexPay account and financing limits from it at runtime — so nothing about your FlexPay account is pasted into your page, and moving to live FlexPay is a change on your ClientLoop configuration, not a change to your markup.

This component needs no server-side call: there is no session to create, so nothing here uses your API key.

Step 2: Load the checkout script (Client)

<flexpay-pay-monthly> ships in the checkout bundle. Load it ideally in the <head> of your page. If the page already loads the checkout script for <checkout-session>, you are done — do not load it twice.

<script type="module" src="https://js.clientloop.com/checkout.iife.js"></script>

Step 3: Render the component (Client)

Place it wherever the price is shown, and pass that price as amount.

<flexpay-pay-monthly
  checkout-configuration-id="CHECKOUT_CONFIGURATION_ID"
  amount="999.00"
  currency="USD"
></flexpay-pay-monthly>

By default the component reads your configuration from ClientLoop production. To test your integration against the ClientLoop staging environment, set the optional env attribute to stage:

<flexpay-pay-monthly
  checkout-configuration-id="CHECKOUT_CONFIGURATION_ID"
  amount="999.00"
  env="stage"
></flexpay-pay-monthly>

Omit env (or set it to prod) for production.

Try it against stage

This is the exact markup behind the live demo — a stage checkout configuration with FlexPay enabled. Paste it into a page to see a real offer before you have a configuration ID of your own:

<script
  type="module"
  src="https://js.stage.clientloop.com/checkout.iife.js"
></script>

<flexpay-pay-monthly
  checkout-configuration-id="38wrAJLeirEkhV4uiwp1h3LTE3o"
  env="stage"
  amount="999.00"
  currency="USD"
></flexpay-pay-monthly>

Note that the stage graph only answers pages served from a known ClientLoop origin, so this snippet renders on localhost and on the ClientLoop docs sites but not from an arbitrary host. Ask your account manager to have your own origin added while you integrate.

Attributes

Attribute Required Default Purpose
checkout-configuration-id yes The checkout configuration to read the FlexPay account and limits from.
amount yes The price to quote against, in dollars — "999.00", not cents.
currency no USD USD or CAD. FlexPay supports no other currencies.
env no prod ClientLoop environment the configuration is read from — stage to test.
locale no en-US, or en-CA for CAD The locale FlexPay formats its wording and currency in, e.g. fr-CA.
theme no checkout Theme the line is styled with, matching <checkout-session> by default.
debug no false Logs configuration and offer activity to the browser console.

Step 4: Keep a cart in step (Client)

On a cart, the total moves as items are added and removed. Assign amount and the offer is re-quoted:

<flexpay-pay-monthly
  id="cart-offer"
  checkout-configuration-id="CHECKOUT_CONFIGURATION_ID"
  amount="1499.00"
></flexpay-pay-monthly>

<script>
  const offer = document.getElementById('cart-offer');

  // Call this whenever your cart total changes.
  function cartTotalChanged(total) {
    offer.amount = total.toFixed(2);
  }
</script>

The previous monthly figure disappears while FlexPay prices the new total, so the line never shows a monthly amount that does not match the total next to it. It reappears as soon as the new offer arrives.

Multiple offers on one page

A category or search-results page can hold one <flexpay-pay-monthly> per item — give each its own amount. The configuration lookup, the FlexPay script, its setup and the offer request are all shared across every widget on the page, so twenty products cost the same one lookup and one offer request as a single product.

Every widget on a page must use the same checkout-configuration-id, currency, locale and env: the first one to render sets them for the page.

When nothing renders

The component renders nothing at all unless an offer is available. That is deliberate — an unavailable offer leaves your page exactly as it was, with no empty space or placeholder to design around. Expect an empty result when:

  • the amount is outside the range your configuration will finance,
  • FlexPay declines to quote for the visitor,
  • the checkout configuration ID is wrong, disabled, or has no FlexPay enabled,
  • you are pointed at the wrong env for that configuration ID, or
  • the currency is not USD or CAD.

Add debug while integrating to see what the component is doing in the console; it reports which of these applied. Because the line appears only once an offer arrives, give it a container that can collapse to nothing rather than a fixed-height slot.

Note that the financing range comes from your ClientLoop configuration, not just from FlexPay — so a product priced above your configured ceiling advertises nothing, exactly as checkout would decline to offer FlexPay for it.

Listening for the offer

<flexpay-pay-monthly> emits a DOM CustomEvent each time FlexPay prices an offer for it. It bubbles and is composed, so a single listener on the element sees it.

Event When it fires
flexpay-pay-monthly-offer-changed FlexPay returned a new monthly amount for this widget.

The event's detail is the monthly amount as a plain string of dollars (for example "83"), or an empty string when the offer was withdrawn.

<script>
  const offer = document.querySelector('flexpay-pay-monthly');

  offer.addEventListener('flexpay-pay-monthly-offer-changed', (event) => {
    analytics.track('pay_monthly_offer_shown', { monthly: event.detail });
  });
</script>