OuiPay
Guides

Send Money

Payouts : create a beneficiary, submit a transfer, track hold lifecycle, and confirm via webhook.

Sending funds out to a bank account, mobile money number, or another wallet.

Transfer pipeline flow

sequenceDiagram
    autonumber
    participant Merchant as Merchant App
    participant OuiPay as OuiPay API
    participant Hold as Wallet Hold Engine
    participant Compliance as Compliance Gating
    participant Provider as Payout Provider

    Merchant->>OuiPay: POST /v1/beneficiaries
    OuiPay-->>Merchant: Beneficiary created & name-verified
    Merchant->>OuiPay: POST /v1/transfers (Idempotency-Key: trf_8842)
    OuiPay->>Compliance: Sanction & Tier Limit Check
    OuiPay->>Hold: Reserve minor units (Hold State: active)
    OuiPay-->>Merchant: 201 Created (status: pending)
    OuiPay->>Provider: Dispatch payout to bank/momo
    alt Payout Success
        Provider-->>OuiPay: Webhook: Success
        OuiPay->>Hold: Convert hold to ledger debit
        OuiPay->>Merchant: Webhook (transfer.completed)
    else Payout Failure
        Provider-->>OuiPay: Webhook: Rail Failed
        OuiPay->>Hold: Release hold (Available balance restored)
        OuiPay->>Merchant: Webhook (transfer.failed)
    end

1. Create a beneficiary

Register and verify a payout destination:

curl https://api.ouipay.com/v1/beneficiaries \
  -H "Authorization: Bearer sk_test_..." \
  -H "Idempotency-Key: ben-001" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "01M2S17...",
    "type": "bank_account",
    "bank_code": "058",
    "account_number": "0123456789",
    "currency": "NGN"
  }'

2. Submit the transfer

curl https://api.ouipay.com/v1/transfers \
  -H "Authorization: Bearer sk_test_..." \
  -H "Idempotency-Key: trf-8842" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "01M2S17...",
    "beneficiary_id": "01M2S17...",
    "amount_minor": 250000,
    "currency": "NGN",
    "narration": "Invoice 8842 payout"
  }'

3. Track the outcome

The transfer moves pending → processing → completed | failed and your endpoint receives transfer.completed or transfer.failed.

For synchronous status polling:

curl https://api.ouipay.com/v1/transfers/01M2S18... \
  -H "Authorization: Bearer sk_test_..."

The hold lifecycle

  1. pending: hold placed; available balance reduced by amount + fee.
  2. completed: hold converts into immutable ledger debit.
  3. failed: hold released; available balance restored.
  4. unknown: hold stays active until reconciliation resolves outcome.

On this page