UNPKG

nestjs-khalti

Version:

This is simple wrapper for Khalti Payment extended from @dallotech/nestjs-khalti. It supports ePayment Gateway(NEW) and transaction verification, but later more will be added. Just ping us or open pull request and contribute :)

120 lines (111 loc) 4.51 kB
import {BadRequestException, Inject, Injectable, InternalServerErrorException} from '@nestjs/common'; import {HttpService} from '@nestjs/axios'; import {firstValueFrom} from 'rxjs'; import { KHALTI_CONFIG_OPTIONS, KHALTI_LOOKUP_TEST_URL, KHALTI_LOOKUP_URL, KHALTI_PAYMENT_TEST_URL, KHALTI_PAYMENT_URL, KHALTI_VERIFY_URL, KhaltiDto, KhaltiInitResponse, KhaltiOptions, KhaltiRequestDto, KhaltiResponseDto, PaymentMode } from "./khalti.interface"; @Injectable() export class KhaltiService { private readonly paymentMode = null; private readonly secretKey = null; private readonly initiateUrl = null; private readonly initiateUrlForTest = null; private readonly lookupUrl = null; private readonly lookupUrlForTest = null; private readonly verifyUrl = null; constructor(@Inject(KHALTI_CONFIG_OPTIONS) private readonly options: KhaltiOptions, private readonly httpService: HttpService) { if (!options.secretKey) { throw new InternalServerErrorException("Secret Key for khalti payment is missing") } this.paymentMode = options.paymentMode || PaymentMode.TEST; this.secretKey = options.secretKey; this.initiateUrl = options.initiateUrl || KHALTI_PAYMENT_URL; this.initiateUrlForTest = options.initiateUrlForTest || KHALTI_PAYMENT_TEST_URL; this.lookupUrl = options.lookupUrl || KHALTI_LOOKUP_URL; this.lookupUrlForTest = options.lookupUrl || KHALTI_LOOKUP_TEST_URL; this.verifyUrl = KHALTI_VERIFY_URL; } async init(khaltiRequestDto: KhaltiRequestDto):Promise<KhaltiInitResponse> { const { returnUrl, websiteUrl, amount, purchaseOrderId, purchaseOrderName, customerInfo, amountBreakdown, productDetails } = khaltiRequestDto; if (!returnUrl || !websiteUrl || !amount || !purchaseOrderId || !purchaseOrderName) { throw new BadRequestException("Data missing for initiating Khalti payment"); } const khaltiDto: KhaltiDto = { return_url: returnUrl, website_url: websiteUrl, amount: amount, purchase_order_id: purchaseOrderId, purchase_order_name: purchaseOrderName, customer_info: customerInfo, amount_breakdown: amountBreakdown, product_details: productDetails } const response = await firstValueFrom(this.httpService .post( this.paymentMode.localeCompare(PaymentMode.TEST) == 0 ? this.initiateUrlForTest : this.initiateUrl, khaltiDto, { headers: { Authorization: this.secretKey, }, })); if(response && response?.status == 200 && response?.data){ const {pidx,payment_url,expires_in,expires_at} = response?.data; return{ pidx: pidx, paymentUrl: payment_url, expiresIn: expires_in, expiresAt: expires_at, } } } async lookUp(data: any):Promise<KhaltiResponseDto> { try{ const {pidx} = data; if (!pidx) { throw new BadRequestException("pidx missing for validating khalti payment"); } const response = await firstValueFrom(this.httpService .post( this.paymentMode.localeCompare(PaymentMode.TEST) == 0 ? this.lookupUrlForTest : this.lookupUrl, {pidx}, { headers: { Authorization: this.secretKey, }, }, )); if(response && response?.status == 200 && response?.data){ const {pidx,total_amount,status,transaction_id,fee,refunded} = response?.data; return{ pidx, totalAmount:total_amount, status, transactionId:transaction_id, fee, refunded } } throw new InternalServerErrorException('Unexpected response from Khalti lookup endpoint'); }catch (error:any) { throw new InternalServerErrorException(`Error in payment verification \n ${error?.message}`); } } }