Collect via wallet

Collect in-app from a wallet your customer already holds. Create a virtual_wallet payment, settle it with /wallets/:id/pay: a pure internal transfer, no bank rail.

Sometimes the money is already inside Acute. Your customer holds a wallet, they want to pay another wallet, and there's no reason to round-trip through the banks. A virtual_wallet payment collects wallet → wallet, in-app, instantly: a pure internal ledger transfer with no bank rail and no provider fee.

Two steps: create the payment to say "₦X is owed to this wallet," then have the payer's wallet settle it.

Same POST /payments, but method: "virtual_wallet". There's no NUBAN to mint: the response is just the amount owed and the fee breakdown.

# create a virtual_wallet payment"
curl -X POST https://sandbox.api.acute.network/v1/payments \
  -H "Authorization: Bearer acuinf_test_..." \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "virtual_wallet",
    "baseAmount": 250000,
    "targetWalletId": "acuinf830192847561wlt",
    "description": "Tip for ride #92"
  }'
201 Created
json
{
  "success": true,
  "statusCode": 201,
  "data": {
    "id": "acuinf558712049336pay",
    "method": "virtual_wallet",
    "status": "pending",
    "baseAmount": 250000,
    "fee": 3750,
    "payableAmount": 253750,
    "amountReceived": 0,
    "currency": "NGN",
    "targetWalletId": "acuinf830192847561wlt",
    "description": "Tip for ride #92",
    "expiresAt": null,
    "settledAt": null,
    "createdAt": "2026-06-26T12:00:00.000Z",
    "virtualAccount": null
  }
}

No provider fee, no NUBAN

virtual_wallet payments never touch the bank rail, so there's no provider fee and virtualAccount is null. The fee on this payment is the transfer fee (clamp(₦10, 1.5%, ₦100)), billed to the paying wallet, not the bank-collection fee.

The payer's wallet pays the payment by its reference. This is a payment-scoped call with the payment id in the query:

# payer wallet settles the payment
curl -X POST "https://sandbox.api.acute.network/v1/wallets/acuinf661043820917wlt/pay?paymentId=acuinf558712049336pay" \
  -H "Authorization: Bearer acuinf_test_..." \
  -H "Idempotency-Key: $(uuidgen)"

Both wallets must be kycStatus: tier1, they must belong to the same org, and the payer can't be the target (PAYMENT_SELF_PAY422). Settlement is synchronous: the response comes back settled.

Settling a virtual_wallet payment is one internal transfer. The payer's wallet is debited the full payableAmount; the target gets the base; the Acute fee is remitted. No suspense account, because no money left Acute.

Wallet payment settles

₦2,500.00 base · ₦37.50 Acute (transfer) fee · no provider fee

ledger_transaction kind: payment_settlement. Identical posting shape to a wallet→wallet transfer, because that's exactly what it is.

If that diagram looks familiar, good: it is a transfer, just framed as a payment so you get a payment record, a payment status, and a payment.settled webhook. The accounting is the same three legs.

Shorter than the bank-transfer story: there's no expiry window and no NUBAN to wait on. A virtual_wallet payment is pending until a wallet settles it, then settled.

pendingentry status

Created and waiting for a wallet to pay it via /wallets/:id/pay. No money has moved.

Transitions out

  • pendingsettled

    A wallet calls /wallets/:id/pay?paymentId=… and covers payableAmount

    firespayment.settled

  • pendingfailed

    The payer wallet can't cover the amount, or settlement otherwise faults

webhook: payment.settled
json
{
  "id": "acuinf913660472518evt",
  "type": "payment.settled",
  "createdAt": "2026-06-26T12:01:09.000Z",
  "data": {
    "id": "acuinf558712049336pay",
    "status": "settled",
    "baseAmount": 250000,
    "amountReceived": 253750,
    "currency": "NGN"
  }
}

Both wallets need tier-1 KYC

In-app collection moves real ledger balances, so both the payer and target wallets must be tier1. A wallet at kycStatus: none can't pay or be paid: you'll get a 403 WALLET_KYC_REQUIRED. Submit KYC on the wallet first (POST /wallets/:id/kyc).

bank_transfervirtual_wallet
Money sourceexternal bank, via NIPa wallet already in your org
Provider feeyes (clamp(₦0.5, 0.5%, ₦200))none
Settlementasync (webhook on inbound)sync (the pay call returns settled)
Has a NUBANyes, expiringno
Use it forfirst-touch collection from anyonein-app payments between your users