Accept Clave
Clave is Recurrente’s one-click checkout. A payer saves a payment method once, at any business that charges with Recurrente, and from then on pays with Pagar con ⚡ Clave without typing their card again. More than 420,000 people already have payment methods saved in Clave.
If you have used Stripe’s Link or Shop Pay, Clave plays the same role and integrates the same way: a button in your checkout that opens a Clave window, where the payer identifies themselves, picks their card, and pays.
Two ways to accept Clave
How it works for the payer
- They see Pagar con ⚡ Clave on your page. If their browser already has Clave and they already paid with it at your store, the button shows their card: ⚡ Clave | Visa •••• 4242.
- They tap it. We create the checkout from what is in the cart and a Clave window opens (a new tab on phones). Your page dims, with a notice to go back to the window or cancel.
- In the window they identify themselves with their email or phone and confirm a one-time code sent by WhatsApp or email. If they already did this in that browser, they go straight through.
- They pick their card and pay. If 3D Secure is needed, it happens in the same window.
- The window closes itself and your page receives
onSuccess.
Payers without Clave pay with a card in the same window, and the card is saved in Clave for next time, at your store or any other.
Add the Clave button
1. List your domains
Configuración → Botón Clave holds the ready-to-paste code, with your account id filled in, and the list of domains the button lives on, such as mystore.com. Adding the first domain is what turns the button on: it only renders on those pages and checkouts only return to them; each domain covers its subdomains. Add localhost while you develop.
There is no publishable key: your account id is already public, and it only draws the button and opens checkouts in your name within your domains. The API keeps using your secret key.
2. Show the button
Nothing is created until the payer taps the button; the checkout created then expires after 3 hours if unpaid. Each item comes in one of two shapes:
- A Recurrente product:
product_id(orprice_id) andquantity. Your catalog in Recurrente sets the price. - An amount:
name,amount_in_cents,currencyandquantity. Your page sets the price; read step 3.
If you need a shipping address, ask for it on the item with address_requirement: "required". The button fills its container’s width and is 48px tall.
button.update({ items, successUrl, cancelUrl, metadata, customer, reference, signature }) changes what the button will send on the click. button.unmount() removes it.
3. Confirm the payment, and the amount, on your server
A browser event is not proof of payment. Fulfill the order when your server receives the intent.succeeded webhook, or when GET /api/checkouts/{id} returns status: paid. Both carry the checkout with its metadata and the amount_in_cents charged. See Webhooks.
If you send amounts from your page, compare the amount. The payer’s browser set it, and a payer can edit it. Those payments arrive with amount_set_in_browser: true, in the webhook and in the API.
A Clave payment arrives like any card payment, with details.used_presaved_payment_method: true. Once paid, the address is also in the API, under payment.paymentable.address.
Sign the total (optional)
If you send amounts from the page but want the payment to count as priced by your server, sign it. Botón Clave holds your signing secret (sig_live_…); never put it in the page. On your server:
For example, sha256("order-1042" + "25000" + "GTQ" + "sig_live_…"), in hex. Pass reference and signature to Clave.button. If the total or the currency does not match the items, the signature does not count and the payment arrives as set in the browser. Send currency on every item when you sign.
If your server already creates the checkout
Pass url: checkout.checkout_url, the one POST /api/checkouts returns, instead of account and items. In that mode you need no domains: only your server can create a checkout_url, with your secret key. If the cart changes, update the checkout with PATCH /api/checkouts/{id}; the button does not need to know.
In-app browsers
Instagram, Facebook, TikTok, and WhatsApp open links in their own browser, where a new window can’t report back to your page. There the button takes the payer to the checkout in the same tab and, once paid, returns them to your successUrl. The same happens if the browser blocks the window. You don’t need to do anything beyond setting successUrl and confirming the payment on your server.
Testing
Use your Sandbox’s id as account and the button runs in test mode, like Link’s:
- Any email or phone has Clave.
- No code is sent. Enter 000000.
- The test wallet offers the Visa •••• 4242 card, and the payment is approved.
- The window says TEST next to your business name.
That lets you walk the whole flow (button, window, code, payment, onSuccess, and webhook) without a real wallet. Your integration doesn’t change in production: you switch the account id and that’s it.
While you develop on localhost, the button doesn’t show the payer’s card even if they already used it: that depends on cookies browsers only share between HTTPS sites. It works normally in production.
With Recurrente’s checkout
If you’d rather not build your payment form, embed the whole checkout. Clave shows up there on its own, for whoever has it.
The embedded checkout leads with a Pay with Clave button that opens the same Clave window; whoever would rather stay in the form identifies themselves with their email or phone and a code. See Embedded Checkouts.
Brand rules
The button already carries the official brand; don’t draw your own. If your page mentions Clave anywhere else, use the official files.
- Text: “Pagar con ⚡ Clave”. The bolt goes before “Clave”.
- Color: purple
#6C5CE7with white text. Clave is never green. - Don’t draw a Clave button that opens anything other than Clave.
FAQ
Do I need to turn Clave on for my account?
No. Every account that accepts cards accepts Clave, with the button or inside Recurrente’s checkout.
Do I need a publishable key or to register my domains?
No publishable key: the button uses your account id, which is already public. Domains, yes: the list keeps another page from using your name or sending the payer somewhere else. If your server already creates the checkout and you pass url, you don’t need domains either.
What does amount_set_in_browser mean?
That the amount came from the payer’s page, not from your server or your catalog in Recurrente. Compare it with your order before fulfilling, or sign the total so it arrives as set by your server.
Why didn’t the button show the payer’s card?
It does when their browser already has Clave and they already confirmed a code at your store, in browsers that allow third-party cookies. Elsewhere it shows Pagar con ⚡ Clave, and the payer identifies themselves with their code in the window.
Can I tell which payments used Clave?
Payments made with a saved method carry details.used_presaved_payment_method: true in the webhook.
Can I hide Clave?
On your e-commerce, just don’t show the button. In Recurrente’s checkout, Clave shows up where the payer has it and the checkout accepts cards.

