# Split payments

A **split rule** attached to a collecting wallet automatically moves part of every payment it
receives into other wallets you own, by **percentage** or **fixed amount**. Whatever isn't
allocated stays in the collecting wallet.

Typical uses:

- setting aside tax or commission;
- separating revenue per branch or product;
- funding a payout float from sales.

```text
Customer pays KES 10,000 ──► Collecting wallet
                              │  − IntaSend fees and reserve
                              ▼
                       Net (split base)
                    ┌─────────┼─────────────┐
                    ▼         ▼             ▼
               Marketing     Tax      Remainder stays
                 20 %     KES 1,000   in collecting wallet
```

> **Availability**
Splits move funds between **your own wallets** in the **same currency**. Split payments must be
enabled on your account. Contact support if split rules have no effect.

## How it works

1. You create a split rule on a collecting wallet (for example your KES settlement wallet).
2. Every payment into that wallet (M-Pesa, mobile money, checkout, payment links, card, …) is covered by the wallet's active rule.
3. When the payment **clears** and its funds become available, IntaSend:
   - calculates the **split base**: the amount paid, minus IntaSend fees, minus any risk reserve held;
   - works through the rule's items in `sort_order`, moving each share into its destination wallet as a `SPLIT` transaction;
   - leaves the remainder in the collecting wallet.
4. Each executed share sends a `wallet_transfer_event` [webhook](https://developers.intasend.com/guides/webhooks/), and the result is recorded on the invoice under `splits[]`.

> **The rule is applied at clearing time**
The split is calculated from the rule that is active on the wallet **when the payment clears**,
not when the customer paid. If you change or deactivate a rule, it also affects payments that
are still clearing.

## Worked example

A rule on the collecting wallet:

| Item | `allocation_type` | `value` |
|---|---|---|
| Marketing wallet | `PERCENTAGE` | `20` |
| Tax wallet | `FIXED` | `1000` |

A customer pays **KES 10,000**, and fees are KES 300 with no reserve:

| | Amount |
|---|---|
| Split base (10,000 − 300) | KES 9,700.00 |
| Marketing: 20 % of 9,700 | KES 1,940.00 |
| Tax: fixed | KES 1,000.00 |
| **Left in the collecting wallet** | **KES 6,760.00** |

Percentages are always calculated on the **split base**, not on what is left after earlier items.
Amounts are rounded down to 2 decimal places.

## Create a rule

```bash
curl -X POST https://api.intasend.com/api/v1/split-rules/ \
  -H "Authorization: Bearer $INTASEND_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Marketing and tax",
    "wallet_id": "COLLECTING_WALLET_ID",
    "is_active": true,
    "items": [
      {"wallet_id": "MARKETING_WALLET_ID", "allocation_type": "PERCENTAGE", "value": 20, "sort_order": 0, "narrative": "Marketing"},
      {"wallet_id": "TAX_WALLET_ID", "allocation_type": "FIXED", "value": 1000, "sort_order": 1, "narrative": "Tax"}
    ]
  }'
```

### Request

| Field | Required | Description |
|---|---|---|
| `name` | Yes | Name of the rule (letters, numbers, spaces, `-`, `_` and `:`; max 140 characters) |
| `wallet_id` | Yes | The **collecting** wallet whose payments are split |
| `is_active` | No | Defaults to `true`. A wallet has one active rule at a time, so activating a rule deactivates the wallet's others. |
| `items` | Yes | One or more destinations (below) |

**Item fields:**

| Field | Required | Description |
|---|---|---|
| `wallet_id` | Yes | Destination wallet |
| `allocation_type` | Yes | `PERCENTAGE` or `FIXED` |
| `value` | Yes | A percentage (greater than 0, up to 100), or a fixed amount in the wallet currency |
| `sort_order` | No | The order items are processed in (lowest first). This matters when the split base can't cover every item |
| `narrative` | No | Description shown on both wallet transactions |

### Response

A successful create or replace returns `200` with the rule:

```json
{
  "id": "12",
  "name": "Marketing and tax",
  "wallet_id": "COLLECTING_WALLET_ID",
  "is_active": true,
  "percentage_total": 20,
  "items": [
    {"id": "…", "wallet_id": "MARKETING_WALLET_ID", "allocation_type": "PERCENTAGE", "value": 20, "sort_order": 0, "narrative": "Marketing"},
    {"id": "…", "wallet_id": "TAX_WALLET_ID", "allocation_type": "FIXED", "value": 1000, "sort_order": 1, "narrative": "Tax"}
  ],
  "created_at": "…",
  "updated_at": "…"
}
```

### Validation

A rule is rejected with `400` and `{"detail": "..."}` if:

- the `PERCENTAGE` items add up to more than 100;
- the same destination wallet appears more than once;
- a destination wallet isn't yours, is archived, or is in a different currency from the collecting wallet;
- a destination is the collecting wallet itself (the remainder already stays there).

## Manage rules

Use the rule's `id` from the create response. Full request and response schemas are in the
[API Reference → Split Payments](https://developers.intasend.com/reference/split-payments).

| Call | Purpose |
|---|---|
| `GET /split-rules/` | List rules |
| `GET /split-rules/{id}/` | Get a rule |
| `PUT /split-rules/{id}/` | Replace a rule, including its items |
| `POST /split-rules/{id}/activate/` | Make this the wallet's active rule |
| `POST /split-rules/{id}/deactivate/` | Stop splitting with this rule |
| `DELETE /split-rules/{id}/` | Delete a rule. A rule that has already been used is deactivated instead, to keep history. |

## Tracking splits

Each invoice (in [payment status](https://developers.intasend.com/guides/collections/overview/#check-payment-status) and the `collection_event`
webhook) includes a `splits` array once the payment has cleared:

```json
"splits": [
  {
    "id": "…",
    "origin": "WALLET",
    "destination_wallet": "MARKETING_WALLET_ID",
    "allocation_type": "PERCENTAGE",
    "value": 20,
    "computed_amount": 1940.0,
    "narrative": "Marketing",
    "status": "EXECUTED",
    "failed_reason": null,
    "executed_at": "…"
  }
]
```

| `status` | Meaning |
|---|---|
| `PENDING` | Waiting for the payment to clear |
| `EXECUTED` | Moved to the destination wallet |
| `SKIPPED` | Nothing to move: the computed amount was below the minimum, or fees and reserve used up the whole payment |
| `FAILED` | Not moved, and `failed_reason` explains why. For example, a fixed amount larger than what was left, or a destination wallet that was archived |

Each item is handled on its own, so one failed item never blocks the others or the payment itself.
Anything not moved stays in the collecting wallet.

## Edge cases

| Situation | What happens |
|---|---|
| Items add up to more than the split base | Items are processed in `sort_order` until the base runs out, and later items are marked `FAILED`. The collecting wallet never goes negative because of a split. |
| Fees and reserve use up the whole payment | Every item is marked `SKIPPED`. |
| Destination wallet archived after the rule was created | That item is marked `FAILED`, and the rest are processed. |
| Payment isn't a sale (a deposit, adjustment or transfer) | No split. |
| Refund or chargeback after a split | Split transfers aren't reversed automatically. Move the funds back yourself with an [intra-wallet transfer](https://developers.intasend.com/guides/wallets/#move-funds-between-wallets) if needed. |
