/ Payouts v1 Dashboard ↗

Checkout Setup

1 · Business account One organization per business 2 · Verify the business Once. Name the control person 3 · Enable card payments Consent, then the ID check 4 · Developers API key + webhook endpoint Organization verified Checkout routes answer 200 instead of 403 Your server creates and publishes a link POST /checkout/organizations/{orgId}/links · Idempotency-Key checkout_payment.paid arrives on your endpoint Signed with the whsec_ secret. Dedupe on id, then fulfil review approved card processor: charges enabled either one opens the door API key checkout_payment.* buyer pays on shareUrl
Steps 1 to 4 happen in the dashboard, once. Bank and crypto links need only step 2; card links also need step 3, and until it is done a publish: true create keeps the link as a draft with a publishError.

Everything that has to be in place before you accept your first payment, in the order it happens: a business account, card payments switched on, an API key with a webhook endpoint, and the API itself. The first three are set up in the dashboard. The fourth is your integration.

Checkout is money arriving. It shares one organization, one API key, one webhook endpoint and one event feed with payouts, so if your organization already pays out, steps 1 and 3 are done and you can start at step 2.

With a test key you can skip steps 1 and 2 entirely. An avvio_test_… key addresses your sandbox organization, which is provisioned already verified and already able to sell by card, and a simulated buyer pays the link for you. Do the whole integration there first and come back to this page when you are ready to take real money. Sandbox is the reference.


1. Create a business account#

Go to business.avvio.xyz and sign in with your work email. You get a one-time code; after the first sign-in you can add a passkey, which is the fastest way back in. Then name your business and choose Create Business Account. That creates your organization: the thing that holds the balance, the links, the API keys and the team.

The dashboard home shows the setup steps in order: Create account, Verify your account, Fund your account, Add members. Checkout needs the first two. Funding is for paying out and is not required to be paid.

Verify the business#

Open Verify and complete business verification (KYB) once. It asks for the legal entity, its beneficial owners, and one control person: the individual who runs the business. Mark that person clearly. Card onboarding in step 2 verifies exactly that person, and cannot start until the application names one.

Status What it means
Draft Not sent yet. Finish and submit it
Under review With us. We email you when it is done
Needs information We asked for something. The dashboard shows what, and a button to answer
Approved Every organization-scoped route opens, including checkout
Rejected Contact support

Checkout routes answer 403 until the organization is verified, with the message *"This organization must complete business verification before it can accept payments."* Verification counts when either our review approves it or the card processor reports the business able to charge (step 2), so a card application that clears first also opens the door. Links, bank transfer and stablecoin payments go live as soon as verification is approved; cards are a separate application.


2. Enable card payments in checkout#

Open Checkout in the sidebar and choose Accept card payments. Anyone on your team can file the application. Only the control person does the identity check, and only if one is needed.

What you agree to. Cards are processed by Whop, and Whop verifies the control person your KYB names. The consent screen lists exactly what is shared: the business's registered name, address, tax ID, structure and what it does; the control person's name, date of birth, phone, home address and tax identification number; and photos of their government ID and a selfie. Read it and tick the two boxes. If you are not the control person, you attest that you are authorized to consent on their behalf. Consent is recorded once and not asked for again.

What happens next. The application is filed from the details already on your verification, so there is usually nothing to upload again. The card account opens in about a minute. Then one of two things:

The panel tells you where the application stands the whole time, and the two switches that come out of it are separate:

Switch Turns on when What it lets you do
Card payments The card account is open Publish links with methods: [{ "kind": "card" }]; buyers pay by card, Apple Pay and Google Pay
Withdrawals The identity check passes Move card money to your bank from Checkout → Balance

You can take card payments before withdrawals are on; the money waits in your card balance. Buyers see WHOP* followed by your business name on their statement, and you can edit the descriptor from the same panel.

If you publish a card link before this is done, the create call still answers 201 with the link kept as a draft and a publishError reading *"This business is not set up to accept cards yet. Finish card onboarding, then publish the link."* Finish here, then POST /checkout/organizations/{orgId}/links/{linkId}/publish. Bank and crypto links do not need this step at all.

Cards are in pilot and opening to verified businesses a few at a time. If the Accept card payments button is not there yet, the panel says so.


3. Create a webhook endpoint and an API key#

Both live under Developers in the sidebar. Owners, admins and operators can open it.

The API key#

Choose Create API key and fill in four things:

Field Pick
Name Where it will live (orders-service), so a leaked key is traceable
Permission Transact to create products and links. Read-only can list links and payments and reconcile, and gets 403 INSUFFICIENT_SCOPE on any write
Expiry One year by default, two at most. The key stops on its own
Allowed IP addresses Optional. Your servers' egress addresses; requests from anywhere else are refused

The complete key is shown once. Copy it into your secrets vault or an environment variable then; we store only a hash. Never put it in a browser bundle, a mobile app, a screenshot or a support ticket. If it leaks, revoke it and issue a successor from the same page; the successor works before the old one stops. Authentication has the rest.

bash
export AVVIO_API_KEY=avvio_…
export AVVIO_ORG_ID=cmsx…        # your organization id, a cuid
export AVVIO_BASE_URL=https://api.avvio.xyz/business/api/v1

Your organization id is on the same page. It is the opaque cmsx… value, not an org_-prefixed alias, and it goes unchanged into every path.

The webhook endpoint#

Switch to the Webhooks tab and choose Add endpoint:

  1. URL: https only. Plain http://localhost is accepted only against a

local development backend.

  1. Events: the payout types are pre-selected; the checkout family is

not. Tick the ones you want: checkout_payment.paid, checkout_payment.failed, checkout_payment.refunded, checkout_payment.reversed. An endpoint that never named them never receives them, so a receiver built for payouts is not surprised by a family it does not handle.

  1. Signing secret: shown once, as whsec_…. Copy it beside the API key.

Every delivery is signed with it; Webhooks shows the four headers and the two lines of verification.

Registering, pausing, rotating and replaying an endpoint are dashboard actions and cannot be done with an API key: a credential that could repoint its own webhook URL could quietly redirect every payment notification you receive. GET /organizations/{organizationId}/webhook-endpoints lists them read-only, and the events feed at GET /payments/organizations/{orgId}/events is the record you recover from if a delivery is missed.


4. The API#

Base URL https://api.avvio.xyz/business/api/v1
Auth x-api-key: avvio_… on every request. Nothing to sign
Routes /checkout/organizations/{orgId}/…
Contract partner-checkout.openapi.yaml, the checkout OpenAPI spec
Writes Every POST, PATCH and DELETE requires Idempotency-Key. Same key on a retry returns the original result; without it, 400 IDEMPOTENCY_KEY_REQUIRED
Amounts Decimal strings in the link's currency ("150.00") on links and events; base units with decimals on payment rows
Errors One envelope, { type, message, status }. Branch on type
Tools @avvio/payments ≥ 0.6.0 (Node SDK, CLI, MCP server) covers every operation below. Or generate a client from the contract in any language

The checkout contract is its own OpenAPI file, separate from payouts, so a client generated from it has only these thirteen operations:

Operation Method and path
List products GET /checkout/organizations/{orgId}/products
Create a product POST /checkout/organizations/{orgId}/products
Read, update, archive a product GET, PATCH, DELETE …/products/{productId}
Create a link POST /checkout/organizations/{orgId}/links
List links GET /checkout/organizations/{orgId}/links
Read, edit a draft, delete a draft GET, PATCH, DELETE …/links/{linkId}
Publish a draft POST …/links/{linkId}/publish
Pause a live link POST …/links/{linkId}/pause
List a link's payments GET …/links/{linkId}/payments

Prove the key and the verification in one read before you write anything:

bash
curl -s "$AVVIO_BASE_URL/checkout/organizations/$AVVIO_ORG_ID/products" \
  -H "x-api-key: $AVVIO_API_KEY"

[] is the right answer for a new organization. 403 with the verification message means step 1 is not finished; 401 means the key is wrong or revoked.

Refunds are a dashboard action in this version (an owner or admin, on the payment's row); they reach you as checkout_payment.refunded. There is no API refund yet.


Then#