Create a payment Link

Below we discuss:

  1. What is in a payment link?
  2. What happens during the checkout process?
  3. Payment Link architecture
  4. How to create a payment link with and without code
  5. FAQs

What is in a payment link?

A payment link is a Loop-hosted payment page that allows a customer to purchase one or many products, start a subscriptions or pay an invoice. Your customers click a button on your site and get redirected to a payment page hosted by Loop. Payment links are designed to be a customizable and reduce your development time.

To create a payment link, merchants define the Stripe products (using Stripe’s price-ids) they would like the customer to see and purchase. Payment links can be created with no-code by using the company dashboard or by calling the Checkout Sessions Endpoint.

Payment links can:

  • Take an immediate payment for an invoice, product purchase, or subscription purchase and record the customer, invoice, and subscription in Stripe
  • Take immediate payment for an existing Stripe subscription and set future invoices for that subscription to be paid by crypto
  • Collect a payment method to charge a customer in the future for an existing Stripe subscription or invoice

Payment links are completely configurable. Below we outline the various configurations a payment link can have, from free trials to acceptable tokens to pre-filled coupons and emails.

Payment Links: General Purpose and One-time

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

General-Purpose Links

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 Links

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.


What happens during the checkout process?

When a customer uses a payment link, Loop will:

  1. Create a new customer in Stripe or find an existing customer
  2. Tell Stripe about the product(s) being purchased
  3. Stripe creates an invoice based on the billing settings associated with the products and/or subscription purchased
  4. Loop charges the customer onchain based on the Stripe bill and checkout session settings
  5. Loop marks the invoice in Stripe as paid, adding the tx hash, wallet address and amount to the invoice's metadata and saves this data in our backend for easy querying

These steps happen within a matter of seconds, with any delays due to chain confirmation times. The customer will be held on the payment page until the payment is confirmed.


Architecture

The base URL for all Loop payment links is:

checkout.loopcrypto.xyz/<checkout-sessions-id>

Where a checkout-session-id looks like cs_01jtnkb6gafqfvhq4j37xydxdr This id is provided in the response to the Checkout Sessions endpoint and the full link is provided on the company dashboard.

For demo accounts, the environment is defined by adding demo to the link:

demo.checkout.loopcrypto.xyz/<checkout-sessions-id>

Important Notes

  1. Every checkout session will be a unique ID regardless if the details are the same
  2. By default checkout sessions expire in 14 days
  3. Currently, the tokens that a payment link can be paid with are defined at the product level. By default all items accept USDC on the networks that are deployed for your account. If you’d like to accept additional tokens, you can add them while creating the payment link on the dashboard or via API call to the update _items_ endpoint for all the products contained in the link. A link for multiple products will accept the subset of tokens that both products accept.
  4. To apply a free trial to a subscription, you must set this as a parameter in the checkout sessions creation. This can be done with no-code or by API.

Creating a payment link

No-code

Loop’s dashboard makes it easy to create a payment link. You can create two types of links:

  1. General purpose link: For new customers. Reusable across multiple customers, like on your website or in marketing emails.
  2. Link for a specific customer: Tied to an existing customer in Stripe. Useful for sending personalized links or managing subscriptions.

Here is a quick walkthrough video.

For Developers

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.


FAQs

Can I programmatically generate checkout URLs?

Yes, you can programmatically generate checkout URLs using the Create CheckoutSessions endpoint.

When should I generate checkout sessions dynamically vs. using the dashboard?

Generate checkout sessions from your front-end when you need to pass parameters that change with each purchase, such as reference IDs, success URL redirects, or metadata. This allows you to create links with unique parameters for each transaction. The pre-generated dashboard checkout URL works best for no-code solutions with static parameters.

Can I pre-fill the customer's email address?

Yes, you can automatically populate the email address using the email parameter on the checkout sessions endpoint. When this parameter is provided, the email address is automatically filled on the checkout page and the customer cannot edit it.

How does subscription billing work with Loop?

Each billing cycle, Stripe creates an invoice and Loop automatically listens for this invoice to charge the customer. As long as Stripe has a finalized invoice for the subscription and the customer's payment method has no issues, Loop will charge the customer and mark the invoice in Stripe as paid.

How do payment authorizations work?

When customers make their first payment, they also set an authorization amount for future payments. This isn't a pre-payment but rather permission to charge them automatically going forward. The authorization typically covers a full year of payments, so customers won't need to approve individual transactions since they've already pre-authorized them.

What happens if a customer's authorization runs low?

If the authorization amount runs low, customers receive an email from Loop directing them to the customer portal (my.loopcrypto.xyz) to increase their approval limit.

Can I require customers to set a minimum authorization amount?

Yes, you can force customers to set an approval for any amount you specify (as long as it's higher than the cost of the first payment) using the minimumAllowanceAmount parameter on the checkout session.

How should I monitor payment confirmations?

We recommend listening to Stripe's webhooks to confirm payments. However, if you passed parameters like reference IDs or metadata, you'll need to listen to Loop's TransferProcessed webhook instead. These webhooks fire for both the initial payment and any recurring payments.

When do Loop webhooks fire?

Loop's TransferProcessed webhook fires for both the first payment and any recurring payments when you need to track custom parameters like reference IDs or metadata that aren't available in Stripe's webhooks.