# Paying partners

Pay every promoter with one press from your own PayPal, Wise, Stripe, Tremendous, Trolley or Tango account. BoltClaw never holds the money.

A referral program pays its partners and referrers from **your own account** at a payout
provider, with one press. BoltClaw tells your provider what to pay and keeps the books. It
never receives, holds or passes on the money, and it takes no fee: every payout goes from
your PayPal, Wise, Stripe, Tremendous, Trolley or Tango balance straight to the promoter,
and what the provider charges is charged to you, as it would be if you paid by hand.

You can also pay with a file you upload to PayPal or Wise yourself, as before, or have
[your own payout system](https://boltclaw.ai/docs/referral-payout-webhook) do it.

## The providers

| Provider | How you connect it | What a promoter gives | What it costs you |
|---|---|---|---|
| **Tremendous** | Sign in with Tremendous (a sandbox takes a `TEST_` key) | An email | Gift cards and prepaid cards at face value; cash, PayPal and Venmo 4% (at least 0.25 USD), up to 6% |
| **Stripe** | A restricted key you make for payouts (below) | An account on your Stripe, set up on Stripe's own page | 0.25% + 0.25 USD per payout, and 2.00 USD a month for each promoter paid that month (US) |
| **Trolley** | Your Trolley access key and secret, and a webhook key | Their payout method, on Trolley's own page | Your Trolley plan |
| **Tango** | Your Tango platform name and key, the customer and account you pay from, and the reward | An email | No fee on digital rewards |
| **PayPal** | The client id and secret of a Live REST app with Payouts switched on | A PayPal email | About 2% of each payment, at most 1.00 USD in the US and 20.00 USD across borders |
| **Wise** | A personal API token from your Wise business account | The email their Wise account receives at, or an IBAN | Wise's fee for each route, shown before you fund |
| **Your own system** | One of your webhook endpoints | Whatever your system needs | Nothing from BoltClaw |
| **A file** | Nothing | A PayPal or Wise email, or bank details | Nothing from BoltClaw |

The fees are estimates from each provider's own price list, shown before you press Send
and labelled "estimate, charged by <provider> to your account". Your provider's own screen
is the authority.

Connect a provider on the program's **Payouts** tab, under **How you pay**. Connecting one,
sending, and changing how a program pays need the **Payouts** permission, two-step
verification (turn it on in Settings, Account) and a sign-in in the last 15 minutes. So does
making, re-scoping or rotating an API key that holds `referrals:payouts`. Credentials are
sealed when they are saved, never shown again, and deleted the moment you disconnect.
Disconnecting also stops BoltClaw asking that provider about payouts still on their way:
check one in the provider before you mark it paid or cancel it.

Each provider has a **Sandbox** switch for its test account. A sandbox connection never pays
a batch; it sends one small test payout to an address you type, so you can watch the path
work. Test data never reaches a batch at all.

### Stripe's payouts key

A Stripe App cannot open accounts for your partners on your platform, or pay them: Stripe's
own documentation says an app "can't make API calls on behalf of those connected accounts".
So Stripe payouts use a **restricted key** you make in Stripe, Developers, API keys, with
exactly these permissions and nothing more:

| Resource | Access | Why |
|---|---|---|
| Connect: Accounts | Write | An account on your platform for each promoter |
| Connect: Account Links | Write | The link a promoter uses to set up their account |
| Connect: Transfers | Write | Paying a promoter from your balance |
| Balance | Read | Showing what you can pay before you press Send |

A secret key (`sk_`) is refused: it can do anything in your account, and BoltClaw never
holds one. Two currency rules are Stripe's own: a payout in ISK or UGX is not sent through
Stripe (its APIs do not all count those the same way), and one in a three-decimal currency
(BHD, JOD, KWD, OMR, TND) is sent only when its last digit is 0. An amount is never
rounded; such a payout fails with the reason, and goes in a file instead. Your Stripe Connect platform must be switched on. Each promoter's account is on
**your** platform; BoltClaw's own Stripe account is never in the flow, and Stripe's Global
Payouts (for licence holders) is never used.

### Wise: you fund it

BoltClaw builds the batch in your Wise account and marks it complete. **You fund it in
Wise**: UK and EEA business accounts cannot fund a batch through the API, and one step for
everyone is simpler to trust. Until you do, the batch shows "Waiting for you to fund it in
Wise", with a link. A transfer Wise does not see funded within 14 days is cancelled, and its
commissions come back to Ready to pay. Wise asks businesses to contact it before paying
email recipients; an IBAN always works.

## How a payout run goes

1. **Ready to pay** shows, per currency and provider, who a batch would pay and the
   provider's estimated fees, and everyone who would wait, with why: an open fraud flag,
   payout details changed in the last 48 hours, payouts they locked, below your minimum,
   or details the provider needs that they have not given yet.
2. **Create payout batch** freezes it: one payout per promoter per currency, each with the
   provider that pays it. Nothing is sent yet, and you can still export a file instead.
3. **Send** asks you to confirm the total and the provider. A payout larger than ten times
   the promoter's average, or above your program's largest payout, is named and needs a
   second confirmation.
4. Each payout is sent **once**: the send is claimed in the database before any provider
   is called, and every call carries an idempotency key made from the payout's own id. If a
   provider does not answer in time, nothing is sent again until BoltClaw has asked it what
   happened. A batch at Trolley or Wise is recorded on its payouts before anything is added
   to it, and a long send stops calling providers after about a minute and a half: the
   rest are sent within minutes, into the same batch, with the same keys.
5. Results come from the provider's webhooks (PayPal, Trolley) and from asking it every
   few minutes (all of them). A payout is `paid`, or `failed`, `returned` (it came back
   before it was paid) or `unclaimed` (the promoter has not claimed it yet). A failed or
   returned payout puts its commissions back in Ready to pay, with the reason, and the
   promoter is emailed what to fix. If a provider pays one you had already marked failed or
   cancelled, that is recorded in your activity log.

A payout's amount never changes after it is created. If a refund arrives while a batch is
still a draft, that payout cannot be sent: cancel it and make a new batch. A refund after a
payout was sent is taken from the promoter's **next** payout, never from the one on its
way. A payout that comes back after it was paid changes nothing on its own: the batch says
so, and you decide.

## Gift cards

A promoter's gift card reward (a [reward that is not cash](https://boltclaw.ai/docs/rewards-not-cash)) can be
given through Tremendous from the **Grants** tab, or with
`POST /v1/referrals/grants/{id}/send`. The order's id is made from the grant's, so pressing
again never buys a second card. A grant whose promoter or sale has an open fraud flag waits.
A friend's gift card is yours to give: BoltClaw holds no address for a friend.

## Promoters

A partner sees, for each program they belong to, how it pays them and what it still needs:
an email for Tremendous, Tango or PayPal, a Wise email or IBAN, **Set up payouts** with
Stripe (Stripe's own page, which asks them for their email itself), or **Open Trolley**
(Trolley's own page, given the email in their payout details, or their account's only if
they share it with the program). Choosing another
provider, or setting up a new account, counts as a change of payout details: it needs a
recent sign-in, the account's own address is told, and payouts to it wait 48 hours. Each
payout shows its provider, status, date and reference, and a failed one says what to fix.

Referrers in your own product are paid the same way; the panel asks for what their
provider needs.

## Sending on a schedule

A program can make its batch on a day of the month you choose. **Sending it by itself is
built and switched off:** it becomes available after a legal review, and until then a
person presses Send for every batch. When it is on, your payout managers are emailed 24
hours before, and any of them can stop it.

## Through the API and an AI assistant

| What | Operation | An assistant asks a person |
|---|---|---|
| The program's payout accounts | `GET /v1/referrals/programs/{id}/payout-providers` | no |
| Test one | `POST /v1/referrals/payout-providers/{id}/test` | no |
| How the program pays | `GET` / `PATCH /v1/referrals/programs/{id}/payout-settings` | always, to change |
| Ready to pay | `GET /v1/referrals/programs/{id}/payout-preview` | no |
| Make a batch | `POST /v1/referrals/programs/{id}/payout-batches` | no: nothing is sent |
| The batch, ready to send | `GET /v1/referrals/payout-batches/{id}` | no |
| **Send** | `POST /v1/referrals/payout-batches/{id}/send` | **always** |
| Stop a scheduled send | `POST /v1/referrals/payout-batches/{id}/cancel-auto-send` | no: a stop |
| One payout | `GET /v1/referrals/payouts/{id}` | no |
| Cancel a payout | `POST /v1/referrals/payouts/{id}/cancel` | no for a draft (a stop); **always** for one already exported or sent, or to mark one `failed` |
| Give a gift card | `POST /v1/referrals/grants/{id}/send` | **always** |

Sending, and changing how a program pays, needs a key with `referrals:payouts` (your own
server's) as well as `referrals:write`, or an assistant with a person's approval;
`referrals:write` alone never sends money. A person approving an assistant's send, its
gift card, or its cancelling a payout that was already exported or sent (its commissions may
then be paid again), must be signed in with two-step verification, and nobody approves a
payment to themselves. Connecting a provider is done in the dashboard only, because a credential
never passes through a chat with a model.

The events are `referral.payout.sent`, `referral.payout.paid`, `referral.payout.failed` and
`referral.payout.returned` ([Webhooks](https://boltclaw.ai/docs/webhooks)).

<!-- https://boltclaw.ai/docs/referral-payouts as markdown. Generated from openapi.yaml; API version 1.22.0. -->
<!-- Every /docs page answers as markdown: add .md to its path, or send Accept: text/markdown. -->
