---
id: guides/react
title: React
summary: <RipperCheckout/> — a thin wrapper over collect().
faces: ["public", "agent"]
personalises: ["publishable_key"]
section: front-end
group: Accept a payment
slug: react
order: 22
---
# React

```tsx
import { RipperCheckout } from 'ripperpay/react';

export function Checkout() {
  return (
    <RipperCheckout
      publishableKey="rip_pk_EXAMPLE-KEY_00000000abcZ"
      amount={4200}
      currency="GBP"
      aria-label="Pay Acme Coffee"
      aria-describedby="order-summary"
      onSuccess={(r) => console.log('paid', r.paymentId)}
      onError={(e) => console.log('not paid', e.code)}
    />
  );
}
```

Props are the `collect()` options minus `mount` and `onStatus`, plus `publishableKey`, `onSuccess`,
`onError`, `onStatus`, `className`, `aria-label` and `aria-describedby` (host-page ids, bridged into
the checkout). `aria-labelledby` is not a prop. React 18 and 19 are supported. Escape inside the
checkout reaches `onError` as `user_cancelled`.

The same wiring without JSX, so it runs here:

```js run id=react-plain
import { loadRipper } from 'ripperpay';
const ripper = await loadRipper({ key: 'rip_pk_EXAMPLE-KEY_00000000abcZ' });
const result = await ripper.collect({ amount: 4200, currency: 'GBP', accessibility: { ariaLabel: 'Pay Acme Coffee' } });
```
