Skip to content
ripper docs Open the console

collect()

ripper.collect(options) resolves exactly once with a CollectResult.

Amount and currency #

const result = await ripper.collect({ amount: 4200, currency: 'GBP' }); // minor units, ISO 4217

Items instead of an amount #

With items, ripper recomputes the amount from the merchant's price list and marks it verified. items[].type is a short token (at most 32 characters) stored on the session and returned on the payment read and the webhook body.

const result = await ripper.collect({ items: [{ sku: 'flat-white', quantity: 2, type: 'drink' }] });

Customer #

customer.account_created (ISO date) and customer.email are stored on the session. Every payment needs the shopper's email — it is the receipt address and the customer's identifier. Pass customer.email (or call ripper.setEmail()) and the checkout does not ask for it; leave it out and the form shows a required Email field. A session your server created with the customer's email needs neither. An email that is not valid (exactly one @, at most 254 characters) is shown in the field with an error so the shopper can correct it.

const result = await ripper.collect({ amount: 4200, currency: 'GBP', customer: { email: 'shopper@example.test', account_created: '2024-03-15' } });

Your order reference #

Pass the reference your shop and your customer already use for the order. It is stored on the session, and the checkout's confirmation shows it first — Order ORD-1042 — with ripper's payment ID smaller beneath it (the payment ID alone when there is no order reference). A session your server created with an order reference shows it the same way. It is shown as plain text.

const result = await ripper.collect({ amount: 4200, currency: 'GBP', orderReference: 'ORD-1042' });

Tell the shopper their order reference. On your server, match the payment to the order by the payment ID (pay_…, result.paymentId) or by your order reference. If your integration sets a confirmation URL, the reference travels there with the payment ID — see Integration parameters.

Metadata #

Keys are sent verbatim — orderId stays orderId.

const result = await ripper.collect({ amount: 4200, currency: 'GBP', metadata: { orderId: '1042' } });

A named integration #

const result = await ripper.collect({ amount: 4200, currency: 'GBP', integration: 'default' });

Where to mount #

An element, a selector, or the first [data-ripper-checkout] on the page.

const result = await ripper.collect({ amount: 4200, currency: 'GBP', mount: '[data-ripper-checkout]' });

Watching the state #

onStatus is an observer, never load-bearing.

const states = [];
const result = await ripper.collect({ amount: 4200, currency: 'GBP', onStatus: (s) => states.push(s) });
// states: loading_config → collecting_card → authenticating → confirming → captured

Cancelling #

Pass an AbortSignal to take the checkout down from your own code (a route change, a closed modal). Aborted before the pay button locks, the checkout is removed and collect() resolves user_cancelled; aborted while a payment is being confirmed, nothing is interrupted and the payment's own result arrives. <RipperCheckout/> does this for you when it unmounts.

const controller = new AbortController();
controller.abort(); // e.g. the shopper navigated away before the checkout was needed
const result = await ripper.collect({ amount: 4200, currency: 'GBP', signal: controller.signal });
// { success: false, method: 'card', error: { code: 'user_cancelled', … } }

A session your server created #

Pass { id, client_secret, expires_in_seconds } from the server-side create; the amount, currency and billing-address presence then come from the session, never from the page.

const session = await fetch('/api/checkout-session', { method: 'POST' }).then((r) => r.json());
const result = await ripper.collect({ session });

The result #

const result = await ripper.collect({ amount: 4200, currency: 'GBP' });
// { success: true, status: 'captured', paymentId: 'pay_…', method: 'card' }

Reserved options — flash, bnpl, splits, paymentType, subscriptionDetails, agent — are accepted and ignored today so your TypeScript compiles tomorrow.