Use Hosted Checkout

Guide

A checkout session is a branded, CHING-hosted payment page. You create it, redirect the customer, and CHING handles card entry, 3DS, charging, and fulfilment of the resulting subscription, one-off purchase, or cart.

When to use it

  • You want zero PCI scope and no custom card UI.
  • You want a consistent upgrade / downgrade flow for subscriptions.
  • You're building a marketing site that needs a "Buy now" button.
  • You run your own e-commerce site and want CHING to charge an arbitrary cart of items.

Two modes

The same endpoint accepts two body shapes - pass exactly one:

  • price mode - price references a row in your CHING prices table. Use this for subscription products and for catalog one-time prices you maintain in CHING.
  • cart mode - line_items is a list of ad-hoc items (name, amount, quantity, optional description and image). Useful when the SKUs live on your storefront and not in CHING. Negative line amounts render as discounts; the cart sum must be non-negative.

The Flow

  1. Create a customer (or re-use an existing one).
  2. POST /v1/checkout_sessions with either a price id or a list of line items, plus your success / cancel URLs.
  3. Redirect the customer to the returned url.
  4. When the customer completes the session, CHING redirects them to your success URL. The resulting charge or subscription fires its own webhook (charge.succeeded for one-off prices and carts, subscription.created for recurring), so fulfil from those instead of the browser landing.

Create the session - price mode

curl -X POST https://api.ching.co.il/ching/v1/checkout_sessions \
  -H "Authorization: Bearer ck_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "customer": "cus_V8ltq1pK_MWH",
    "price": "price_QA8qF3B3VIqE",
    "success_url": "https://app.example.com/welcome",
    "cancel_url": "https://app.example.com/pricing"
  }'

Create the session - cart mode

curl -X POST https://api.ching.co.il/ching/v1/checkout_sessions \
  -H "Authorization: Bearer ck_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "customer": "cus_V8ltq1pK_MWH",
    "line_items": [
      { "name": "Blue T-Shirt (M)", "amount_agorot": 12000, "quantity": 2 },
      { "name": "Shipping",         "amount_agorot": 1500,  "quantity": 1,
        "description": "Standard delivery" },
      { "name": "Discount: WELCOME10", "amount_agorot": -1500, "quantity": 1 }
    ],
    "success_url": "https://shop.example.com/thank-you",
    "cancel_url":  "https://shop.example.com/cart"
  }'

Amounts are gross (VAT-inclusive). Compute shipping yourself and pass it as a line item - CHING does not collect addresses or calculate shipping rates.

Skipping invoice issuance

By default CHING issues a tax invoice receipt for every successful charge produced by a checkout session (one-time, cart, subscription start, subscription upgrade). If you handle invoicing elsewhere, opt out per-session:

{ ..., "create_document": false }

Subscription renewals (issued by the renewal cron, after the initial charge) are not affected by this flag.

Fulfil server-side

Don't rely on the browser landing on your success URL - customers close tabs. Fulfil from the underlying resource event:

// Pseudo-code inside your webhook handler
switch (event.type) {
  case "charge.succeeded":
    if (event.data.line_items) {
      // Cart checkout completed. event.data.line_items mirrors the line items
      // you posted, and event.data.checkout_session lets you correlate.
      await fulfilCart(event.data.customer, event.data.line_items);
    } else {
      // Single one-off price checkout. event.data.customer tells you who.
      await grantOneOffPurchase(event.data.customer, event.data.id);
    }
    break;
  case "subscription.created":
    // Subscription checkout completed. Ignore incomplete status (customer's
    // card was declined) and wait for a follow-up charge.succeeded.
    if (event.data.status === "active" || event.data.status === "trialing") {
      await grantAccess(event.data.id);
    }
    break;
}
No dedicated checkout event yet:Hosted checkout doesn't emit its own completion webhook - subscribe to charge.succeeded and subscription.created to observe the outcome.