---
id: collect
title: collect() reference
summary: Every option, every result, and what the session stores.
faces: ["public", "agent"]
personalises: ["publishable_key", "integration_name"]
section: front-end
group: Accept a payment
order: 24
---
# collect()

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

## Amount and currency

```js run id=collect-amount
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.

```js run id=collect-items
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.

```js run id=collect-customer
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.

```js run id=collect-order-reference
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`.

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

## A named integration

```js run id=collect-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.

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

## Watching the state

`onStatus` is an observer, never load-bearing.

```js run id=collect-status
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.

```js run id=collect-signal outcome=error:user_cancelled
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.

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

## The result

```js run id=collect-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.
