pesafy 0.4.1 → 0.4.3

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/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var crypto = require('crypto');
3
+ var crypto$1 = require('crypto');
4
4
 
5
5
  // Pesafy - Payment Gateway Library
6
6
  // https://github.com/levos-snr/pesafy
@@ -45,11 +45,11 @@ function createError(options) {
45
45
  function encryptSecurityCredential(initiatorPassword, certificatePem) {
46
46
  try {
47
47
  const passwordBuffer = Buffer.from(initiatorPassword, "utf-8");
48
- const encrypted = crypto.publicEncrypt(
48
+ const encrypted = crypto$1.publicEncrypt(
49
49
  {
50
50
  key: certificatePem,
51
51
  // RSA_PKCS1_PADDING = 1 (NOT RSA_PKCS1_OAEP_PADDING = 4)
52
- padding: crypto.constants.RSA_PKCS1_PADDING
52
+ padding: crypto$1.constants.RSA_PKCS1_PADDING
53
53
  },
54
54
  passwordBuffer
55
55
  );
@@ -217,6 +217,255 @@ var TokenManager = class {
217
217
  }
218
218
  };
219
219
 
220
+ // src/mpesa/b2b-express-checkout/initiate.ts
221
+ function generateRequestRefId() {
222
+ try {
223
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
224
+ return crypto.randomUUID();
225
+ }
226
+ } catch {
227
+ }
228
+ return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}-${Math.random().toString(16).slice(2)}`;
229
+ }
230
+ async function initiateB2BExpressCheckout(baseUrl, accessToken, request) {
231
+ if (!request.primaryShortCode?.trim()) {
232
+ throw createError({
233
+ code: "VALIDATION_ERROR",
234
+ message: "primaryShortCode is required \u2014 the merchant's till number (debit party)."
235
+ });
236
+ }
237
+ if (!request.receiverShortCode?.trim()) {
238
+ throw createError({
239
+ code: "VALIDATION_ERROR",
240
+ message: "receiverShortCode is required \u2014 the vendor's Paybill account (credit party)."
241
+ });
242
+ }
243
+ const amount = Math.round(request.amount);
244
+ if (!Number.isFinite(amount) || amount < 1) {
245
+ throw createError({
246
+ code: "VALIDATION_ERROR",
247
+ message: `amount must be a whole number \u2265 1 (got ${request.amount} which rounds to ${amount}).`
248
+ });
249
+ }
250
+ if (!request.paymentRef?.trim()) {
251
+ throw createError({
252
+ code: "VALIDATION_ERROR",
253
+ message: "paymentRef is required \u2014 shown in the merchant's USSD prompt as the payment reference."
254
+ });
255
+ }
256
+ if (!request.callbackUrl?.trim()) {
257
+ throw createError({
258
+ code: "VALIDATION_ERROR",
259
+ message: "callbackUrl is required \u2014 Safaricom POSTs the transaction result here."
260
+ });
261
+ }
262
+ if (!request.partnerName?.trim()) {
263
+ throw createError({
264
+ code: "VALIDATION_ERROR",
265
+ message: "partnerName is required \u2014 your friendly name shown in the merchant's USSD prompt."
266
+ });
267
+ }
268
+ const payload = {
269
+ primaryShortCode: String(request.primaryShortCode),
270
+ receiverShortCode: String(request.receiverShortCode),
271
+ amount: String(amount),
272
+ paymentRef: request.paymentRef,
273
+ callbackUrl: request.callbackUrl,
274
+ partnerName: request.partnerName,
275
+ RequestRefID: request.requestRefId ?? generateRequestRefId()
276
+ };
277
+ const { data } = await httpRequest(
278
+ `${baseUrl}/v1/ussdpush/get-msisdn`,
279
+ {
280
+ method: "POST",
281
+ headers: { Authorization: `Bearer ${accessToken}` },
282
+ body: payload
283
+ }
284
+ );
285
+ return data;
286
+ }
287
+
288
+ // src/mpesa/b2b-express-checkout/webhooks.ts
289
+ function isB2BCheckoutSuccess(callback) {
290
+ return callback.resultCode === "0";
291
+ }
292
+ function isB2BCheckoutCancelled(callback) {
293
+ return callback.resultCode === "4001";
294
+ }
295
+ function isB2BCheckoutCallback(body) {
296
+ if (!body || typeof body !== "object") return false;
297
+ const b = body;
298
+ return typeof b["resultCode"] === "string" && typeof b["requestId"] === "string" && typeof b["amount"] === "string";
299
+ }
300
+ function getB2BTransactionId(callback) {
301
+ if (!isB2BCheckoutSuccess(callback)) return null;
302
+ return callback.transactionId ?? null;
303
+ }
304
+ function getB2BAmount(callback) {
305
+ return Number(callback.amount);
306
+ }
307
+ function getB2BRequestId(callback) {
308
+ return callback.requestId;
309
+ }
310
+ function getB2BConversationId(callback) {
311
+ if (!isB2BCheckoutSuccess(callback)) return null;
312
+ return callback.conversationID ?? null;
313
+ }
314
+
315
+ // src/mpesa/b2c/payment.ts
316
+ async function initiateB2CPayment(baseUrl, accessToken, securityCredential, initiatorName, request) {
317
+ if (!request.commandId) {
318
+ throw createError({
319
+ code: "VALIDATION_ERROR",
320
+ message: 'commandId is required: "BusinessPayToBulk" | "BusinessPayment" | "SalaryPayment" | "PromotionPayment"'
321
+ });
322
+ }
323
+ const validCommandIds = [
324
+ "BusinessPayToBulk",
325
+ "BusinessPayment",
326
+ "SalaryPayment",
327
+ "PromotionPayment"
328
+ ];
329
+ if (!validCommandIds.includes(request.commandId)) {
330
+ throw createError({
331
+ code: "VALIDATION_ERROR",
332
+ message: `commandId must be one of: ${validCommandIds.join(", ")}. Got: "${request.commandId}"`
333
+ });
334
+ }
335
+ const amount = Math.round(request.amount);
336
+ if (!Number.isFinite(amount) || amount < 1) {
337
+ throw createError({
338
+ code: "VALIDATION_ERROR",
339
+ message: `amount must be a whole number \u2265 1 (got ${request.amount} which rounds to ${amount}).`
340
+ });
341
+ }
342
+ if (!request.partyA?.trim()) {
343
+ throw createError({
344
+ code: "VALIDATION_ERROR",
345
+ message: "partyA is required \u2014 your business shortcode from which money is deducted."
346
+ });
347
+ }
348
+ if (!request.partyB?.trim()) {
349
+ throw createError({
350
+ code: "VALIDATION_ERROR",
351
+ message: "partyB is required \u2014 the recipient shortcode (BusinessPayToBulk) or customer MSISDN (other commands)."
352
+ });
353
+ }
354
+ if (!request.accountReference?.trim()) {
355
+ throw createError({
356
+ code: "VALIDATION_ERROR",
357
+ message: "accountReference is required \u2014 a reference for this transaction."
358
+ });
359
+ }
360
+ if (!request.resultUrl?.trim()) {
361
+ throw createError({
362
+ code: "VALIDATION_ERROR",
363
+ message: "resultUrl is required \u2014 Safaricom POSTs the B2C result here."
364
+ });
365
+ }
366
+ if (!request.queueTimeOutUrl?.trim()) {
367
+ throw createError({
368
+ code: "VALIDATION_ERROR",
369
+ message: "queueTimeOutUrl is required \u2014 Safaricom calls this on request timeout."
370
+ });
371
+ }
372
+ const payload = {
373
+ Initiator: initiatorName,
374
+ SecurityCredential: securityCredential,
375
+ CommandID: request.commandId,
376
+ SenderIdentifierType: request.senderIdentifierType ?? "4",
377
+ RecieverIdentifierType: request.receiverIdentifierType ?? "4",
378
+ Amount: String(amount),
379
+ PartyA: String(request.partyA),
380
+ PartyB: String(request.partyB),
381
+ AccountReference: request.accountReference,
382
+ Remarks: request.remarks ?? "B2C Payment",
383
+ QueueTimeOutURL: request.queueTimeOutUrl,
384
+ ResultURL: request.resultUrl
385
+ };
386
+ if (request.requester?.trim()) {
387
+ payload["Requester"] = String(request.requester);
388
+ }
389
+ const { data } = await httpRequest(
390
+ `${baseUrl}/mpesa/b2b/v1/paymentrequest`,
391
+ {
392
+ method: "POST",
393
+ headers: { Authorization: `Bearer ${accessToken}` },
394
+ body: payload
395
+ }
396
+ );
397
+ return data;
398
+ }
399
+
400
+ // src/mpesa/b2c/webhooks.ts
401
+ function isB2CResult(body) {
402
+ if (!body || typeof body !== "object") return false;
403
+ const b = body;
404
+ if (!b["Result"] || typeof b["Result"] !== "object") return false;
405
+ const result = b["Result"];
406
+ return typeof result["ResultCode"] === "number" && typeof result["ConversationID"] === "string";
407
+ }
408
+ function isB2CSuccess(result) {
409
+ return result.Result.ResultCode === 0;
410
+ }
411
+ function isB2CFailure(result) {
412
+ return result.Result.ResultCode !== 0;
413
+ }
414
+ function getB2CTransactionId(result) {
415
+ return result.Result.TransactionID ?? null;
416
+ }
417
+ function getB2CConversationId(result) {
418
+ return result.Result.ConversationID;
419
+ }
420
+ function getB2COriginatorConversationId(result) {
421
+ return result.Result.OriginatorConversationID;
422
+ }
423
+ function getB2CResultDesc(result) {
424
+ return result.Result.ResultDesc;
425
+ }
426
+ function getB2CAmount(result) {
427
+ const value = getB2CResultParam(result, "Amount");
428
+ if (value === void 0) return null;
429
+ return Number(value);
430
+ }
431
+ function getB2CTransactionCompletedTime(result) {
432
+ const value = getB2CResultParam(result, "TransCompletedTime");
433
+ if (value === void 0) return null;
434
+ return String(value);
435
+ }
436
+ function getB2CDebitPartyCharges(result) {
437
+ const value = getB2CResultParam(result, "DebitPartyCharges");
438
+ if (value === void 0 || value === "") return null;
439
+ return String(value);
440
+ }
441
+ function getB2CReceiverPublicName(result) {
442
+ const value = getB2CResultParam(result, "ReceiverPartyPublicName");
443
+ if (value === void 0) return null;
444
+ return String(value);
445
+ }
446
+ function getB2CCurrency(result) {
447
+ const value = getB2CResultParam(result, "Currency");
448
+ if (value === void 0) return "KES";
449
+ return String(value);
450
+ }
451
+ function getB2CDebitAccountBalance(result) {
452
+ const value = getB2CResultParam(result, "DebitAccountBalance");
453
+ if (value === void 0) return null;
454
+ return String(value);
455
+ }
456
+ function getB2CInitiatorAccountBalance(result) {
457
+ const value = getB2CResultParam(result, "InitiatorAccountCurrentBalance");
458
+ if (value === void 0) return null;
459
+ return String(value);
460
+ }
461
+ function getB2CResultParam(result, key) {
462
+ const params = result.Result.ResultParameters?.ResultParameter;
463
+ if (!params) return void 0;
464
+ const paramArray = Array.isArray(params) ? params : [params];
465
+ const item = paramArray.find((p) => p.Key === key);
466
+ return item?.Value;
467
+ }
468
+
220
469
  // src/mpesa/c2b/register-url.ts
221
470
  var FORBIDDEN_URL_KEYWORDS = [
222
471
  "mpesa",
@@ -732,7 +981,7 @@ var Mpesa = class {
732
981
  }
733
982
  return encryptSecurityCredential(this.config.initiatorPassword, cert);
734
983
  }
735
- // ── STK Push ──────────────────────────────────────────────────────────────
984
+ // ── STK Push ───────────────────────────────────────────────────────────────
736
985
  /**
737
986
  * M-Pesa Express — sends a payment prompt to the customer's phone.
738
987
  *
@@ -789,6 +1038,7 @@ var Mpesa = class {
789
1038
  passKey
790
1039
  });
791
1040
  }
1041
+ // ── Transaction Status ─────────────────────────────────────────────────────
792
1042
  /**
793
1043
  * Transaction Status — queries the result of a completed M-Pesa transaction.
794
1044
  *
@@ -827,116 +1077,71 @@ var Mpesa = class {
827
1077
  request
828
1078
  );
829
1079
  }
830
- // ── Dynamic QR Code ───────────────────────────────────────────────────────
1080
+ // ── Dynamic QR Code ────────────────────────────────────────────────────────
831
1081
  /**
832
1082
  * Dynamic QR — generates an M-PESA QR code for LNM merchant payments.
833
1083
  *
834
- * Customers scan the code with My Safaricom App or M-PESA app to
835
- * capture the till/paybill number and amount, then authorize payment.
836
- *
837
1084
  * @example
838
1085
  * const res = await mpesa.generateDynamicQR({
839
1086
  * merchantName: "My Shop",
840
1087
  * refNo: "INV-001",
841
1088
  * amount: 500,
842
- * trxCode: "BG", // Buy Goods (till number)
1089
+ * trxCode: "BG",
843
1090
  * cpi: "373132",
844
1091
  * size: 300,
845
1092
  * });
846
- *
847
- * // res.QRCode is a base64-encoded PNG — render in an <img> tag:
848
1093
  * // <img src={`data:image/png;base64,${res.QRCode}`} />
849
1094
  */
850
1095
  async generateDynamicQR(request) {
851
1096
  const token = await this.getToken();
852
1097
  return generateDynamicQR(this.baseUrl, token, request);
853
1098
  }
854
- // ── C2B Register URL ──────────────────────────────────────────────────────
1099
+ // ── C2B Register URL ───────────────────────────────────────────────────────
855
1100
  /**
856
1101
  * Registers your Confirmation and Validation URLs with M-PESA.
857
1102
  *
858
- * Use v2 (default) for new integrations — callbacks include a masked MSISDN.
859
- * Use v1 only if you need SHA256-hashed MSISDN in callbacks.
860
- *
861
- * Sandbox: URLs can be re-registered freely (overwriting existing ones).
862
- * Production: One-time call. To change URLs, delete them via Daraja Self
863
- * Services → URL Management, then call this again.
864
- *
865
- * URL rules (Daraja docs — enforced by this library):
866
- * ✓ Must be publicly accessible
867
- * ✓ Production: HTTPS required
868
- * ✗ Must NOT contain: M-PESA, Safaricom, exe, exec, cmd, sql, query
869
- * ✗ Do NOT use ngrok, mockbin, requestbin in production
870
- * ✓ responseType must be exactly "Completed" or "Cancelled" (sentence case)
871
- *
872
- * External Validation (optional):
873
- * By default it is disabled. To enable, email apisupport@safaricom.co.ke.
874
- * When enabled, Safaricom calls your validationUrl before processing payment.
875
- * You must respond within ~8 seconds.
876
- *
877
1103
  * @example
878
1104
  * await mpesa.registerC2BUrls({
879
1105
  * shortCode: "600984",
880
1106
  * responseType: "Completed",
881
1107
  * confirmationUrl: "https://yourdomain.com/mpesa/c2b/confirmation",
882
1108
  * validationUrl: "https://yourdomain.com/mpesa/c2b/validation",
883
- * apiVersion: "v2", // default — recommended
1109
+ * apiVersion: "v2",
884
1110
  * });
885
1111
  */
886
1112
  async registerC2BUrls(request) {
887
1113
  const token = await this.getToken();
888
1114
  return registerC2BUrls(this.baseUrl, token, request);
889
1115
  }
890
- // ── C2B Simulate (Sandbox ONLY) ───────────────────────────────────────────
1116
+ // ── C2B Simulate (Sandbox ONLY) ────────────────────────────────────────────
891
1117
  /**
892
1118
  * Simulates a C2B customer payment. SANDBOX ONLY.
893
1119
  *
894
- * In production, real customers initiate payments via M-PESA App, USSD,
895
- * or SIM Toolkit — simulation is not available.
896
- *
897
- * The API version used here should match the version used when registering URLs.
898
- *
899
1120
  * @example
900
1121
  * await mpesa.simulateC2B({
901
1122
  * shortCode: 600984,
902
1123
  * commandId: "CustomerPayBillOnline",
903
1124
  * amount: 10,
904
- * msisdn: 254708374149, // Daraja test MSISDN
905
- * billRefNumber: "INV-001", // account ref for Paybill; null for Till
906
- * apiVersion: "v2", // must match registered URL version
1125
+ * msisdn: 254708374149,
1126
+ * billRefNumber: "INV-001",
1127
+ * apiVersion: "v2",
907
1128
  * });
908
1129
  */
909
1130
  async simulateC2B(request) {
910
1131
  const token = await this.getToken();
911
1132
  return simulateC2B(this.baseUrl, token, request);
912
1133
  }
913
- // ── Tax Remittance ────────────────────────────────────────────────────────
1134
+ // ── Tax Remittance ─────────────────────────────────────────────────────────
914
1135
  /**
915
1136
  * Tax Remittance — remits tax to Kenya Revenue Authority (KRA) via M-PESA.
916
1137
  *
917
- * Requires:
918
- * - initiatorName in config
919
- * - initiatorPassword + certificate (or pre-computed securityCredential)
920
- *
921
- * This is ASYNCHRONOUS. The synchronous response only confirms receipt.
922
- * Final details are POSTed to your resultUrl.
923
- *
924
- * Prerequisites (from Daraja docs):
925
- * - Prior integration with KRA for tax declaration.
926
- * - A Payment Registration Number (PRN) from KRA.
927
- * - Initiator with "Tax Remittance ORG API" role on M-PESA org portal.
928
- *
929
- * Fixed values (set automatically — do NOT override unless Safaricom changes them):
930
- * CommandID: "PayTaxToKRA"
931
- * SenderIdentifierType: "4"
932
- * RecieverIdentifierType: "4"
933
- * PartyB: "572572" (KRA shortcode)
1138
+ * Requires: initiatorName + certificate (or pre-computed securityCredential).
934
1139
  *
935
1140
  * @example
936
1141
  * await mpesa.remitTax({
937
1142
  * amount: 5000,
938
1143
  * partyA: "888880",
939
- * accountReference: "PRN1234XN", // PRN from KRA
1144
+ * accountReference: "PRN1234XN",
940
1145
  * resultUrl: "https://yourdomain.com/mpesa/tax/result",
941
1146
  * queueTimeOutUrl: "https://yourdomain.com/mpesa/tax/timeout",
942
1147
  * remarks: "Monthly PAYE remittance",
@@ -956,6 +1161,94 @@ var Mpesa = class {
956
1161
  ]);
957
1162
  return remitTax(this.baseUrl, token, securityCred, initiator, request);
958
1163
  }
1164
+ // ── B2B Express Checkout ───────────────────────────────────────────────────
1165
+ /**
1166
+ * B2B Express Checkout — initiates a USSD Push to a merchant's till.
1167
+ *
1168
+ * @example
1169
+ * const res = await mpesa.b2bExpressCheckout({
1170
+ * primaryShortCode: "000001",
1171
+ * receiverShortCode: "000002",
1172
+ * amount: 5000,
1173
+ * paymentRef: "INV-001",
1174
+ * callbackUrl: "https://yourdomain.com/mpesa/b2b/callback",
1175
+ * partnerName: "My Vendor Co.",
1176
+ * });
1177
+ */
1178
+ async b2bExpressCheckout(request) {
1179
+ const token = await this.getToken();
1180
+ return initiateB2BExpressCheckout(this.baseUrl, token, request);
1181
+ }
1182
+ // ── B2C Payment ────────────────────────────────────────────────────────────
1183
+ /**
1184
+ * B2C Payment — sends money from a business to customers, or loads funds
1185
+ * to a B2C shortcode for bulk disbursement.
1186
+ *
1187
+ * Requires: initiatorName + (initiatorPassword + certificate) OR securityCredential.
1188
+ * The initiator must have the appropriate role for the chosen CommandID.
1189
+ *
1190
+ * This is ASYNCHRONOUS. The synchronous response only confirms receipt.
1191
+ * Final details are POSTed to your resultUrl.
1192
+ *
1193
+ * CommandID options:
1194
+ * "BusinessPayToBulk" — Load funds to a B2C shortcode (Account Top Up)
1195
+ * "BusinessPayment" — Direct unsecured payment to a customer
1196
+ * "SalaryPayment" — Salary disbursement to a customer
1197
+ * "PromotionPayment" — Promotion/bonus payment to a customer
1198
+ *
1199
+ * Required M-PESA org portal roles:
1200
+ * BusinessPayToBulk → "Org Business Pay to Bulk API initiator"
1201
+ * BusinessPayment → "Org Business Payment API initiator"
1202
+ * SalaryPayment → "Org Salary Payment API initiator"
1203
+ * PromotionPayment → "Org Promotion Payment API initiator"
1204
+ *
1205
+ * @example
1206
+ * // B2C Account Top Up (load funds to B2C shortcode)
1207
+ * await mpesa.b2cPayment({
1208
+ * commandId: "BusinessPayToBulk",
1209
+ * amount: 10000,
1210
+ * partyA: "600979",
1211
+ * partyB: "600000",
1212
+ * accountReference: "BATCH-001",
1213
+ * resultUrl: "https://yourdomain.com/mpesa/b2c/result",
1214
+ * queueTimeOutUrl: "https://yourdomain.com/mpesa/b2c/timeout",
1215
+ * remarks: "Monthly salary batch load",
1216
+ * });
1217
+ *
1218
+ * @example
1219
+ * // Direct customer payment
1220
+ * await mpesa.b2cPayment({
1221
+ * commandId: "SalaryPayment",
1222
+ * amount: 5000,
1223
+ * partyA: "600979",
1224
+ * partyB: "254712345678",
1225
+ * accountReference: "SAL-JAN-2024",
1226
+ * requester: "254712345678",
1227
+ * resultUrl: "https://yourdomain.com/mpesa/b2c/result",
1228
+ * queueTimeOutUrl: "https://yourdomain.com/mpesa/b2c/timeout",
1229
+ * remarks: "January salary",
1230
+ * });
1231
+ */
1232
+ async b2cPayment(request) {
1233
+ const initiator = this.config.initiatorName ?? "";
1234
+ if (!initiator) {
1235
+ throw new PesafyError({
1236
+ code: "VALIDATION_ERROR",
1237
+ message: "initiatorName is required for B2C Payment"
1238
+ });
1239
+ }
1240
+ const [token, securityCred] = await Promise.all([
1241
+ this.getToken(),
1242
+ this.buildSecurityCredential()
1243
+ ]);
1244
+ return initiateB2CPayment(
1245
+ this.baseUrl,
1246
+ token,
1247
+ securityCred,
1248
+ initiator,
1249
+ request
1250
+ );
1251
+ }
959
1252
  /** Force the cached OAuth token to be refreshed on the next API call */
960
1253
  clearTokenCache() {
961
1254
  this.tokenManager.clearCache();
@@ -1094,6 +1387,22 @@ exports.extractAmount = extractAmount;
1094
1387
  exports.extractPhoneNumber = extractPhoneNumber;
1095
1388
  exports.extractTransactionId = extractTransactionId;
1096
1389
  exports.formatPhoneNumber = formatSafaricomPhone;
1390
+ exports.getB2BAmount = getB2BAmount;
1391
+ exports.getB2BConversationId = getB2BConversationId;
1392
+ exports.getB2BRequestId = getB2BRequestId;
1393
+ exports.getB2BTransactionId = getB2BTransactionId;
1394
+ exports.getB2CAmount = getB2CAmount;
1395
+ exports.getB2CConversationId = getB2CConversationId;
1396
+ exports.getB2CCurrency = getB2CCurrency;
1397
+ exports.getB2CDebitAccountBalance = getB2CDebitAccountBalance;
1398
+ exports.getB2CDebitPartyCharges = getB2CDebitPartyCharges;
1399
+ exports.getB2CInitiatorAccountBalance = getB2CInitiatorAccountBalance;
1400
+ exports.getB2COriginatorConversationId = getB2COriginatorConversationId;
1401
+ exports.getB2CReceiverPublicName = getB2CReceiverPublicName;
1402
+ exports.getB2CResultDesc = getB2CResultDesc;
1403
+ exports.getB2CResultParam = getB2CResultParam;
1404
+ exports.getB2CTransactionCompletedTime = getB2CTransactionCompletedTime;
1405
+ exports.getB2CTransactionId = getB2CTransactionId;
1097
1406
  exports.getC2BAccountRef = getC2BAccountRef;
1098
1407
  exports.getC2BAmount = getC2BAmount;
1099
1408
  exports.getC2BCustomerName = getC2BCustomerName;
@@ -1101,6 +1410,14 @@ exports.getC2BTransactionId = getC2BTransactionId;
1101
1410
  exports.getCallbackValue = getCallbackValue;
1102
1411
  exports.getTimestamp = getTimestamp;
1103
1412
  exports.handleWebhook = handleWebhook;
1413
+ exports.initiateB2BExpressCheckout = initiateB2BExpressCheckout;
1414
+ exports.initiateB2CPayment = initiateB2CPayment;
1415
+ exports.isB2BCheckoutCallback = isB2BCheckoutCallback;
1416
+ exports.isB2BCheckoutCancelled = isB2BCheckoutCancelled;
1417
+ exports.isB2BCheckoutSuccess = isB2BCheckoutSuccess;
1418
+ exports.isB2CFailure = isB2CFailure;
1419
+ exports.isB2CResult = isB2CResult;
1420
+ exports.isB2CSuccess = isB2CSuccess;
1104
1421
  exports.isBuyGoodsPayment = isBuyGoodsPayment;
1105
1422
  exports.isC2BPayload = isC2BPayload;
1106
1423
  exports.isPaybillPayment = isPaybillPayment;