Skip to main content

What actually happens during a payment

1

The customer clicks Buy on your site

Your frontend sends the product and quantity to your own backend. It does not call Clink.
2

Your backend creates its own order first

Record what was bought, for how much, and by whom. This record is the source of truth in your system, and every status below hangs off it.
3

Your backend creates a Checkout Session

Clink returns a sessionId and a url. That url is the checkout page.
4

The customer pays

Choosing a payment method, entering card details, and passing 3DS all happen on Clink’s page. You never touch card numbers.
5

Clink sends the result to your webhook

order.succeeded on success, order.failed on failure.
6

Your backend confirms payment, then fulfills

Only after the event is received, verified, and matched to your order do you ship, top up, or grant access.
Step 2 is the one people skip. If you use Clink’s Session as your order record, reconciliation breaks down later: Clink knows someone paid 19.99 USD, but not which user of yours bought which thing.

Three things called “order”

Three things in those six steps can all be called an order: the Checkout Session Clink creates, the Order the customer’s payment produces, and the merchant backend’s own record. Similar names, completely different jobs. One Session can produce several Orders. A customer whose first card is declined and who then pays with a second card produces two Orders under the same Session. So read the Order to determine the payment result, not the Session.

Reading the statuses

Checkout Session

status tells you whether the payment entry point is still usable: paymentStatus separately reports unpaid, processing, or paid, which is convenient for showing progress in your UI. For reconciliation, still read the Order.
expired does not mean the payment failed. A customer may have started a payment moments before expiry, and that Order can still succeed afterwards. Do not mark your order as failed just because the Session expired.

Order

status is the payment result, and the field you map onto your own business status: pending causes the most damage. It means “not known yet”, not “failed”. Starting a second charge here is how customers get billed twice.

What counts as grounds for fulfillment

Exactly one thing: your backend received a signature-verified order.succeeded event, or polled GET /order/{id} and got success, and that Order matches your own order record.
These four look like the money arrived. On their own, none of them count:
  • The customer landed on your successUrl — anyone can type that address
  • The Session status became completed — that only says the entry point closed
  • Your webhook returned HTTP 200 — that only tells Clink you received something
  • A frontend SDK fired complete or session-success — browser events can be forged

Two environments

Clink has a sandbox and a production environment. The sandbox is what people usually call the test environment; no real money moves. The two environments are separate dashboards. You use the same account and password for both, but data and keys are fully isolated — products, customers, and orders created in the sandbox do not exist in production.
During development, log in to the sandbox dashboard at uat-dashboard.clinkbill.com. Keys initialized in the production dashboard start with sk_prod_, and using one against the sandbox API fails authentication with an error that does not mention environments at all.
Test card 4242 4242 4242 4242, any 3-digit CVC, any future expiry. It works in the sandbox only.

Next

Quickstart

Follow along and see a successful order in about fifteen minutes.

Choose an integration

Redirect to checkout, or embed it in your own page.