Skip to main content
Card Checkout lets your customers accept debit and credit card payments on a secure, Yativo-hosted checkout page. Each of your customers that sells is verified once through its card_checkout endorsement. You then create orders for it through the API, send the buyer to the returned checkout_url, and receive a webhook for every change in the order. Each card payment lands on the selling customer’s own connected business account (biz_… from card-checkout onboarding). Yativo collects its fee from the seller’s account (processor fee, plus 1%, plus a fixed fee). The rest stays on the customer’s account. Open the withdrawal page for that customer with POST /v1/card-checkout/customers/{customer_id}/withdrawal.

Before you start

Card Checkout must be enabled for your account. Request access with POST /v1/card-checkout/account/request-access; our team reviews the request. Submitting a customer’s endorsement before then also files the request for you (see Before your account is enabled). Until access is approved, the other endpoints below return 403 with code: card_checkout_not_enabled. Your pricing (fee, settlement delay, reserve and currencies) is set when access is granted and is shown by GET /v1/card-checkout/account.

Request access

note is optional (max 1000 characters): tell us what you sell and to whom. The response is your account object with access_status: "requested" (HTTP 202). Sending the request again while it is open changes nothing. If access is already enabled you get 200 with access_status: "enabled". The status codes in this guide are the status_code in the response envelope. Every request needs your API credentials, and your Yativo account must have passed KYC:
Send an Idempotency-Key header on every POST so a retried request is never executed twice. See Payin & Payout Integration → Idempotency. All responses use the standard envelope: { "status": "success" | "failed", "status_code": ..., "message": "...", "data": { ... } }. Amounts in requests and responses are decimal strings in major units ("49.99"). Currency codes are ISO 4217; only USD is enabled today.

How it works

  • The amount is set when you create the order. The buyer cannot change it.
  • Card details are entered in secure, isolated fields; they never reach your servers or ours.
  • Only the card_checkout.order.paid webhook means the payment was made. The buyer’s browser being redirected to your success_url is not proof of payment: browsers close, redirects fail, and URLs can be typed by hand.

1. Endorse the customers who sell

Each of your customers that sells by card must be verified first. This is the customer’s card_checkout endorsement, next to its other endorsements. Individual and business customers can both be endorsed.

Submit the endorsement

No body. What the customer already gave Yativo is used straight away:
  • Business customer: its KYB submission (legal name, entity type, tax and registration numbers, registered address, and the signer among its associated persons) is sent for verification. The customer then uploads the company documents on the onboarding page.
  • Individual customer: its KYC submission (name, date of birth, address, phone, ID document) is sent for verification when its ID photos and a selfie are on file. Otherwise the customer confirms the prefilled details and adds the photos on the onboarding page.
Send the customer to onboarding_url. It opens a Yativo-hosted page showing only the form for the customer’s type, prefilled with what is on file:
  • Individual: confirm the details, add a government ID and a selfie.
  • Business: confirm the company details, then upload the company documents and the representative’s ID in a secure step embedded in the same page.
If the review needs more (a clearer photo, an extra detail), the same page lists each item and takes the answers and uploads. You can also submit the endorsement with the customer endpoint you already use for other endorsements: POST /v1/customer/kyc/resubmit/{customer_id}/card_checkout (see KYC endorsement resubmission; for card_checkout it accepts business customers too). Submitting again is safe: an approved customer is left as it is, and nothing already sent is sent twice.

Before your account is enabled

A customer can ask for card checkout before your account has access. In that case the endorsement request is held instead of refused:
  • If you never requested access, the request is filed for you (access_status becomes requested) and the note says which customer asked.
  • The customer’s card_checkout endorsement is set to pending, with metadata.awaiting_business_access: true and an errors entry explaining that access was requested. You receive the usual endorsement.updated webhook.
  • The response is 202:
When our team enables your account, every waiting customer is submitted automatically and you get endorsement.updated webhooks as they progress. You don’t need to call the endpoint again. If your access request was declined, the endorsement request returns 403 with code: card_checkout_access_declined. Send a new access request with more detail first.

Follow the endorsement

The card_checkout endorsement appears with the customer’s other endorsements on the customer object (GET /v1/customer/{customer_id}), and every change sends you the usual endorsement.updated webhook. While there is something for the customer to do, hosted_kyc_url holds the onboarding link; it is renewed automatically whenever you read the endorsements, so the one you get always works. You can also read it on its own:
The response has the same shape as the submit response.
Both fields are optional https URLs: return_url is the “Back to app” link on the page, refresh_url is where the customer lands once this link has expired. Returns { "customer_id", "endorsement_status", "onboarding_url", "expires_at" }. This link is valid for 2 hours.

Or verify a business customer through the API (your own form)

1. Get the form, prefilled from the customer’s KYB
For an individual customer kind is individual and prefill holds the person’s details; individuals add their ID photos and selfie on the onboarding page. The tax identification number is never prefilled. 2. Submit corrections (business customers)
Any field you leave out is taken from prefill. A field you send overrides it. Returns 201:
3. Answer what the review asks for (any customer) Each item in information_requested is one thing to collect:
ID document slots: Files are JPG, PNG or PDF, up to 10 MB each and 10 per item (a selfie must be JPG or PNG). Yativo forwards them for review and does not keep them. You can answer some items now and the rest later; answered items leave the list. Everything is checked before anything is sent, so one bad answer sends nothing. The response has the same shape as the submit response. Errors from these endpoints:

Business structures

Other countries have no structures: send business_name and omit business_structure.

2. Create a checkout order

Response 201
  • platform_fee, reserve and net_amount are fixed when the order is created. Pricing changes made later don’t affect existing orders.
  • The checkout link expires after 60 minutes (expires_at). Create a new order if the customer comes back later.
  • A reference you’ve already used returns 409 with code: duplicate_reference.
  • A payment_methods entry that isn’t enabled returns 422 with code: payment_method_not_enabled. When you limit the methods, the order includes them as payment_methods.
  • A customer whose endorsement isn’t approved returns 403 with code: customer_not_endorsed; another business’s customer returns 404.

3. Send the buyer to the checkout page

Redirect the buyer to checkout_url exactly as returned. Don’t change it: the URL is signed, and any edit makes it invalid. On the checkout page, which shows your customer as the seller, the buyer:
  1. enters their email, name and billing address, then their card details;
  2. completes 3-D Secure if their bank asks for it;
  3. lands on a receipt page showing the confirmed result, with a link to your success_url if you set one.
The page supports light and dark mode and works on mobile.
Buyer activity log. To protect you and your customers from fraud, the checkout page records the buyer’s actions on the page, device and browser details, IP address and approximate location. The page tells the buyer this. The log is used for fraud review and dispute evidence.

4. Follow orders with webhooks

Card Checkout events go to the webhook URL you registered (see the Webhooks Guide), signed in the same way as every other event. You get one for every change in an order’s status, and for every refund or dispute amount change: The payload is the order, including the customer_id that sold it:
Make your handler idempotent. You may receive an event more than once, and events can arrive out of order. When in doubt, read the order with GET /v1/card-checkout/orders/{id} and act on its status. On sandbox you can send a sample Card Checkout event to your registered URL without creating an order: POST /api/v1/demo/webhook/card_checkout (defaults to card_checkout.order.paid) or POST /api/v1/demo/webhook/card_checkout.order.expired. See Testing on sandbox.

Read orders

GET /orders/{id} returns the same object as above. While the order can still be paid, it also includes a fresh checkout_url. You can only read your own orders; any other id returns 404. The list response is paginated: { "data": [ …orders… ], "pagination": { "current_page", "per_page", "total", "last_page" } }.

Order statuses


Your balance

balance is what Yativo owes you from your customers’ card sales: balance_by_customer splits it by the customer whose sales it came from (customer_id is null for amounts not tied to a customer). Use it to settle with your customers. The customer’s own money stays on their Whop account. To let them withdraw it:
The response includes withdrawal_url (Whop’s hosted payouts portal). Send the customer there. return_url and refresh_url are optional and must be https when you send them. The customer must already have a submitted card_checkout endorsement. When the endorsement is approved, list/read endpoints also expose a long-lived signed link on the checkout domain as whop_withdrawal_url (on the endorsement and on GET /v1/card-checkout/customers/{id}). Opening it redirects into Whop so the customer can manage payouts on their connected biz_… account. Renew it with POST …/withdrawal if you need a fresh Whop URL directly.

Fees, settlement and reserves

For every paid order:
  • Settlement delay. net_amount is added to your balance, against the selling customer, as soon as the payment is confirmed, and becomes available after settlement_delay_days (often 0). Until then it counts as on_hold.
  • Reserve. If your account has a reserve, that part becomes available after a fixed period.

Refunds and disputes

Refunds and chargebacks come out of your balance, against the customer that made the sale:
  • The refunded or disputed amount is deducted from your balance. If that makes the balance negative, your next sales cover it.
  • Disputes: the disputed amount is deducted when the dispute opens. If you win, it is credited back. Pre-dispute inquiries don’t move funds.
  • The full refunded amount is deducted. The platform fee on a refunded order is not returned.

Errors


Testing

Use your sandbox credentials and these test cards: Use any future expiry date, any 3-digit CVC and any billing address.