Skip to main content

Create checkout forms dynamically

Quaderno Checkout is a checkout form that you can use to sell your digital products and subscriptions from any website, email or message.

A Checkout Session represents your customer’s session as they pay for one-off purchases or subscriptions through Checkout.

You can create simple sessions by using Checkout Links.

But if you want to fine tune the Checkout experience for a particular customer or create sessions on-the-fly, you can also create a Checkout Session directly. You can find more information about how to manage the Sessions in our API docs

How to create a Checkout Session and fulfill the order

In this example, you will learn how to create a Checkout Session for your customer and how to asynchrnonously identify the transaction once it has been completed by using the checkout.succeeded event.

Creating the Session

First you need to dynamically create a Checkout Session for your customer (more details here)

curl -u sk_test123123123123123:x \
-H 'Content-Type: application/json' \
-d '{"billing_details_collection":"auto","cancel_url":"string","coupon_collection":true,"customer":{"first_name":"John","last_name":"Doe","email":""},"items":[{"product":"prod_61ffa845b4a0b8"}]}' \

This will return a new session like the following:

"payment_methods":["card", "paypal"],
"name":"A test item",
"description":"This a test item.",

The session's permalink (e.g is the URL your customer will use to complete their purchase.

Please keep in mind this permalink is unique for a specific customer and it can only be used once. If you need to charge another customer, create another session.

As a general recommendation, do not dynamically generate a new session for your customer for a same purchase everytime he loads your page. First check if there's already an existing session generated for him and try to reuse it if it's still pending or abandoned. Otherwise you might end with tons of abandoned sessions.

Fulfilling the order

Due to the SCA (Strong Customer Authentication) requirements, the only way to guarantee the transaction has succeeded is by checking it asynchrnously via webhooks.

Once your customer visits the permalink and completes the purchase, you need to set up some webhooks to track succeeded sessions.

Quaderno provides a checkout.succeeded event to send you a notification every time a customer completes a purchase on the Checkout.

You can subscribe to Quaderno webhooks by using our API (more details here):

# body
"url": "",
"events_types": ["checkout.succeed"]

curl -u YOUR_API_KEY:x \
-H 'Content-Type: application/json' \
--data-binary @body.json \

or by using the web interface (in Developers -> Webhooks -> Create Webhook):


Once you've subscribed to the checkout.succeeded event you need to create an endpoint in your app to handle the webhooks notifications.

This is a what a checkout.succeeded notification should look like:

"response_message":"Checkout succeeded",
"first_name":"John ",
"full_name":"John Doe",
"street_line_1":"Fake Street 1",
"postal_code":"SW15 5PU",

With the session id, product_id and the customer's email you should be able to identify the customer and fulfill the order.

Managing recurring payments

To receive updates from installment plans or subscriptions on PayPal, you can specify where to receive future updates using the custom field:

"…": "…",
"cancel_url": "https://cancel.url",
"success_url": "https://success.url",
"custom": {
"paypal": {
"notify_url": "https://notify.url"
"…": "…"

To achieve the same on Stripe, the webhook notification URL needs to be configured from the Stripe dashboard.