Collecting payment

Loop offers two types of pre-built payment UIs to accept payments online

  1. Loop hosted-payment links to embed or share a link to a Loop payment page to accept payments
  2. Checkout sessions component, a low-code, prebuilt payment form that can embedded into your website

Both payment types use Checkout Sessions API to instantiate the payment instance.


Checkout sessions overview

Checkout sessions define the Stripe products, using price-ids, and if applicable the cus-id, inv-id, sub-id, ref-id, metadata, coupons, free trials parameters. This allows Loop to either create a new subscription in Stripe with the desired requirements or link a payment to an existing customer / subscription in Stripee.

Checkout Sessions come in two types: general-purpose (reusable templates) and one-time (session-specific) links.

General-Purpose

General-purpose links are reusable templates created with the template: true parameter.

Characteristics:

  • Reusable: Can be shared and used multiple times
  • Evergreen: Never expire
  • Fixed parameters: All generated one-time links will have the same parameter values
  • Template behavior: Best for scenarios where all customers should have identical parameters

Behavior: Each time a customer clicks a general-purpose link, a new one-time payment link is automatically generated with a unique id. This new link represents that specific customer's payment session and inherits all the same parameter values from the template.

One-Time

One-time links are session-specific and handle individual customer payments.

Characteristics:

  • Single-use: Become inactive after successful payment
  • 14-day expiration: Valid for 14 days from creation
  • Unique parameters: Can include unique values for each customer (cus-id, inv-id, sub-id, ref-id, metadata, coupons, free trials)
  • Customer-specific: Each link can have different parameter values

Creation:

  • Automatically generated when a general-purpose link is clicked
  • Created directly via API for specific customers

When to Use Each Type

Use CaseLink TypeReason
Public product page with fixed discountGeneral-purposeSame discount for all customers
Email marketing with universal couponGeneral-purposeOne coupon code works for all recipients
Customer-specific invoiceOne-timeRequires unique inv-id for each customer
Existing customer checkoutOne-timeRequires unique cus-id for each customer
Existing subscriptionOne-timeRequires unique sub-id for each customer
Personalized referral linksOne-timeRequires unique ref-id for each customer

Important Rule

If you need unique parameter values for different customers (e.g., different ref-id, cus-id, inv-id, or custom metadata for each customer), you must create individual one-time links for each customer. General-purpose templates can only create one-time links with identical parameter values.


Checkout Sessions endpoint

Payment links can be made by calling the Checkout Sessions endpoint.

Required parameters

Links must either contain elements, externalSubscriptionId or an externalInvoiceId. These inputs are mutually exclusive. This is the only required field.

As noted above, payment links can either be general-purpose links that are reusable and not tied to a specific customer, subscription or invoice or one-time links that once consumed they become inactive. General purpose links are created using the parameter template: true.

Each time a customer clicks on a general purpose link, a new one-time payment link is created with a unique id. This link represents a specific customer's payment session and once a payment confirms with that link, it will become inactive.

One-time payment links are valid only for 14 days. Conversely, general-purpose payment links are ever-green and can continue to generate new one-time payment links when clicked on by a customer.

Below we go through some example links to help outline how to use the endpoint.

Take payment for a new subscription or purchase

To take a payment for a new subscription or purchase, you will need to define the element(s). An element is the Stripe products (sometimes referred to as items in Loop) the customer is purchasing. Elements are defined by using either Stripe’s price-id or Loop’s internal item-id. You can combine multiple items in one payment link.

In Stripe, price-ids can be found under Product Catalogue -> Products -> Price, in the top right corner. They started with price_

When combining multiple products with recurring payment terms, the combination of products must follow Stripe rules for a valid subscription. Thus, the products must have the same payment frequency (e.g. monthly payments). Products that take a one-time payment can be combined with any frequency.

To take a payment for an existing Stripe customer, pass in the externalCustomerId along with the elements.

The externalCustomerId looks like cus_SEQNcTSJ7jSktU. This id can be found by clicking on the specific customer you want to charge, under details.

<h4>To take a payment for a new subscription that you want to start on a specific date<h4>

To take a payment for a new subscription that you want to start on a specific date (e.g. Jan 1), use the billDate in conjunction with the elements.

Switch an existing Stripe customer with an existing Stripe subscription to crypto

To switch an existing Stripe customer with an existing Stripe subscription to pay in crypto, create a link using the externalSubscriptionId. There is no need to pass in any elements, invoice-id/number or customer-id - we will automatically grab the products for you based on the subscription's details.

Please note, if you just made a new subscription in Stripe and Stripe just made the 1st invoice, you must finalize that first invoice in Stripe before sending the payment link. When you do this, Stripe will set the due date to midnight UTC in your account's timezone. Loop collects on payments based on Stripe's due date. Thus, if you want this payment to be collected immediately, set the payInvoiceImmediately: true.

Example sub-id: sub_1RJwTRPRR297Cb62I2FSWjgi

When switching a customer from fiat to crypto, Loop will charge the customer on the billDate for the next upcoming invoice, using the exact due date to the minute.

If you are modifying a subscription (i.e. changing the products), resetting the billing cycle, and moving the customer to crypto, you should use the payInvoiceImmediately in conjunction with the sub-id. The payInvoiceImmediately parameter will ignore the Stripe bill date and process the invoice immediately. This is important because when you reset the billing cycle, Stripe will finalize the invoice in 1 hour and by default set the bill date to midnight UTC (it will display the bill date in your account's timezone - i.e. you may see a time that is the next day or before midnight if your account is not in UTC). Thus, if you want to get paid immediately, you can override this by using the payInvoiceImmediately: true parameter.

Charging for an invoice that is not tied to a Stripe subscription

To charge for an invoice that is not tied to a Stripe subscription, you can create a Checkout Session using either the externalInvoiceId or the externalInvoiceNumber.

Example externalInvoiceId: in_1RJwTRPRR297Cb62OuQn6ogQ Example externalInvoiceNumber: A3XRD8ZK-0004

Additional parameters

Loop provides several additional parameters:

ParameterDescription
freeTrialDaysOnly for subscriptions. If provided, the Stripe subscription will be created with this trial period.
couponCodeWe use the user facing code, called the promotion codes, as the input (e.g. SUMMERSALE) If provided, the discount will automatically be applied to the payment link. We only support certain coupon parameters defined here
emailIf provided, the customer will not be able to change this email. If a Stripe customer does not exist, it will be created with this email.
referenceIdThis will be included in all webhooks
cartEnabledEnable or disable cart on the checkout page
MetadataInfo that will be included on the Agreement Created webhook (Loop webhook) that is sent when someone uses the payment link to attach a payment method
minimumAllowanceAmountBy default loop requires payers to have enough to make the first payment made via loop. You can require an amount higher than the 1st payment using this parameter.
minimumBalanceAmountBy default loop requires the customer to have enough to cover the first payment made via loop, you can require a higher amount using this parameter.
successUrlIf you would like to provide a dynamic redirect link specific to individual customers at the end of the checkout session, use this parameter. By passing this URL it sets the redirect link for that session and will override any redirect URL set at the entity or merchant level.

Dynamic URL redirect

As noted above in the table, you can use the parameter successUrl if you would like to have a dynamic redirect at the end of the checkout session. This allows you to direct specific users to a login page or their dedicated dashboard after checkout is complete.

The redirect URL is embedded within the Return button on the confirmation screen.