Skip to main content

Payment Constants

Payment method options and configurations for different regions and payment processing scenarios in the WorkPayCore frontend application.

Overview

The payment constants provide standardized payment method options that vary by geographic region and regulatory requirements, ensuring compliance with local payment systems and user preferences.

Payment Method Options

PaymentMethods (Default/Kenya)

Standard payment methods available for Kenyan market operations.

export const PaymentMethods = [
{ label: 'Employee Default', value: 'OTHER' },
{ label: 'Mpesa', value: 'MPESA' },
{ label: 'Bank', value: 'BANK' },
{ label: 'Paybill', value: 'PAYBILL' },
{ label: 'Buy Goods & Services', value: 'TILL' },
{ label: 'Cash', value: 'CASH' },
];

Payment Methods:

  • Employee Default: Uses the employee's preferred payment method
  • Mpesa: Mobile money transfer service (Safaricom)
  • Bank: Traditional bank transfer
  • Paybill: Pay bill service for corporate payments
  • Buy Goods & Services: Till number-based payments
  • Cash: Physical cash payments

Use Cases:

  • Salary disbursement
  • Expense reimbursements
  • Vendor payments
  • Employee benefits distribution

NigeriaPaymentMethods

Simplified payment methods for Nigerian market operations.

export const NigeriaPaymentMethods = [
{ label: 'Employee Default', value: 'OTHER' },
{ label: 'Bank', value: 'BANK' },
];

Payment Methods:

  • Employee Default: Uses the employee's preferred payment method
  • Bank: Bank transfer (primary method in Nigeria)

Regional Considerations:

  • Focuses on bank transfers due to regulatory environment
  • Simplified options for compliance with Nigerian banking regulations
  • Support for local banking infrastructure

Usage Examples

Payment Method Selection

import {
PaymentMethods,
NigeriaPaymentMethods,
} from '@/utils/constants/payment';

const PaymentMethodSelector = ({ country, selectedMethod, onMethodChange }) => {
const getPaymentMethods = () => {
switch (country) {
case 'Nigeria':
return NigeriaPaymentMethods;
case 'Kenya':
default:
return PaymentMethods;
}
};

const methods = getPaymentMethods();

return (
<select
value={selectedMethod}
onChange={e => onMethodChange(e.target.value)}
>
<option value=''>Select Payment Method</option>
{methods.map(method => (
<option key={method.value} value={method.value}>
{method.label}
</option>
))}
</select>
);
};

Salary Disbursement Setup

import { PaymentMethods } from '@/utils/constants/payment';

const SalaryDisbursementForm = ({ employee, onUpdate }) => {
const handlePaymentMethodChange = method => {
onUpdate({
...employee,
payment_method: method,
});
};

return (
<div>
<h3>Payment Method for {employee.name}</h3>
<div>
{PaymentMethods.map(method => (
<label key={method.value}>
<input
type='radio'
name='payment_method'
value={method.value}
checked={employee.payment_method === method.value}
onChange={() => handlePaymentMethodChange(method.value)}
/>
{method.label}
</label>
))}
</div>
</div>
);
};

Country-Specific Payment Processing

import {
PaymentMethods,
NigeriaPaymentMethods,
} from '@/utils/constants/payment';

const PaymentProcessor = {
getAvailableMethods: country => {
const methodMap = {
Kenya: PaymentMethods,
Nigeria: NigeriaPaymentMethods,
};

return methodMap[country] || PaymentMethods;
},

validatePaymentMethod: (method, country) => {
const availableMethods = PaymentProcessor.getAvailableMethods(country);
const validMethods = availableMethods.map(m => m.value);

return validMethods.includes(method);
},

getPaymentMethodLabel: (value, country) => {
const availableMethods = PaymentProcessor.getAvailableMethods(country);
const method = availableMethods.find(m => m.value === value);

return method ? method.label : 'Unknown Payment Method';
},
};

// Usage
const isValidMethod = PaymentProcessor.validatePaymentMethod('MPESA', 'Kenya'); // true
const methodLabel = PaymentProcessor.getPaymentMethodLabel('BANK', 'Nigeria'); // 'Bank'

Employee Payment Preferences

import { PaymentMethods } from '@/utils/constants/payment';

const EmployeePaymentPreferences = ({ employee, onSave }) => {
const [preferences, setPreferences] = useState({
primary_method: employee.payment_method || 'OTHER',
backup_method: employee.backup_payment_method || '',
});

const availableMethods = PaymentMethods.filter(
method => method.value !== preferences.primary_method,
);

return (
<form onSubmit={() => onSave(preferences)}>
<div>
<label>Primary Payment Method:</label>
<select
value={preferences.primary_method}
onChange={e =>
setPreferences({
...preferences,
primary_method: e.target.value,
})
}
>
{PaymentMethods.map(method => (
<option key={method.value} value={method.value}>
{method.label}
</option>
))}
</select>
</div>

<div>
<label>Backup Payment Method:</label>
<select
value={preferences.backup_method}
onChange={e =>
setPreferences({
...preferences,
backup_method: e.target.value,
})
}
>
<option value=''>None</option>
{availableMethods.map(method => (
<option key={method.value} value={method.value}>
{method.label}
</option>
))}
</select>
</div>

<button type='submit'>Save Preferences</button>
</form>
);
};

Bulk Payment Processing

import { PaymentMethods } from '@/utils/constants/payment';

const BulkPaymentProcessor = {
groupByPaymentMethod: employees => {
return employees.reduce((groups, employee) => {
const method = employee.payment_method || 'OTHER';

if (!groups[method]) {
groups[method] = [];
}

groups[method].push(employee);
return groups;
}, {});
},

generatePaymentBatches: employees => {
const groupedByMethod =
BulkPaymentProcessor.groupByPaymentMethod(employees);

return Object.entries(groupedByMethod).map(([method, employeeList]) => {
const methodInfo = PaymentMethods.find(m => m.value === method);

return {
payment_method: method,
payment_method_label: methodInfo?.label || 'Unknown',
employee_count: employeeList.length,
employees: employeeList,
total_amount: employeeList.reduce(
(sum, emp) => sum + (emp.salary || 0),
0,
),
};
});
},
};

// Usage
const paymentBatches = BulkPaymentProcessor.generatePaymentBatches(employees);
console.log('Payment batches:', paymentBatches);

Regional Considerations

Kenya Market Features

  • Mpesa Integration: Mobile money dominance in the market
  • Paybill Services: Corporate payment solutions
  • Till Numbers: Small business payment acceptance
  • Bank Transfers: Traditional banking support
  • Cash Payments: Support for informal sectors

Nigeria Market Features

  • Bank-Centric: Primary focus on bank transfers
  • Regulatory Compliance: Simplified options for compliance
  • Employee Default: Flexible fallback option
  • Future Expansion: Framework for additional methods

Payment Method Validation

Validation Rules

import {
PaymentMethods,
NigeriaPaymentMethods,
} from '@/utils/constants/payment';

const PaymentValidator = {
validateMethod: (method, country, additionalInfo = {}) => {
const availableMethods =
country === 'Nigeria' ? NigeriaPaymentMethods : PaymentMethods;

const validMethods = availableMethods.map(m => m.value);

if (!validMethods.includes(method)) {
return {
isValid: false,
error: 'Invalid payment method for this region',
};
}

// Additional validation based on method type
switch (method) {
case 'MPESA':
if (!additionalInfo.phone_number) {
return {
isValid: false,
error: 'Phone number required for Mpesa payments',
};
}
break;

case 'BANK':
if (!additionalInfo.account_number || !additionalInfo.bank_code) {
return {
isValid: false,
error: 'Account number and bank code required for bank transfers',
};
}
break;

case 'PAYBILL':
if (!additionalInfo.paybill_number) {
return {
isValid: false,
error: 'Paybill number required for paybill payments',
};
}
break;
}

return { isValid: true };
},
};

Required Information by Payment Method

const PAYMENT_METHOD_REQUIREMENTS = {
OTHER: [],
MPESA: ['phone_number'],
BANK: ['account_number', 'bank_code', 'account_name'],
PAYBILL: ['paybill_number', 'account_number'],
TILL: ['till_number'],
CASH: [],
};

const getRequiredFields = paymentMethod => {
return PAYMENT_METHOD_REQUIREMENTS[paymentMethod] || [];
};

Integration Examples

Form Integration

import { PaymentMethods } from '@/utils/constants/payment';

const PaymentMethodForm = () => {
const [formData, setFormData] = useState({
payment_method: '',
phone_number: '',
account_number: '',
bank_code: '',
});

const selectedMethod = PaymentMethods.find(
m => m.value === formData.payment_method,
);

return (
<form>
<select
value={formData.payment_method}
onChange={e =>
setFormData({ ...formData, payment_method: e.target.value })
}
>
<option value=''>Select Payment Method</option>
{PaymentMethods.map(method => (
<option key={method.value} value={method.value}>
{method.label}
</option>
))}
</select>

{formData.payment_method === 'MPESA' && (
<input
type='tel'
placeholder='Phone Number'
value={formData.phone_number}
onChange={e =>
setFormData({ ...formData, phone_number: e.target.value })
}
/>
)}

{formData.payment_method === 'BANK' && (
<>
<input
type='text'
placeholder='Account Number'
value={formData.account_number}
onChange={e =>
setFormData({ ...formData, account_number: e.target.value })
}
/>
<input
type='text'
placeholder='Bank Code'
value={formData.bank_code}
onChange={e =>
setFormData({ ...formData, bank_code: e.target.value })
}
/>
</>
)}
</form>
);
};

Best Practices

1. Regional Customization

// Always use country-specific payment methods
const getPaymentMethods = country => {
const countryMethods = {
Nigeria: NigeriaPaymentMethods,
Kenya: PaymentMethods,
// Add more countries as needed
};

return countryMethods[country] || PaymentMethods;
};

2. Fallback Handling

// Always provide fallback for unknown payment methods
const getPaymentMethodDisplay = (value, country) => {
const methods = getPaymentMethods(country);
const method = methods.find(m => m.value === value);

return method ? method.label : 'Employee Default';
};

3. Validation

// Validate payment methods before processing
const validatePaymentSetup = (employee, country) => {
const methods = getPaymentMethods(country);
const validMethods = methods.map(m => m.value);

if (!validMethods.includes(employee.payment_method)) {
throw new Error(`Invalid payment method: ${employee.payment_method}`);
}
};


TypeScript Definitions

interface PaymentMethod {
label: string;
value: 'OTHER' | 'MPESA' | 'BANK' | 'PAYBILL' | 'TILL' | 'CASH';
}

export const PaymentMethods: PaymentMethod[];
export const NigeriaPaymentMethods: PaymentMethod[];

type PaymentMethodValue = PaymentMethod['value'];

interface PaymentInfo {
method: PaymentMethodValue;
phone_number?: string;
account_number?: string;
bank_code?: string;
paybill_number?: string;
till_number?: string;
}

Future Enhancements

Planned Additions

  • Additional Countries: Ghana, Uganda, Tanzania payment methods
  • Digital Wallets: Support for additional mobile money services
  • Cryptocurrency: Future support for crypto payments
  • International: Cross-border payment options

Migration Path

When adding new payment methods:

  1. Create regional constants for new markets
  2. Update validation logic to handle new methods
  3. Add required field definitions for new payment types
  4. Update forms and UI to support new methods
  5. Test integration with payment processors

These payment constants ensure consistent and region-appropriate payment method handling across the WorkPayCore frontend application while maintaining flexibility for future expansion.