When to use it
- You want to get paid this week, not after building a checkout page.
- You’re selling one-time products or services and want a page that just works.
- You’re launching subscriptions and want signup and the first charge handled for you.
- You want card data and PCI scope nowhere near your servers.
How it works
Before you start
- Create a test-mode secret key (
sk_v1_test_...) in the Dashboard. - Have a success page and a cancel page on your site.
1. Create a Checkout Session
CallPOST /v1/checkout/sessions from your server, calculating the amount
from prices you trust, never from the browser.
amountis in cents:15000is $150.00. USD only for now.order_1001is your order’s ID; it threads throughIdempotency-Key,client_reference_id, andmetadataso the webhook can find the order.[email protected]pre-fills the buyer’s email (optional).success_urlandcancel_urlare pages on your site.IONIC_SECRET_KEYis an environment variable holding your test-mode secret key.
price_id instead and Ionic uses
the price you defined there:
cs_... ID on your order and use url unchanged; it carries its
own token (hcs_...), not the session ID.
If the call times out, retry it with the same Idempotency-Key and body to
get the original session back. See Idempotency.
Selling a subscription?
Same call withmode: "subscription", where every line item is a recurring
Catalog price sharing one billing cadence:
price_Monthly00000000000000000 stands in for one of your recurring prices.
Pass customer when the buyer already has an Ionic customer record;
otherwise the hosted page collects their details and creates one. Everything
downstream (redirect, webhook, fulfillment) is identical; see
Subscriptions for the recurring lifecycle:
renewals, dunning, cancellation.
2. Redirect the buyer
From your page, call your server route and follow the returned URL:{CHECKOUT_SESSION_ID} placeholder
in success_url with the real session ID and redirects. The back button
returns the buyer to cancel_url; that and a closed tab both leave the
session open and unpaid.
On your success page, verify before you show “paid”: send the session_id
query value to your backend, retrieve the session with your secret key, and
check both status fields.
open, show a short “Confirming payment” state and
poll your backend.
Don’t call
POST /v1/checkout/sessions/{id}/confirm here; that endpoint
is for Embedded Checkout.3. Fulfill from the webhook
Subscribe an endpoint tocheckout.session.completed and
checkout.session.expired (delivered when a session lapses unpaid, after 24
hours by default). The completed event carries the order references you set at
creation:
Your backend can verify deliveries with
webhooks.unwrap() from the
server SDK. Signature verification
documents the raw-body and header contract. A redirect or browser callback alone
does not prove payment.
Events can be duplicated or arrive out of order. Your application owns order
storage and fulfillment policy under the delivery and acknowledgment
contracts.
Developing locally? Webhooks need a URL Ionic can reach. Expose your dev
server with a tunnel (for example ngrok or cloudflared), register the tunnel
URL as a test-mode endpoint, and pay again. The
webhooks quickstart covers endpoint setup.
See it work
Pay with4111 1111 1111 1111, any future expiration date, and any
three-digit CVC. Then check:
- The buyer lands on your success page.
- Your endpoint receives
checkout.session.completed, and the retrieved session iscompleteandpaid. - The payment appears in your Dashboard.
open and the buyer can retry. More scenarios in
Test cards.
Advanced options
The Checkout Sessions reference has the complete request and response contract. Commonly used:- Known customers: pass
customerto link the session. See Customers. - Optional items and quantities:
optional_itemsoffers add-ons the buyer can select;adjustable_quantityon a line item lets the buyer change the count. Fulfill from the completed session’s line items, not the original cart. - Field collection:
collect_configrequires contact, billing, or shipping fields. - Button label:
submit_typeacceptsauto,pay,book, ordonate. - Expiration:
expires_at, 30 minutes to 24 hours from creation; the default is 24 hours. - Capture and reuse:
payment_intent_datafor supported capture and future-usage behavior. - Metadata: up to 50 keys per session and 20 per line item; non-sensitive values only.
- Apple Pay: offered on the hosted page without merchant domain registration. See Apple Pay.
- Save a card without a purchase: use a Setup Intent; Checkout Session
creation does not accept
mode: "setup". See Save cards.
What’s next
Go live
Swap test keys for live keys and launch.
Refund and capture payments
Refund, capture, or cancel a payment.
Embed checkout on your site
Keep buyers on your own domain.
Sell with a payment link
Turn a catalog price into a reusable link you can share.

