pesafy 0.0.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,183 +1,35 @@
1
- import { A as TransactionStatusResult, D as MpesaConfig, T as AccountBalanceResult, b as B2BExpressCheckoutCallback, f as C2BValidationPayload, g as B2CDisbursementResult, o as ReversalResult, p as C2BValidationResponse, r as TaxRemittanceResult, s as C2BConfirmationPayload, y as B2CResult } from "../types.js";
1
+ import { i as Mpesa, n as StkFailurePayload, r as StkSuccessPayload, t as MpesaAdapterConfig } from "../types.js";
2
2
 
3
- //#region src/adapters/nextjs.d.ts
4
- interface MpesaNextConfig extends MpesaConfig {
5
- callbackUrl: string;
6
- resultUrl?: string;
7
- queueTimeoutUrl?: string;
8
- skipIPCheck?: boolean;
9
- webhookSecret?: string;
10
- requireHMAC?: boolean;
11
- signatureHeader?: string;
12
- balance?: {
13
- resultUrl?: string;
14
- queueTimeoutUrl?: string;
15
- partyA?: string;
16
- };
17
- reversal?: {
18
- resultUrl?: string;
19
- queueTimeoutUrl?: string;
20
- };
21
- txStatus?: {
22
- resultUrl?: string;
23
- queueTimeoutUrl?: string;
24
- };
25
- tax?: {
26
- resultUrl?: string;
27
- queueTimeoutUrl?: string;
28
- partyA?: string;
29
- };
30
- b2c?: {
31
- resultUrl?: string;
32
- queueTimeoutUrl?: string;
33
- partyA?: string;
34
- };
35
- c2b?: {
36
- shortCode?: string;
37
- confirmationUrl?: string;
38
- validationUrl?: string;
39
- responseType?: 'Completed' | 'Cancelled';
40
- apiVersion?: 'v1' | 'v2';
41
- };
42
- b2b?: {
43
- receiverShortCode?: string;
44
- callbackUrl?: string;
45
- };
46
- onStkSuccess?: (data: StkSuccessPayload) => Awaitable<void>;
47
- onStkFailure?: (data: StkFailurePayload) => Awaitable<void>;
48
- onC2BValidation?: (payload: C2BValidationPayload) => Awaitable<C2BValidationResponse>;
49
- onC2BConfirmation?: (payload: C2BConfirmationPayload) => Awaitable<void>;
50
- onAccountBalanceResult?: (result: AccountBalanceResult) => Awaitable<void>;
51
- onReversalResult?: (result: ReversalResult) => Awaitable<void>;
52
- onTxStatusResult?: (result: TransactionStatusResult) => Awaitable<void>;
53
- onTaxResult?: (result: TaxRemittanceResult) => Awaitable<void>;
54
- onB2BCheckoutCallback?: (cb: B2BExpressCheckoutCallback) => Awaitable<void>;
55
- onB2CResult?: (result: B2CResult) => Awaitable<void>;
56
- onB2CDisbursementResult?: (result: B2CDisbursementResult) => Awaitable<void>;
57
- }
58
- type Awaitable<T> = T | Promise<T>;
59
- type RouteHandler = (req: Request, ctx?: {
3
+ //#region src/adapters/shared/mount-nextjs.d.ts
4
+ type RouteHandler$1 = (req: Request, ctx?: {
60
5
  params?: Record<string, string>;
61
6
  }) => Promise<Response>;
62
- interface StkSuccessPayload {
63
- receiptNumber: string | null;
64
- amount: number | null;
65
- phone: string | null;
66
- checkoutRequestId: string;
67
- merchantRequestId: string;
68
- }
69
- interface StkFailurePayload {
70
- resultCode: number;
71
- resultDesc: string;
72
- checkoutRequestId: string;
73
- merchantRequestId: string;
74
- }
75
- /**
76
- * Returns a POST Route Handler for STK Push initiation.
77
- *
78
- * @example
79
- * // app/api/mpesa/stk/push/route.ts
80
- * import { createStkPushHandler } from 'pesafy/adapters/nextjs'
81
- * export const POST = createStkPushHandler(config)
82
- */
83
- declare function createStkPushHandler(config: MpesaNextConfig): RouteHandler;
84
- /**
85
- * Returns a POST Route Handler for STK Push Query.
86
- *
87
- * @example
88
- * // app/api/mpesa/stk/query/route.ts
89
- * export const POST = createStkQueryHandler(config)
90
- */
91
- declare function createStkQueryHandler(config: MpesaNextConfig): RouteHandler;
92
- /**
93
- * Returns a POST Route Handler for STK Push callbacks.
94
- *
95
- * @example
96
- * // app/api/mpesa/stk/callback/route.ts
97
- * export const POST = createStkCallbackHandler(config)
98
- */
99
- declare function createStkCallbackHandler(config: MpesaNextConfig): RouteHandler;
100
- /**
101
- * Returns a POST Route Handler for C2B Validation.
102
- *
103
- * @example
104
- * // app/api/mpesa/c2b/validation/route.ts
105
- * export const POST = createC2BValidationHandler(config)
106
- */
107
- declare function createC2BValidationHandler(config: MpesaNextConfig): RouteHandler;
108
- /**
109
- * Returns a POST Route Handler for C2B Confirmation.
110
- *
111
- * @example
112
- * // app/api/mpesa/c2b/confirmation/route.ts
113
- * export const POST = createC2BConfirmationHandler(config)
114
- */
115
- declare function createC2BConfirmationHandler(config: MpesaNextConfig): RouteHandler;
116
- /**
117
- * Returns POST handler for Account Balance result callback.
118
- *
119
- * @example
120
- * // app/api/mpesa/balance/result/route.ts
121
- * export const POST = createBalanceResultHandler(config)
122
- */
123
- declare function createBalanceResultHandler(config: MpesaNextConfig): RouteHandler;
124
- /**
125
- * Returns POST handler for Reversal result callback.
126
- *
127
- * @example
128
- * // app/api/mpesa/reversal/result/route.ts
129
- * export const POST = createReversalResultHandler(config)
130
- */
131
- declare function createReversalResultHandler(config: MpesaNextConfig): RouteHandler;
132
- /**
133
- * Returns POST handler for B2B Express Checkout callback.
134
- *
135
- * @example
136
- * // app/api/mpesa/b2b/callback/route.ts
137
- * export const POST = createB2BCallbackHandler(config)
138
- */
139
- declare function createB2BCallbackHandler(config: MpesaNextConfig): RouteHandler;
140
- /**
141
- * Returns POST handler for B2C result callback.
142
- *
143
- * @example
144
- * // app/api/mpesa/b2c/result/route.ts
145
- * export const POST = createB2CResultHandler(config)
146
- */
147
- declare function createB2CResultHandler(config: MpesaNextConfig): RouteHandler;
148
- /**
149
- * Returns POST handler for Tax Remittance result callback.
150
- *
151
- * @example
152
- * // app/api/mpesa/tax/result/route.ts
153
- * export const POST = createTaxResultHandler(config)
154
- */
155
- declare function createTaxResultHandler(config: MpesaNextConfig): RouteHandler;
156
- /**
157
- * Returns POST handler for B2C Disbursement result callback.
158
- */
159
- declare function createB2CDisbursementResultHandler(config: MpesaNextConfig): RouteHandler;
160
- /**
161
- * Returns POST handler for Transaction Status result callback.
162
- */
163
- declare function createTxStatusResultHandler(config: MpesaNextConfig): RouteHandler;
164
7
  interface MpesaHandlers {
165
- POST: RouteHandler;
166
- GET: RouteHandler;
167
- PATCH: RouteHandler;
168
- DELETE: RouteHandler;
8
+ POST: RouteHandler$1;
9
+ GET: RouteHandler$1;
10
+ PATCH: RouteHandler$1;
11
+ DELETE: RouteHandler$1;
169
12
  }
170
- /**
171
- * Creates all route handlers as a single catch-all.
172
- * Mount at `app/api/mpesa/[[...route]]/route.ts`.
173
- *
174
- * The request pathname is resolved relative to the segment after `/mpesa/`.
175
- *
176
- * @example
177
- * // app/api/mpesa/[[...route]]/route.ts
178
- * import { createMpesaHandlers } from 'pesafy/adapters/nextjs'
179
- * export const { POST, GET, PATCH, DELETE } = createMpesaHandlers(config)
180
- */
13
+ declare function createDispatchHandler(mpesa: Mpesa, config: MpesaAdapterConfig): RouteHandler$1;
14
+ //#endregion
15
+ //#region src/adapters/nextjs.d.ts
16
+ type MpesaNextConfig = MpesaAdapterConfig;
17
+ type RouteHandler = (req: Request, ctx?: {
18
+ params?: Record<string, string>;
19
+ }) => Promise<Response>;
20
+ declare const createStkPushHandler: (config: MpesaNextConfig) => RouteHandler;
21
+ declare const createStkQueryHandler: (config: MpesaNextConfig) => RouteHandler;
22
+ declare const createStkCallbackHandler: (config: MpesaNextConfig) => RouteHandler;
23
+ declare const createC2BValidationHandler: (config: MpesaNextConfig) => RouteHandler;
24
+ declare const createC2BConfirmationHandler: (config: MpesaNextConfig) => RouteHandler;
25
+ declare const createBalanceResultHandler: (config: MpesaNextConfig) => RouteHandler;
26
+ declare const createReversalResultHandler: (config: MpesaNextConfig) => RouteHandler;
27
+ declare const createB2BCallbackHandler: (config: MpesaNextConfig) => RouteHandler;
28
+ declare const createB2CResultHandler: (config: MpesaNextConfig) => RouteHandler;
29
+ declare const createTaxResultHandler: (config: MpesaNextConfig) => RouteHandler;
30
+ declare const createB2CDisbursementResultHandler: (config: MpesaNextConfig) => RouteHandler;
31
+ declare const createTxStatusResultHandler: (config: MpesaNextConfig) => RouteHandler;
181
32
  declare function createMpesaHandlers(config: MpesaNextConfig): MpesaHandlers;
182
33
  //#endregion
183
- export { MpesaHandlers, MpesaNextConfig, StkFailurePayload, StkSuccessPayload, createB2BCallbackHandler, createB2CDisbursementResultHandler, createB2CResultHandler, createBalanceResultHandler, createC2BConfirmationHandler, createC2BValidationHandler, createMpesaHandlers, createReversalResultHandler, createStkCallbackHandler, createStkPushHandler, createStkQueryHandler, createTaxResultHandler, createTxStatusResultHandler };
34
+ export { type MpesaHandlers, MpesaNextConfig, type StkFailurePayload, type StkSuccessPayload, createB2BCallbackHandler, createB2CDisbursementResultHandler, createB2CResultHandler, createBalanceResultHandler, createC2BConfirmationHandler, createC2BValidationHandler, createDispatchHandler, createMpesaHandlers, createMpesaHandlers as createMpesaNextHandlers, createReversalResultHandler, createStkCallbackHandler, createStkPushHandler, createStkQueryHandler, createTaxResultHandler, createTxStatusResultHandler };
35
+ //# sourceMappingURL=nextjs.d.ts.map
@@ -1 +1,166 @@
1
- import{A as e,D as t,E as n,O as r,S as i,T as a,_ as o,a as s,b as c,c as l,d as u,f as d,g as f,h as p,i as m,j as h,k as g,l as _,m as v,n as y,o as b,p as x,r as S,s as C,t as w,u as T,w as E,x as D,y as O}from"../webhook-guard.js";function k(e,t=200){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":`application/json`}})}function A(e){return k({ok:!0,data:e})}function j(e){return e instanceof h?k({ok:!1,error:e.code,message:e.message},e.statusCode??400):k({ok:!1,error:`INTERNAL_ERROR`,message:`Unexpected error`},500)}function M(e){return e.headers.get(`x-forwarded-for`)?.split(`,`)[0]?.trim()??e.headers.get(`cf-connecting-ip`)??e.headers.get(`x-real-ip`)??``}function N(...e){return e.find(e=>e?.trim())??``}function P(e,t){e?.().catch(e=>console.error(`[pesafy/nextjs] ${t} hook error:`,e))}async function F(e,t,n){await w(M(e),n,t=>e.headers.get(t)??void 0,t)}function I(e){let t=new y(e);return async n=>{try{let{amount:r,phoneNumber:i,accountReference:a,transactionDesc:o,transactionType:s,partyB:c}=await n.json();if(!r||r<=0)throw new h({code:`VALIDATION_ERROR`,message:`amount must be > 0`});if(!i)throw new h({code:`VALIDATION_ERROR`,message:`phoneNumber is required`});return A(await t.stkPush({amount:r,phoneNumber:i,callbackUrl:e.callbackUrl,accountReference:a??`REF-${Date.now().toString(36).toUpperCase()}`,transactionDesc:o??`Payment`,...s===void 0?{}:{transactionType:s},...c===void 0?{}:{partyB:c}}))}catch(e){return j(e)}}}function L(e){let t=new y(e);return async e=>{try{let{checkoutRequestId:n}=await e.json();if(!n)throw new h({code:`VALIDATION_ERROR`,message:`checkoutRequestId is required`});return A(await t.stkQuery({checkoutRequestId:n}))}catch(e){return j(e)}}}function R(e){return async t=>{let n=await t.text();await F(t,e,n);let r=JSON.parse(n),i=r?.Body?.stkCallback;if(!i)return k({ResultCode:0,ResultDesc:`Accepted`});if(b(r)){let t={receiptNumber:s(r),amount:S(r),phone:m(r),checkoutRequestId:i.CheckoutRequestID,merchantRequestId:i.MerchantRequestID};console.info(`[pesafy/nextjs] STK success:`,t),P(e.onStkSuccess?()=>Promise.resolve(e.onStkSuccess(t)):void 0,`onStkSuccess`)}else{let t={resultCode:i.ResultCode,resultDesc:i.ResultDesc,checkoutRequestId:i.CheckoutRequestID,merchantRequestId:i.MerchantRequestID};console.warn(`[pesafy/nextjs] STK failure:`,t),P(e.onStkFailure?()=>Promise.resolve(e.onStkFailure(t)):void 0,`onStkFailure`)}return k({ResultCode:0,ResultDesc:`Accepted`})}}function z(e){return async t=>{let n=await t.text();await F(t,e,n);let r=JSON.parse(n);return k(e.onC2BValidation?await e.onC2BValidation(r):v())}}function B(e){return async t=>{let n=await t.json();return console.info(`[pesafy/nextjs] C2B confirmation:`,{txId:n.TransID,amount:n.TransAmount}),P(e.onC2BConfirmation?()=>Promise.resolve(e.onC2BConfirmation(n)):void 0,`onC2BConfirmation`),k({ResultCode:0,ResultDesc:`Success`})}}function V(t){return async n=>{let i=await n.json();if(g(i)){let t=r(i);console.info(`[pesafy/nextjs] Balance result:`,t?e(t):i)}else console.warn(`[pesafy/nextjs] Balance failed:`,i);return P(t.onAccountBalanceResult?()=>Promise.resolve(t.onAccountBalanceResult(i)):void 0,`onAccountBalanceResult`),k({ResultCode:0,ResultDesc:`Accepted`})}}function H(e){return async t=>{let n=await t.json();return d(n)&&(x(n)?console.info(`[pesafy/nextjs] Reversal success:`,u(n)):console.warn(`[pesafy/nextjs] Reversal failed:`,n.Result.ResultDesc),P(e.onReversalResult?()=>Promise.resolve(e.onReversalResult(n)):void 0,`onReversalResult`)),k({ResultCode:0,ResultDesc:`Accepted`})}}function U(e){return async r=>{let o=await r.json();if(!a(o))return console.warn(`[pesafy/nextjs] Unknown B2B callback`),k({ResultCode:0,ResultDesc:`Accepted`});let s=o;return t(s)?console.info(`[pesafy/nextjs] B2B success:`,{txId:E(s),amount:i(s)}):n(s)?console.warn(`[pesafy/nextjs] B2B cancelled`):console.warn(`[pesafy/nextjs] B2B failed:`,s.resultDesc),P(e.onB2BCheckoutCallback?()=>Promise.resolve(e.onB2BCheckoutCallback(s)):void 0,`onB2BCheckoutCallback`),k({ResultCode:0,ResultDesc:`Accepted`})}}function W(e){return async t=>{let n=await t.json();return c(n)&&(D(n)?console.info(`[pesafy/nextjs] B2C success:`,{txId:O(n),amount:o(n)}):console.warn(`[pesafy/nextjs] B2C failed:`,n.Result.ResultDesc),P(e.onB2CResult?()=>Promise.resolve(e.onB2CResult(n)):void 0,`onB2CResult`)),k({ResultCode:0,ResultDesc:`Accepted`})}}function G(e){return async t=>{let n=await t.json();return _(n)&&(T(n)?console.info(`[pesafy/nextjs] Tax success:`,n.Result.TransactionID):console.warn(`[pesafy/nextjs] Tax failed:`,n.Result.ResultDesc),P(e.onTaxResult?()=>Promise.resolve(e.onTaxResult(n)):void 0,`onTaxResult`)),k({ResultCode:0,ResultDesc:`Accepted`})}}function K(e){return async t=>{let n=await t.json();return p(n)&&(f(n)?console.info(`[pesafy/nextjs] Disbursement success:`,n.Result.TransactionID):console.warn(`[pesafy/nextjs] Disbursement failed:`,n.Result.ResultDesc),P(e.onB2CDisbursementResult?()=>Promise.resolve(e.onB2CDisbursementResult(n)):void 0,`onB2CDisbursementResult`)),k({ResultCode:0,ResultDesc:`Accepted`})}}function q(e){return async t=>{let n=await t.json();return C(n)&&(l(n)?console.info(`[pesafy/nextjs] Tx-status success:`,n.Result.TransactionID):console.warn(`[pesafy/nextjs] Tx-status failed:`,n.Result.ResultDesc),P(e.onTxStatusResult?()=>Promise.resolve(e.onTxStatusResult(n)):void 0,`onTxStatusResult`)),k({ResultCode:0,ResultDesc:`Accepted`})}}function J(e){let t=new y(e);async function n(n){let r=new URL(n.url).pathname.replace(/^.*?(\/mpesa\/.*)$/,`$1`).replace(/\/$/,``);switch(r){case`/mpesa/stk/push`:try{let{amount:r,phoneNumber:i,accountReference:a,transactionDesc:o,transactionType:s,partyB:c}=await n.json();if(!r||r<=0)throw new h({code:`VALIDATION_ERROR`,message:`amount must be > 0`});if(!i)throw new h({code:`VALIDATION_ERROR`,message:`phoneNumber is required`});return A(await t.stkPush({amount:r,phoneNumber:i,callbackUrl:e.callbackUrl,accountReference:a??`REF-${Date.now().toString(36).toUpperCase()}`,transactionDesc:o??`Payment`,...s===void 0?{}:{transactionType:s},...c===void 0?{}:{partyB:c}}))}catch(e){return j(e)}case`/mpesa/stk/query`:try{let{checkoutRequestId:e}=await n.json();if(!e)throw new h({code:`VALIDATION_ERROR`,message:`checkoutRequestId is required`});return A(await t.stkQuery({checkoutRequestId:e}))}catch(e){return j(e)}case`/mpesa/stk/callback`:return R(e)(n);case`/mpesa/c2b/register`:try{let{shortCode:r,confirmationUrl:i,validationUrl:a,responseType:o,apiVersion:s}=await n.json(),c=r??e.c2b?.shortCode??``,l=i??e.c2b?.confirmationUrl??``,u=a??e.c2b?.validationUrl??``;if(!c)throw new h({code:`VALIDATION_ERROR`,message:`shortCode is required`});if(!l)throw new h({code:`VALIDATION_ERROR`,message:`confirmationUrl is required`});if(!u)throw new h({code:`VALIDATION_ERROR`,message:`validationUrl is required`});return A(await t.registerC2BUrls({shortCode:c,confirmationUrl:l,validationUrl:u,responseType:o??e.c2b?.responseType??`Completed`,apiVersion:s??e.c2b?.apiVersion??`v2`}))}catch(e){return j(e)}case`/mpesa/c2b/simulate`:try{let{commandId:r,amount:i,msisdn:a,billRefNumber:o,shortCode:s}=await n.json();return A(await t.simulateC2B({shortCode:s??e.c2b?.shortCode??``,commandId:r,amount:i,msisdn:a,apiVersion:e.c2b?.apiVersion??`v2`,...o===void 0?{}:{billRefNumber:o}}))}catch(e){return j(e)}case`/mpesa/c2b/validation`:return z(e)(n);case`/mpesa/c2b/confirmation`:return B(e)(n);case`/mpesa/balance/query`:try{let r=await n.json();return A(await t.accountBalance({partyA:r.partyA??e.balance?.partyA??``,identifierType:r.identifierType??`4`,resultUrl:N(r.resultUrl,e.balance?.resultUrl,e.resultUrl),queueTimeOutUrl:N(r.queueTimeoutUrl,e.balance?.queueTimeoutUrl,e.queueTimeoutUrl),...r.remarks===void 0?{}:{remarks:r.remarks}}))}catch(e){return j(e)}case`/mpesa/balance/result`:return V(e)(n);case`/mpesa/qr/generate`:try{return A(await t.generateDynamicQR(await n.json()))}catch(e){return j(e)}case`/mpesa/reversal/request`:try{let r=await n.json();if(!r.transactionId)throw new h({code:`VALIDATION_ERROR`,message:`transactionId is required`});if(!r.receiverParty)throw new h({code:`VALIDATION_ERROR`,message:`receiverParty is required`});if(!r.amount||r.amount<=0)throw new h({code:`VALIDATION_ERROR`,message:`amount must be > 0`});return A(await t.reverseTransaction({transactionId:r.transactionId,receiverParty:r.receiverParty,amount:r.amount,resultUrl:N(r.resultUrl,e.reversal?.resultUrl,e.resultUrl),queueTimeOutUrl:N(r.queueTimeoutUrl,e.reversal?.queueTimeoutUrl,e.queueTimeoutUrl),...r.remarks===void 0?{}:{remarks:r.remarks},...r.occasion===void 0?{}:{occasion:r.occasion}}))}catch(e){return j(e)}case`/mpesa/reversal/result`:return H(e)(n);case`/mpesa/tx-status/query`:try{let r=await n.json();return A(await t.transactionStatus({...r.transactionId===void 0?{}:{transactionId:r.transactionId},...r.originalConversationId===void 0?{}:{originalConversationId:r.originalConversationId},partyA:r.partyA,identifierType:r.identifierType,resultUrl:N(r.resultUrl,e.txStatus?.resultUrl,e.resultUrl),queueTimeOutUrl:N(r.queueTimeoutUrl,e.txStatus?.queueTimeoutUrl,e.queueTimeoutUrl),...r.remarks===void 0?{}:{remarks:r.remarks},...r.occasion===void 0?{}:{occasion:r.occasion}}))}catch(e){return j(e)}case`/mpesa/tx-status/result`:return q(e)(n);case`/mpesa/tax/remit`:try{let r=await n.json();if(!r.amount||r.amount<=0)throw new h({code:`VALIDATION_ERROR`,message:`amount must be > 0`});if(!r.accountReference)throw new h({code:`VALIDATION_ERROR`,message:`accountReference (KRA PRN) is required`});return A(await t.remitTax({amount:r.amount,partyA:r.partyA??e.tax?.partyA??``,accountReference:r.accountReference,resultUrl:N(r.resultUrl,e.tax?.resultUrl,e.resultUrl),queueTimeOutUrl:N(r.queueTimeoutUrl,e.tax?.queueTimeoutUrl,e.queueTimeoutUrl),...r.partyB===void 0?{}:{partyB:r.partyB},...r.remarks===void 0?{}:{remarks:r.remarks}}))}catch(e){return j(e)}case`/mpesa/tax/result`:return G(e)(n);case`/mpesa/b2b/checkout`:try{let r=await n.json(),i=r.receiverShortCode??e.b2b?.receiverShortCode??``,a=r.callbackUrl??e.b2b?.callbackUrl??``;if(!i)throw new h({code:`VALIDATION_ERROR`,message:`receiverShortCode is required`});if(!a)throw new h({code:`VALIDATION_ERROR`,message:`callbackUrl is required`});return A(await t.b2bExpressCheckout({...r,receiverShortCode:i,callbackUrl:a}))}catch(e){return j(e)}case`/mpesa/b2b/callback`:return U(e)(n);case`/mpesa/b2c/payment`:try{let r=await n.json();if(r.commandId!==`BusinessPayToBulk`)throw new h({code:`VALIDATION_ERROR`,message:`commandId must be "BusinessPayToBulk"`});if(!r.partyB)throw new h({code:`VALIDATION_ERROR`,message:`partyB is required`});return A(await t.b2cPayment({commandId:`BusinessPayToBulk`,amount:r.amount,partyA:r.partyA??e.b2c?.partyA??``,partyB:r.partyB,accountReference:r.accountReference,resultUrl:N(r.resultUrl,e.b2c?.resultUrl,e.resultUrl),queueTimeOutUrl:N(r.queueTimeoutUrl,e.b2c?.queueTimeoutUrl,e.queueTimeoutUrl),...r.requester===void 0?{}:{requester:r.requester},...r.remarks===void 0?{}:{remarks:r.remarks}}))}catch(e){return j(e)}case`/mpesa/b2c/result`:return W(e)(n);case`/mpesa/b2c/disburse`:try{let{queueTimeoutUrl:r,resultUrl:i,...a}=await n.json();return A(await t.b2cDisbursement({...a,resultUrl:N(i,e.b2c?.resultUrl,e.resultUrl),queueTimeOutUrl:N(r,e.b2c?.queueTimeoutUrl,e.queueTimeoutUrl)}))}catch(e){return j(e)}case`/mpesa/b2c/disburse/result`:return K(e)(n);case`/mpesa/bills/optin`:try{return A(await t.billManagerOptIn(await n.json()))}catch(e){return j(e)}case`/mpesa/bills/invoice`:if(n.method===`DELETE`)try{return A(await t.cancelInvoice(await n.json()))}catch(e){return j(e)}try{return A(await t.sendInvoice(await n.json()))}catch(e){return j(e)}case`/mpesa/bills/invoice/bulk`:if(n.method===`DELETE`)try{return A(await t.cancelBulkInvoices(await n.json()))}catch(e){return j(e)}try{return A(await t.sendBulkInvoices(await n.json()))}catch(e){return j(e)}case`/mpesa/bills/reconcile`:try{return A(await t.reconcilePayment(await n.json()))}catch(e){return j(e)}case`/mpesa/health`:return k({ok:!0,environment:t.environment,ts:new Date().toISOString()});default:return k({ok:!1,error:`NOT_FOUND`,message:`No handler for ${r}`},404)}}return{POST:e=>n(e),GET:e=>n(e),PATCH:e=>n(e),DELETE:e=>n(e)}}export{U as createB2BCallbackHandler,K as createB2CDisbursementResultHandler,W as createB2CResultHandler,V as createBalanceResultHandler,B as createC2BConfirmationHandler,z as createC2BValidationHandler,J as createMpesaHandlers,H as createReversalResultHandler,R as createStkCallbackHandler,I as createStkPushHandler,L as createStkQueryHandler,G as createTaxResultHandler,q as createTxStatusResultHandler};
1
+ import { a as PesafyError, i as Mpesa, n as getRoutePaths, r as createRouteHandlers, t as ROUTE_DEFINITIONS } from "../route-definitions.js";
2
+
3
+ //#region src/adapters/shared/mount-nextjs.ts
4
+ const NEXTJS_ROUTE_PATHS = getRoutePaths();
5
+ function json$1(data, status = 200) {
6
+ return new Response(JSON.stringify(data), {
7
+ status,
8
+ headers: { "Content-Type": "application/json" }
9
+ });
10
+ }
11
+ function sendErr$1(error) {
12
+ if (error instanceof PesafyError) return json$1({
13
+ ok: false,
14
+ error: error.code,
15
+ message: error.message
16
+ }, error.statusCode ?? 400);
17
+ return json$1({
18
+ ok: false,
19
+ error: "INTERNAL_ERROR",
20
+ message: "Unexpected error"
21
+ }, 500);
22
+ }
23
+ function sendHandlerResult(result, routeId) {
24
+ if (routeId === "health") return json$1(result.body);
25
+ if (result.type === "daraja") return json$1(result.body);
26
+ return json$1({
27
+ ok: true,
28
+ data: result.body
29
+ });
30
+ }
31
+ function getIP$1(req) {
32
+ return req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() ?? req.headers.get("cf-connecting-ip") ?? req.headers.get("x-real-ip") ?? "";
33
+ }
34
+ async function buildContext$1(req, isWebhook) {
35
+ if (isWebhook) {
36
+ const rawBody = await req.text();
37
+ return {
38
+ body: JSON.parse(rawBody),
39
+ rawBody,
40
+ requestIP: getIP$1(req),
41
+ getHeader: (name) => req.headers.get(name) ?? void 0
42
+ };
43
+ }
44
+ return {
45
+ body: req.method === "GET" ? void 0 : await req.json().catch(() => ({})),
46
+ requestIP: getIP$1(req),
47
+ getHeader: (name) => req.headers.get(name) ?? void 0
48
+ };
49
+ }
50
+ const KNOWN_PATHS = new Set(ROUTE_DEFINITIONS.map((r) => r.path));
51
+ const PATH_METHOD_TO_ROUTE = new Map(ROUTE_DEFINITIONS.map((route) => [`${route.path}:${route.method}`, route]));
52
+ function createDispatchHandler(mpesa, config) {
53
+ const handlers = createRouteHandlers(mpesa, config);
54
+ return async (req) => {
55
+ const path = new URL(req.url).pathname.replace(/^.*?(\/mpesa\/.*)$/, "$1").replace(/\/$/, "");
56
+ if (!KNOWN_PATHS.has(path)) return json$1({
57
+ ok: false,
58
+ error: "NOT_FOUND",
59
+ message: `No handler for ${path}`
60
+ }, 404);
61
+ const route = PATH_METHOD_TO_ROUTE.get(`${path}:${req.method}`);
62
+ if (!route) return json$1({
63
+ ok: false,
64
+ error: "METHOD_NOT_ALLOWED",
65
+ message: `${req.method} not allowed for ${path}`
66
+ }, 405);
67
+ try {
68
+ const ctx = await buildContext$1(req, route.webhook ?? false);
69
+ return sendHandlerResult(await handlers[route.id](ctx), route.id);
70
+ } catch (e) {
71
+ return sendErr$1(e);
72
+ }
73
+ };
74
+ }
75
+ function createMpesaHandlersFromDispatch(config) {
76
+ const dispatch = createDispatchHandler(new Mpesa(config), config);
77
+ return {
78
+ POST: dispatch,
79
+ GET: dispatch,
80
+ PATCH: dispatch,
81
+ DELETE: dispatch
82
+ };
83
+ }
84
+
85
+ //#endregion
86
+ //#region src/adapters/nextjs.ts
87
+ /**
88
+ * @file src/adapters/nextjs.ts
89
+ * Next.js App Router adapter for pesafy.
90
+ *
91
+ * Usage (catch-all):
92
+ * // app/api/mpesa/[[...route]]/route.ts
93
+ * export const { POST, GET, PATCH, DELETE } = createMpesaHandlers(config)
94
+ */
95
+ function json(data, status = 200) {
96
+ return new Response(JSON.stringify(data), {
97
+ status,
98
+ headers: { "Content-Type": "application/json" }
99
+ });
100
+ }
101
+ function sendErr(error) {
102
+ if (error instanceof PesafyError) return json({
103
+ ok: false,
104
+ error: error.code,
105
+ message: error.message
106
+ }, error.statusCode ?? 400);
107
+ return json({
108
+ ok: false,
109
+ error: "INTERNAL_ERROR",
110
+ message: "Unexpected error"
111
+ }, 500);
112
+ }
113
+ function getIP(req) {
114
+ return req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() ?? req.headers.get("cf-connecting-ip") ?? req.headers.get("x-real-ip") ?? "";
115
+ }
116
+ async function buildContext(req, routeId) {
117
+ if (routeId === "stk.callback" || routeId === "c2b.validation") {
118
+ const rawBody = await req.text();
119
+ return {
120
+ body: JSON.parse(rawBody),
121
+ rawBody,
122
+ requestIP: getIP(req),
123
+ getHeader: (name) => req.headers.get(name) ?? void 0
124
+ };
125
+ }
126
+ return {
127
+ body: await req.json(),
128
+ requestIP: getIP(req),
129
+ getHeader: (name) => req.headers.get(name) ?? void 0
130
+ };
131
+ }
132
+ function createSingleRouteHandler(config, routeId) {
133
+ const handlers = createRouteHandlers(new Mpesa(config), config);
134
+ return async (req) => {
135
+ try {
136
+ const ctx = await buildContext(req, routeId);
137
+ const result = await handlers[routeId](ctx);
138
+ if (routeId === "health" || result.type === "daraja") return json(result.body);
139
+ return json({
140
+ ok: true,
141
+ data: result.body
142
+ });
143
+ } catch (e) {
144
+ return sendErr(e);
145
+ }
146
+ };
147
+ }
148
+ const createStkPushHandler = (config) => createSingleRouteHandler(config, "stk.push");
149
+ const createStkQueryHandler = (config) => createSingleRouteHandler(config, "stk.query");
150
+ const createStkCallbackHandler = (config) => createSingleRouteHandler(config, "stk.callback");
151
+ const createC2BValidationHandler = (config) => createSingleRouteHandler(config, "c2b.validation");
152
+ const createC2BConfirmationHandler = (config) => createSingleRouteHandler(config, "c2b.confirmation");
153
+ const createBalanceResultHandler = (config) => createSingleRouteHandler(config, "balance.result");
154
+ const createReversalResultHandler = (config) => createSingleRouteHandler(config, "reversal.result");
155
+ const createB2BCallbackHandler = (config) => createSingleRouteHandler(config, "b2b.callback");
156
+ const createB2CResultHandler = (config) => createSingleRouteHandler(config, "b2c.result");
157
+ const createTaxResultHandler = (config) => createSingleRouteHandler(config, "tax.result");
158
+ const createB2CDisbursementResultHandler = (config) => createSingleRouteHandler(config, "b2c.disburse.result");
159
+ const createTxStatusResultHandler = (config) => createSingleRouteHandler(config, "txStatus.result");
160
+ function createMpesaHandlers(config) {
161
+ return createMpesaHandlersFromDispatch(config);
162
+ }
163
+
164
+ //#endregion
165
+ export { createB2BCallbackHandler, createB2CDisbursementResultHandler, createB2CResultHandler, createBalanceResultHandler, createC2BConfirmationHandler, createC2BValidationHandler, createDispatchHandler, createMpesaHandlers, createMpesaHandlers as createMpesaNextHandlers, createReversalResultHandler, createStkCallbackHandler, createStkPushHandler, createStkQueryHandler, createTaxResultHandler, createTxStatusResultHandler };
166
+ //# sourceMappingURL=nextjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextjs.js","names":["json","sendErr","getIP","buildContext"],"sources":["../../src/adapters/shared/mount-nextjs.ts","../../src/adapters/nextjs.ts"],"sourcesContent":["import { Mpesa } from '../../mpesa'\nimport { PesafyError } from '../../utils/errors'\nimport { createRouteHandlers } from './handlers'\nimport {\n ROUTE_DEFINITIONS,\n getRoutePaths,\n type RouteOperationId,\n type HttpMethod,\n} from './route-definitions'\nexport const NEXTJS_ROUTE_PATHS = getRoutePaths()\nimport type { HandlerContext, HandlerResult, MpesaAdapterConfig } from './types'\n\ntype RouteHandler = (req: Request, ctx?: { params?: Record<string, string> }) => Promise<Response>\n\nfunction json(data: unknown, status = 200): Response {\n return new Response(JSON.stringify(data), {\n status,\n headers: { 'Content-Type': 'application/json' },\n })\n}\n\nfunction sendErr(error: unknown): Response {\n if (error instanceof PesafyError) {\n return json({ ok: false, error: error.code, message: error.message }, error.statusCode ?? 400)\n }\n return json({ ok: false, error: 'INTERNAL_ERROR', message: 'Unexpected error' }, 500)\n}\n\nfunction sendHandlerResult(result: HandlerResult, routeId: RouteOperationId): Response {\n if (routeId === 'health') {\n return json(result.body)\n }\n if (result.type === 'daraja') {\n return json(result.body)\n }\n return json({ ok: true, data: result.body })\n}\n\nfunction getIP(req: Request): string {\n return (\n req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ??\n req.headers.get('cf-connecting-ip') ??\n req.headers.get('x-real-ip') ??\n ''\n )\n}\n\nasync function buildContext(req: Request, isWebhook: boolean): Promise<HandlerContext> {\n if (isWebhook) {\n const rawBody = await req.text()\n return {\n body: JSON.parse(rawBody) as unknown,\n rawBody,\n requestIP: getIP(req),\n getHeader: (name) => req.headers.get(name) ?? undefined,\n }\n }\n const body = req.method === 'GET' ? undefined : ((await req.json().catch(() => ({}))) as unknown)\n return {\n body,\n requestIP: getIP(req),\n getHeader: (name) => req.headers.get(name) ?? undefined,\n }\n}\n\n// Two-level lookup: first check if the path is known at all (→ 404 vs 405),\n// then match on path + method (→ correct handler).\nconst KNOWN_PATHS = new Set(ROUTE_DEFINITIONS.map((r) => r.path))\nconst PATH_METHOD_TO_ROUTE = new Map(\n ROUTE_DEFINITIONS.map((route) => [`${route.path}:${route.method}`, route] as const),\n)\n\nexport interface MpesaHandlers {\n POST: RouteHandler\n GET: RouteHandler\n PATCH: RouteHandler\n DELETE: RouteHandler\n}\n\nexport function createDispatchHandler(mpesa: Mpesa, config: MpesaAdapterConfig): RouteHandler {\n const handlers = createRouteHandlers(mpesa, config)\n\n return async (req) => {\n const url = new URL(req.url)\n const path = url.pathname.replace(/^.*?(\\/mpesa\\/.*)$/, '$1').replace(/\\/$/, '')\n\n if (!KNOWN_PATHS.has(path)) {\n return json({ ok: false, error: 'NOT_FOUND', message: `No handler for ${path}` }, 404)\n }\n\n const route = PATH_METHOD_TO_ROUTE.get(`${path}:${req.method as HttpMethod}`)\n if (!route) {\n return json(\n {\n ok: false,\n error: 'METHOD_NOT_ALLOWED',\n message: `${req.method} not allowed for ${path}`,\n },\n 405,\n )\n }\n\n try {\n const ctx = await buildContext(req, route.webhook ?? false)\n const result = await handlers[route.id](ctx)\n return sendHandlerResult(result, route.id)\n } catch (e) {\n return sendErr(e)\n }\n }\n}\n\nexport function createMpesaHandlersFromDispatch(config: MpesaAdapterConfig): MpesaHandlers {\n const mpesa = new Mpesa(config)\n const dispatch = createDispatchHandler(mpesa, config)\n return {\n POST: dispatch,\n GET: dispatch,\n PATCH: dispatch,\n DELETE: dispatch,\n }\n}\n","/**\n * @file src/adapters/nextjs.ts\n * Next.js App Router adapter for pesafy.\n *\n * Usage (catch-all):\n * // app/api/mpesa/[[...route]]/route.ts\n * export const { POST, GET, PATCH, DELETE } = createMpesaHandlers(config)\n */\n\nimport { Mpesa } from '../mpesa'\nimport { PesafyError } from '../utils/errors'\nimport { createRouteHandlers } from './shared/handlers'\nimport {\n createDispatchHandler,\n createMpesaHandlersFromDispatch,\n type MpesaHandlers,\n} from './shared/mount-nextjs'\nimport type { RouteOperationId } from './shared/route-definitions'\nimport type {\n HandlerContext,\n MpesaAdapterConfig,\n StkFailurePayload,\n StkSuccessPayload,\n} from './shared/types'\n\nexport type MpesaNextConfig = MpesaAdapterConfig\nexport type { StkSuccessPayload, StkFailurePayload, MpesaHandlers }\n\ntype RouteHandler = (req: Request, ctx?: { params?: Record<string, string> }) => Promise<Response>\n\nfunction json(data: unknown, status = 200): Response {\n return new Response(JSON.stringify(data), {\n status,\n headers: { 'Content-Type': 'application/json' },\n })\n}\n\nfunction sendErr(error: unknown): Response {\n if (error instanceof PesafyError) {\n return json({ ok: false, error: error.code, message: error.message }, error.statusCode ?? 400)\n }\n return json({ ok: false, error: 'INTERNAL_ERROR', message: 'Unexpected error' }, 500)\n}\n\nfunction getIP(req: Request): string {\n return (\n req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ??\n req.headers.get('cf-connecting-ip') ??\n req.headers.get('x-real-ip') ??\n ''\n )\n}\n\nasync function buildContext(req: Request, routeId: RouteOperationId): Promise<HandlerContext> {\n const needsRaw = routeId === 'stk.callback' || routeId === 'c2b.validation'\n if (needsRaw) {\n const rawBody = await req.text()\n return {\n body: JSON.parse(rawBody) as unknown,\n rawBody,\n requestIP: getIP(req),\n getHeader: (name) => req.headers.get(name) ?? undefined,\n }\n }\n return {\n body: await req.json(),\n requestIP: getIP(req),\n getHeader: (name) => req.headers.get(name) ?? undefined,\n }\n}\n\nfunction createSingleRouteHandler(\n config: MpesaNextConfig,\n routeId: RouteOperationId,\n): RouteHandler {\n const mpesa = new Mpesa(config)\n const handlers = createRouteHandlers(mpesa, config)\n\n return async (req) => {\n try {\n const ctx = await buildContext(req, routeId)\n const result = await handlers[routeId](ctx)\n if (routeId === 'health' || result.type === 'daraja') {\n return json(result.body)\n }\n return json({ ok: true, data: result.body })\n } catch (e) {\n return sendErr(e)\n }\n }\n}\n\nexport const createStkPushHandler = (config: MpesaNextConfig) =>\n createSingleRouteHandler(config, 'stk.push')\nexport const createStkQueryHandler = (config: MpesaNextConfig) =>\n createSingleRouteHandler(config, 'stk.query')\nexport const createStkCallbackHandler = (config: MpesaNextConfig) =>\n createSingleRouteHandler(config, 'stk.callback')\nexport const createC2BValidationHandler = (config: MpesaNextConfig) =>\n createSingleRouteHandler(config, 'c2b.validation')\nexport const createC2BConfirmationHandler = (config: MpesaNextConfig) =>\n createSingleRouteHandler(config, 'c2b.confirmation')\nexport const createBalanceResultHandler = (config: MpesaNextConfig) =>\n createSingleRouteHandler(config, 'balance.result')\nexport const createReversalResultHandler = (config: MpesaNextConfig) =>\n createSingleRouteHandler(config, 'reversal.result')\nexport const createB2BCallbackHandler = (config: MpesaNextConfig) =>\n createSingleRouteHandler(config, 'b2b.callback')\nexport const createB2CResultHandler = (config: MpesaNextConfig) =>\n createSingleRouteHandler(config, 'b2c.result')\nexport const createTaxResultHandler = (config: MpesaNextConfig) =>\n createSingleRouteHandler(config, 'tax.result')\nexport const createB2CDisbursementResultHandler = (config: MpesaNextConfig) =>\n createSingleRouteHandler(config, 'b2c.disburse.result')\nexport const createTxStatusResultHandler = (config: MpesaNextConfig) =>\n createSingleRouteHandler(config, 'txStatus.result')\n\nexport { createDispatchHandler }\n\nexport function createMpesaHandlers(config: MpesaNextConfig): MpesaHandlers {\n return createMpesaHandlersFromDispatch(config)\n}\n\nexport { createMpesaHandlers as createMpesaNextHandlers }\n"],"mappings":"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"}