Skip to main content
Hosted Checkout is the fastest way to take a payment with Ionic: one API call from your server, a redirect, and you’re done. Ionic hosts the payment page (the card form, Apple Pay, declines and retries) so you never build payment UI or touch card data.

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.
Create Checkout Sessions from your server. Never expose an Ionic secret key in browser code, a mobile app, a public repository, or a client-visible error.
On Node, install the server SDK: typed requests and responses, an idempotency key generated for each call, and automatic retries on transient failures.
Every step below also shows raw curl. Finished the Quickstart? Skip to Fulfill from the webhook.

1. Create a Checkout Session

Call POST /v1/checkout/sessions from your server, calculating the amount from prices you trust, never from the browser.
In this example:
  • amount is in cents: 15000 is $150.00. USD only for now.
  • order_1001 is your order’s ID; it threads through Idempotency-Key, client_reference_id, and metadata so the webhook can find the order.
  • [email protected] pre-fills the buyer’s email (optional).
  • success_url and cancel_url are pages on your site.
  • IONIC_SECRET_KEY is an environment variable holding your test-mode secret key.
The line items here are inline: a name, an amount, a currency. If you sell from your Catalog, send a price_id instead and Ionic uses the price you defined there:
Inline items are the quickest way to start. Catalog prices keep amounts in one place and are required for subscriptions. The response includes the session and its hosted URL:
Save the 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 with mode: "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:
When the buyer pays, Ionic replaces the {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.
If the session is still 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 to checkout.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:
Verify the signature on the raw body before parsing. On Node, webhooks.unwrap() from the server SDK checks the signature and replay window, then returns a typed event; this Next.js example uses it. On another stack, Verify signatures has the manual implementation in Node, Python, and Go.
app/api/webhooks/ionic/route.ts
fulfillOrderOnce stores the event ID under a unique constraint so each order fulfills once, and hands slow work (shipping, provisioning, email) to a queue. Ionic delivers events at least once and in no guaranteed order; see Idempotency and retries. Ionic doesn’t email the buyer a receipt; send your order confirmation from this fulfillment path.
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 with 4111 1111 1111 1111, any future expiration date, and any three-digit CVC. Then check:
  1. The buyer lands on your success page.
  2. Your endpoint receives checkout.session.completed, and the retrieved session is complete and paid.
  3. The payment appears in your Dashboard.
If all three check out, you have a working integration. When you’re ready, go live. To see a decline, create a session whose total is under $1.00; the session stays 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 customer to link the session. See Customers.
  • Optional items and quantities: optional_items offers add-ons the buyer can select; adjustable_quantity on a line item lets the buyer change the count. Fulfill from the completed session’s line items, not the original cart.
  • Field collection: collect_config requires contact, billing, or shipping fields.
  • Button label: submit_type accepts auto, pay, book, or donate.
  • Expiration: expires_at, 30 minutes to 24 hours from creation; the default is 24 hours.
  • Capture and reuse: payment_intent_data for 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.

Next steps

Webhooks

Verify signatures and manage endpoints.

Going live

Swap test keys for live keys and launch.

Refunds and captures

Refund, capture, or cancel a payment.

Embedded Checkout

Keep buyers on your own domain.