pesafy 0.1.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.
- package/README.md +177 -0
- package/dist/components/react/index.cjs +230 -0
- package/dist/components/react/index.cjs.map +1 -0
- package/dist/components/react/index.d.cts +63 -0
- package/dist/components/react/index.d.ts +63 -0
- package/dist/components/react/index.js +200 -0
- package/dist/components/react/index.js.map +1 -0
- package/dist/components/react/styles.css +90 -0
- package/dist/components/react/styles.css.map +1 -0
- package/dist/components/react/styles.d.cts +2 -0
- package/dist/components/react/styles.d.ts +2 -0
- package/dist/index.cjs +729 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +416 -0
- package/dist/index.d.ts +416 -0
- package/dist/index.js +717 -0
- package/dist/index.js.map +1 -0
- package/package.json +105 -0
- package/src/components/vue/PaymentButton.vue +71 -0
- package/src/components/vue/PaymentForm.vue +164 -0
- package/src/components/vue/PaymentStatus.vue +68 -0
- package/src/components/vue/QRCode.vue +39 -0
- package/src/components/vue/index.ts +13 -0
- package/src/components/vue/shims-vue.d.ts +39 -0
- package/src/components/vue/types.ts +15 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth token manager for Daraja API
|
|
3
|
+
* Token validity: 3600 seconds (1 hour)
|
|
4
|
+
*/
|
|
5
|
+
declare class TokenManager {
|
|
6
|
+
private consumerKey;
|
|
7
|
+
private consumerSecret;
|
|
8
|
+
private baseUrl;
|
|
9
|
+
private cachedToken;
|
|
10
|
+
private tokenExpiresAt;
|
|
11
|
+
constructor(consumerKey: string, consumerSecret: string, baseUrl: string);
|
|
12
|
+
private getAuthHeader;
|
|
13
|
+
getAccessToken(): Promise<string>;
|
|
14
|
+
clearCache(): void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Security credential encryption for B2C, B2B, Reversal APIs
|
|
19
|
+
* Uses RSA with PKCS#1.5 padding per Daraja API spec
|
|
20
|
+
* Download certificates from: https://developer.safaricom.co.ke/APIs
|
|
21
|
+
*/
|
|
22
|
+
/** Encrypt initiator password with M-Pesa public certificate (PEM format) */
|
|
23
|
+
declare function encryptSecurityCredential(initiatorPassword: string, certificatePem: string): string;
|
|
24
|
+
|
|
25
|
+
/** B2B (Business to Business) types */
|
|
26
|
+
type B2BCommandId = "BusinessPayBill" | "BusinessBuyGoods" | "DisburseFundsToBusiness" | "BusinessToBusinessTransfer";
|
|
27
|
+
interface B2BRequest {
|
|
28
|
+
amount: number;
|
|
29
|
+
shortCode: string;
|
|
30
|
+
receiverShortCode: string;
|
|
31
|
+
resultUrl: string;
|
|
32
|
+
timeoutUrl: string;
|
|
33
|
+
commandId?: B2BCommandId;
|
|
34
|
+
senderIdentifierType?: number;
|
|
35
|
+
receiverIdentifierType?: number;
|
|
36
|
+
remarks?: string;
|
|
37
|
+
accountReference?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* B2B - Business to Business payments
|
|
42
|
+
* API: POST /mpesa/b2b/v1/paymentrequest
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
interface B2BResponse {
|
|
46
|
+
OriginatorConversationID: string;
|
|
47
|
+
ConversationID: string;
|
|
48
|
+
ResponseCode: string;
|
|
49
|
+
ResponseDescription: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** B2C (Business to Customer) types */
|
|
53
|
+
type B2CCommandId = "BusinessPayment" | "SalaryPayment" | "PromotionPayment";
|
|
54
|
+
interface B2CRequest {
|
|
55
|
+
amount: number;
|
|
56
|
+
phoneNumber: string;
|
|
57
|
+
shortCode: string;
|
|
58
|
+
resultUrl: string;
|
|
59
|
+
timeoutUrl: string;
|
|
60
|
+
commandId?: B2CCommandId;
|
|
61
|
+
remarks?: string;
|
|
62
|
+
occasion?: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* B2C - Business to Customer payments
|
|
67
|
+
* API: POST /mpesa/b2c/v3/paymentrequest
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
interface B2CResponse {
|
|
71
|
+
OriginatorConversationID: string;
|
|
72
|
+
ConversationID: string;
|
|
73
|
+
ResponseCode: string;
|
|
74
|
+
ResponseDescription: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** C2B (Customer to Business) types */
|
|
78
|
+
interface C2BRegisterUrlRequest {
|
|
79
|
+
shortCode: string;
|
|
80
|
+
confirmationUrl: string;
|
|
81
|
+
validationUrl: string;
|
|
82
|
+
responseType?: "Completed" | "Cancelled";
|
|
83
|
+
}
|
|
84
|
+
interface C2BSimulateRequest {
|
|
85
|
+
shortCode: string;
|
|
86
|
+
amount: number;
|
|
87
|
+
phoneNumber: string;
|
|
88
|
+
billRefNumber?: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* C2B Register URLs - Register validation and confirmation URLs
|
|
93
|
+
* API: POST /mpesa/c2b/v2/registerurl
|
|
94
|
+
*/
|
|
95
|
+
|
|
96
|
+
interface C2BRegisterUrlResponse {
|
|
97
|
+
ConversationID: string;
|
|
98
|
+
OriginatorCoversationID: string;
|
|
99
|
+
ResponseCode: string;
|
|
100
|
+
ResponseDescription: string;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* C2B Simulate - Simulate C2B payment (sandbox only)
|
|
105
|
+
* API: POST /mpesa/c2b/v2/simulate
|
|
106
|
+
*/
|
|
107
|
+
|
|
108
|
+
interface C2BSimulateResponse {
|
|
109
|
+
ConversationID: string;
|
|
110
|
+
OriginatorCoversationID: string;
|
|
111
|
+
ResponseCode: string;
|
|
112
|
+
ResponseDescription: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Transaction Reversal types */
|
|
116
|
+
interface ReversalRequest {
|
|
117
|
+
transactionId: string;
|
|
118
|
+
amount: number;
|
|
119
|
+
shortCode: string;
|
|
120
|
+
resultUrl: string;
|
|
121
|
+
timeoutUrl: string;
|
|
122
|
+
remarks?: string;
|
|
123
|
+
occasion?: string;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Transaction Reversal
|
|
128
|
+
* API: POST /mpesa/reversal/v1/request
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
interface ReversalResponse {
|
|
132
|
+
OriginatorConversationID: string;
|
|
133
|
+
ConversationID: string;
|
|
134
|
+
ResponseCode: string;
|
|
135
|
+
ResponseDescription: string;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Transaction Status Query types */
|
|
139
|
+
interface TransactionStatusRequest {
|
|
140
|
+
shortCode: string;
|
|
141
|
+
transactionId: string;
|
|
142
|
+
resultUrl: string;
|
|
143
|
+
timeoutUrl: string;
|
|
144
|
+
identifierType?: number;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Transaction Status Query
|
|
149
|
+
* API: POST /mpesa/transactionstatus/v1/query
|
|
150
|
+
*/
|
|
151
|
+
|
|
152
|
+
interface TransactionStatusResponse {
|
|
153
|
+
OriginatorConversationID: string;
|
|
154
|
+
ConversationID: string;
|
|
155
|
+
ResponseCode: string;
|
|
156
|
+
ResponseDescription: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Dynamic QR Code types - LIPA NA M-PESA */
|
|
160
|
+
type TrxCode = "BG" | "WA" | "PB" | "SM" | "SB";
|
|
161
|
+
interface DynamicQRRequest {
|
|
162
|
+
merchantName: string;
|
|
163
|
+
refNo: string;
|
|
164
|
+
amount: number;
|
|
165
|
+
trxCode: TrxCode;
|
|
166
|
+
cpi: string;
|
|
167
|
+
size?: string;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Dynamic QR Code - Generate LIPA NA M-PESA QR codes
|
|
172
|
+
* API: POST /mpesa/qrcode/v1/generate
|
|
173
|
+
*/
|
|
174
|
+
|
|
175
|
+
interface DynamicQRResponse {
|
|
176
|
+
ResponseCode: string;
|
|
177
|
+
RequestID: string;
|
|
178
|
+
ResponseDescription: string;
|
|
179
|
+
QRCode: string;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** STK Push (M-Pesa Express) types */
|
|
183
|
+
type TransactionType = "CustomerPayBillOnline" | "CustomerBuyGoodsOnline";
|
|
184
|
+
interface StkPushRequest {
|
|
185
|
+
amount: number;
|
|
186
|
+
phoneNumber: string;
|
|
187
|
+
callbackUrl: string;
|
|
188
|
+
accountReference: string;
|
|
189
|
+
transactionDesc: string;
|
|
190
|
+
/** Business shortcode - Paybill or Till number */
|
|
191
|
+
shortCode: string;
|
|
192
|
+
passKey: string;
|
|
193
|
+
transactionType?: TransactionType;
|
|
194
|
+
}
|
|
195
|
+
interface StkPushResponse {
|
|
196
|
+
MerchantRequestID: string;
|
|
197
|
+
CheckoutRequestID: string;
|
|
198
|
+
ResponseCode: string;
|
|
199
|
+
ResponseDescription: string;
|
|
200
|
+
CustomerMessage: string;
|
|
201
|
+
}
|
|
202
|
+
interface StkQueryRequest {
|
|
203
|
+
checkoutRequestId: string;
|
|
204
|
+
shortCode: string;
|
|
205
|
+
passKey: string;
|
|
206
|
+
}
|
|
207
|
+
interface StkQueryResponse {
|
|
208
|
+
ResponseCode: string;
|
|
209
|
+
ResponseDescription: string;
|
|
210
|
+
MerchantRequestID: string;
|
|
211
|
+
CheckoutRequestID: string;
|
|
212
|
+
ResultCode: string;
|
|
213
|
+
ResultDesc: string;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
type Environment = "sandbox" | "production";
|
|
217
|
+
declare const DARAJA_BASE_URLS: {
|
|
218
|
+
readonly sandbox: "https://sandbox.safaricom.co.ke";
|
|
219
|
+
readonly production: "https://api.safaricom.co.ke";
|
|
220
|
+
};
|
|
221
|
+
interface MpesaConfig {
|
|
222
|
+
consumerKey: string;
|
|
223
|
+
consumerSecret: string;
|
|
224
|
+
environment: Environment;
|
|
225
|
+
/** Required for STK Push - Lipa Na M-Pesa passkey from Daraja portal */
|
|
226
|
+
lipaNaMpesaShortCode?: string;
|
|
227
|
+
lipaNaMpesaPassKey?: string;
|
|
228
|
+
/** Required for B2C, B2B, Reversal - initiator name and password */
|
|
229
|
+
initiatorName?: string;
|
|
230
|
+
initiatorPassword?: string;
|
|
231
|
+
/** PEM certificate for encrypting initiator password. Download from Daraja portal */
|
|
232
|
+
certificatePath?: string;
|
|
233
|
+
/** PEM certificate string (alternative to certificatePath) */
|
|
234
|
+
certificatePem?: string;
|
|
235
|
+
/** Pre-encrypted security credential (alternative to initiatorPassword + certificate) */
|
|
236
|
+
securityCredential?: string;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
declare class Mpesa {
|
|
240
|
+
private config;
|
|
241
|
+
private tokenManager;
|
|
242
|
+
private baseUrl;
|
|
243
|
+
constructor(config: MpesaConfig);
|
|
244
|
+
private getToken;
|
|
245
|
+
private getSecurityCredential;
|
|
246
|
+
/** STK Push (M-Pesa Express) - Initiate payment on customer phone */
|
|
247
|
+
stkPush(request: Omit<StkPushRequest, "shortCode" | "passKey">): Promise<StkPushResponse>;
|
|
248
|
+
/** STK Query - Check STK Push transaction status */
|
|
249
|
+
stkQuery(request: Omit<StkQueryRequest, "shortCode" | "passKey">): Promise<StkQueryResponse>;
|
|
250
|
+
/** B2C - Send money to customer */
|
|
251
|
+
b2c(request: B2CRequest): Promise<B2CResponse>;
|
|
252
|
+
/** B2B - Send money to business */
|
|
253
|
+
b2b(request: B2BRequest): Promise<B2BResponse>;
|
|
254
|
+
/** C2B - Register validation/confirmation URLs */
|
|
255
|
+
c2bRegisterUrls(request: C2BRegisterUrlRequest): Promise<C2BRegisterUrlResponse>;
|
|
256
|
+
/** C2B - Simulate payment (sandbox only) */
|
|
257
|
+
c2bSimulate(request: C2BSimulateRequest): Promise<C2BSimulateResponse>;
|
|
258
|
+
/** Dynamic QR - Generate LIPA NA M-PESA QR code */
|
|
259
|
+
qrCode(request: DynamicQRRequest): Promise<DynamicQRResponse>;
|
|
260
|
+
/** Transaction Status - Query transaction status */
|
|
261
|
+
transactionStatus(request: TransactionStatusRequest): Promise<TransactionStatusResponse>;
|
|
262
|
+
/** Reversal - Reverse a transaction */
|
|
263
|
+
reversal(request: ReversalRequest): Promise<ReversalResponse>;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Webhook retry mechanism with exponential backoff
|
|
268
|
+
* For at-least-once delivery guarantee
|
|
269
|
+
*/
|
|
270
|
+
interface RetryOptions {
|
|
271
|
+
maxRetries?: number;
|
|
272
|
+
initialDelay?: number;
|
|
273
|
+
maxDelay?: number;
|
|
274
|
+
backoffMultiplier?: number;
|
|
275
|
+
maxRetryDuration?: number;
|
|
276
|
+
}
|
|
277
|
+
interface RetryResult<T> {
|
|
278
|
+
success: boolean;
|
|
279
|
+
data?: T;
|
|
280
|
+
attempts: number;
|
|
281
|
+
error?: Error;
|
|
282
|
+
}
|
|
283
|
+
declare function retryWithBackoff<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<RetryResult<T>>;
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Webhook event types from Daraja API
|
|
287
|
+
*/
|
|
288
|
+
type WebhookEventType = "stk_push" | "b2c" | "b2b" | "c2b" | "transaction_status" | "reversal";
|
|
289
|
+
interface WebhookEvent {
|
|
290
|
+
eventType: WebhookEventType;
|
|
291
|
+
timestamp: string;
|
|
292
|
+
data: unknown;
|
|
293
|
+
}
|
|
294
|
+
/** STK Push webhook payload */
|
|
295
|
+
interface StkPushWebhook {
|
|
296
|
+
Body: {
|
|
297
|
+
stkCallback: {
|
|
298
|
+
MerchantRequestID: string;
|
|
299
|
+
CheckoutRequestID: string;
|
|
300
|
+
ResultCode: number;
|
|
301
|
+
ResultDesc: string;
|
|
302
|
+
CallbackMetadata?: {
|
|
303
|
+
Item: Array<{
|
|
304
|
+
Name: string;
|
|
305
|
+
Value: string | number;
|
|
306
|
+
}>;
|
|
307
|
+
};
|
|
308
|
+
};
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
/** B2C webhook payload */
|
|
312
|
+
interface B2CWebhook {
|
|
313
|
+
Result: {
|
|
314
|
+
ResultType: number;
|
|
315
|
+
ResultCode: number;
|
|
316
|
+
ResultDesc: string;
|
|
317
|
+
OriginatorConversationID: string;
|
|
318
|
+
ConversationID: string;
|
|
319
|
+
TransactionID: string;
|
|
320
|
+
ResultParameters: {
|
|
321
|
+
ResultParameter: Array<{
|
|
322
|
+
Key: string;
|
|
323
|
+
Value: string | number;
|
|
324
|
+
}>;
|
|
325
|
+
};
|
|
326
|
+
ReferenceData: {
|
|
327
|
+
ReferenceItem: Array<{
|
|
328
|
+
Key: string;
|
|
329
|
+
Value: string;
|
|
330
|
+
}>;
|
|
331
|
+
};
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
/** C2B webhook payload */
|
|
335
|
+
interface C2BWebhook {
|
|
336
|
+
TransactionType: string;
|
|
337
|
+
TransID: string;
|
|
338
|
+
TransTime: string;
|
|
339
|
+
TransAmount: string;
|
|
340
|
+
BusinessShortCode: string;
|
|
341
|
+
BillRefNumber: string;
|
|
342
|
+
InvoiceNumber?: string;
|
|
343
|
+
OrgAccountBalance: string;
|
|
344
|
+
ThirdPartyTransID?: string;
|
|
345
|
+
MSISDN: string;
|
|
346
|
+
FirstName?: string;
|
|
347
|
+
MiddleName?: string;
|
|
348
|
+
LastName?: string;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Webhook signature verification
|
|
353
|
+
* Note: Daraja API doesn't provide webhook signatures in the same way as Stripe
|
|
354
|
+
* Instead, verify by whitelisting IPs: 196.201.214.200, 196.201.214.206, etc.
|
|
355
|
+
* This utility helps parse and validate webhook payloads
|
|
356
|
+
*/
|
|
357
|
+
|
|
358
|
+
declare function verifyWebhookIP(requestIP: string, allowedIPs?: string[]): boolean;
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Webhook event handler utilities
|
|
362
|
+
*/
|
|
363
|
+
|
|
364
|
+
interface WebhookHandlerOptions {
|
|
365
|
+
/** IP address of incoming request */
|
|
366
|
+
requestIP?: string;
|
|
367
|
+
/** Custom IP whitelist */
|
|
368
|
+
allowedIPs?: string[];
|
|
369
|
+
/** Skip IP verification (for testing) */
|
|
370
|
+
skipIPCheck?: boolean;
|
|
371
|
+
}
|
|
372
|
+
interface WebhookHandlerResult<T = unknown> {
|
|
373
|
+
success: boolean;
|
|
374
|
+
eventType: WebhookEventType | null;
|
|
375
|
+
data: T | null;
|
|
376
|
+
error?: string;
|
|
377
|
+
}
|
|
378
|
+
declare function handleWebhook(body: unknown, options?: WebhookHandlerOptions): WebhookHandlerResult;
|
|
379
|
+
declare function extractTransactionId(webhook: StkPushWebhook | B2CWebhook | C2BWebhook): string | null;
|
|
380
|
+
declare function extractAmount(webhook: StkPushWebhook | B2CWebhook | C2BWebhook): number | null;
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Error types for Pesafy library
|
|
384
|
+
*/
|
|
385
|
+
type ErrorCode = "AUTH_FAILED" | "INVALID_CREDENTIALS" | "ENCRYPTION_FAILED" | "API_ERROR" | "NETWORK_ERROR" | "VALIDATION_ERROR" | "INVALID_RESPONSE" | "REQUEST_FAILED" | "TIMEOUT";
|
|
386
|
+
interface PesafyErrorOptions {
|
|
387
|
+
code: ErrorCode;
|
|
388
|
+
message: string;
|
|
389
|
+
cause?: unknown;
|
|
390
|
+
statusCode?: number;
|
|
391
|
+
response?: unknown;
|
|
392
|
+
requestId?: string;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Error creation utilities for Pesafy
|
|
397
|
+
*/
|
|
398
|
+
|
|
399
|
+
declare class PesafyError extends Error {
|
|
400
|
+
readonly code: ErrorCode;
|
|
401
|
+
readonly statusCode?: number;
|
|
402
|
+
readonly response?: unknown;
|
|
403
|
+
readonly requestId?: string;
|
|
404
|
+
readonly cause?: unknown;
|
|
405
|
+
constructor(options: PesafyErrorOptions);
|
|
406
|
+
toJSON(): {
|
|
407
|
+
name: string;
|
|
408
|
+
code: ErrorCode;
|
|
409
|
+
message: string;
|
|
410
|
+
statusCode: number | undefined;
|
|
411
|
+
requestId: string | undefined;
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
declare function createError(options: PesafyErrorOptions): PesafyError;
|
|
415
|
+
|
|
416
|
+
export { type B2BRequest, type B2BResponse, type B2CRequest, type B2CResponse, type B2CWebhook, type C2BRegisterUrlRequest, type C2BRegisterUrlResponse, type C2BSimulateRequest, type C2BSimulateResponse, type C2BWebhook, DARAJA_BASE_URLS, type DynamicQRRequest, type DynamicQRResponse, type ErrorCode, Mpesa, type MpesaConfig, PesafyError, type RetryOptions, type RetryResult, type ReversalRequest, type ReversalResponse, type StkPushRequest, type StkPushResponse, type StkPushWebhook, type StkQueryRequest, type StkQueryResponse, TokenManager, type TransactionStatusRequest, type TransactionStatusResponse, type WebhookEvent, type WebhookEventType, type WebhookHandlerOptions, type WebhookHandlerResult, createError, encryptSecurityCredential, extractAmount, extractTransactionId, handleWebhook, retryWithBackoff, verifyWebhookIP };
|