> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beinfi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Payment link

> One call, one URL: charge without building a checkout, without touching a card.

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.

## First: two things the link requires

```ts theme={null}
const link = await infi.links.create(productId, { slug: "your-tenant" });

link.url;
// https://app-sandbox.beinfi.com/pay/your-tenant/links/plink_…  ← send this
// (with sk_live_ the host is app.beinfi.com)
```

That line only works if both pieces below exist — both come from
[catalog](https://beinfi.com/en/catalogo):

| Piece                           | Where it comes from                                                                                                                |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `productId`                     | `products.create()` (or `products.list()`). The `productId` from provisioning belongs to the seed product, which does **not** work |
| A **published** product version | `products.versions.publish(...)` — without it, `links.create` answers `422 product has no published version`                       |

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 money is received by **your** provider account. Which provider processes it
is decided by [Infi Routing](https://beinfi.com/en/introducao) at payment time, not when the
link is created.

<Warning>
  **Pix and boleto require the payer's tax id.** The provider refuses to create the payer without a document: the charge stops at
  `422 customer_tax_id_required` ("A CPF/CNPJ is required to process this
  payment"). This applies to pix **and** boleto. If you build the checkout in your
  own app instead of using the link, pass `taxId` with the customer:
  `infi.checkout({ slug, productId, customer: { externalId, email, taxId } })`.
</Warning>

## 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:

```ts theme={null}
const link = await infi.links.create(productId, {
  slug: "your-tenant",
  successUrl: "https://your-app.com/thanks?order=42",
  cancelUrl: "https://your-app.com/cart",
});
```

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.

<Warning>
  **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.
</Warning>

## Listing and revoking

```ts theme={null}
await infi.links.list(productId, { slug: "your-tenant" });

await infi.links.revoke(productId, link.id);
```

<Warning>
  **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.
</Warning>

## 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](https://beinfi.com/en/webhooks).

## When to use the link, and when not to

<CardGroup cols={2}>
  <Card title="Use the link">
    A one-off sale, charging over WhatsApp, a first sale before you have an app.
  </Card>

  <Card title="Use metering">
    Continuous usage billing (tokens, requests), where the amount only exists
    after the customer consumed it — see [SDK](https://beinfi.com/en/sdk).
  </Card>
</CardGroup>

## If you want to control the screen and still use a link

The buyer's flow over HTTP — opening a session, charging, and where the invoice
shows up — is in [the thank-you page](https://beinfi.com/en/pagina-de-obrigado).
