Subscribe a customer
A checkout your customer signs once. Its sub@ id is the subscription's, for life.
Your server creates a checkout; your customer picks a token, chooses how many periods to authorize and signs once from their wallet.
From the catalog · sample terms
Create a subscription checkout
checkout-create-subscription.sh
# A monthly subscription with a 7-day trial. The subscription exists, with the session's id, once# the customer signed (here: started the trial): act on the subscription.created webhook.curl https://api.qbitflow.app/v2/checkout-sessions/subscription \ -H "X-API-Key: $QBITFLOW_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{ "productName": "T-shirt", "description": "Blue, size M", "priceUsd": "4.99", "frequency": { "value": 1, "unit": "months" }, "trialPeriod": { "value": 7, "unit": "days" }, "reference": "order-1043", "successUrl": "https://shop.example.com/orders/success?uuid={{UUID}}", "cancelUrl": "https://shop.example.com/orders/cancel" }'# 201: a CreatedCheckoutSession ({ "link": "https://…/checkout?uuid=sub@…", "uuid": "sub@…", "expiresAt": "…" })// The subscription exists, with the session's id, once the customer signed (here: started the// trial). Act on the subscription.created webhook.const session = await client. checkoutSessions. createSubscription( { productName: 'T-shirt', description: 'Blue, size M', priceUsd: '4.99', // USD per period, a decimal string frequency: { value: 1, unit: DurationUnit.Months }, trialPeriod: { value: 7, unit: DurationUnit.Days }, reference: 'order-1043', successUrl: `https://shop.example.com/orders/success?uuid=${Placeholders. UUID}`, cancelUrl: 'https://shop.example.com/orders/cancel',});console.log(`Redirect the customer to ${session.link}`);session = client. checkout_sessions. create_subscription( product_name="T-shirt", description="Blue, size M", price_usd="4.99", # USD per period, a decimal string frequency=qbitflow. Duration( value=1, unit=qbitflow. DurationUnit. MONTHS), trial_period=qbitflow. Duration( value=7, unit=qbitflow. DurationUnit. DAYS), reference="order-1043", success_url=f"https://shop.example.com/orders/success?uuid={qbitflow. PLACEHOLDER_UUID}", cancel_url="https://shop.example.com/orders/cancel",)print("Send the customer to", session.link) # sub@…: the subscription's id once signedsubscriptions/main.go
// The Subscription exists, with the session's id (sub@…), once the customer signed: act on// the subscription.created webhook.session, err := client. CheckoutSessions. CreateSubscription( ctx, &qbitflow. CreateSubscriptionSessionParams{ ProductName: "T-shirt", Description: "Blue, size M", PriceUSD: "4.99", // USD per period, a decimal string Frequency: &qbitflow.Duration{Value: 1, Unit: qbitflow.DurationUnitMonths}, TrialPeriod: &qbitflow.Duration{Value: 7, Unit: qbitflow.DurationUnitDays}, Reference: "order-1043", SuccessURL: "https://shop.example.com/orders/success?uuid=" + qbitflow.PlaceholderUUID, CancelURL: "https://shop.example.com/orders/cancel",})if err != nil { log.Fatal(err)}fmt.Println("Redirect the customer to", session.Link)$session = $client->checkoutSessions->createSubscription( new \QBitFlow\Params\CreateSubscriptionSessionParams( productName: 'T-shirt', description: 'Blue, size M', priceUsd: '4.99', // USD per period, a decimal string reference: 'order-1043', frequency: \QBitFlow\Models\Duration::months( 1), trialPeriod: \QBitFlow\Models\Duration::days( 7), // the first bill comes after the trial successUrl: 'https://shop.example.com/orders/success?uuid=' . \QBitFlow\Placeholders::UUID, cancelUrl: 'https://shop.example.com/orders/cancel',));echo "Subscribe at {$session->link}\n";This one writes its plan inline: a price per period, a frequency and a 7-day trialPeriod. To sell
a catalog plan, send its productUuid (or productReference): its terms are the defaults, and each
term you send overrides that one.
It answers 201 with a link and a uuid. That uuid (sub@…) is the subscription's id, for
life: every read and webhook names it. Store it with your customer.
Add taxes or the processing fee
A subscription checkout takes the same fees as a payment's (checkout fees):
your lines and processingFee. They're locked with the price: every bill charges the price plus
every line, the session's amountUsd, and the allowance your customer signs is sized on it. In test
mode, a bill is at most $5, lines included.
What your customer signs
- No trial: the subscription itself, an allowance of a number of periods (at least the
checkout's
minPeriods), each at most a maximum amount of the token. The first period is charged at once, the next ones on their due dates. - A trial: a message that moves no funds and authorizes nothing. The subscription starts in
trial; they confirm it (sign the subscription) before the trial ends to be billed. A wallet gets one trial per plan: a wallet that already started one meets409 trial_already_used, and subscribes without the trial instead (skipTrial: trueon its intent).
It doesn't exist until it's signed
Before the customer pays the first period or starts the trial, there is no subscription: reading
sub@… answers 404, and no list has it. Only the checkout exists, with its
status.
Grant access on subscription.created (the next step), sent once it's confirmed on-chain (a trial:
once its message is signed). Never on the redirect: anyone can open your success page, and its
{{UUID}} only says which sub@… to look up.
Check it
The answer's uuid starts with sub@. Pay its link with QBFT faucet tokens: the
same sub@… shows in Dashboard/Subscriptions, trial here,
active for a plan without one.