The PaymentService handles payment-related operations, including mobile money account verification using Paystack integration.
Service Creation
import { createPaymentService } from '@/services/payment/payment.service' ;
import { httpClient } from '@/services/http.service' ;
const paymentService = createPaymentService ( httpClient );
Source: src/services/payment/payment.service.ts:5-14
Methods
verifyMobileMoneyNumber
Verifies a mobile money account number with a provider to ensure it’s valid and retrieve the account holder’s name.
paymentService . verifyMobileMoneyNumber (
accountNumber : string ,
provider : string
): ApiResponse < VerifyMobileMoneyResponse >
Parameters
The mobile money account number to verify. This is typically a phone number formatted according to the provider’s requirements.
The mobile money provider code. Supported providers include:
mtn - MTN Mobile Money
orange - Orange Money
moov - Moov Money
Response
The verified account holder’s name as registered with the mobile money provider
Example Usage
import { paymentService } from '@/services' ;
try {
const response = await paymentService . verifyMobileMoneyNumber (
'237670000000' ,
'mtn'
);
console . log ( 'Account verified:' , response . data . accountName );
// Output: "Account verified: John Doe"
// Use verified name to confirm with user
const confirmed = await confirmAccountName ( response . data . accountName );
if ( confirmed ) {
// Proceed with payout request
}
} catch ( error ) {
if ( error . status === 422 ) {
console . error ( 'Invalid account number or provider' );
} else if ( error . status === 404 ) {
console . error ( 'Account not found with provider' );
} else {
console . error ( 'Verification failed:' , error . message );
}
}
API Endpoint
The verification method calls the following endpoint:
POST /payment/verify-mobile-money-account
Source: src/services/api/end-points.ts:43-45
Request Body
{
"accountNumber" : "237670000000" ,
"provider" : "mtn"
}
Response Body
{
"accountName" : "John Doe"
}
Mobile Money Providers
The service supports verification for major mobile money operators in Cameroon:
MTN Mobile Money
Provider Code : mtn
Account Format : Phone number with country code (237XXXXXXXXX)
Coverage : Nationwide
Orange Money
Provider Code : orange
Account Format : Phone number with country code (237XXXXXXXXX)
Coverage : Nationwide
Moov Money
Provider Code : moov
Account Format : Phone number with country code (237XXXXXXXXX)
Coverage : Regional
Paystack Integration
The verification service is powered by Paystack’s Transfer Recipients API, which validates mobile money accounts in real-time.
How It Works
The app submits account number and provider to the backend
Backend forwards the request to Paystack API
Paystack verifies the account with the mobile money operator
Backend returns the verified account holder’s name
User confirms the name matches their intended recipient
Type Definitions
VerifyMobileMoneyResponse
interface VerifyMobileMoneyResponse {
accountName : string ;
}
Source: src/types/payout.types.ts:34-36
Error Handling
The verification method can throw various errors:
422 - Validation Error
{
"message" : "Erreur de validation" ,
"status" : 422 ,
"data" : {
"message" : "Invalid account number format" ,
"errors" : [
{
"field" : "accountNumber" ,
"message" : "Account number must be a valid phone number"
}
]
},
"isApiError" : true
}
Caused by:
Invalid account number format
Unsupported provider
Missing required parameters
404 - Account Not Found
{
"message" : "Ressource non trouvée" ,
"status" : 404 ,
"data" : {
"message" : "Account not found with the specified provider"
},
"isApiError" : true
}
Caused by:
Account number doesn’t exist
Wrong provider specified
Account is inactive or closed
500 - Provider Service Error
{
"message" : "Erreur serveur: Veuillez réessayer plus tard" ,
"status" : 500 ,
"isApiError" : true
}
Caused by:
Paystack API is down
Mobile money provider service unavailable
Network timeout with provider
Use Cases
Payout Request Flow
Verify mobile money accounts before creating payout requests:
import { paymentService , usersService } from '@/services' ;
const requestPayout = async (
amount : number ,
accountNumber : string ,
provider : string
) => {
try {
// Step 1: Verify the mobile money account
const verification = await paymentService . verifyMobileMoneyNumber (
accountNumber ,
provider
);
// Step 2: Show verified name to user for confirmation
const confirmed = await showConfirmationDialog (
`Le nom du compte est: ${ verification . data . accountName } . Confirmer?`
);
if ( ! confirmed ) {
throw new Error ( 'Payout cancelled by user' );
}
// Step 3: Create the payout request
const payout = await usersService . createPayoutRequest ({
amount ,
payoutMethod: 'mobile_money' ,
mobileMoneyProvider: provider ,
mobileMoneyNumber: accountNumber ,
mobileMoneyAccountName: verification . data . accountName ,
});
console . log ( 'Payout request created:' , payout . data . reference );
return payout . data ;
} catch ( error ) {
if ( error . status === 404 ) {
throw new Error ( 'Numéro de compte invalide' );
} else if ( error . status === 422 ) {
throw new Error ( 'Format de numéro incorrect' );
} else {
throw new Error ( 'Échec de la vérification du compte' );
}
}
};
Integrate verification into payout forms:
import { useState } from 'react' ;
import { paymentService } from '@/services' ;
const PayoutForm = () => {
const [ accountNumber , setAccountNumber ] = useState ( '' );
const [ provider , setProvider ] = useState ( 'mtn' );
const [ verifiedName , setVerifiedName ] = useState < string | null >( null );
const [ isVerifying , setIsVerifying ] = useState ( false );
const [ error , setError ] = useState < string | null >( null );
const handleVerify = async () => {
setIsVerifying ( true );
setError ( null );
try {
const response = await paymentService . verifyMobileMoneyNumber (
accountNumber ,
provider
);
setVerifiedName ( response . data . accountName );
} catch ( err ) {
setError ( 'Impossible de vérifier le numéro de compte' );
setVerifiedName ( null );
} finally {
setIsVerifying ( false );
}
};
return (
< View >
< Input
value = { accountNumber }
onChangeText = { setAccountNumber }
placeholder = "Numéro de téléphone"
/>
< Picker
selectedValue = { provider }
onValueChange = { setProvider }
>
< Picker . Item label = "MTN Mobile Money" value = "mtn" />
< Picker . Item label = "Orange Money" value = "orange" />
< Picker . Item label = "Moov Money" value = "moov" />
</ Picker >
< Button
title = "Vérifier le compte"
onPress = { handleVerify }
loading = { isVerifying }
/>
{ verifiedName && (
< Text style = {{ color : 'green' }} >
Nom du compte : { verifiedName }
</ Text >
)}
{ error && (
< Text style = {{ color : 'red' }} > { error } </ Text >
)}
</ View >
);
};
Best Practices
Always verify mobile money accounts before creating payouts
Display the verified account name to users for confirmation
Handle verification errors gracefully with user-friendly messages
Cache verification results to avoid redundant API calls
Implement retry logic for transient network errors
Validate account number format before calling the API
Never store sensitive payment information locally
Always use HTTPS for payment-related requests
Implement rate limiting to prevent abuse
Log verification attempts for audit purposes
Ensure account numbers are properly formatted before verification:
const formatAccountNumber = ( phoneNumber : string , countryCode : string = '237' ) : string => {
// Remove spaces, dashes, and special characters
let formatted = phoneNumber . replace ( / [ ^ 0-9 ] / g , '' );
// Add country code if not present
if ( ! formatted . startsWith ( countryCode )) {
formatted = countryCode + formatted ;
}
return formatted ;
};
// Usage
const accountNumber = formatAccountNumber ( '670 00 00 00' );
// Output: "237670000000"
Users Service Create payout requests after verification
Services Overview Back to services overview