Treasury: stablecoin intake & payout

StarPay is the sole counterparty for stablecoin↔fiat. Aggregators collect stablecoins into per-user deposit addresses and pay stablecoins out to external wallets; StarPay terminates the exchange as principal. Custody is handled by Cobo WaaS (MPC) — internal custody identifiers, the master/consolidation address, and raw provider payloads are never exposed. Crypto amounts are integer minor units (USDT/USDC use 6 decimals: 10.50 USDT is 10500000).

Supported assets: USDT and USDC on TRON (TRC20), Ethereum (ERC20), and BNB Smart Chain (BEP20).

Collections: deposit addresses

POST /api/v1/treasury/collections/addresses provisions (or reuses) a unique deposit address for your account. Requires the treasury:write scope. Each address is dedicated to you but settles, in the background, into StarPay's Cobo-managed wallet — that wallet is never surfaced.

curl -X POST https://api-dev.starpay.app/api/v1/treasury/collections/addresses \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{ "asset": "USDT", "network": "TRC20" }'
{
  "status": true,
  "message": "Deposit address ready",
  "data": { "address": "TXk9...he2", "asset": "USDT", "network": "TRC20" }
}

Send funds to that address. Cobo detects the on-chain deposit (webhook, with a poll fallback), it's screened (KYT), and once confirmed your balance updates and a deposit.confirmed webhook fires. List deposits with GET /api/v1/treasury/deposits. GET /collections/addresses lists your addresses.

Payouts: fiat to a recipient (remittance)

POST /api/v1/treasury/payouts converts your stablecoin liability to GHS and disburses it to a mobile-money or bank recipient — the aggregator remittance flow. Money-out, so it requires the treasury:write scope, an Idempotency-Key, and an HMAC signature.

{
  "usd_amount": 10000,
  "target_channel": "momo",
  "recipient": "0240000000"
}

For a bank payout, add bank_code. Before any value moves, StarPay name-enquires the recipient on the rail (momo/bank) and refuses a payout whose holder can't be verified (validation_error); the resolved recipient_name is returned on the payout and included in the end-recipient's SMS receipt. The payout returns requested/converting and resolves to settled (or failed, which reverses the conversion) via callback — poll GET /api/v1/treasury/payouts/{reference}. Successful payouts emit payout.success (and payout.failed on failure).

Payouts: stablecoin out

POST /api/v1/treasury/payouts/crypto sends stablecoin from StarPay's inventory to an external wallet you specify. Money-out, so it requires the treasury:write scope, an Idempotency-Key, and an HMAC signature.

{
  "asset": "USDT",
  "network": "TRC20",
  "to_address": "TRecipient...addr",
  "amount": 10500000
}

The payout returns pending and resolves to its terminal status via callback — poll GET /api/v1/treasury/payouts/{reference} rather than blocking. To fund a stablecoin payout from a GHS balance instead, use POST /api/v1/treasury/payouts/crypto-from-ghs with ghs_amount (StarPay applies the configured USD↔GHS rate and spread).

Settlement reports

GET /api/v1/treasury/settlement-reports lists periodic settlement reports; POST generates one for a period_start/period_end window. Useful for reconciling intake against payouts.

Test every flow against the Simulator custody backend first — see Testing in Postman for a ready-made collection and a step-by-step run. The exact request/response schemas live in the API Reference.