Skip to main content
The shortest path between “I have a published product” and “somebody paid me”. You create a link, send it, and that is it — there is no checkout to build: no payment page, no card input, no provider SDK in your app, no PCI scope.
That line only works if both pieces below exist — both come from catalog: The slug is your tenant’s and goes into the public URL, so it is an argument: the SDK does not infer it from a secret key.

What happens when somebody opens it

The link has no payer. Whoever opens it fills in their own details and pays; the customer and the invoice are materialised on submit. That is what lets you send the same link to several people — or to a group — without registering anyone beforehand. The sale happens in Brazil (you and the buyer in Brazil), by Pix or card (single payment), in test environment, and the charge lands on your receiving account at the payment provider. International sales through Infi UK Ltd are coming soon. Until receiving setup is ready, the link opens but the store cannot receive payments yet, and the checkout says so. See going to production.
The contract still asks for taxId when the session opens. POST .../sessions takes email and taxId (a valid CPF/CNPJ) together, and refuses one without the other. If you build the checkout in your own app instead of using the link, pass taxId with the customer.

Where the payer goes afterwards

By default they stay on our receipt. If you want the payer back on your site, pass the URLs when creating the link:
After paying, the checkout takes the payer to successUrl with ?status=success&invoice=<id> appended — your own parameters are kept. cancelUrl shows up as “Back to {your store}” while the checkout is open. Both must be absolute http(s) URLs; a relative path or any other scheme answers 422. The same pair exists on infi.checkout({ successUrl, cancelUrl }) for invoices created on your server, and in the embed (@beinfi/checkout) the equivalent is the returnUrl prop.
A redirect is not a confirmation. status=success in the URL is an event in the payer’s browser. Release the product on the payment.confirmed webhook, never on the parameter.

Listing and revoking

Revoking is final. The token stops resolving immediately. Invoices already created from that link stay payable — somebody mid-checkout does not lose the charge in their hands.

So how do I know they paid?

Not from what links.create returns: payment is asynchronous. In production, a signed webhook (payment.confirmed); in sandbox, polling the invoice — both in webhooks.

Use the link

A one-off sale, charging over WhatsApp, a first sale before you have an app.

Use metering

Continuous usage billing (tokens, requests), where the amount only exists after the customer consumed it — see SDK.
The buyer’s flow over HTTP — opening a session, charging, and where the invoice shows up — is in the thank-you page.