Wallet Service
Manage user wallets for stored value, rewards, and payments
Overview
The Wallet Service is the system of record for user value, balance, and wallet transactions. It can be used by any channel — apps, websites, partner platforms, and internal services.
- Loyalty rewards storage
- Cashback programs
- Prepaid balances
- In-store redemption
- Mobile apps
- Websites / eCommerce
- Partner platforms
- In-store (via wiCode)
- Real-time balance
- Auth / Finalise / Reverse
- Full audit trail
- Pre-integrated in-store
Wallet APIs
| Method | Endpoint | Description |
|---|---|---|
| POST | /wallet/users | Create Wallet User |
| GET | /wallet/users/{externalUserId}/balance | Get Wallet Balance |
| GET | /wallet/wallets/{walletId} | Get Wallet Balance (by ID) |
| POST | /wallet/users/{externalUserId}/credit | Credit Wallet |
| POST | /wallet/users/{externalUserId}/authorise | Authorise Wallet Debit |
| POST | /wallet/users/{externalUserId}/finalise/{authorisationId} | Finalise Wallet Debit |
| POST | /wallet/users/{externalUserId}/reverse/{authorisationId} | Reverse Wallet Debit |
| GET | /wallet/users/{externalUserId}/transactions | List Wallet Transactions |
Flow 1: Direct Digital Wallet
For apps, websites, and digital channels
- 1Call Authorise Debit to hold funds
- 2Complete your checkout / order flow
- 3Call Finalise Debit on success
- 4Or call Reverse Debit if cancelled
Flow 2: Redeem In-Store
Pre-integrated via Yoyo VSP
- 1The returned PAN value can be rendered as a wiCode for the wallet user
- 2Display the wiCode in your app (QR or numeric)
- 3The customer presents the wiCode at a participating store
- 4Yoyo receives the POS transaction via VSP
- 5Yoyo automatically calls Wallet Authorise Debit
- 6Yoyo automatically calls Wallet Finalise Debit (or Reverse) based on outcome
Create Wallet User
Creates a wallet user for the partner shopper reference and returns the active wallet profile
# Create a new wallet user
curl -X POST "https://api.yoyo.co.za/wallet/users" \
-H "accept: application/json" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-d '{
"externalUserId": "partner-shopper-9f04706a",
"mobileNumber": "+27710003000",
"firstName": "Runtime",
"lastName": "Check",
"email": "runtime.check@example.com"
}'
# Response (201 Created)
{
"userId": 4812,
"walletId": 9264,
"externalUserId": "partner-shopper-9f04706a",
"mobileNumber": "+27710003000",
"pan": "6007851234567890",
"balance": 0,
"currency": "ZAR",
"status": "ACTIVE",
"createdAt": "2026-03-23T08:13:35.069Z"
}
# Duplicate Request (409 Conflict) - Returns existing resource
{
"userId": 4812,
"walletId": 9264,
"externalUserId": "partner-shopper-9f04706a",
...
}Get Wallet Balance
Reads the current wallet balance using the partner shopper reference
# Get wallet balance by external user ID
curl -X GET "https://api.yoyo.co.za/wallet/users/partner-shopper-9f04706a/balance" \
-H "accept: application/json" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json"
# Response (200 OK)
{
"walletId": 9264,
"userId": 4812,
"availableBalance": 100000,
"reservedBalance": 0,
"balance": 100000,
"currency": "ZAR",
"status": "ACTIVE"
}Alternatively, look up by the numeric wallet ID returned during user creation:
# Get wallet balance by wallet ID
curl -X GET "https://api.yoyo.co.za/wallet/wallets/9264" \
-H "accept: application/json" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json"
# Response (200 OK)
{
"walletId": 9264,
"userId": 4812,
"availableBalance": 100000,
"reservedBalance": 0,
"balance": 100000,
"currency": "ZAR",
"status": "ACTIVE"
}Credit Wallet
Credits funds into the shopper wallet using the partner transaction reference
# Credit funds to a wallet
curl -X POST "https://api.yoyo.co.za/wallet/users/partner-shopper-9f04706a/credit" \
-H "accept: application/json" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"description": "Promotional wallet credit",
"externalTransactionRef": "PARTNER_TOPUP_1711180812000_5000"
}'
# Response (200 OK)
{
"transactionId": 834201,
"walletId": 9264,
"type": "CREDIT",
"amount": 5000,
"availableBalance": 105000,
"reservedBalance": 0,
"status": "COMPLETED"
}
# Duplicate Request (409 Conflict) - Returns existing transaction
{
"transactionId": 834201,
"walletId": 9264,
...
}Finalise Wallet Debit
Finalises an existing authorisation once checkout succeeds
Call Finalise to convert the reserved balance into a completed debit. The finalAmount is optional and can be omitted to settle the full authorised amount.
# Finalise an authorised debit (completes the transaction)
curl -X POST "https://api.yoyo.co.za/wallet/users/partner-shopper-9f04706a/finalise/834245" \
-H "accept: application/json" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-d '{
"finalAmount": 25000
}'
# Response (200 OK)
{
"transactionId": 834245,
"walletId": 9264,
"type": "DEBIT",
"amount": 25000,
"availableBalance": 80000,
"reservedBalance": 0,
"status": "COMPLETED",
"createdAt": "2026-03-23T08:13:42.069Z",
"authorisationId": 834245,
"finalAmount": 25000
}
# Note: finalAmount is optional - omit to settle the full authorised amountReverse Wallet Debit
Releases a reserved wallet amount when checkout fails or is cancelled
Call Reverse to release the reserved funds back to the customer's available balance. Use this when an order is cancelled or the transaction is abandoned by the merchant.
# Reverse an authorised debit (releases the hold)
curl -X POST "https://api.yoyo.co.za/wallet/users/partner-shopper-9f04706a/reverse/834245" \
-H "accept: application/json" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-d '{
"reason": "Order cancelled by merchant"
}'
# Response (200 OK)
{
"transactionId": 834245,
"walletId": 9264,
"availableBalance": 105000,
"reservedBalance": 0,
"status": "REVERSED",
"createdAt": "2026-03-23T08:14:01.069Z",
"authorisationId": 834245,
"reason": "Order cancelled by merchant"
}List Wallet Transactions
Returns the wallet activity stream with pagination support
Use this endpoint to inspect credits, authorisations, captures, and reversals. Supports pagination with offset and limit query parameters.
# List wallet transactions
curl -X GET "https://api.yoyo.co.za/wallet/users/partner-shopper-9f04706a/transactions?offset=0&limit=20" \
-H "accept: application/json" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json"
# Response (200 OK)
{
"walletId": 9264,
"transactions": [
{
"transactionId": 834245,
"authorisationId": 834245,
"type": "DEBIT",
"amount": 25000,
"balanceAfter": 80000,
"description": "Checkout reserve for order 4f5c5d5f",
"status": "COMPLETED",
"createdAt": "2026-03-23T08:13:42.069Z"
},
{
"transactionId": 834201,
"type": "CREDIT",
"amount": 5000,
"balanceAfter": 105000,
"description": "Promotional wallet credit",
"status": "COMPLETED",
"createdAt": "2026-03-23T08:12:10.069Z"
}
],
"totalCount": 2,
"offset": 0,
"hasMore": false
}Redeem In-Store
Pre-built capability for in-store wallet redemption
How it works
Redeem In-Store provides an off-the-shelf capability for in-store wallet redemption using a wiCode. Yoyo uses the VSP service underneath and automatically stitches the redemption into the wallet authorise/finalise lifecycle — you don't need to orchestrate those calls.
- 1The returned PAN value can be rendered as a wiCode for the wallet user
- 2Display the wiCode in your app (QR or numeric)
- 3The customer presents the wiCode at a participating store
- 4Yoyo receives the POS transaction via VSP
- 5Yoyo automatically calls Wallet Authorise Debit
- 6Yoyo automatically calls Wallet Finalise Debit (or Reverse) based on outcome
Key Benefit
This is a pre-built capability built on top of the wallet service. The integrator only needs to display the PAN — Yoyo handles the entire downstream redemption flow, including wallet authorisation and finalisation.
