Prerequisites
Before writing Checkout code:- connect the intended Stripe account and environment to the workspace;
- enable conversion tracking;
- configure the website hostname and a Biqli publishable key;
- install
@biqli/analyticsin the browser or use the global script; - keep the Stripe secret key on your server;
- decide whether the flow is a one-time payment, paid subscription, or subscription with trial.
Create Checkout on the server
This Express-style example accepts an authenticated customer and creates a one-time Checkout Session. Validate product and price choices on the server rather than trusting the browser.cs_... ID and Checkout URL. It must not contain your Stripe secret key.
Register and redirect in the browser
storeStripeSession() fails, show a retryable error before redirecting. Do not continue and assume the success page can repair attribution later.
The browser SDK generates an idempotency key for this registration. A repeated exact request is safe. Reusing an identity for another click or reusing an idempotency key with different data is rejected.
One-time payment behavior
Formode: 'payment':
checkout.session.completedcreates a sale only whenpayment_statusispaid;amount_totalis recorded as integer minor units;- the Checkout Session ID is the durable Biqli invoice identity for this path;
- PaymentIntent attribution is stored when Stripe includes it;
- an unpaid completion establishes mapping but creates no sale.
Delayed payment methods
Some payment methods complete Checkout before payment settles.checkout.session.completedcan leave the mapping in an awaiting-payment state.checkout.session.async_payment_succeededrecords the one-time sale after settlement.checkout.session.async_payment_failedmarks the mapped Checkout failed and records no sale.
Declines, 3DS, cancellation, and abandonment
Payment Links and Pricing Tables
Stripe Payment Links and Pricing Tables create the Checkout Session inside Stripe, often after the browser has left the part of your application that knowsbq_id. That means the recommended exact pre-redirect registration is not automatically available.
Do not assume that installing the Stripe App makes arbitrary Payment Link sales attributable. Use one of these approaches:
- Prefer a server-created Checkout Session and register its
cs_...ID. - If your application already knows a verified customer email, create one pending mapping immediately before launch and rely on the unique-email fallback only when one eligible candidate exists.
- Build a trusted server-side attribution flow and use Biqli’s generic sale API after verifying Stripe’s webhook yourself.
Embedded Checkout and custom frontends
Embedded Checkout uses the same principle: create the session on your server and callstoreStripeSession() as soon as the browser receives the session ID, before the customer can complete payment.
If you build directly with PaymentIntents rather than Checkout Sessions, preserve bq_id in your trusted order record and use the server tracking API after verified payment. The managed app’s browser registration endpoint accepts Checkout Session IDs, not arbitrary PaymentIntent IDs.
Keep product data authoritative
Biqli records the paid Stripe amount and currency. Subscription product labels come from invoice line data included in the allowed event payload. Biqli does not make a separate Product or Price lookup just to decorate conversion activity. Use Stripe as the authority for Checkout price, tax, discounts, and final amount. Never calculate the recorded sale from a browser-submitted display price.Production checklist
- Use
stripe_environment: 'live'withcs_live_...sessions. - Use the live Stripe account ID connected to the intended workspace.
- Use an allowed production hostname and the production workspace publishable key.
- Keep all secret keys and Checkout creation on the server.
- Register before every redirect, including retry and upgrade flows.
- Test one real low-value payment and refund before sending production traffic.

