@yengapay/nodejs-sdk
Version:
Official Node.js SDK for YengaPay - Accept mobile money payments and send payouts in West Africa
372 lines (371 loc) • 10.7 kB
JavaScript
class i extends Error {
constructor(t, s, e) {
super(t), this.statusCode = s, this.code = e, this.name = "YengaPayError", Error.captureStackTrace(this, this.constructor);
}
}
class y extends i {
constructor(t = "Authentication failed") {
super(t, 401, "AUTHENTICATION_ERROR"), this.name = "AuthenticationError";
}
}
class m extends i {
constructor(t) {
super(t, 400, "VALIDATION_ERROR"), this.name = "ValidationError";
}
}
class E extends i {
constructor(t) {
super(t, 404, "NOT_FOUND"), this.name = "NotFoundError";
}
}
class A extends i {
constructor(t, s = 400) {
super(t, s, "PAYMENT_ERROR"), this.name = "PaymentError";
}
}
class f extends i {
constructor(t = "Network request failed") {
super(t, 0, "NETWORK_ERROR"), this.name = "NetworkError";
}
}
class d {
constructor(t) {
this.config = t;
}
/**
* Make a GET request
*/
async get(t) {
return this.request("GET", t);
}
/**
* Make a POST request
*/
async post(t, s) {
return this.request("POST", t, s);
}
/**
* Make a PUT request
*/
async put(t, s) {
return this.request("PUT", t, s);
}
/**
* Make a DELETE request
*/
async delete(t) {
return this.request("DELETE", t);
}
/**
* Make an HTTP request
*/
async request(t, s, e) {
const c = `${this.config.baseURL}${s}`, g = {
"Content-Type": "application/json",
"x-api-key": this.config.apiKey
}, p = {
method: t,
headers: g
};
e && (p.body = JSON.stringify(e));
const n = this.config.environment === "development";
n && (console.log(`
[YengaPay SDK Request]`), console.log("Method:", t), console.log("URL:", c), e && console.log("Body:", JSON.stringify(e, null, 2)));
try {
const o = await fetch(c, p);
if (!o.ok) {
const a = await o.json().catch(() => ({})), u = a.message || a.error || o.statusText;
throw n && (console.log("[YengaPay SDK Response] ERROR"), console.log("Status:", o.status), console.log("Error:", a)), o.status === 401 || o.status === 403 ? new y(u) : new i(u, o.status);
}
const h = await o.json();
return n && (console.log("[YengaPay SDK Response] SUCCESS"), console.log("Status:", o.status), console.log("Body:", JSON.stringify(h, null, 2)), console.log("")), h;
} catch (o) {
throw o instanceof i ? o : new f(
o instanceof Error ? o.message : "Unknown error occurred"
);
}
}
}
class l {
constructor(t) {
this.config = t, this.http = new d(t);
}
/**
* Initialize a direct payment
*
* Creates a PaymentIntent and returns available payment operators
*
* @param params - Payment initialization parameters
* @returns Payment intent ID and available operators
*
* @example
* ```typescript
* const payment = await client.directPayment.init({
* amount: 1000,
* reference: 'ORDER-123',
* customerEmailToNotify: 'customer@example.com'
* });
* console.log(payment.paymentIntentId);
* console.log(payment.availableOperators);
* ```
*/
async init(t) {
const s = `/groups/${this.config.groupId}/projects/${this.config.projectId}/direct-payment/init`, e = await this.http.post(
s,
t
);
return {
...e,
expiresAt: new Date(e.expiresAt)
};
}
/**
* Process payment with selected operator
*
* Executes the payment transaction with the chosen mobile money operator
*
* @param params - Payment processing parameters
* @returns Payment status and details
*
* @example
* ```typescript
* // One-step flow (Orange Money)
* const result = await client.directPayment.pay({
* paymentIntentId: 'pi_123...',
* operatorCode: 'ORANGE',
* countryCode: 'BF',
* customerMSISDN: '+22670123456',
* otp: '123456'
* });
*
* // Two-step flow (Moov Money - after sending OTP)
* const result = await client.directPayment.pay({
* paymentIntentId: 'pi_123...',
* operatorCode: 'MOOV',
* countryCode: 'BF',
* customerMSISDN: '+22670123456'
* });
* ```
*/
async pay(t) {
const s = `/groups/${this.config.groupId}/projects/${this.config.projectId}/direct-payment/pay`;
return await this.http.post(s, t);
}
/**
* Send OTP for two-step operators (Coris, Sank)
*
* Requests an OTP to be sent to the customer's phone
*
* @param params - OTP request parameters
* @returns OTP sent confirmation
*
* @example
* ```typescript
* const result = await client.directPayment.sendOtp({
* paymentIntentId: 'pi_123...',
* operatorCode: 'CORISM',
* countryCode: 'BF',
* customerMSISDN: '+22670123456'
* });
* console.log(result.message); // "Coris Money vous a envoyé un code OTP par SMS"
* ```
*/
async sendOtp(t) {
const s = `/groups/${this.config.groupId}/projects/${this.config.projectId}/direct-payment/send-otp`;
return await this.http.post(s, t);
}
/**
* Get payment status by PaymentIntent ID
*
* Check if a payment is pending, completed, or failed
*
* @param paymentIntentId - The PaymentIntent ID to check
* @returns Payment status and details
*
* @example
* ```typescript
* const status = await client.directPayment.getStatus('pi_123...');
* if (status.status === 'DONE') {
* console.log('Payment completed:', status.transactionId);
* }
* ```
*/
async getStatus(t) {
const s = `/groups/${this.config.groupId}/projects/${this.config.projectId}/direct-payment/status/${t}`, e = await this.http.get(s);
return {
...e,
createdAt: e.createdAt ? new Date(e.createdAt) : void 0,
completedAt: e.completedAt ? new Date(e.completedAt) : void 0
};
}
}
class w {
constructor(t) {
this.config = t, this.http = new d(t);
}
/**
* Create a single payout transaction
*
* Send money to a customer's mobile money account
*
* @param params - Payout creation parameters
* @returns Payout transaction details
*
* @example
* ```typescript
* const payout = await client.payout.create({
* amount: 5000,
* destNumber: '+22670123456',
* destName: 'John Doe',
* destEmail: 'john@example.com',
* paymentMethod: 'ORANGE_MONEY',
* description: 'Payment for service'
* });
* console.log(payout.id, payout.status);
* ```
*/
async create(t) {
const s = `/groups/${this.config.groupId}/project/${this.config.projectId}/payout`, e = await this.http.post(s, t);
return {
...e,
createdAt: new Date(e.createdAt)
};
}
/**
* Get payout transaction status
*
* Check the status of a payout transaction
*
* @param payoutId - The payout transaction ID
* @returns Payout transaction status and details
*
* @example
* ```typescript
* const status = await client.payout.getStatus('payout_123...');
* if (status.status === 'SUCCESS') {
* console.log('Payout completed:', status.operatorTransId);
* }
* ```
*/
async getStatus(t) {
const s = `/groups/${this.config.groupId}/project/${this.config.projectId}/payout/${t}`, e = await this.http.get(s);
return {
...e,
createdAt: new Date(e.createdAt),
processedAt: e.processedAt ? new Date(e.processedAt) : void 0
};
}
/**
* Retry a failed payout transaction
*
* Retry a payout transaction that has failed
*
* @param payoutId - The payout transaction ID to retry
* @returns Updated payout transaction details
*
* @example
* ```typescript
* const retried = await client.payout.retry('payout_123...');
* console.log('Payout retried:', retried.status);
* ```
*/
async retry(t) {
const s = `/groups/${this.config.groupId}/project/${this.config.projectId}/payout/${t}/retry`, e = await this.http.post(s);
return {
...e,
createdAt: new Date(e.createdAt),
processedAt: e.processedAt ? new Date(e.processedAt) : void 0
};
}
}
class R {
constructor() {
this.config = {
environment: "production"
}, this.config.baseURL = "https://api.yengapay.com/api";
}
/**
* Set the API base URL
* @param url - Base URL for API requests (e.g., 'https://api.yengapay.com/api')
*/
withApiBaseURL(t) {
return this.config.baseURL = t, this._directPayment = void 0, this._payout = void 0, this;
}
/**
* Set the environment (automatically sets the base URL)
* @param env - Environment ('production', 'staging', 'development')
*/
withEnvironment(t) {
switch (this.config.environment = t, t) {
case "production":
this.config.baseURL = "https://api.yengapay.com/api/v1";
break;
case "staging":
this.config.baseURL = "https://api.staging.yengapay.com/api/v1";
break;
case "development":
this.config.baseURL = "http://localhost:3332/api/v1";
break;
}
return this._directPayment = void 0, this._payout = void 0, this;
}
/**
* Set the API key for authentication
* @param apiKey - Your YengaPay API key
*/
withApiKey(t) {
return this.config.apiKey = t, this._directPayment = void 0, this._payout = void 0, this;
}
/**
* Set the group ID
* @param groupId - Your YengaPay group ID
*/
withGroupId(t) {
return this.config.groupId = t, this._directPayment = void 0, this._payout = void 0, this;
}
/**
* Set the project ID
* @param projectId - Your YengaPay project ID
*/
withProjectId(t) {
return this.config.projectId = t, this._directPayment = void 0, this._payout = void 0, this;
}
/**
* Get Direct Payment module
*/
get directPayment() {
return this.validateConfig(), this._directPayment || (this._directPayment = new l(this.config)), this._directPayment;
}
/**
* Get Payout module
*/
get payout() {
return this.validateConfig(), this._payout || (this._payout = new w(this.config)), this._payout;
}
/**
* Validate that all required configuration is set
*/
validateConfig() {
if (!this.config.apiKey)
throw new Error("API key is required. Use .withApiKey() to set it.");
if (!this.config.groupId)
throw new Error("Group ID is required. Use .withGroupId() to set it.");
if (!this.config.projectId)
throw new Error(
"Project ID is required. Use .withProjectId() to set it."
);
if (!this.config.baseURL)
throw new Error(
"Base URL is required. Use .withApiBaseURL() or .withEnvironment() to set it."
);
}
}
export {
y as AuthenticationError,
f as NetworkError,
E as NotFoundError,
A as PaymentError,
m as ValidationError,
R as YengaPayClient,
i as YengaPayError
};