Skip to navigation

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 worksWhen to use it
Clave buttonYou place Pagar con ⚡ Clave next to your own payment form. Tapping it opens a Clave window, and we tell your page when it was paid.You already have your own e-commerce
Recurrente checkoutYou embed the checkout in your page or redirect to it. Clave shows up for whoever has it, next to cards, installments, and bank transfers.You want every payment method without building your form

Both start the same way: your server creates a checkout through the API.

How it works for the payer

  1. 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.
  2. They tap it and a Clave window opens (a new tab on phones). Your page dims, with a notice to go back to the window or cancel.
  3. 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.
  4. They pick their card and pay. If 3D Secure is needed, it happens in the same window.
  5. 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. Create a checkout from your server

curl https://app.recurrente.com/api/checkouts \
-H "X-SECRET-KEY: $RECURRENTE_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [{
"name": "Order #1042",
"amount_in_cents": 25000,
"currency": "GTQ",
"quantity": 1
}],
"success_url": "https://yourstore.com/orders/1042/thanks",
"cancel_url": "https://yourstore.com/cart"
}'

The response includes the checkout’s id and checkout_url. The checkout_url is all the button needs: there is no publishable key and no domain to register. If you need a shipping address, ask for it on the item with address_requirement. See Create a checkout.

Always set success_url: it is where the payer returns when the button can’t open a window (see below).

2. Show the button

<script src="https://app.recurrente.com/clave/v1/clave.js"></script>
<div id="clave-button"></div>
<script>
Clave.button("#clave-button", {
url: checkoutUrl, // the checkout_url your server received
onReady: (event) => {
// event.available: this payer already has Clave
// event.payable: false if the checkout is already paid or expired
},
onSuccess: (event) => {
// event.checkoutId, event.shippingAddress
// confirm it on your server before fulfilling (step 3)
},
onCancel: () => {
// they closed the window without paying: let them pay another way
},
onFailure: (event) => {
console.warn(event.message) // invalid setup, e.g. a url that is not a checkout_url
},
});
</script>

The button fills its container’s width and is 48px tall. Call Clave.button once per checkout; if the cart changes, create a new checkout, call unmount() on the old one, and mount the new one.

EventWhen
onReady({ available, payable })The button loaded. available is true if we recognized the payer by their browser or by the customer you created the checkout with.
onSuccess({ checkoutId, pending, shippingAddress })It was paid. shippingAddress is the address they picked in Clave, if the checkout asked for one.
onCancel()They closed the window or tapped Cancelar pago without paying.
onFailure({ message })The button couldn’t mount. Declined payments stay in the window so the payer can try again; they don’t reach you as an event.

3. Confirm the payment on your server

A browser event is not proof of payment. Fulfill the order when your server receives the intent.succeeded webhook for that checkout, or when GET /api/checkouts/{id} returns status: paid. See Webhooks.

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.

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 success_url. The same happens if the browser blocks the window. You don’t need to do anything beyond setting success_url and confirming the payment on your server.

Testing

Create the checkout with a Sandbox key 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 key 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.

npm install recurrente-checkout
<div id="recurrente-checkout-container"></div>
import RecurrenteCheckout from "recurrente-checkout";
RecurrenteCheckout.load({
url: checkoutUrl,
onSuccess: (data) => { /* data.checkoutId: confirm it on your server */ },
onFailure: (data) => { console.warn(data.error); },
onPaymentInProgress: (data) => { /* bank transfers only */ },
});

Inside the embedded checkout, the payer identifies themselves with their email or phone and a code, the same as in the Clave window. 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.

FileURL
Checkout button (320×48, 10px radius)https://www.recurrente.com/images/clave/brand/clave-button-checkout.svg
Purple logohttps://www.recurrente.com/images/clave/brand/clave-logo-purple.svg
White logohttps://www.recurrente.com/images/clave/brand/clave-logo-white.svg
  • Text: “Pagar con ⚡ Clave”. The bolt goes before “Clave”.
  • Color: purple #6C5CE7 with 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 checkout 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. Only your server can create a checkout_url, with your secret key, and the result is only sent to the page that mounted the button.

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.