@yengapay/nodejs-sdk
Version:
Official Node.js SDK for YengaPay - Accept mobile money payments and send payouts in West Africa
273 lines (218 loc) • 7.03 kB
Markdown
# @yengapay/nodejs-sdk
Official Node.js SDK for YengaPay - Accept mobile money payments and send payouts in West Africa.
## Installation
```bash
npm install @yengapay/nodejs-sdk
# or
yarn add @yengapay/nodejs-sdk
```
## Features
- 💳 **Direct Payment API** - Accept mobile money payments via API
- 💸 **Payout API** - Send money to customers
- 🔄 **Fluent Interface** - Clean and intuitive API design
- 📦 **TypeScript Support** - Full type definitions included
- 🌍 **Multi-Operator** - Support for Orange Money, Moov Money, Coris Money, Sank Money
- 🔐 **Secure** - API key authentication
## Quick Start
```typescript
import { YengaPayClient } from '@yengapay/nodejs-sdk';
// Initialize the client with fluent interface
const client = new YengaPayClient()
.withEnvironment('production') // or 'staging', 'development'
.withApiKey('your-api-key')
.withGroupId('your-group-id')
.withProjectId('your-project-id');
// Alternative: custom base URL
const clientCustom = new YengaPayClient()
.withApiBaseURL('https://api.yengapay.com')
.withApiKey('your-api-key')
.withGroupId('your-group-id')
.withProjectId('your-project-id');
```
## Direct Payment
### 1. Initialize Payment
```typescript
// Step 1: Initialize payment and get available operators
const payment = await client.directPayment.init({
amount: 1000, // Amount in XOF
reference: 'ORDER-123', // Optional: your order reference
customerEmailToNotify: 'customer@example.com', // Optional
articles: [ // Optional: items being paid for
{
title: 'Product 1',
description: 'Description',
price: 1000,
pictures: ['https://example.com/image.jpg']
}
],
metadata: { orderId: '123', customField: 'value' } // Optional
});
console.log('Payment Intent ID:', payment.paymentIntentId);
console.log('Expires at:', payment.expiresAt);
console.log('Available operators:', payment.availableOperators);
// Example operator:
// {
// code: 'ORANGE',
// name: 'Orange Money',
// countryCode: 'BF',
// countryName: 'Burkina Faso',
// flow: 'ONE_STEP',
// amount: 1000,
// fees: 25,
// totalAmount: 1025,
// minAmount: 200,
// maxAmount: 1000000
// }
```
### 2. Process Payment
#### One-Step Flow (Orange Money)
```typescript
const result = await client.directPayment.pay({
paymentIntentId: payment.paymentIntentId,
operatorCode: 'ORANGE',
countryCode: 'BF',
customerMSISDN: '+22670123456',
otp: '123456' // Customer enters OTP from their phone
});
if (result.status === 'DONE') {
console.log('Payment successful!', result.transactionId);
} else if (result.status === 'PENDING') {
console.log('Payment pending, wait for webhook');
}
```
#### Two-Step Flow (Coris Money, Sank Money)
```typescript
// Step 2a: Send OTP
const otpResult = await client.directPayment.sendOtp({
paymentIntentId: payment.paymentIntentId,
operatorCode: 'CORISM',
countryCode: 'BF',
customerMSISDN: '+22670123456'
});
console.log(otpResult.message); // "Coris Money vous a envoyé un code OTP par SMS"
// Step 2b: Complete payment with OTP
const result = await client.directPayment.pay({
paymentIntentId: payment.paymentIntentId,
operatorCode: 'CORISM',
countryCode: 'BF',
customerMSISDN: '+22670123456',
otp: '123456' // OTP received by customer
});
```
#### Push Notification Flow (Moov Money)
```typescript
const result = await client.directPayment.pay({
paymentIntentId: payment.paymentIntentId,
operatorCode: 'MOOV',
countryCode: 'BF',
customerMSISDN: '+22670123456'
// No OTP needed - customer approves on their phone
});
console.log(result.message); // "Le client doit valider sur son téléphone"
```
### 3. Check Payment Status
```typescript
const status = await client.directPayment.getStatus(payment.paymentIntentId);
console.log('Status:', status.status); // PENDING, DONE, FAILED
if (status.status === 'DONE') {
console.log('Transaction ID:', status.transactionId);
console.log('Amount:', status.amount);
console.log('Fees:', status.fees);
}
```
## Payout
### Single Payout
```typescript
const payout = await client.payout.create({
amount: 5000, // Amount in XOF
destNumber: '+22670123456',
destName: 'John Doe', // Optional
destEmail: 'john@example.com', // Optional
paymentMethod: 'ORANGE_MONEY', // ORANGE_MONEY, MOOV_MONEY, TELECEL_MONEY, CORIS_MONEY, SANK_MONEY
description: 'Payment for services' // Optional
});
console.log('Payout ID:', payout.id);
console.log('Status:', payout.status); // PENDING, PROCESSING, SUCCESS, FAILED
```
### Bulk Payout
```typescript
const bulkPayout = await client.payout.createBulk({
name: 'Monthly Salaries', // Optional
payouts: [
{
amount: 50000,
destNumber: '+22670111111',
destName: 'Employee 1',
paymentMethod: 'ORANGE_MONEY'
},
{
amount: 45000,
destNumber: '+22670222222',
destName: 'Employee 2',
paymentMethod: 'MOOV_MONEY'
}
]
});
console.log('Bulk Payout ID:', bulkPayout.id);
console.log('Total Count:', bulkPayout.totalCount);
console.log('Success Count:', bulkPayout.successCount);
console.log('Failed Count:', bulkPayout.failedCount);
```
### Check Payout Status
```typescript
// Single payout
const payoutStatus = await client.payout.getStatus('payout-id');
console.log(payoutStatus.status); // PENDING, PROCESSING, SUCCESS, FAILED, CANCELLED
// Bulk payout
const bulkStatus = await client.payout.getBulkStatus('bulk-payout-id');
console.log(`Progress: ${bulkStatus.successCount}/${bulkStatus.totalCount}`);
```
## Error Handling
```typescript
import { YengaPayError, AuthenticationError, ValidationError } from '@yengapay/nodejs-sdk';
try {
const payment = await client.directPayment.init({ amount: 100 });
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key or permissions');
} else if (error instanceof ValidationError) {
console.error('Validation error:', error.message);
} else if (error instanceof YengaPayError) {
console.error('YengaPay error:', error.message, error.statusCode);
} else {
console.error('Unknown error:', error);
}
}
```
## Supported Operators
| Operator | Code | Countries | Flow Type |
|----------|------|-----------|-----------|
| Orange Money | `ORANGE` | BF, CI, SN, ML, NE | ONE_STEP |
| Moov Money | `MOOV` | BF, CI, TG, BJ | TWO_STEP (Push) |
| Coris Money | `CORISM` | BF | TWO_STEP (OTP) |
| Sank Money | `SANKM` | BF | TWO_STEP (OTP) |
| Telecel Money | `TELECEL` | BF | TWO_STEP |
## TypeScript Support
The SDK is written in TypeScript and includes full type definitions:
```typescript
import type {
InitDirectPaymentParams,
ProcessPaymentParams,
PaymentStatusResponse,
CreatePayoutParams,
AvailableOperator
} from '@yengapay/nodejs-sdk';
```
## Development
```bash
# Build the SDK
nx build nodejs-sdk
# Run tests
nx test nodejs-sdk
# Lint
nx lint nodejs-sdk
```
## License
MIT
## Support
For support, email support@yengapay.com or visit https://yengapay.com/docs