afrimomo-sdk
Version:
A unified SDK for African payment providers
395 lines • 17.7 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PayChangu = void 0;
const axios_1 = __importDefault(require("axios"));
const baseService_1 = require("../../utils/baseService");
const logger_1 = require("../../utils/logger");
const providerClients_1 = require("../../utils/providerClients");
__exportStar(require("./types"), exports);
class PayChangu extends baseService_1.BaseService {
network;
constructor(secretKey, environment = "DEVELOPMENT", sandboxUrl, productionUrl) {
super();
this.network = (0, providerClients_1.createPaychanguClient)(secretKey, environment, sandboxUrl, productionUrl);
}
handleApiError(error, context) {
logger_1.logger.error(`PayChangu API Error - ${context}:`, error);
if (axios_1.default.isAxiosError(error) && error.response?.data) {
if (error.response.data.status === "error" ||
error.response.data.status === "failed") {
return error.response.data;
}
return {
message: error.response.data.message || `An error occurred during ${context}`,
status: "error",
};
}
return {
message: error instanceof Error
? error.message
: `An unexpected error occurred during ${context}`,
status: "error",
};
}
createErrorResponse(error, context, defaultPayload) {
logger_1.logger.error(`PayChangu Service Error - ${context}:`, error);
return {
type: "error",
payload: { ...defaultPayload, HasError: true, StackTraceError: error },
};
}
createSuccessResponse(payload) {
return { type: "success", payload: { ...payload, HasError: false } };
}
async wrapApiCall(operation, context) {
try {
return await operation();
}
catch (error) {
return this.handleApiError(error, context);
}
}
async initiatePayment(data) {
logger_1.logger.info("Initiating PayChangu payment:", data);
try {
return await this.network.post("/payment", data, "payment initiation");
}
catch (error) {
if (axios_1.default.isAxiosError(error) && error.response?.data) {
return error.response.data;
}
return {
status: "failed",
message: error instanceof Error
? error.message
: "An unexpected error occurred",
data: null,
};
}
}
async initializeDirectCharge(data) {
logger_1.logger.info("Initializing PayChangu direct charge payment:", data);
try {
return await this.network.post("/direct-charge/payments/initialize", data, "direct charge initialization");
}
catch (error) {
if (axios_1.default.isAxiosError(error) &&
error.response?.data?.status === "failed") {
return error.response.data;
}
return this.handleApiError(error, "direct charge initialization");
}
}
async getTransactionDetails(chargeId) {
logger_1.logger.info("Getting PayChangu transaction details:", chargeId);
return this.wrapApiCall(() => this.network.get(`/direct-charge/transactions/${chargeId}/details`, `transaction details retrieval for ${chargeId}`), "transaction details retrieval");
}
async processBankTransferDirect(data) {
logger_1.logger.info("Processing PayChangu bank transfer:", data);
return this.wrapApiCall(() => this.network.post("/direct-charge/payments/bank-transfer", data, "bank transfer processing"), "bank transfer processing");
}
async initializeDirectChargePayment(amount, chargeId, currency = "MWK", accountInfo) {
const defaultPayload = {
TransactionDetails: {},
PaymentAccountDetails: {
account_name: "",
account_number: "",
code: "",
name: "",
},
};
const context = "direct charge payment initialization";
const directChargeData = {
amount: amount.toString(),
currency,
payment_method: "mobile_bank_transfer",
charge_id: chargeId,
...(accountInfo?.email && { email: accountInfo.email }),
...(accountInfo?.first_name && { first_name: accountInfo.first_name }),
...(accountInfo?.last_name && { last_name: accountInfo.last_name }),
};
logger_1.logger.info("PayChangu: initializing direct charge payment", {
directChargeData,
});
const response = await this.initializeDirectCharge(directChargeData);
if (!response || response.status !== "success") {
return this.createErrorResponse(response, context, defaultPayload);
}
return this.createSuccessResponse({
TransactionDetails: response.data.transaction,
PaymentAccountDetails: response.data.payment_account_details,
});
}
async getDirectChargeTransactionDetails(chargeId) {
const defaultPayload = {
TransactionDetails: {},
};
const context = "direct charge transaction details retrieval";
logger_1.logger.info("PayChangu: getting direct charge transaction details", {
chargeId,
});
const response = await this.getTransactionDetails(chargeId);
if (!response || response.status !== "success") {
return this.createErrorResponse(response, context, defaultPayload);
}
return this.createSuccessResponse({
TransactionDetails: response.data.transaction,
});
}
async processBankTransfer(bankUuid, accountName, accountNumber, amount, chargeId, currency = "MWK", options) {
const defaultPayload = {
TransactionDetails: {},
PaymentAccountDetails: {
account_name: "",
account_number: "",
code: "",
name: "",
},
};
const context = "bank transfer processing";
const bankTransferData = {
bank_uuid: bankUuid,
bank_account_name: accountName,
bank_account_number: accountNumber,
amount: amount.toString(),
currency,
charge_id: chargeId,
payment_method: "bank_transfer",
...(options?.email && { email: options.email }),
...(options?.firstName && { first_name: options.firstName }),
...(options?.lastName && { last_name: options.lastName }),
};
logger_1.logger.info("PayChangu: processing bank transfer", { bankTransferData });
const response = await this.processBankTransferDirect(bankTransferData);
if (!response || response.status !== "success") {
return this.createErrorResponse(response, context, defaultPayload);
}
return this.createSuccessResponse({
TransactionDetails: response.data.transaction,
PaymentAccountDetails: response.data.payment_account_details,
RedirectUrl: response.data.redirectUrl,
});
}
async getMobileMoneyOperatorsDirect() {
logger_1.logger.info("Getting PayChangu mobile money operators");
return this.wrapApiCall(() => this.network.get("/mobile-money", "mobile money operators retrieval"), "mobile money operators retrieval");
}
async initializeMobileMoneyPayoutDirect(data) {
logger_1.logger.info("Initializing PayChangu mobile money payout:", data);
return this.wrapApiCall(() => this.network.post("/mobile-money/payouts/initialize", data, "mobile money payout initialization"), "mobile money payout initialization");
}
async getPayoutDetailsDirect(chargeId) {
logger_1.logger.info("Getting PayChangu payout details:", chargeId);
return this.wrapApiCall(() => this.network.get(`/mobile-money/payments/${chargeId}/details`, `payout details retrieval for ${chargeId}`), "payout details retrieval");
}
async getMobileMoneyOperators() {
const defaultPayload = { Operators: [] };
const context = "mobile money operators retrieval";
logger_1.logger.info("PayChangu: getting mobile money operators");
const response = await this.getMobileMoneyOperatorsDirect();
if (!response || response.status !== "success") {
return this.createErrorResponse(response, context, defaultPayload);
}
return this.createSuccessResponse({ Operators: response.data });
}
async initializeMobileMoneyPayout(mobile, operatorRefId, amount, chargeId, options) {
const defaultPayload = {
PayoutDetails: {
charge_id: "",
mobile: "",
amount: "",
status: "",
created_at: "",
completed_at: null,
},
};
const context = "mobile money payout initialization";
const payoutData = {
mobile,
mobile_money_operator_ref_id: operatorRefId,
amount: amount.toString(),
charge_id: chargeId,
...(options?.email && { email: options.email }),
...(options?.firstName && { first_name: options.firstName }),
...(options?.lastName && { last_name: options.lastName }),
...(options?.transactionStatus && {
transaction_status: options.transactionStatus,
}),
};
logger_1.logger.info("PayChangu: initializing mobile money payout", { payoutData });
const response = await this.initializeMobileMoneyPayoutDirect(payoutData);
if (!response || response.status !== "success") {
return this.createErrorResponse(response, context, defaultPayload);
}
return this.createSuccessResponse({ PayoutDetails: response.data });
}
async getMobileMoneyPayoutDetails(chargeId) {
const defaultPayload = {
PayoutDetails: {
charge_id: "",
mobile: "",
amount: "",
status: "",
created_at: "",
completed_at: null,
},
};
const context = "mobile money payout details retrieval";
logger_1.logger.info("PayChangu: getting mobile money payout details", { chargeId });
const response = await this.getPayoutDetailsDirect(chargeId);
if (!response || response.status !== "success") {
return this.createErrorResponse(response, context, defaultPayload);
}
return this.createSuccessResponse({ PayoutDetails: response.data });
}
async getSupportedBanksDirect(currency = "MWK") {
logger_1.logger.info("Getting PayChangu supported banks for currency:", currency);
return this.wrapApiCall(() => this.network.get("/direct-charge/payouts/supported-banks", `supported banks retrieval for ${currency}`, { params: { currency } }), "supported banks retrieval");
}
async initializeBankPayoutDirect(data) {
logger_1.logger.info("Initializing PayChangu bank payout:", data);
return this.wrapApiCall(() => this.network.post("/direct-charge/payouts/initialize", data, "bank payout initialization"), "bank payout initialization");
}
async getBankPayoutDetailsDirect(chargeId) {
logger_1.logger.info("Getting PayChangu bank payout details:", chargeId);
return this.wrapApiCall(() => this.network.get(`/direct-charge/payouts/${chargeId}/details`, `bank payout details retrieval for ${chargeId}`), "bank payout details retrieval");
}
async getAllBankPayoutsDirect(page, perPage) {
logger_1.logger.info("Getting all PayChangu bank payouts");
return this.wrapApiCall(() => this.network.get("/direct-charge/payouts", `all bank payouts retrieval (page ${page || 1})`, {
params: {
...(page && { page }),
...(perPage && { per_page: perPage }),
},
}), "bank payouts retrieval");
}
async getSupportedBanks(currency = "MWK") {
const defaultPayload = { Banks: [] };
const context = "supported banks retrieval";
logger_1.logger.info("PayChangu: getting supported banks", { currency });
const response = await this.getSupportedBanksDirect(currency);
if (!response || response.status !== "success") {
return this.createErrorResponse(response, context, defaultPayload);
}
return this.createSuccessResponse({ Banks: response.data });
}
async initializeBankPayout(bankUuid, accountName, accountNumber, amount, chargeId, options) {
const defaultPayload = {
TransactionDetails: {
id: "",
charge_id: "",
bank_uuid: "",
bank_name: "",
bank_code: "",
bank_account_name: "",
bank_account_number: "",
amount: "",
currency: "",
status: "",
email: null,
first_name: null,
last_name: null,
created_at: "",
completed_at: null,
},
};
const context = "bank payout initialization";
const payoutData = {
payout_method: "bank_transfer",
bank_uuid: bankUuid,
bank_account_name: accountName,
bank_account_number: accountNumber,
amount: amount.toString(),
charge_id: chargeId,
...(options?.email && { email: options.email }),
...(options?.firstName && { first_name: options.firstName }),
...(options?.lastName && { last_name: options.lastName }),
};
logger_1.logger.info("PayChangu: initializing bank payout", { payoutData });
const response = await this.initializeBankPayoutDirect(payoutData);
if (!response || response.status !== "success") {
return this.createErrorResponse(response, context, defaultPayload);
}
return this.createSuccessResponse({
TransactionDetails: response.data.transaction,
});
}
async getBankPayoutDetails(chargeId) {
const defaultPayload = {
PayoutDetails: {
id: "",
charge_id: "",
bank_uuid: "",
bank_name: "",
bank_code: "",
bank_account_name: "",
bank_account_number: "",
amount: "",
currency: "",
status: "",
email: null,
first_name: null,
last_name: null,
created_at: "",
completed_at: null,
},
};
const context = "bank payout details retrieval";
logger_1.logger.info("PayChangu: getting bank payout details", { chargeId });
const response = await this.getBankPayoutDetailsDirect(chargeId);
if (!response ||
(response.status !== "successful" && response.status !== "success")) {
return this.createErrorResponse(response, context, defaultPayload);
}
return this.createSuccessResponse({ PayoutDetails: response.data });
}
async getAllBankPayouts(page, perPage) {
const defaultPayload = {
Payouts: [],
Pagination: {
CurrentPage: 0,
TotalPages: 0,
PerPage: 0,
NextPageUrl: null,
},
};
const context = "bank payouts list retrieval";
logger_1.logger.info("PayChangu: getting all bank payouts", { page, perPage });
const response = await this.getAllBankPayoutsDirect(page, perPage);
if (!response || response.status !== "success") {
return this.createErrorResponse(response, context, defaultPayload);
}
return this.createSuccessResponse({
Payouts: response.data,
Pagination: {
CurrentPage: response.current_page,
TotalPages: response.total_pages,
PerPage: response.per_page,
NextPageUrl: response.next_page_url,
},
});
}
async verifyTransaction(txRef) {
logger_1.logger.info("Verifying PayChangu transaction:", txRef);
return this.wrapApiCall(() => this.network.get(`/verify-payment/${txRef}`, `transaction verification for ${txRef}`), "transaction verification");
}
}
exports.PayChangu = PayChangu;
//# sourceMappingURL=index.js.map