ngx-pesapal
Version:
Angular schematics lib for abstracting Pesapal APIs
361 lines (350 loc) • 16.6 kB
JavaScript
import * as i0 from '@angular/core';
import { InjectionToken, Injectable, inject, Inject, DestroyRef, Directive, Input, HostListener, NgModule } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { HttpClient, HttpHeaders, HttpClientModule } from '@angular/common/http';
import { BehaviorSubject, catchError, map, switchMap } from 'rxjs';
const baseURL = new URL('https://pay.pesapal.com/v3');
var EFrequency;
(function (EFrequency) {
EFrequency["DAILY"] = "DAILY";
EFrequency["WEEKLY"] = "WEEKLY";
EFrequency["MONTHLY"] = "MONTHLY";
EFrequency["YEARLY"] = "YEARLY";
})(EFrequency || (EFrequency = {}));
const PESAPAL_CONFIGS = new InjectionToken('pesapal.keys');
class StoreService {
constructor() {
/**
* BehaviorSubject holding the authentication token response.
* It stores the received authentication token response or null if no response is available.
*
* This BehaviorSubject is used to track and provide the latest authentication token response.
*
* @publicApi
*/
this.authenticationResponseBs = new BehaviorSubject(null);
/**
* BehaviorSubject for storing the response after submitting an order request.
* It holds the received order submission response or null if no response is available.
*
* This BehaviorSubject is employed to maintain and distribute the most recent order submission response.
*
* @publicApi
*/
this.submitOrderResponseBs = new BehaviorSubject(null);
/**
* BehaviorSubject for storing the response related to the transaction status.
* It holds the received transaction status response or null if no response is available.
*
* This BehaviorSubject is utilized to keep track of and distribute the most recent transaction status response.
* It allows components or services to subscribe to changes in transaction status information.
*
* @publicApi
*/
this.transactionStatusResponseBs = new BehaviorSubject(null);
/**
* BehaviorSubject for storing the response related to the recurring request.
* It holds the received response or null if no response is available.
*
* @publicApi
*/
this.refundsResponseBs = new BehaviorSubject(null);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: StoreService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: StoreService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: StoreService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}] });
class TokenService {
constructor(credentials) {
this.credentials = credentials;
this.store = inject(StoreService);
this.http = inject(HttpClient);
}
/**
* Initiates the process to authenticate keys by requesting an authentication token.
* It sends a POST request to the server to obtain an authentication token based on provided consumer key and secret.
* Upon successful authentication, the received token is stored in session storage and in the authenticationResponseBs BehaviorSubject for further usage.
*
* @returns An Observable containing the received authentication token as ITokenResponse
* @private
*/
AuthenticateKeys() {
const { consumer_key, consumer_secret } = this.credentials;
return this.http.post(`
${baseURL}/api/Auth/RequestToken`, { consumer_key, consumer_secret }).pipe(catchError((e) => {
throw new Error(JSON.stringify(e));
}), map((res) => {
sessionStorage.setItem('12111997', res.token);
this.store.authenticationResponseBs.next(res);
return res;
}));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: TokenService, deps: [{ token: PESAPAL_CONFIGS }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: TokenService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: TokenService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [PESAPAL_CONFIGS]
}] }] });
class ApiService {
constructor(credentials) {
this.credentials = credentials;
this.http = inject(HttpClient);
this.destroy = inject(DestroyRef);
this.token = inject(TokenService);
this.store = inject(StoreService);
}
submitOrderRequest(data) {
return this.token.AuthenticateKeys().pipe(takeUntilDestroyed(this.destroy), switchMap((tokenResponse) => {
const requestBody = {
...data,
notification_id: this.credentials.ipn_id // Set the notification_id here
};
const token = new HttpHeaders({
'Authorization': `Bearer ${tokenResponse.token}`
});
return this.http.post(`${baseURL}/api/Transactions/SubmitOrderRequest`, requestBody, { headers: token });
}), catchError((error) => {
throw new Error(JSON.stringify(error));
}), map((response) => {
this.store.submitOrderResponseBs.next(response);
return response;
}));
}
/**
* Retrieves transaction status from the Pesapal API based on the provided tracking ID.
* This method sends a GET request to the Pesapal API endpoint responsible for retrieving transaction status.
*
* @param trackingId - The unique identifier for tracking the transaction.
* @returns An Observable that resolves to the transaction status response (ITransactionStatusResponse).
* @publicApi
*/
getTransactionStatus(trackingId) {
return this.token.AuthenticateKeys().pipe(takeUntilDestroyed(this.destroy), switchMap((tokenResponse) => {
const token = new HttpHeaders({
'Authorization': `Bearer ${tokenResponse.token}`
});
return this.http.get(`${baseURL}/api/Transactions/GetTransactionStatus?orderTrackingId=${trackingId}`, { headers: token });
}), catchError((error) => {
throw new Error(JSON.stringify(error));
}), map((response) => {
this.store.transactionStatusResponseBs.next(response);
return response;
}));
}
/**
* Submits an recurring order request to Pesapal for processing and handling payment transactions.
* The method sends a POST request to the Pesapal API endpoint responsible for recurring order submissions.
* Upon successful submission, the response data is stored in an Observable for further processing.
*
* @param data - A partial or complete object conforming to the IRecurringPaymentsRequest interface
* @returns An Observable that resolves to the response of the order submission as IRecurringPaymentsResponse
* @publicApi
*/
submitRecurringPayment(data) {
return this.token.AuthenticateKeys().pipe(takeUntilDestroyed(this.destroy), switchMap((tokenResponse) => {
const requestBody = {
...data,
notification_id: this.credentials.ipn_id // Set the notification_id here
};
const token = new HttpHeaders({
'Authorization': `Bearer ${tokenResponse.token}`
});
return this.http.post(`${baseURL}/api/Transactions/SubmitRecurringPayment`, requestBody, { headers: token });
}), catchError((error) => {
throw new Error(JSON.stringify(error));
}), map((response) => {
this.store.refundsResponseBs.next(response);
return response;
}));
}
/**
* Submits a payment refund.
* Upon successful submission, the response data is stored in an Observable for further processing.
*
* @param data - A partial or complete object conforming to the IRefundRequest interface
* @returns An Observable that resolves to the response of the order submission as IRefundResponse
* @publicApi
*/
requestRefund(data) {
return this.token.AuthenticateKeys().pipe(takeUntilDestroyed(this.destroy), switchMap((tokenResponse) => {
const token = new HttpHeaders({
'Authorization': `Bearer ${tokenResponse.token}`
});
return this.http.post(`${baseURL}/api/Transactions/RequestRefund`, data, { headers: token });
}), catchError((error) => {
throw new Error(JSON.stringify(error));
}), map((response) => {
return response;
}));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: ApiService, deps: [{ token: PESAPAL_CONFIGS }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: ApiService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: ApiService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [PESAPAL_CONFIGS]
}] }] });
class NgxPesapalDirective {
constructor() {
this.id = Date.now().toString(36) + Math.random().toString(36).substring(2);
this.currency = 'KES';
this.errorMessages = false;
this.api = inject(ApiService);
this.destroy = inject(DestroyRef);
}
onClick() {
this.api.submitOrderRequest({
id: this.id,
amount: this.amount,
currency: this.currency,
description: this.description,
callback_url: this.callback_url,
billing_address: {
phone_number: this.phone_number,
email_address: this.email_address,
country_code: this.country_code,
first_name: this.first_name,
middle_name: this.middle_name,
last_name: this.last_name,
line_1: this.line_1,
line_2: this.line_2,
city: this.city,
state: this.state,
postal_code: this.postal_code,
zip_code: this.zip_code,
}
}).pipe(takeUntilDestroyed(this.destroy)).subscribe({
error: (e) => {
throw new Error(e);
}
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: NgxPesapalDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.3", type: NgxPesapalDirective, selector: "[ngx-pesapal]", inputs: { currency: "currency", amount: "amount", description: "description", callback_url: "callback_url", phone_number: "phone_number", email_address: "email_address", country_code: "country_code", first_name: "first_name", middle_name: "middle_name", last_name: "last_name", line_1: "line_1", line_2: "line_2", city: "city", state: "state", postal_code: "postal_code", zip_code: "zip_code", cancellation_url: "cancellation_url", errorMessages: "errorMessages" }, host: { listeners: { "click": "onClick($event)" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: NgxPesapalDirective, decorators: [{
type: Directive,
args: [{
selector: '[ngx-pesapal]'
}]
}], propDecorators: { currency: [{
type: Input,
args: [{ required: true }]
}], amount: [{
type: Input,
args: [{ required: true }]
}], description: [{
type: Input,
args: [{ required: true }]
}], callback_url: [{
type: Input,
args: [{ required: true }]
}], phone_number: [{
type: Input,
args: [{ required: true }]
}], email_address: [{
type: Input
}], country_code: [{
type: Input
}], first_name: [{
type: Input
}], middle_name: [{
type: Input
}], last_name: [{
type: Input
}], line_1: [{
type: Input
}], line_2: [{
type: Input
}], city: [{
type: Input
}], state: [{
type: Input
}], postal_code: [{
type: Input
}], zip_code: [{
type: Input
}], cancellation_url: [{
type: Input
}], errorMessages: [{
type: Input
}], onClick: [{
type: HostListener,
args: ['click', ['$event']]
}] } });
class NgxPesapal {
// save domain names of sites using lib
constructor() {
// if (!isDevMode()) {
// inject(HttpClient).post('', document.location.origin ).subscribe((r: any) => { console.log(r)})
// }
}
/**
* Static method to initialize and configure the PesapalModule with essential configuration values.
* It is used to set up necessary configurations for the Pesapal module, including consumer key, consumer secret, and IPN (Instant Payment Notification) ID.
*
* @param consumer_key - The consumer key used for Pesapal API authentication.
* @param consumer_secret - The consumer secret associated with the consumer key for authentication.
* @param ipn_id - The Instant Payment Notification (IPN) ID used for Pesapal configuration.
* @returns A ModuleWithProviders object for initializing the PesapalModule with the provided configurations.
* @publicApi
*/
static forRoot(consumer_key, consumer_secret, ipn_id) {
return {
ngModule: NgxPesapal,
providers: [
{ provide: PESAPAL_CONFIGS, useValue: { consumer_key, consumer_secret, ipn_id } }
]
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: NgxPesapal, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.3", ngImport: i0, type: NgxPesapal, declarations: [NgxPesapalDirective], imports: [HttpClientModule], exports: [NgxPesapalDirective] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: NgxPesapal, providers: [
StoreService,
TokenService,
ApiService
], imports: [HttpClientModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: NgxPesapal, decorators: [{
type: NgModule,
args: [{
imports: [
HttpClientModule,
],
providers: [
StoreService,
TokenService,
ApiService
],
declarations: [
NgxPesapalDirective
],
exports: [
NgxPesapalDirective
]
}]
}], ctorParameters: () => [] });
/*
* Public API Surface of pesapal
*/
/**
* Generated bundle index. Do not edit.
*/
export { ApiService, NgxPesapal, NgxPesapalDirective, PESAPAL_CONFIGS, StoreService, baseURL };
//# sourceMappingURL=ngx-pesapal.mjs.map