Quickstart: Create a subscription with Checkout

Use this quickstart to create the beginner subscription path: a customer chooses a plan, completes Checkout, and your backend grants access from confirmed server-side billing events.

What you will build

You will:

  1. Create or select a recurring Price.
  2. Create a Checkout Session in subscription mode.
  3. Send the customer to Checkout.
  4. Handle server-side events.
  5. Store the IDs needed for future renewals and support.
  6. Grant or extend access from invoice events.

Before you start

You need:

  • Paypercut API keys.
  • An internal user, account, workspace, or tenant that will receive access.
  • A Product and recurring Price for the plan.
  • A webhook endpoint that verifies Paypercut signatures.

For pricing setup, see Products and Prices. For webhook signatures, see Webhook Signature Verification.

If you are starting from an empty test account, create the customer, product, and recurring price first. Keep the returned IDs and use them in the Checkout Session request.

curl https://api.paypercut.io/v1/customers \
  -X POST \
  -H "Authorization: Bearer $PAYPERCUT_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: subscription-customer-01" \
  -d '{
    "email": "customer@example.com",
    "name": "Example Customer"
  }'
curl https://api.paypercut.io/v1/products \
  -X POST \
  -H "Authorization: Bearer $PAYPERCUT_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: subscription-product-01" \
  -d '{
    "name": "Pro plan"
  }'
curl https://api.paypercut.io/v1/prices \
  -X POST \
  -H "Authorization: Bearer $PAYPERCUT_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: subscription-price-01" \
  -d '{
    "product": "01HPRODUCT000000000000000",
    "type": "recurring",
    "currency": "EUR",
    "unit_amount": 1900,
    "recurring": {
      "interval": "monthly",
      "interval_count": 1,
      "usage_type": "licensed"
    }
  }'

Flow overview

Step Actor Action
1 Your backend Creates a Checkout Session in subscription mode.
2 Your frontend Redirects or embeds the Checkout Session.
3 Customer Completes Checkout.
4 Paypercut Creates the subscription flow and sends server-side events.
5 Your backend Stores IDs and processes checkout_session.completed, invoice.paid, and invoice.payment_failed.
6 Your backend Grants, extends, or recovers access from confirmed state.

Step 1: Create or select a recurring Price

Subscription Checkout line items must use recurring pricing. Use a catalog Price for plans you sell repeatedly.

Store the price_id with your internal plan, such as:

Internal plan Paypercut Price
pro_monthly 01HFRECURRINGPRICE000000000

Do not use a one-time Price for a subscription Checkout Session.

Step 2: Create a Checkout Session in subscription mode

Create a Checkout Session from your backend. This example uses the public Checkout Session create shape.

curl https://api.paypercut.io/v1/checkouts \
  -X POST \
  -H "Authorization: Bearer $PAYPERCUT_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: checkout-subscription-01" \
  -d '{
    "mode": "subscription",
    "ui_mode": "hosted",
    "currency": "EUR",
    "customer": "01HD7M6DRKZ4Q4QEVWJB0RC1S6",
    "line_items": [
      {
        "price": "01HFRECURRINGPRICE000000000",
        "quantity": 1
      }
    ],
    "success_url": "https://example.com/billing/success",
    "cancel_url": "https://example.com/billing/cancel",
    "client_reference_id": "user_123"
  }'

Use client_reference_id or your own database row to connect the Checkout Session to your internal user or account.

Step 3: Send the customer to Checkout

Use the Checkout Session url returned by the API to redirect the customer, or render the session with the Paypercut checkout SDK if you are using embedded Checkout.

The success URL should show a confirmation or pending state. Do not grant production access only because the customer reached this URL.

Step 4: Handle server-side confirmation

Configure webhooks before going live.

At minimum, handle:

Event What to do
checkout_session.completed Retrieve or store the Checkout Session and linked subscription.
invoice.paid Grant or extend access for the paid billing period.
invoice.payment_failed Start recovery and fetch the latest subscription and invoice state.

Step 5: Store IDs and grant access

Store:

  • your internal user, account, workspace, or tenant ID;
  • customer_id;
  • price_id;
  • checkout_session_id;
  • subscription_id;
  • relevant invoice_id values;
  • webhook event or delivery IDs for idempotency.

Grant or extend paid access after your backend processes a paid-period signal, such as invoice.paid, and maps the invoice back to the subscription and internal account.

Step 6: Test the flow

Before going live, test:

  1. Checkout Session creation.
  2. Hosted or embedded Checkout completion.
  3. checkout_session.completed delivery.
  4. invoice.paid handling.
  5. invoice.payment_failed handling.
  6. Duplicate webhook delivery idempotency.
  7. The success URL when the webhook has not been processed yet.

Do not do this

  • Do not grant access only from the success URL.
  • Do not skip webhook handling.
  • Do not use a one-time Price for subscription Checkout.
  • Do not lose the mapping between your internal user or account and the Paypercut Customer or Subscription.
  • Do not use PaymentIntent events as the primary subscription lifecycle source.
  • Do not assume public subscription.* webhooks exist.
  • Do not assume send_invoice is supported for this beginner path.

Next