Skip to main content
The UsersService provides methods for managing rider wallets, viewing transaction history, retrieving rider statistics, and creating payout requests.

Service Creation

import { createUserService } from '@/services/users/users.service';
import { httpClient } from '@/services/http.service';

const usersService = createUserService(httpClient);
Source: src/services/users/users.service.ts:5-17

Methods

getWallet

Retrieve the current user’s wallet information including balance and total earnings.
usersService.getWallet(): ApiResponse<Wallet>

Response

id
string
required
Unique wallet identifier
balance
string
required
Current wallet balance (string formatted number)
totalEarned
string
required
Total amount earned to date (string formatted number)
createdAt
string
Wallet creation timestamp (ISO 8601 format)
updatedAt
string
Last update timestamp (ISO 8601 format)

Example Usage

import { usersService } from '@/services';

try {
  const response = await usersService.getWallet();
  const wallet = response.data;
  
  console.log(`Current Balance: ${wallet.balance} FCFA`);
  console.log(`Total Earned: ${wallet.totalEarned} FCFA`);
  
  // Format for display
  const formattedBalance = parseFloat(wallet.balance).toLocaleString('fr-FR');
  console.log(`Balance: ${formattedBalance} FCFA`);
} catch (error) {
  console.error('Failed to fetch wallet:', error.message);
}

transactions

Retrieve a paginated list of wallet transactions with optional filtering.
usersService.transactions(query: Query): ApiResponse<GetWalletTransactionsResponse>

Parameters

query
Query
required
Query parameters for filtering and pagination
query.page
number
Page number (1-based)
query.limit
number
Number of items per page
query.type
string
Filter by transaction type (e.g., “CREDIT”, “DEBIT”, “PAYOUT”)
query.startDate
string
Filter transactions from this date (ISO 8601 format)
query.endDate
string
Filter transactions until this date (ISO 8601 format)

Response

meta
PaginationMeta
required
Pagination metadata
meta.totalItems
number
Total number of transactions across all pages
meta.itemCount
number
Number of transactions in current page
meta.itemsPerPage
number
Items per page
meta.totalPages
number
Total number of pages
meta.currentPage
number
Current page number
items
Transaction[]
required
Array of transaction objects
items[].id
string
Unique transaction identifier
items[].amount
string
Transaction amount (string formatted number)
items[].type
WalletTransactionTypes
Transaction type (e.g., “CREDIT”, “DEBIT”, “PAYOUT”)
items[].reference
string
Transaction reference number for tracking
items[].createdAt
string
Transaction timestamp (ISO 8601 format)

Example Usage

import { usersService } from '@/services';

try {
  const response = await usersService.transactions({
    page: 1,
    limit: 20,
    type: 'CREDIT',
  });
  
  console.log(`Total transactions: ${response.data.meta.totalItems}`);
  
  response.data.items.forEach(transaction => {
    const amount = parseFloat(transaction.amount);
    const sign = transaction.type === 'CREDIT' ? '+' : '-';
    console.log(`${sign}${amount} FCFA - ${transaction.reference}`);
  });
} catch (error) {
  console.error('Failed to fetch transactions:', error.message);
}

createPayoutRequest

Create a new payout request to withdraw funds from the rider’s wallet.
usersService.createPayoutRequest(
  data: CreatePayoutRequestDto
): ApiResponse<PayoutRequest>

Parameters

data
CreatePayoutRequestDto
required
Payout request data
data.amount
number
required
Amount to withdraw (must be less than or equal to wallet balance)
data.payoutMethod
PayoutMethod
required
Payment method: "mobile_money" or "bank_transfer"
data.mobileMoneyProvider
string
Mobile money provider code (required if payoutMethod is “mobile_money”)
  • "mtn" - MTN Mobile Money
  • "orange" - Orange Money
  • "moov" - Moov Money
data.mobileMoneyNumber
string
Mobile money account number (required if payoutMethod is “mobile_money”)
data.mobileMoneyAccountName
string
Account holder’s name (required if payoutMethod is “mobile_money”)
data.accountNumber
string
Bank account number (required if payoutMethod is “bank_transfer”)
data.accountName
string
Bank account holder’s name (required if payoutMethod is “bank_transfer”)
data.bankName
string
Bank name (required if payoutMethod is “bank_transfer”)
data.bankCode
string
Bank code (required if payoutMethod is “bank_transfer”)
data.notes
string
Additional notes or instructions for the payout

Response

id
string
required
Unique payout request identifier
amount
string
required
Payout amount (string formatted number)
status
PayoutRequestStatus
required
Current status: "pending", "processing", "completed", "failed", "cancelled"
payoutMethod
string
required
Payment method used
reference
string
required
Unique reference number for tracking the payout
mobileMoneyProvider
string | null
Mobile money provider (if applicable)
mobileMoneyNumber
string | null
Mobile money account number (if applicable)
mobileMoneyAccountName
string | null
Mobile money account holder’s name (if applicable)
accountNumber
string | null
Bank account number (if applicable)
accountName
string | null
Bank account holder’s name (if applicable)
bankName
string | null
Bank name (if applicable)
bankCode
string | null
Bank code (if applicable)
notes
string | null
Additional notes
createdAt
string
Request creation timestamp (ISO 8601 format)
updatedAt
string
Last update timestamp (ISO 8601 format)

Example Usage - Mobile Money Payout

import { usersService, paymentService } from '@/services';

try {
  // Step 1: Verify the mobile money account
  const verification = await paymentService.verifyMobileMoneyNumber(
    '237670000000',
    'mtn'
  );
  
  // Step 2: Create the payout request
  const response = await usersService.createPayoutRequest({
    amount: 50000,
    payoutMethod: 'mobile_money',
    mobileMoneyProvider: 'mtn',
    mobileMoneyNumber: '237670000000',
    mobileMoneyAccountName: verification.data.accountName,
    notes: 'Weekly earnings withdrawal',
  });
  
  console.log('Payout request created:', response.data.reference);
  console.log('Status:', response.data.status);
  console.log('Amount:', response.data.amount, 'FCFA');
} catch (error) {
  if (error.status === 422) {
    console.error('Validation error:', error.message);
    // Check if insufficient balance
  } else {
    console.error('Failed to create payout:', error.message);
  }
}

Example Usage - Bank Transfer Payout

try {
  const response = await usersService.createPayoutRequest({
    amount: 100000,
    payoutMethod: 'bank_transfer',
    accountNumber: '1234567890',
    accountName: 'John Doe',
    bankName: 'Afriland First Bank',
    bankCode: 'AFBK',
    notes: 'Monthly earnings withdrawal',
  });
  
  console.log('Bank transfer request created:', response.data.reference);
} catch (error) {
  console.error('Failed to create payout:', error.message);
}

riders.stats

Retrieve statistics for a specific rider including delivery counts and performance metrics.
usersService.riders.stats(riderId: string): ApiResponse<RiderStats>

Parameters

riderId
string
required
The unique identifier of the rider

Response

total_orders_delivered
number
required
Total number of successfully delivered orders
total_orders_cancelled
number
required
Total number of cancelled orders
total_deliveries_today
number
required
Number of deliveries completed today
total_orders_assigned
number
required
Total number of orders currently assigned to the rider

Example Usage

import { usersService } from '@/services';

try {
  const response = await usersService.riders.stats('rider-123');
  const stats = response.data;
  
  console.log('Rider Statistics:');
  console.log(`Total Delivered: ${stats.total_orders_delivered}`);
  console.log(`Total Cancelled: ${stats.total_orders_cancelled}`);
  console.log(`Deliveries Today: ${stats.total_deliveries_today}`);
  console.log(`Currently Assigned: ${stats.total_orders_assigned}`);
  
  // Calculate success rate
  const total = stats.total_orders_delivered + stats.total_orders_cancelled;
  const successRate = (stats.total_orders_delivered / total) * 100;
  console.log(`Success Rate: ${successRate.toFixed(2)}%`);
} catch (error) {
  console.error('Failed to fetch rider stats:', error.message);
}

API Endpoints

MethodEndpointDescription
getWalletGET /users/walletGet current user’s wallet
transactionsGET /users/wallet/transactionsList wallet transactions
createPayoutRequestPOST /wallets/payout-requestCreate a payout request
riders.statsGET /rider/{riderId}/statsGet rider statistics
Source: src/services/api/end-points.ts:11-27

Type Definitions

Wallet

interface Wallet {
  id: string;
  createdAt: string;
  updatedAt: string;
  deletedAt: string;
  balance: string;
  totalEarned: string;
}
Source: src/types/wallet.types.ts:3-10

Transaction

interface Transaction {
  id: string;
  createdAt: string;
  updatedAt: string;
  deletedAt: string;
  amount: string;
  type: WalletTransactionTypes;
  reference: string;
}
Source: src/types/transactions.types.ts:9-17

CreatePayoutRequestDto

interface CreatePayoutRequestDto {
  amount: number;
  payoutMethod: PayoutMethod;
  mobileMoneyProvider?: string;
  mobileMoneyNumber?: string;
  mobileMoneyAccountName?: string;
  accountNumber?: string;
  accountName?: string;
  bankName?: string;
  bankCode?: string;
  notes?: string;
}
Source: src/types/payout.types.ts:3-14

PayoutRequest

interface PayoutRequest {
  id: string;
  createdAt: string;
  updatedAt: string;
  amount: string;
  status: PayoutRequestStatus;
  payoutMethod: string;
  accountNumber?: string | null;
  accountName?: string | null;
  bankName?: string | null;
  bankCode?: string | null;
  mobileMoneyProvider?: string | null;
  mobileMoneyNumber?: string | null;
  mobileMoneyAccountName?: string | null;
  reference: string;
  notes?: string | null;
}
Source: src/types/payout.types.ts:16-32

RiderStats

interface RiderStats {
  total_orders_delivered: number;
  total_orders_cancelled: number;
  total_deliveries_today: number;
  total_orders_assigned: number;
}
Source: src/types/users.types.ts:1-6

Common Use Cases

Display Wallet Dashboard

import { usersService } from '@/services';
import { useEffect, useState } from 'react';

const WalletDashboard = () => {
  const [wallet, setWallet] = useState<Wallet | null>(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    fetchWalletData();
  }, []);
  
  const fetchWalletData = async () => {
    try {
      const response = await usersService.getWallet();
      setWallet(response.data);
    } catch (error) {
      console.error('Failed to load wallet:', error);
    } finally {
      setLoading(false);
    }
  };
  
  if (loading) return <Loading />;
  if (!wallet) return <Error />;
  
  return (
    <View>
      <Text>Balance: {parseFloat(wallet.balance).toLocaleString()} FCFA</Text>
      <Text>Total Earned: {parseFloat(wallet.totalEarned).toLocaleString()} FCFA</Text>
    </View>
  );
};

Transaction History

const TransactionHistory = () => {
  const [transactions, setTransactions] = useState<Transaction[]>([]);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(true);
  
  const loadTransactions = async () => {
    try {
      const response = await usersService.transactions({
        page,
        limit: 20,
      });
      
      setTransactions(prev => [...prev, ...response.data.items]);
      setHasMore(response.data.meta.currentPage < response.data.meta.totalPages);
    } catch (error) {
      console.error('Failed to load transactions:', error);
    }
  };
  
  const loadMore = () => {
    if (hasMore) {
      setPage(prev => prev + 1);
    }
  };
  
  useEffect(() => {
    loadTransactions();
  }, [page]);
  
  return (
    <FlatList
      data={transactions}
      renderItem={({ item }) => <TransactionItem transaction={item} />}
      onEndReached={loadMore}
      onEndReachedThreshold={0.5}
    />
  );
};

Request Payout Flow

import { paymentService, usersService } from '@/services';

const requestPayout = async (
  amount: number,
  provider: string,
  accountNumber: string
) => {
  try {
    // Step 1: Check if amount is valid
    const walletResponse = await usersService.getWallet();
    const balance = parseFloat(walletResponse.data.balance);
    
    if (amount > balance) {
      throw new Error('Montant supérieur au solde disponible');
    }
    
    // Step 2: Verify mobile money account
    const verificationResponse = await paymentService.verifyMobileMoneyNumber(
      accountNumber,
      provider
    );
    
    // Step 3: Show confirmation
    const confirmed = await showConfirmation(
      `Retirer ${amount} FCFA vers ${verificationResponse.data.accountName}?`
    );
    
    if (!confirmed) return;
    
    // Step 4: Create payout request
    const payoutResponse = await usersService.createPayoutRequest({
      amount,
      payoutMethod: 'mobile_money',
      mobileMoneyProvider: provider,
      mobileMoneyNumber: accountNumber,
      mobileMoneyAccountName: verificationResponse.data.accountName,
    });
    
    // Step 5: Show success
    showSuccess(
      `Demande de retrait créée: ${payoutResponse.data.reference}`
    );
    
    return payoutResponse.data;
  } catch (error) {
    showError(error.message);
    throw error;
  }
};

Error Handling

422 - Insufficient Balance

{
  "message": "Erreur de validation",
  "status": 422,
  "data": {
    "message": "Insufficient balance for payout",
    "errors": ["Amount exceeds available balance"]
  },
  "isApiError": true
}

422 - Invalid Payout Method

{
  "message": "Erreur de validation",
  "status": 422,
  "data": {
    "message": "Invalid payout method configuration",
    "errors": ["mobileMoneyNumber is required for mobile_money payout method"]
  },
  "isApiError": true
}

Best Practices

  • Always check wallet balance before creating payout requests
  • Verify mobile money accounts before submitting payouts
  • Display formatted currency values with proper localization
  • Implement pull-to-refresh for wallet and transaction data
  • Cache wallet data to reduce unnecessary API calls
  • Show loading states during async operations
  • Handle pagination properly for transaction history
  • Never expose sensitive wallet data in logs
  • Validate payout amounts on both client and server
  • Implement proper error handling for failed payouts
  • Consider minimum payout amounts and fees

Payout Status Flow

Payment Service

Verify mobile money accounts

Services Overview

Back to services overview

Build docs developers (and LLMs) love