Skip to content
ripper docs Open the console

Keys

There are two, they are not interchangeable, and the difference is not about secrecy alone: it is about what each one can do.

The publishable key #

Starts rip_pk_, then 24 more characters drawn from A–Z, a–z, 0–9, - and _. Thirty-one in all. It goes in your page, on the script tag, and anyone who views source can read it. That is the design rather than a concession.

If you are writing your own check on a key before you send it, match the shape above rather than a narrower one. Keys are random, so a given key can easily look like it is only digits and lowercase letters without that being the rule.

It grants no permission at all. Asked what a publishable key may do, the platform answers with every capability set to false. What it does instead is identify the merchant and the integration, and every route that accepts it also checks the page's origin against that integration's allowed origins. So a copied key on somebody else's site does not work: the origin check refuses it before anything else happens.

The secret key #

Starts rip_sk_, then 32 more characters from the same set. Thirty-nine in all. It belongs on your server, read from an environment variable. Never a page, never an app, never a repository, never a log line.

It is shown once, when it is created. There is no route that reads it back, by design: if the one copy is lost, issue a new one rather than looking for the old.

A secret key carries named permissions, and a route refuses a key that lacks the one it needs rather than half-working. The three most integrations need:

permission what it is for
create_payments creating checkout sessions from your server
read_transactions reading sessions and payments
manage_webhooks registering webhook endpoints and reading deliveries

Give a key the permissions its job needs and no more. A key that can only read transactions cannot take a payment even if it leaks.

Test and live #

A key allows test mode, live mode, or both, and that is a property of the key rather than of the request. A live-only key used while the effective mode is test is refused with key_live_only, and a browser meets that as an unavailable checkout rather than as an error it can fix.

If a key gets out #

Revoke first. Investigate afterwards. In that order, and the order is the whole advice.

The instinct under pressure is to work out how bad it is before doing anything: which key, whose commit, what it could reach, whether it was ever used. Every minute of that is a minute the key still works. Revoking is one action, it is immediate, and it costs you a redeploy with a new key — which you will be doing anyway, and which you can do calmly once nothing is exposed.

A revoked key answers key_revoked at once, so anything still using it fails loudly and immediately and you find your own forgotten deployments in minutes. A key quietly rotated while the old one still works fails slowly and silently: the old key keeps paying, and you learn where it was used only when something breaks weeks later, or never.

This applies to a publishable key too, though less urgently. It grants nothing on its own, but a key in someone else's page is a signal worth acting on rather than explaining away.