Where the customer pays
Hosted Checkout
SenduiMode: "hostedPage" when creating the Session, hand the returned url to the frontend, and redirect.
successUrl. On that page, look up the local order by merchantOrderId and show the result.
Full server-side code is in Hosted Checkout.
JS SDK redirect and embedded
Install@clink-ai/clink-js and initialize it with a Publishable Key.
redirectToCheckout()sends the customer to the full checkout pageinitEmbeddedCheckout()mounts that same checkout page as an iframe in a supplied container
fetchSession callback. Create it with uiMode: "hostedPage" — the SDK mounts the full hosted checkout page, so elements mode is not involved. The browser only ever sees the Publishable Key and Session-related fields.
Methods, parameters, and events are in the JavaScript SDK reference.
Elements
Elements splits the page in two. The merchant owns the order summary, pay button, promo code input, and status messages. The SDK owns card entry, wallet buttons, 3DS, and QR codes. Two backend changes:- Create the Session with
uiMode: "elements" returnUrlbecomes required. A typical value ishttps://YOUR_DOMAIN/complete.html?session_id={ELEMENTS_SESSION_ID}, where Clink substitutes the real session ID for{ELEMENTS_SESSION_ID}
sessionId to the frontend — not a url, and not Clink’s raw response passed straight through.
publishKey and environment are not part of the Create Session response. They are frontend deployment config, held in a VITE_ or NEXT_PUBLIC_ style environment variable.
Full usage is in Elements.
The embedded mode of
@clink-ai/clink-js and the @clink-ai/clink-elements package are different things. The first mounts a complete checkout iframe; the second mounts composable payment components. Pick one per checkout page.Which endpoint the backend calls
Most website payments use the first.
POST /payment creates a payment server-side without providing a full Checkout UI. It covers more than background charging — customer-present payments, wallets, and QR codes all go through it. What it does not provide is the payment interface, which the merchant builds.
Because there is no hosted UI, when 3DS or another verification is required it returns status: 5 and an action the customer has to be guided through.
Cards and similar methods need a stored payment instrument (paymentInstrumentId) first. Wallets — CashApp, GCash, TNG, WeChat, Kakao, Alipay, QRIS, PromptPay — are created by the backend from the payment method, so none has to be set up in advance.
How to define products
Two modes, chosen by whether the item is a permanent part of the catalog. Registered products — created ahead of time in the dashboard or throughPOST /product and POST /price, then referenced by productId and priceId when creating a Session. Use this for plans, membership tiers, and anything sold long-term. Subscriptions require it, and the price must be a recurring price.
Inline products — not created ahead of time. Describe the name, unit price, and quantity directly in priceDataList when creating the Session. Use this for top-ups, custom amounts, and one-off items.
Both can coexist in one system. Choose per item type.
Amounts in both modes use the major currency unit. USD 19.99 is
19.99, not 1999.Subscriptions require registered products, and the price must be recurring (priceType: "recurring"). Inline items cannot create one — see Subscriptions.Whether to offer discounts
If so, decide where the promo code appears:
Creation rules, validation, and how long a subscription discount lasts are in Discounts and promotion codes.
Write the choices down
Once decided, record these somewhere the team can find them. They determine most of the code below.Next
Hosted Checkout
What to write on the backend, the frontend, and the webhook.
Checkout Session
Every Checkout Session parameter, in detail.
Integrate with an AI agent
If an agent is already writing the code, let it do the integration.