payme-sdk
Version:
A Node.js SDK to integrate with PAYME API
263 lines (244 loc) • 6.33 kB
text/typescript
// src/payme-sdk.ts
import * as dotenv from 'dotenv';
import * as _ from 'lodash';
import { ExternalDataService } from './services/external-data.service';
export type Payment = {
reference: string;
account_id: number;
amount: number;
fees: number;
tva: number;
description: string;
status: string;
created_at: string;
updated_at: string;
};
export type PaymentItem = {
reference: string;
payment_id: number;
customer_id: number;
amount: number;
fees: number;
phone: string;
payment_method: string;
payment_proof: string;
status: string;
created_at: string;
updated_at: string;
};
export type Fees = {
operation_type: string;
corridor_tag: string;
operand: string;
min_amount: number;
max_amount: number;
value: number;
};
export interface PaymentParam {
reference: string;
amount: number;
fees: number;
tva: number;
description: string;
}
export interface PaymentItemParam {
reference?: string;
currency?: string;
customer_name?: string;
customer_email?: string;
customer_country?: string;
amount: number;
fees: number;
transaction_id: number;
phone: string;
}
class PayMeSDK {
private email: string;
private password: string;
private apiKey: string;
private merchant: any;
private token: string;
private account: any;
private externalDataService: ExternalDataService;
constructor(email: string, password: string, apiKey: string) {
// Set up dotenv
dotenv.config({ path: '.env' });
this.email = email;
this.password = password;
this.apiKey = apiKey;
this.token = '';
this.externalDataService = new ExternalDataService();
}
/**
* This function check if a merchant with a specific key exists
* @param key apiKey of the merchant
*/
public async init() {
const resp =
await this.externalDataService.postDataFromOnboarding(
`users/developer/authenticate`,
{
email: this.email,
password: this.password,
subscription_key: this.apiKey,
}
);
if (!resp || resp.length == 0) {
throw new Error(
'Unable to fetch account related to the key provided'
);
}
this.merchant = resp.data.user;
this.account = this.merchant.individualProfiles[0];
this.token = resp.data.token;
console.log(this.account, this.token);
this.externalDataService.setToken(this.token);
}
/**
* This function calculate the applicable fees of a payment
* @param amount amount of the payment
* @param country country where the payment will be done
*/
async getFees(amount: number, country: string) {
const resp = await this.externalDataService.getDataFromBilling(
`fees?filter={"where":{"min_amount":{"lte": ${amount}},"max_amount":{"gt": ${amount}}}}`
);
if (!resp || resp.length == 0) {
throw new Error(
'Fees has not yet been define for this amount, please contact support'
);
}
const fees = _.pick(resp[0], [
'operation_type',
'corridor_tag',
'operand',
'min_amount',
'max_amount',
'value',
]);
return fees;
}
/**
* This function register a payment / simple / partial / grouped
* @param param payment parameters
*/
async postPayment(param: PaymentParam) {
let data = {
...param,
account_id: this.account.id,
};
const resp = this.externalDataService.postDataFromPayment(
'transactions',
data
);
return resp;
}
/**
* This function check the status of a payment
* @param reference uniq reference of the transaction
*/
async getPaymentStatus(reference: string) {
const resp = await this.externalDataService.getDataFromPayment(
`transactions?filter={"where":{"reference":"${reference}"}}`
);
if (!resp || resp.length == 0) {
throw new Error(
'Fees has not yet been define for this amount, please contact support'
);
}
const payment = _.pick(resp[0], [
'reference',
'account_id',
'amount',
'fees',
'tva',
'description',
'status',
'created_at',
'updated_at',
]);
return payment;
}
/**
* This function init the payment of a customer
* @param param parameters of the item payment
*/
async postPaymentItem(param: PaymentItemParam) {
const resp = this.externalDataService.postDataFromPayment(
'payment-items',
param
);
return resp;
}
/**
* This function check the status of a payment item
* @param reference uniq reference of the payment item
*/
async getPaymentItemStatus(reference: string) {
const resp = await this.externalDataService.getDataFromPayment(
`payment-items?filter={"where":{"reference":"${reference}"}}`
);
if (!resp || resp.length == 0) {
throw new Error(
'Fees has not yet been define for this amount, please contact support'
);
}
const payment_item = _.pick(resp[0], [
'reference',
'payment_id',
'customer_id',
'amount',
'fees',
'phone',
'payment_method',
'payment_proof',
'status',
'created_at',
'updated_at',
]);
return payment_item;
}
/**
* This function return the payment and his associated payment items
* @param reference uniq reference of the payment
*/
async getPaymentWithItems(reference: string) {
const resp = await this.externalDataService.getDataFromPayment(
`transactions?filter={"where":{"reference":"${reference}"}, "include":["paymentItems"]}`
);
if (!resp || resp.length == 0) {
throw new Error('');
}
const payment = _.pick(resp[0], [
'reference',
'account_id',
'payment_type',
'amount',
'fees',
'tva',
'description',
'status',
'created_at',
'updated_at',
'paymentItems',
]);
const items = resp[0].paymentItems.map((item: any) =>
_.pick(item, [
'reference',
'payment_id',
'customer_id',
'amount',
'fees',
'phone',
'payment_method',
'payment_proof',
'status',
'created_at',
'updated_at',
])
);
payment.paymentItems = items;
return payment;
}
}
export default PayMeSDK;