Payments
Checkout
KrokoPay hosts the payment page for every charge and payment link. Send the buyer to one URL; the checkout handles Pix, cards, your brand and every outcome.
On this page
The checkout is the page where the buyer pays. It is hosted by KrokoPay, carries your brand and works for two kinds of id: a charge you created through the API, or a payment link you share as many times as you like. You never render card fields yourself, so card numbers never pass through your servers.
How the checkout opens
Every checkout lives at https://krokopay.app/pay/{id}. The id decides what the buyer sees:
chg_…: a charge created with POST /v1/charges. Itscheckout_urlalready points here. One charge, one payment.plink_…: a payment link. Itsurlpoints here. Every buyer who submits the form gets a new charge withlink_idset.
# A charge created through the API (returned as checkout_url)https://krokopay.app/pay/chg_9Qs5MbT2kXn8Vd# A payment link (returned as url): reusable, one charge per buyerhttps://krokopay.app/pay/plink_2Wn6HsT9cVb4Lq// In the browser. Your own endpoint creates the charge with the secret key// and returns only its checkout_url.const response = await fetch("/api/orders/1042/checkout", { method: "POST" });if (!response.ok) throw new Error("Could not start the checkout");const { checkout_url } = (await response.json()) as { checkout_url: string };window.location.assign(checkout_url);Success: Nothing to embed
What the buyer sees
Step 1: Your brand and the order
Your display name, initials tile and tagline at the top, then the description and the amount in BRL.
Step 2: A payment method
Only the methods allowed by the charge or link (
methods).Step 3: Pix
A QR code and a copy-and-paste code with a countdown until
expires_at(15 minutes in the test environment; the production window is to be defined).Step 4: Card
Number, expiry, CVC and holder name, validated in the browser before submitting. Only the brand and last four digits are kept.
Step 5: Payer details
Name and email, used to match an existing customer by email or create a new one.
Step 6: The result
A receipt when paid, or a clear message with what to do next when the payment cannot go through.
Brand identity
The checkout reads your brand from the account settings, not from the request. Change it once in Settings and every charge and link uses it.
| Setting | Where it appears |
|---|---|
| Display name | Header of the checkout and the receipt. |
| Accent color | Primary button and the selected payment method. |
| Initials | One or two letters shown in the logo tile. |
| Tagline | Short line under the name. Optional. |
| Support email | Shown on the receipt and on error states, so buyers can reach you. |
Checkout states
The same URL shows a different screen depending on the state of the charge or link behind it.
| State | When | What the buyer can do |
|---|---|---|
| Waiting for payment | A pending charge, or an active payment link. | Choose a method and pay. |
| Paid | The charge is paid (also refunded or partially_refunded). | See the receipt. Opening the URL again never charges twice. |
| Declined | A card attempt failed; the charge is failed. | Read the reason and, if the charge came from a link, start again from the link. |
| Expired | A Pix charge passed expires_at without payment. | Start again from the link, or ask you for a new charge. |
| Unavailable | The payment link is inactive, or its product or price was archived. | Nothing to pay; contact the support email. |
| Invalid | The id does not exist. | Nothing to pay; check the link they received. |
Reproduce every state with the test cards below (any future expiry and any CVC work), or by letting a Pix countdown run out. More in Test environment.
| Test card | Outcome |
|---|---|
4242 4242 4242 4242 | Approved: the charge becomes paid. |
4000 0000 0000 0002 | Declined with card_declined. |
4000 0000 0000 9995 | Declined with insufficient_funds. |
4000 0000 0000 0069 | Declined with expired_card. |
4000 0000 0000 0127 | Declined with incorrect_cvc. |
Language of the checkout
The checkout is available in English and Brazilian Portuguese. The default comes from the checkout language preference in Settings: auto follows the buyer's browser, or you can fix it to en or pt-br. Amounts are always shown in the charge currency (BRL), whatever the language.
After the payment
When the payment is confirmed, the charge becomes paid and KrokoPay sends charge.paid to your webhook endpoints. Fulfil the order from the webhook, not from the browser: the buyer may close the tab before reaching any page of yours.
{ "id": "evt_6Ff7Gg8Hh9Ii0J", "object": "event", "type": "charge.paid", "api_version": "2026-11-01", "created_at": "2026-11-03T14:23:41.000Z", "data": { "object": { "id": "chg_4Fp9KzW1xQm7Rt", "object": "charge", "amount": 49700, "currency": "BRL", "status": "paid", "method": "pix", "card": null, "description": "Curso Identidade Visual do Zero", "customer_id": "cus_8Hq2LmZr4TxN1a", "product_id": "prod_3Vb7QpK9sWd2Ee", "price_id": "price_5Kd1NcR8vYq3Hm", "link_id": "plink_2Wn6HsT9cVb4Lq", "subscription_id": null, "fee": null, "net": null, "refunded_amount": 0, "failure_code": null, "created_at": "2026-11-03T14:22:05.000Z", "paid_at": "2026-11-03T14:23:41.000Z", "expires_at": "2026-11-03T14:37:05.000Z", "available_at": null, "checkout_url": "https://krokopay.app/pay/chg_4Fp9KzW1xQm7Rt" } }}Warning: No redirect field yet
- Failed attempt:
charge.failed, withfailure_codeon the charge. - Pix not paid in time:
charge.expired. - Paying a link with a recurring price also emits
subscription.created. See Subscriptions.
Payment links through the API
A payment link is a reusable checkout: share its url in an email, a chat or a button. It charges either a catalog price (price_id) or a fixed amount.
/v1/payment_linksBody parameters
namestringRequired- Title shown on the checkout.
descriptionstringOptional- Short text under the title.
price_idstringOptional- Charge a catalog price. Required unless
amountis sent. amountintegerOptional- Fixed amount in centavos, when there is no
price_id. methodsstring[]Requiredpix,cardor both.
curl -X POST https://api.krokopay.app/v1/payment_links \ -H "Authorization: Bearer kp_test_sk_4f9a2c7e1b8d4a6f9c3e5d7b" \ -H "Content-Type: application/json" \ -d '{ "name": "Curso Identidade Visual do Zero", "price_id": "price_5Kd1NcR8vYq3Hm", "methods": [ "pix", "card" ] }'curl -X POST https://api.krokopay.app/v1/payment_links \ -H "Authorization: Bearer kp_test_sk_4f9a2c7e1b8d4a6f9c3e5d7b" \ -H "Content-Type: application/json" \ -d '{ "name": "Consultoria — 1 hora", "description": "Sessão online de uma hora.", "amount": 25000, "methods": [ "pix" ] }'List, update and deactivate
/v1/payment_linkscurl https://api.krokopay.app/v1/payment_links \ -H "Authorization: Bearer kp_test_sk_4f9a2c7e1b8d4a6f9c3e5d7b"/v1/payment_links/{id}Updates name, description, methods or active. Changes apply to the next buyer; charges already created keep their amount.
/v1/payment_links/{id}Removes a link. If it already has charges, the link is deactivated instead (active: false) so its history stays intact, and its URL shows the unavailable state.
curl -X DELETE https://api.krokopay.app/v1/payment_links/plink_2Wn6HsT9cVb4Lq \ -H "Authorization: Bearer kp_test_sk_4f9a2c7e1b8d4a6f9c3e5d7b"Related
- Creating charges: the charge behind every checkout.
- Webhooks: verify and handle
charge.paid. - Test environment: test cards and simulated Pix.