Skip to Content
API ReferenceRecipient Verification

Recipient Verification API

Verify recipient details before sending payments to ensure accuracy and reduce failed transactions.

Verify Mobile Money Transfer

Validate mobile money wallet number before transfer.

POST /business/verify-transfer

Request Body

FieldTypeRequiredDescription
countryCodestringYesCountry code: KE, TZ, UG, ZA
phoneNumberstringYesPhone number with international prefix

Example Request - Kenya TESTENV Number

curl -X POST https://api.test.wakapay.io/business/verify-transfer \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "countryCode": "KE", "phoneNumber": "+254700000001" }'
const response = await fetch( "https://api.test.wakapay.io/business/verify-transfer", { method: "POST", headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json", }, body: JSON.stringify({ countryCode: "KE", phoneNumber: "+254700000001", }), }, ); const data = await response.json(); console.log(data);

Response

{ "displayName": "Amina Mjema", "receiverPhone": "+254700000001", "verified": true }

Response Fields

FieldTypeDescription
verifiedbooleanWhether recipient was successfully verified
displayNamestringRegistered name of the account holder
receiverPhonestringVerified phone number

TESTENV Test Phone Numbers

Use these phone numbers for testing mobile money transfers:

CountryPhone NumberVerificationDisplay Name
Kenya (KE)+254700000001verified: trueAmina Mjema
Tanzania (TZ)+255700000001verified: trueAmina Mjema

Non-test phone numbers will return verified: false with empty displayName in TESTENV.

Example Request - Tanzania TESTENV Number

curl -X POST https://api.test.wakapay.io/business/verify-transfer \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "countryCode": "TZ", "phoneNumber": "+255700000001" }'

Response - Tanzania

{ "displayName": "Amina Mjema", "receiverPhone": "+255700000001", "verified": true }

Example Response - Non-Test Number

{ "displayName": "", "receiverPhone": "+254712345678", "verified": false }

Verify Payment (Till/Paybill)

Validate Paybill or Till number before payment.

POST /business/verify-payment

Difference between Till and Paybill:

  • Till (Lipa Number) - No account reference needed. Payment goes directly to the till number.
  • Paybill - Requires an account reference. Payment goes to the paybill number with a specific account reference for tracking.

Till/Paybill Request Body

FieldTypeRequiredDescription
countryCodestringYesCountry code: KE, TZ, UG, ZA
typestringYesPayment type: till or paybill
lipaNumberstringYesTill or Paybill number
accountReferencestringConditionalAccount reference (required for paybill, omit for till)

TESTENV Test Lipa Numbers

Use these numbers for testing till/paybill payments:

CountryTypeLipa NumberAccount RefDisplay Name
Kenya (KE)Till888880-Ugali Point
Kenya (KE)Paybill123456ABC123Ugali Point Paybill
Tanzania (TZ)Till600000-Ugali Point
Tanzania (TZ)Paybill700000ABC123Ugali Point Paybill

Example Request - Kenya Till

curl -X POST https://api.test.wakapay.io/business/verify-payment \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "countryCode": "KE", "type": "till", "lipaNumber": "888880" }'
const response = await fetch( "https://api.test.wakapay.io/business/verify-payment", { method: "POST", headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json", }, body: JSON.stringify({ countryCode: "KE", type: "till", lipaNumber: "888880", }), }, ); const data = await response.json(); console.log(data);

Response - Till

{ "displayName": "Ugali Point", "verified": true }

Example Request - Kenya Paybill

curl -X POST https://api.test.wakapay.io/business/verify-payment \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "countryCode": "KE", "type": "paybill", "lipaNumber": "123456", "accountReference": "ABC123" }'

Response - Paybill

{ "displayName": "Ugali Point Paybill", "verified": true }

Verification Status

StatusDescriptionAction
verified: trueRecipient exists and can receive paymentsProceed with payment
verified: falseRecipient does not exist or not active in TESTENVCheck details and retry, or activate account for production

Use Cases

Verify Before Mobile Money Transfer

async function sendVerifiedTransfer( amount, currency, phoneNumber, countryCode, reference, ) { // Step 1: Verify recipient const verifyResponse = await fetch( "https://api.test.wakapay.io/business/verify-transfer", { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, body: JSON.stringify({ countryCode: countryCode, phoneNumber: phoneNumber, }), }, ); const verifyData = await verifyResponse.json(); if (!verifyData.verified) { throw new Error("Recipient verification failed"); } // Step 2: Use verified name in transfer console.log(`Sending to: ${verifyData.displayName}`); // Step 3: Send transfer const transferResponse = await fetch( "https://api.test.wakapay.io/business/payout/transfer", { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, body: JSON.stringify({ senderCurrency: "USD", receiverCurrency: currency, amount: amount, receiverPhone: phoneNumber, payoutCountry: countryCode, businessReference: reference, // ... other required fields }), }, ); return await transferResponse.json(); }

Verify Before Till/Paybill Payment

async function sendVerifiedPayment( amount, currency, lipaNumber, type, countryCode, reference, ) { // Step 1: Verify payment recipient const verifyPayload = { countryCode: countryCode, type: type, lipaNumber: lipaNumber, }; // Add account reference for paybill if (type === "paybill") { verifyPayload.accountReference = "ABC123"; } const verifyResponse = await fetch( "https://api.test.wakapay.io/business/verify-payment", { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, body: JSON.stringify(verifyPayload), }, ); const verifyData = await verifyResponse.json(); if (!verifyData.verified) { throw new Error("Payment recipient verification failed"); } console.log(`Paying to: ${verifyData.displayName}`); // Step 2: Send payment const paymentResponse = await fetch( "https://api.test.wakapay.io/business/payout/payment", { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, body: JSON.stringify({ type: type, senderCurrency: "USD", receiverCurrency: currency, amount: amount, receiverLipaNumber: lipaNumber, payoutCountry: countryCode, businessReference: reference, // ... other required fields }), }, ); return await paymentResponse.json(); }

Error Responses

400 - Missing countryCode

{ "code": 0, "error": "countryCode is required" }

400 - Invalid countryCode

{ "code": 0, "error": "countryCode must be one of: KE, TZ, UG, ZA" }

400 - Missing phoneNumber

{ "code": 0, "error": "empty mobile number" }

400 - Invalid Phone Format

{ "code": 0, "error": "phoneNumber must use the correct international prefix for the given countryCode" }

400 - Missing type (verify-payment)

{ "code": 0, "error": "type must be \"paybill\" or \"till\"" }

400 - Invalid type (verify-payment)

{ "code": 0, "error": "type must be \"paybill\" or \"till\"" }

400 - Missing lipaNumber

{ "code": 0, "error": "lipaNumber is required" }

401 - No Authorization

{ "message": "missing value in request header" }

Best Practices

  1. Always verify first - Prevents failed payments and reduces costs
  2. Display verification results - Show displayName to user for confirmation
  3. Handle unverified recipients - Show clear error messages
  4. Use TESTENV numbers for testing - Use provided test numbers in test environment
  5. Include accountReference for paybill - Required for paybill type payments

Supported Countries

  • KE - Kenya
  • TZ - Tanzania
  • UG - Uganda
  • ZA - South Africa
Last updated on