Quickstart
Take a test payment in a few minutes: choose your platform, then paste its code.
Before you start you need a publishable key from the console, and your page's origin added to the integration's allowed origins. Test mode needs nothing switched on: a key that allows test mode takes test payments straight away. Only the Server API panel needs a secret key, and that one never leaves your server.
Already on Stripe? Migrating from Stripe
Script tag #
You need your publishable key and this page's origin allowed. Paste the tag, add a container, call
collect().
<script src="https://js.ripper.dev/r.js" data-key="rip_pk_EXAMPLE-KEY_00000000abcZ"></script>
<div data-ripper-checkout></div>
<script>
ripper.collect({ amount: 4200, currency: 'GBP' }).then(function (result) {
console.log(result.status);
});
</script>Pay with the reserved test card 9000 0000 0000 0000, any future expiry and any 3-digit security code.
The checkout shows its own paid confirmation, and result.status is captured.
Next: collect() reference · Test cards
npm #
You need your publishable key and this page's origin allowed. Same call, from the package.
import { loadRipper } from 'ripperpay';
const ripper = await loadRipper({ key: 'rip_pk_EXAMPLE-KEY_00000000abcZ' });
const result = await ripper.collect({ amount: 4200, currency: 'GBP' });
Pay with 9000 0000 0000 0000. result.success is true and result.status is captured.
Next: Script tag and loader · Test cards
React #
You need your publishable key and this page's origin allowed.
import { RipperCheckout } from 'ripperpay/react';
export function Checkout() {
return (
<RipperCheckout
publishableKey="rip_pk_EXAMPLE-KEY_00000000abcZ"
amount={4200}
currency="GBP"
onSuccess={(result) => console.log('paid', result.paymentId)}
onError={(error) => console.log('not paid', error.code)}
/>
);
}
Pay with 9000 0000 0000 0000. onSuccess fires with the payment id.
Next: React for every prop · Test cards
Next.js #
You need your publishable key and this page's origin allowed. Render the checkout from a client
component; ripperpay itself is safe to import on the server.
'use client';
import { RipperCheckout } from 'ripperpay/react';
export default function Pay() {
return (
<RipperCheckout
publishableKey="rip_pk_EXAMPLE-KEY_00000000abcZ"
amount={4200}
currency="GBP"
onSuccess={(result) => console.log('paid', result.paymentId)}
onError={(error) => console.log('not paid', error.code)}
/>
);
}
Pay with 9000 0000 0000 0000. onSuccess fires with the payment id.
Next: Next.js · Test cards
Server API #
You need a secret key with the create_payments permission, read from an environment variable. It is for
your server only: never put it in a page, an app or a repository. Create the session on your server, then
hand the session to the browser. An amount your server set counts as a verified amount.
curl https://api.ripper.dev/v1/checkout/sessions \
-H "X-Ripper-Api-Key: $RIPPER_SECRET_KEY" \
-H "Rip-Idempotency-Key: order-1042" \
-H "Content-Type: application/json" \
-d '{"amount": 4200, "currency": "GBP", "order_reference": "ORDER-1042"}'
The response carries id, client_secret and expires_in_seconds. Send those to your page and pass them
to the checkout, which then uses your session instead of creating one:
const session = await fetch('/api/checkout-session').then((r) => r.json());
const result = await ripper.collect({ session });
Pay with 9000 0000 0000 0000. Read the outcome on your server from the session or the payment, not from
the browser. Never log or store the client_secret.
Next: Checkout sessions · Webhooks
AI coding assistant (Claude Code, Codex, Cursor) #
You need your publishable key. Paste this prompt into your assistant:
Read https://docs.ripper.dev/llms-full.txt before writing any code (https://docs.ripper.dev/llms.txt is its index).
Add a ripper checkout to this project with my publishable key rip_pk_EXAMPLE-KEY_00000000abcZ — never a secret key.
Take a £42.00 test payment with ripper.collect({ amount: 4200, currency: 'GBP' }), pay with the reserved test card 9000 0000 0000 0000 (any future expiry, any 3-digit security code), and show me the result.
These docs publish /llms.txt and /llms-full.txt for agents.
Before the runtime loads #
Every member of ripper works before the runtime has loaded — calls queue and replay in order.
setEmail() provides the shopper's email, so the checkout does not ask for it:
ripper.setEmail('shopper@example.test');
ripper.init({ channel: 'web' });
const traceId = ripper.getTraceId(); // 'rip_sess_…', available as soon as the script loads
const result = await ripper.collect({ amount: 4200, currency: 'GBP' });
A strict Content-Security-Policy #
If your page sends one, the checkout needs a few hosts allowed. The list, which rows have been verified in a
browser and which have not, and where the keys may go, are on Security and CSP.
If font-src does not allow the js host, the checkout paints in system fonts and the payment still
completes.