Seev PlusDocs
Docs
Get Paid

Subaccounts

Give a partner, branch or vendor a percentage share of a payment, settled into their own balance with its own payout record.

A subaccount is a settlement destination owned by your organization. Attach one to a payment and Seev splits that payment between your main balance and the subaccount, each with its own payout record. Use it when someone else has a claim on part of the money: a partner studio, a branch, a vendor on a marketplace.

Dashboard and APICreate and manage from either, apply at checkout
Use it when

Part of a payment belongs to someone else and should settle to them directly rather than being paid on later.

Not for

Your own second balance, or a split you want to decide after the payment. The share is fixed when the payment is created.

Needs

A verified subaccount, and the Checkout API to attach it to a payment.

How a split works

Fees come off the top, then both sides take their percentage. Each side receives its share of the gross, the fee and the net, so a partner on 30% carries 30% of the processing fee on that payment rather than having it absorbed for them.

The share is a percentage above 0 and below 100, with at most two decimal places. A payment cannot be split 0% or 100%.

The share is fixed onto the payment when it is created. Changing the subaccount's default later does not alter payments already made.

Your main balance absorbs the rounding remainder, so the two shares always add back to the exact amount collected.

The subaccount's cut lands in its own balance with its own payout record. Your payouts move only your own share.

A payout smaller than your gross sales can still be correct. Read the payout's reconciliation summary, which separates fees, refunds and subaccount splits. See Payout Schedules.

Create a subaccount

You can create a subaccount from the dashboard or through the API. Both produce the same record and the same SUB_ code.

From the dashboard, go to Subaccounts in the sidebar. Viewing needs the payout_settings.read permission and creating or pausing needs payout_settings.manage, so a teammate on a limited role may not see the page at all.

Business nameReq
string

The partner, branch or vendor this share belongs to. Shown on their payout records.

DestinationReq
enum

A bank account, or mobile money on MTN MoMo, Telecel Cash or AT Money.

Account numberReq
string

The bank account number, or the mobile money phone number.

Account nameReq
string

The account holder. For mobile money this is looked up from the network and filled in for you once the number is complete.

ShareReq
number

The percentage of each payment that goes to this subaccount. Above 0 and below 100.

Currency
string

Defaults to GHS. It has to match the currency of any payment you attach the subaccount to.

A new subaccount is created active, and its code is returned in the form SUB_ followed by sixteen hex characters. That code is what you pass at checkout. Whether it starts verified depends on the destination, covered under How a subaccount gets verified.

Through the API

The subaccount routes take the same developer key as the Checkout API, on the same host, so sandbox and production follow the key you send. Field names are snake_case here and differ from the dashboard labels.

curl -X POST \
  https://api.seevplus.com/api/v1/developer/subaccounts \
  -H "Authorization: Bearer $SEEV_CHECKOUT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "business_name": "Ama Studio",
    "settlement_bank": "mtn",
    "account_number": "0241234567",
    "account_name": "Ama Mensah",
    "default_share_percent": 30
  }'
business_nameReq
string

The partner, branch or vendor this share belongs to.

settlement_bankReq
string

A mobile money network or bank code from the settlement codes list. A code that is not on the list is refused.

settlement_bank_name
string

Display name for the destination. Filled in from the code when you leave it out.

account_numberReq
string

Bank account number, or the mobile money phone number. A mobile money number can be sent as 0241234567 or 233241234567.

account_nameReq
string

The account holder. For mobile money in production this has to agree with the name the network has on record, so look it up first.

currency
string

Defaults to GHS. Has to match the currency of any payment you attach it to.

default_share_percentReq
number

Above 0 and below 100, at most two decimal places.

A successful create returns 201 and the subaccount, with the account number masked to its last four digits. A request Seev refuses, such as an unknown code or a name that does not match, returns 422 with the reason in message.

Settlement codes

settlement_bank takes one of these codes. The three mobile money codes are fixed:

Destinationsettlement_bank
MTN MoMomtn
Telecel Cashtelecel
AT Moneyat

Bank codes come from the live list, along with the mobile money codes above, so read them from the API rather than hard-coding them:

curl https://api.seevplus.com/api/v1/developer/settlement-banks \
  -H "Authorization: Bearer $SEEV_CHECKOUT_API_KEY"
{
    "success": true,
    "data": {
        "mobile_money": [
            { "code": "mtn", "name": "MTN MoMo", "type": "mobile_money" },
            { "code": "telecel", "name": "Telecel Cash", "type": "mobile_money" },
            { "code": "at", "name": "AT Money", "type": "mobile_money" }
        ],
        "banks": [{ "code": "300304", "name": "GCB Bank", "type": "bank" }],
        "banks_available": true
    }
}

banks_available is false on the rare occasion the bank list cannot be loaded. The mobile money codes are always returned.

Look up an account name

Before you create a mobile money subaccount, confirm who the number belongs to. The lookup returns the name the network has registered against it.

curl -X POST \
  https://api.seevplus.com/api/v1/developer/resolve-account \
  -H "Authorization: Bearer $SEEV_CHECKOUT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "settlement_bank": "mtn",
    "account_number": "0241234567"
  }'
{
    "success": true,
    "data": {
        "settlement_bank": "mtn",
        "account_number": "0241234567",
        "account_name": "AMA MENSAH"
    }
}

Pass the returned account_name straight into the create request. A number the network does not recognise returns 404. The lookup covers mobile money only; a bank code returns 422.

How a subaccount gets verified

Sandbox. Every subaccount is verified as soon as it is created, so you can test a split straight away. No money moves in sandbox.

Mobile money, production. Seev checks account_name against the network's record when you create or edit the subaccount. A match verifies it on the spot. A different name is refused with 422.

Bank account, production. The subaccount starts as pending and is confirmed by review, usually within 24 hours.

If the network cannot be reached during a mobile money check, the subaccount is created as pending. Send the same account_number and account_name in a PATCH to run the check again.

Manage through the API

GET /api/v1/developer/subaccounts
route

Lists the organization's subaccounts for the key's environment.

GET /api/v1/developer/subaccounts/{code}
route

Fetches one by its SUB_ code. An unknown code returns 404.

PATCH /api/v1/developer/subaccounts/{code}
route

Edits business_name, settlement_bank, account_number, account_name, default_share_percent, and active to pause or resume.

DELETE /api/v1/developer/subaccounts/{code}
route

Removes a subaccount that has never been attached to a payment. One with payment history returns 409; pause it with active: false instead.

GET /api/v1/developer/settlement-banks
route

Lists every code settlement_bank accepts.

POST /api/v1/developer/resolve-account
route

Returns the registered name for a mobile money number.

Changing the bank, account number or account name runs verification again. Until the new destination is verified, the subaccount cannot be attached to a payment. verification_status is decided by Seev and cannot be set through the API.

Read a subaccount's state

Unverified

The destination has not been confirmed. Cannot be attached to a payment yet.

Verified

Confirmed. Can be attached to a payment.

Paused

Set inactive from the dashboard or the API. Cannot be attached to a new payment until it is resumed.

Only a verified, active subaccount can be attached to a payment. Payments you create without one are unaffected and settle in full to your main balance.

Pausing a subaccount has the same effect as leaving it unverified: a checkout request that names it is refused, so drop the subaccount field to take the payment in full to your main balance. Payments already split keep their share.

Split a payment through the API

Pass the subaccount code as subaccount when you create a checkout session. Everything else about the request is unchanged.

curl -X POST \
  https://api.seevplus.com/api/v1/developer/payments \
  -H "Authorization: Bearer $SEEV_CHECKOUT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "checkout",
    "amount": 10000,
    "currency": "GHS",
    "subaccount": "SUB_9f2k1p7qw4r8c3e1",
    "recipient": {
      "name": "Ama Mensah",
      "email": "ama@example.com"
    },
    "redirect_url": "https://yourapp.com/payment/callback"
  }'

Seev resolves the code before the session is created, and rejects the whole request rather than quietly ignoring the split if any of these does not hold.

The subaccount exists on the organization the API key belongs to, in the same environment as the key.

The subaccount is active, not paused.

The subaccount is verified. Sandbox subaccounts always pass this check.

The subaccount's currency matches the payment's currency.

A failure here reaches you the way every other upstream failure on this route does: a 502 whose message carries the upstream text, such as the subaccount being inactive, still pending verification, or holding a different currency. See Errors and codes for how to read one.

The session response carries a split object describing what was applied, so you can record the share against your own order:

{
    "split": {
        "subaccount": "SUB_9f2k1p7qw4r8c3e1",
        "business_name": "Ama Studio",
        "share_percent": 30
    }
}

Split payments cannot be paid in USDC yet. If you pass crypto in channels together with a subaccount, Seev leaves it out and the checkout offers your other channels; the channels in the response show what the customer will see. A request whose only channel is crypto is refused. To take USDC, create the payment without a subaccount.

A split applies only to payments that pass the subaccount in. Invoices, payment links, storefront and POS charges created from the dashboard are not split, and their full amount stays in your own balance.

Payouts

A split payment is paid out twice: your share to your payout destination, and the subaccount's share to the subaccount's own destination. Both follow your payout schedule. On a GH₵1,000 payment with a 1.5% fee and a subaccount on 80%:

Paid toGrossFeePaid out
YouGH₵200GH₵3GH₵197
SubaccountGH₵800GH₵12GH₵788

In the dashboard, Accounts lists both kinds of payout together, with a Paid to column that names the subaccount.

Read payout history through the API

List every payout made to you and to your subaccounts, newest first:

curl "https://api.seevplus.com/api/v1/developer/payouts" \
  -H "Authorization: Bearer $SEEV_CHECKOUT_API_KEY"

Add subaccount to get one subaccount's payouts, which is what you need to show a partner their own history inside your product. Use subaccount=main for your own payouts only.

curl "https://api.seevplus.com/api/v1/developer/payouts?subaccount=SUB_9f2k1p7qw4r8c3e1" \
  -H "Authorization: Bearer $SEEV_CHECKOUT_API_KEY"
{
    "success": true,
    "data": {
        "payouts": [
            {
                "id": "stlp_66f1a_20260927T000000Z_20260928T000000Z_sub_9f2k1p7qw4r8c3e1",
                "account_type": "subaccount",
                "subaccount": "SUB_9f2k1p7qw4r8c3e1",
                "business_name": "Ama Studio",
                "amount": 78800,
                "gross_amount": 80000,
                "fee_amount": 1200,
                "currency": "GHS",
                "transaction_count": 1,
                "status": "paid",
                "reference": "MOMO-20260928-118",
                "period": {
                    "from": "2026-09-27T00:00:00Z",
                    "to": "2026-09-28T00:00:00Z"
                },
                "paid_at": "2026-09-28T09:14:00Z",
                "destination": {
                    "type": "mobile_money",
                    "network": "mtn",
                    "account_name": "Ama Mensah",
                    "account_number_masked": "******4567"
                }
            }
        ],
        "total": 1,
        "page": 1,
        "limit": 20,
        "env": "production"
    }
}
subaccount
query

A SUB_ code, or main for your own payouts. Leave it out for everything.

page
query

Defaults to 1.

limit
query

Defaults to 20, at most 100.

amount
number

What was paid out, in pesewas: gross_amount less fee_amount.

GET /api/v1/developer/payouts/{id}
route

One payout, with a transactions list of the payments it covers. For a subaccount payout each entry is the subaccount's share of that payment.

Payouts exist in production only. A sandbox key returns an empty list, because sandbox payments move no money.

Common questions

On this page