Skip to content
ripper docs Open the console

Checkout sessions

A session is one amount, for one shopper, with a 30-minute life. Create it on your server when you want the amount to be verified, then hand the client_secret to your page and let the checkout do the rest. Never log or store a client secret.

POST /v1/checkout/sessions #

Create a checkout session

Authentication. Your secret key, in X-Ripper-Api-Key. Server only.

Creates a session for one amount. Send the client_secret from the response to your page and pass it to the checkout; never log it or store it. The session expires 30 minutes after it is created. A session created on your server counts as a verified amount.

Requires a secret key with the create_payments permission. The session uses your default integration.

parameter in required what it is
Rip-Idempotency-Key header yes A key you choose for this create, for example your order id plus an attempt number. Retrying with the same key and body returns the first response instead of creating a second session. Up to 255 printable ASCII characters.

The body you send

{
  "amount": 2500,
  "currency": "GBP",
  "customer": {
    "email": "shopper@example.com",
    "name": "Sam Shopper"
  },
  "metadata": {
    "order_id": "1042"
  },
  "statement_descriptor_suffix": "ORDER 1042",
  "order_reference": "ORDER-1042"
}

Fields in the body you send

field type always sent what it is
amount integer yes The amount in the currency's minor unit.
currency string yes A three-letter ISO 4217 code, for example GBP.
items array no The basket, shown to the shopper on the payment page and returned on every read of this session and its payment. At most 100 lines. TWO RULES THAT CATCH PEOPLE OUT, both of which refuse the whole request: A line that carries its own unit_amount must also carry a name. A sku alone is enough for a line you are pricing from your catalogue, but not for one you are pricing yourself — the name is what the shopper reads on the page, and ripper will not invent it. The basket may not come to less than nothing. Discount lines are subtracted, so a basket whose discounts exceed everything else on it is refused rather than clamped to zero. This is the only rule here about the basket as a whole; every other rule is about one line. amount still decides what is charged. When the lines do not add up to it, the difference is shown to the shopper as one adjustment rather than the basket being refused.
customer object no The shopper. Every payment needs an email; if you leave it out here, the checkout asks the shopper for it.
metadata object no Up to 50 string values of your own, 8 KB in total. Keys come back exactly as you sent them.
statement_descriptor_suffix string no Added to the name on the shopper's card statement.
order_reference string no Your order reference, shown to the shopper on the confirmation page and stored on the payment. 1 to 64 characters with no control characters. A run of 13 to 19 digits that could be a card number is refused; use fewer digits or put a letter among them.
confirmation_url string no Where to send the shopper after the payment, instead of your integration's setting. An absolute https URL on one of your default integration's allowed origins, with no user information, no fragment, no IP address as the host, and no payment_id or order_reference query parameter (ripper adds those).

items fields

field type always sent what it is
kind string no What this line is. Absent means product. Delivery is a shipping line and a reduction is a discount line carrying a POSITIVE unit_amount that is subtracted — never a negative amount.
sku string no Your code for the item. A line needs this or a name.
name string no What the shopper sees. A line needs this or a sku, and always needs it when the line carries its own unit_amount.
quantity integer yes How many. At least 1.
unit_amount integer no What the shopper pays per unit, tax INCLUSIVE, in the currency's minor unit. Not negative: a reduction is a line whose kind is discount.
tax_amount integer no The tax INSIDE this line's total — that is, inside quantity x unit_amount — in minor units. Between 0 and that total.
tax_rate integer no This line's tax rate in basis points, where 2000 is 20.00%.
type string no Your own label for the kind of thing this is, at most 32 characters.

customer fields

field type always sent what it is
email string no The shopper’s email address.
name string no The shopper’s name.
account_id string no Your own identifier for this shopper, returned on the session read, the payment read and the webhook. Same rule as order_reference: 1 to 64 characters, no control characters, and a run of 13 to 19 digits that could be a card number is refused. It is yours and is not checked for uniqueness.
metadata object no Up to 50 string values of your own about this shopper, 8 KB in total. This is customer.metadata and it has its OWN budget, separate from the session's top-level metadata — the two are measured apart, not against one shared limit. Keys come back exactly as you sent them.

201 — The session was created, or a retry with the same idempotency key replayed it.

{
  "id": "cs_0123456789abcdef01234567",
  "client_secret": "cs_0123456789abcdef01234567_secret_9f8e7d6c5b4a39281706f5e4d3c2b1a09f8e7d6c5b4a39281706f5e4d3c2b1a0",
  "status": "requires_payment",
  "mode": "test",
  "amount": 2500,
  "currency": "GBP",
  "public_key": "rip_pk_EXAMPLE-KEY_00000000abcZ",
  "config_url": "/v1/checkout/config/rip_pk_EXAMPLE-KEY_00000000abcZ",
  "created_at": "2026-09-16T10:15:00.0000000+00:00",
  "expires_at": "2026-09-16T10:45:00.0000000+00:00",
  "expires_in_seconds": 1800
}

Fields in the response

field type always sent what it is
id string yes The session. Send its client_secret to your page; send this to us.
client_secret string yes Pass this to the checkout on your page. It is returned only here.
status string yes Where the session is in its life. A new session has taken no attempts yet.
mode string yes test or live. A test session can take only test cards.
amount integer yes What the shopper will be charged, in the currency’s minor unit.
currency string yes A three-letter ISO 4217 code, for example GBP.
public_key string yes Your publishable key, which the checkout loads the session with.
config_url string yes The configuration read's path, relative to the API host.
created_at string yes When the session was created.
expires_at string yes When the session stops accepting attempts.
expires_in_seconds integer yes How long the session has from now.

When it refuses

Operation id createCheckoutSession, for code generators.

GET /v1/checkout/sessions/{session_id} #

Retrieve a checkout session

Authentication. Your secret key, in X-Ripper-Api-Key. Server only.

Returns one of your sessions. A session past its expiry reads as expired straight away. The session's status is the checkout's own progress; succeeded means the shopper paid, and the payment itself is read with payment_id.

Requires a secret key with the read_transactions permission.

parameter in required what it is
session_id path yes The session's id.

200 — The session.

{
  "id": "cs_0123456789abcdef01234567",
  "status": "succeeded",
  "mode": "test",
  "amount": 2500,
  "currency": "GBP",
  "customer": {
    "email": "shopper@example.com",
    "name": "Sam Shopper",
    "account_created": null,
    "account_id": "your-customer-4821",
    "metadata": {
      "tier": "gold"
    }
  },
  "metadata": {
    "order_id": "1042"
  },
  "attempt_count": 1,
  "last_decline": null,
  "payment_id": "pay_89abcdef0123456789abcdef",
  "settlement": null,
  "created_at": "2026-09-16T10:15:00.0000000+00:00",
  "expires_at": "2026-09-16T10:45:00.0000000+00:00",
  "expires_in_seconds": 1612,
  "integration": "Default",
  "minted_by": "server",
  "amount_verified": true,
  "amount_verification_source": "server_minted",
  "amount_verification_detail": null,
  "hold": null
}

Fields in the response

field type always sent what it is
id string yes The session. Send its client_secret to your page; send this to us.
status string yes Where the session is in its life, from created to a finished payment or an expiry.
mode string yes test or live. A test session can take only test cards.
amount integer yes What the shopper will be charged, in the currency’s minor unit.
currency string yes A three-letter ISO 4217 code, for example GBP.
items array or null no The basket, as sent on the server create. null when the session carried no lines — never an empty array, so "no basket" and "an empty basket" stay different answers.
basket_total integer or null no What the lines add up to, in minor units, tax inclusive: products, shipping and fees added, discounts subtracted. Computed by ripper and never accepted in a request. null when there are no lines. When it differs from amount, amount is what was charged and the difference is shown to the shopper as one adjustment.
tax_total integer or null no The tax across the lines, in minor units. null when no line carries a tax_amount.
customer object or null yes The shopper, as you or the checkout supplied them.
metadata object yes The metadata you sent when you created this session, keys exactly as you sent them.
attempt_count integer yes Payment attempts opened, at most 3.
last_decline object or null yes The most recent decline on this session, or null when there has not been one.
payment_id string or null yes The payment this session produced, or null while it has not produced one.
settlement string or null yes awaiting_reconciliation while ripper confirms the outcome of an attempt the acquirer did not answer. Money may already have moved, so do not release goods and do not treat the payment as failed while it is set — reconciliation resolves it, not a clock in the checkout.
created_at string yes When the session was created.
expires_at string yes When the session stops accepting attempts.
expires_in_seconds integer yes Seconds left; 0 once expired.
integration string or null yes The name of the integration the session belongs to.
minted_by string or null yes server when your server created the session, client when the checkout did.
amount_verified boolean yes Whether ripper could check the amount against your price list before charging it. When it could not, an approved payment is held for you to review rather than captured.
amount_verification_source string yes What ripper checked the amount against: the server that created it, your integration’s default, your price list, nothing, or a mismatch.
amount_verification_detail string or null yes Why the amount did not verify, when the source is a mismatch. null otherwise.
hold object or null yes Why this session’s payment is on hold and what was decided, or null when it was never held.

items fields

field type always sent what it is
kind string yes What this line is: product, shipping, discount or fee. A discount carries a positive unit_amount that is subtracted.
sku string or null yes Your code for the item, or null if the line had none.
name string or null yes What the shopper was shown, or null if the line was priced from your catalogue and carried no name.
quantity integer yes How many.
unit_amount integer or null yes What the shopper paid per unit, tax inclusive, in the currency’s minor unit. null on a line your catalogue has not priced.
tax_amount integer or null yes The tax inside this line’s total, in minor units, or null when the line carries no tax.
tax_rate integer or null yes This line’s tax rate in basis points, where 2000 is 20.00%, or null when none was set.
type string or null yes Your own label for the kind of thing this is, or null.

customer fields

field type always sent what it is
email string or null yes The shopper’s email address, or null when none was given.
name string or null yes The shopper’s name, or null when none was given.
account_created string or null yes When the shopper's account with you was created, if a browser session sent it.
account_id string or null yes Your own identifier for this shopper, exactly as you sent it. null when none was sent. Set from a browser session it is whatever the page sent, so treat it as the page's claim rather than as something ripper has checked.
metadata object or null yes Your own values about this shopper, keys exactly as you sent them. null when none were sent. This is the CUSTOMER's metadata; the session's own metadata is a separate field with a separate budget, and the two are never merged.

last_decline fields

field type always sent what it is
code string yes The decline code.
category string or null yes How to treat the decline: soft, hard, fraud, network or provider_error. Since v1.13 the word is the same snake_case everywhere — these routes, the webhook and the checkout — where the merchant routes and webhooks previously spelled it Soft, Hard, ProviderError and so on. It is the payment platform's own category, relayed unchanged rather than re-classified here.
reason string or null yes The acquirer's own words, passed on as received.

hold fields

field type always sent what it is
status string yes Where the hold is. pending_review and escalated are both still waiting on a decision — escalated means a person is looking at it rather than a rule. captured means the money was taken. voided means the hold was released and nothing was taken, and it is final: it is not another kind of waiting. DO NOT RELEASE GOODS until this says captured. That holds for all four values, including escalated, which can still end either way.
reason string yes no_price_list: there was nothing to check the amount against. mismatch: the amount did not match.
detail string or null yes More about why, when there is more to say.
deadline string yes When the hold must be decided by.
decided_by string or null yes Who decided: you, or ripper on your rules.
decided_at string or null yes When the decision was made, or null while it is still waiting.
operation_refusal object or null yes The last capture or void the acquirer refused, if any.

hold.operation_refusal fields

field type always sent what it is
kind string yes Which operation was refused.
sequence integer yes Which attempt this refusal belongs to.
reason string yes Why it was refused.
decline_code string or null yes The decline code, when the refusal came from the acquirer.
at string yes When the refusal happened.

When it refuses

Operation id getCheckoutSession, for code generators.