@nehorai/payments-il 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.
@@ -0,0 +1,734 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/providers/cardcom/index.ts
31
+ var cardcom_exports = {};
32
+ __export(cardcom_exports, {
33
+ CARDCOM_API_BASE: () => CARDCOM_API_BASE,
34
+ CARDCOM_CURRENCY_CODES: () => CARDCOM_CURRENCY_CODES,
35
+ CARDCOM_DEAL_RESPONSE_ACTIONS: () => CARDCOM_DEAL_RESPONSE_ACTIONS,
36
+ CARDCOM_ENDPOINTS: () => CARDCOM_ENDPOINTS,
37
+ CARDCOM_LANGUAGE_CODES: () => CARDCOM_LANGUAGE_CODES,
38
+ CARDCOM_RESPONSE_CODE_MAP: () => CARDCOM_RESPONSE_CODE_MAP,
39
+ CARDCOM_SUPPORTED_CURRENCIES: () => CARDCOM_SUPPORTED_CURRENCIES,
40
+ CARDCOM_WEBHOOK_EVENTS: () => CARDCOM_WEBHOOK_EVENTS,
41
+ CardcomOperation: () => CardcomOperation,
42
+ CardcomProvider: () => CardcomProvider,
43
+ CardcomTransactionType: () => CardcomTransactionType,
44
+ CardcomWebhookHandler: () => CardcomWebhookHandler,
45
+ getCardcomCallbackError: () => getCardcomCallbackError,
46
+ getCurrencyCode: () => getCurrencyCode,
47
+ isCardcomCallbackAuthorized: () => isCardcomCallbackAuthorized,
48
+ isCardcomCallbackSuccess: () => isCardcomCallbackSuccess,
49
+ mapCardcomDealResponseToStatus: () => mapCardcomDealResponseToStatus,
50
+ mapCardcomError: () => mapCardcomError,
51
+ parseCardcomCallbackUrl: () => parseCardcomCallbackUrl,
52
+ validateCardcomCallback: () => validateCardcomCallback
53
+ });
54
+ module.exports = __toCommonJS(cardcom_exports);
55
+
56
+ // src/providers/cardcom/cardcom-provider.ts
57
+ var crypto = __toESM(require("crypto"), 1);
58
+ var import_types = require("@nehorai/payments/types");
59
+
60
+ // src/providers/cardcom/cardcom-types.ts
61
+ var CARDCOM_API_BASE = "https://secure.cardcom.solutions";
62
+ var CARDCOM_ENDPOINTS = {
63
+ LOW_PROFILE_CREATE: "/api/v11/LowProfile/Create",
64
+ LOW_PROFILE_STATUS: "/Interface/BillGoldGetLowProfileIndicator.aspx",
65
+ DIRECT_CHARGE: "/api/v11/Transactions/Transaction",
66
+ REFUND: "/api/v11/Transactions/RefundByTransactionId"
67
+ };
68
+ var CARDCOM_SUPPORTED_CURRENCIES = ["ILS", "USD", "EUR", "GBP"];
69
+ var CardcomOperation = /* @__PURE__ */ ((CardcomOperation2) => {
70
+ CardcomOperation2[CardcomOperation2["BILL_ONLY"] = 1] = "BILL_ONLY";
71
+ CardcomOperation2[CardcomOperation2["BILL_AND_CREATE_TOKEN"] = 2] = "BILL_AND_CREATE_TOKEN";
72
+ CardcomOperation2[CardcomOperation2["CREATE_TOKEN_ONLY"] = 3] = "CREATE_TOKEN_ONLY";
73
+ CardcomOperation2[CardcomOperation2["SUSPEND_DEAL_ONLY"] = 4] = "SUSPEND_DEAL_ONLY";
74
+ return CardcomOperation2;
75
+ })(CardcomOperation || {});
76
+ var CardcomTransactionType = /* @__PURE__ */ ((CardcomTransactionType2) => {
77
+ CardcomTransactionType2[CardcomTransactionType2["REGULAR"] = 1] = "REGULAR";
78
+ CardcomTransactionType2[CardcomTransactionType2["CREDIT"] = 2] = "CREDIT";
79
+ CardcomTransactionType2[CardcomTransactionType2["INSTALLMENTS"] = 3] = "INSTALLMENTS";
80
+ return CardcomTransactionType2;
81
+ })(CardcomTransactionType || {});
82
+ var CARDCOM_WEBHOOK_EVENTS = [
83
+ "payment.completed",
84
+ "payment.declined",
85
+ "payment.authorized"
86
+ ];
87
+ var CARDCOM_DEAL_RESPONSE_ACTIONS = {
88
+ 0: "pending",
89
+ 1: "approved",
90
+ 2: "declined",
91
+ 3: "error"
92
+ };
93
+ var CARDCOM_RESPONSE_CODE_MAP = {
94
+ 0: "created",
95
+ 1: "failed",
96
+ 2: "failed",
97
+ 3: "failed",
98
+ 4: "failed",
99
+ 5: "failed",
100
+ 6: "failed",
101
+ 7: "failed",
102
+ 8: "failed",
103
+ 9: "failed",
104
+ 10: "failed"
105
+ };
106
+ function mapCardcomDealResponseToStatus(dealResponse) {
107
+ switch (dealResponse) {
108
+ case 0:
109
+ return "pending_authorization";
110
+ case 1:
111
+ return "captured";
112
+ case 2:
113
+ return "failed";
114
+ case 3:
115
+ return "failed";
116
+ default:
117
+ return "failed";
118
+ }
119
+ }
120
+ function mapCardcomError(responseCode) {
121
+ const errorMessages = {
122
+ 0: "Success",
123
+ 1: "General error",
124
+ 2: "Invalid API credentials",
125
+ 3: "Invalid terminal number",
126
+ 4: "Invalid operation type",
127
+ 5: "Invalid card details",
128
+ 6: "Card declined by issuer",
129
+ 7: "Insufficient funds",
130
+ 8: "Invalid amount",
131
+ 9: "Transaction not found",
132
+ 10: "Duplicate transaction",
133
+ 11: "Terminal not active",
134
+ 12: "CVV validation failed",
135
+ 13: "Card expired",
136
+ 14: "Invalid currency",
137
+ 15: "Operation not supported"
138
+ };
139
+ return errorMessages[responseCode] ?? `Error code ${responseCode}`;
140
+ }
141
+ var CARDCOM_CURRENCY_CODES = {
142
+ ILS: 1,
143
+ USD: 2,
144
+ EUR: 3,
145
+ GBP: 4
146
+ };
147
+ function getCurrencyCode(currency) {
148
+ return CARDCOM_CURRENCY_CODES[currency.toUpperCase()] ?? 1;
149
+ }
150
+ var CARDCOM_LANGUAGE_CODES = {
151
+ en: "en",
152
+ he: "he"
153
+ };
154
+
155
+ // src/providers/cardcom/cardcom-provider.ts
156
+ var CardcomProvider = class {
157
+ name = "cardcom";
158
+ supportedCurrencies = CARDCOM_SUPPORTED_CURRENCIES;
159
+ supportsRecurring = true;
160
+ supportsSplitPayments = false;
161
+ config;
162
+ constructor(config) {
163
+ if (!config.terminalNumber || !config.apiName || !config.apiPassword) {
164
+ throw new Error(
165
+ "CardcomProvider requires terminalNumber, apiName, and apiPassword in config"
166
+ );
167
+ }
168
+ this.config = config;
169
+ }
170
+ // ==========================================================================
171
+ // Payment Intent Operations
172
+ // ==========================================================================
173
+ async createPaymentIntent(params) {
174
+ try {
175
+ const amountMajor = params.amount.amountMinor / 100;
176
+ const operation = params.captureMethod === "manual" ? 4 /* SUSPEND_DEAL_ONLY */ : params.metadata?.savePaymentMethod ? 2 /* BILL_AND_CREATE_TOKEN */ : 1 /* BILL_ONLY */;
177
+ const request = {
178
+ TerminalNumber: this.config.terminalNumber,
179
+ ApiName: this.config.apiName,
180
+ ApiPassword: this.config.apiPassword,
181
+ Sum: amountMajor,
182
+ CoinID: getCurrencyCode(params.amount.currency),
183
+ Operation: operation,
184
+ Language: "en",
185
+ ReturnUrl: params.returnUrl,
186
+ ErrorUrl: params.returnUrl,
187
+ ProductName: params.description ?? "Payment",
188
+ InternalDealNumber: params.idempotencyKey,
189
+ SendEmail: false
190
+ };
191
+ if (params.metadata?.customerName) {
192
+ request.CustomerName = String(params.metadata.customerName);
193
+ }
194
+ if (params.metadata?.customerEmail) {
195
+ request.Email = String(params.metadata.customerEmail);
196
+ }
197
+ const response = await this.makeRequest(
198
+ CARDCOM_ENDPOINTS.LOW_PROFILE_CREATE,
199
+ request
200
+ );
201
+ if (response.ResponseCode !== 0 || !response.PaymentUrl) {
202
+ return {
203
+ success: false,
204
+ error: mapCardcomError(response.ResponseCode),
205
+ errorCode: String(response.ResponseCode)
206
+ };
207
+ }
208
+ return {
209
+ success: true,
210
+ providerIntentId: response.LowProfileCode,
211
+ redirectUrl: response.PaymentUrl,
212
+ status: "created"
213
+ };
214
+ } catch (error) {
215
+ return this.handleError(error);
216
+ }
217
+ }
218
+ async authorize(params) {
219
+ try {
220
+ const statusResponse = await this.getLowProfileStatus(
221
+ params.providerIntentId
222
+ );
223
+ if (!statusResponse.success || !statusResponse.data) {
224
+ return {
225
+ success: false,
226
+ error: statusResponse.error ?? "Failed to check payment status"
227
+ };
228
+ }
229
+ const status = statusResponse.data;
230
+ if (status.DealResponse === 1) {
231
+ return {
232
+ success: true,
233
+ authorizationCode: status.InternalDealNumber ?? params.providerIntentId,
234
+ status: "authorized",
235
+ captureDeadline: (0, import_types.calculateCaptureDeadline)(/* @__PURE__ */ new Date())
236
+ };
237
+ }
238
+ if (status.DealResponse === 2) {
239
+ return {
240
+ success: false,
241
+ error: "Payment declined",
242
+ status: "failed"
243
+ };
244
+ }
245
+ return {
246
+ success: false,
247
+ error: "Payment not yet completed",
248
+ status: "pending_authorization"
249
+ };
250
+ } catch (error) {
251
+ return this.handleError(error);
252
+ }
253
+ }
254
+ async capture(params) {
255
+ try {
256
+ const statusResponse = await this.getLowProfileStatus(
257
+ params.providerIntentId
258
+ );
259
+ if (!statusResponse.success || !statusResponse.data) {
260
+ return {
261
+ success: false,
262
+ error: statusResponse.error ?? "Failed to capture payment"
263
+ };
264
+ }
265
+ const status = statusResponse.data;
266
+ if (status.DealResponse === 1) {
267
+ return {
268
+ success: true,
269
+ providerTransactionId: status.InternalDealNumber ?? params.providerIntentId,
270
+ status: "captured",
271
+ capturedAmount: {
272
+ amountMinor: Math.round((status.Amount ?? 0) * 100),
273
+ currency: status.Currency ?? params.amount?.currency ?? "ILS"
274
+ }
275
+ };
276
+ }
277
+ return {
278
+ success: false,
279
+ error: "Payment not authorized for capture",
280
+ status: mapCardcomDealResponseToStatus(status.DealResponse ?? 3)
281
+ };
282
+ } catch (error) {
283
+ return this.handleError(error);
284
+ }
285
+ }
286
+ async void(_params) {
287
+ return {
288
+ success: false,
289
+ error: "Void operation not supported via API. Please use Cardcom merchant dashboard."
290
+ };
291
+ }
292
+ async refund(params) {
293
+ try {
294
+ const refundAmount = params.amount ? params.amount.amountMinor / 100 : void 0;
295
+ if (!refundAmount) {
296
+ return {
297
+ success: false,
298
+ error: "Refund amount is required"
299
+ };
300
+ }
301
+ const request = {
302
+ TerminalNumber: this.config.terminalNumber,
303
+ ApiName: this.config.apiName,
304
+ ApiPassword: this.config.apiPassword,
305
+ InternalDealNumber: params.providerTransactionId,
306
+ Amount: refundAmount,
307
+ CoinID: params.amount ? getCurrencyCode(params.amount.currency) : 1
308
+ };
309
+ const response = await this.makeRequest(
310
+ CARDCOM_ENDPOINTS.REFUND,
311
+ request
312
+ );
313
+ if (response.ResponseCode !== 0) {
314
+ return {
315
+ success: false,
316
+ error: mapCardcomError(response.ResponseCode)
317
+ };
318
+ }
319
+ return {
320
+ success: true,
321
+ providerRefundId: response.InternalDealNumber ?? params.providerTransactionId,
322
+ refundedAmount: {
323
+ amountMinor: Math.round((response.Amount ?? 0) * 100),
324
+ currency: params.amount?.currency ?? "ILS"
325
+ },
326
+ status: "succeeded"
327
+ };
328
+ } catch (error) {
329
+ return this.handleError(error);
330
+ }
331
+ }
332
+ // ==========================================================================
333
+ // Payment Method Tokenization
334
+ // ==========================================================================
335
+ async createSetupIntent(params) {
336
+ try {
337
+ const request = {
338
+ TerminalNumber: this.config.terminalNumber,
339
+ ApiName: this.config.apiName,
340
+ ApiPassword: this.config.apiPassword,
341
+ Sum: 0,
342
+ Operation: 3 /* CREATE_TOKEN_ONLY */,
343
+ Language: "en",
344
+ InternalDealNumber: `setup_${params.userId}_${Date.now()}`
345
+ };
346
+ const response = await this.makeRequest(
347
+ CARDCOM_ENDPOINTS.LOW_PROFILE_CREATE,
348
+ request
349
+ );
350
+ if (response.ResponseCode !== 0 || !response.PaymentUrl) {
351
+ return {
352
+ success: false,
353
+ error: mapCardcomError(response.ResponseCode)
354
+ };
355
+ }
356
+ return {
357
+ success: true,
358
+ setupIntentId: response.LowProfileCode,
359
+ clientSecret: response.PaymentUrl
360
+ };
361
+ } catch (error) {
362
+ return this.handleError(error);
363
+ }
364
+ }
365
+ async savePaymentMethod(params) {
366
+ try {
367
+ const lowProfileCode = params.setupData.lowProfileCode;
368
+ if (!lowProfileCode) {
369
+ return {
370
+ success: false,
371
+ error: "Low profile code is required"
372
+ };
373
+ }
374
+ const statusResponse = await this.getLowProfileStatus(lowProfileCode);
375
+ if (!statusResponse.success || !statusResponse.data) {
376
+ return {
377
+ success: false,
378
+ error: statusResponse.error ?? "Failed to retrieve payment method"
379
+ };
380
+ }
381
+ const status = statusResponse.data;
382
+ if (!status.Token) {
383
+ return {
384
+ success: false,
385
+ error: "No token created"
386
+ };
387
+ }
388
+ const [expMonth, expYear] = (status.CardExpiration ?? "/").split("/");
389
+ return {
390
+ success: true,
391
+ paymentMethodId: status.Token,
392
+ cardBrand: status.CardType ?? "unknown",
393
+ cardLast4: status.CardMask?.slice(-4),
394
+ cardExpMonth: expMonth?.padStart(2, "0"),
395
+ cardExpYear: expYear ? `20${expYear}` : void 0,
396
+ cardBin: status.CardBin
397
+ };
398
+ } catch (error) {
399
+ return this.handleError(error);
400
+ }
401
+ }
402
+ async deletePaymentMethod(_paymentMethodId) {
403
+ return {
404
+ success: true
405
+ };
406
+ }
407
+ // ==========================================================================
408
+ // Customer Management
409
+ // ==========================================================================
410
+ async createCustomer(params) {
411
+ return {
412
+ success: true,
413
+ customerId: params.userId
414
+ };
415
+ }
416
+ async getOrCreateCustomer(userId, email) {
417
+ return this.createCustomer({ userId, email });
418
+ }
419
+ // ==========================================================================
420
+ // Health & Status
421
+ // ==========================================================================
422
+ async getHealth() {
423
+ const start = Date.now();
424
+ try {
425
+ const request = {
426
+ TerminalNumber: this.config.terminalNumber,
427
+ ApiName: this.config.apiName,
428
+ ApiPassword: this.config.apiPassword,
429
+ Sum: 1,
430
+ Operation: 1 /* BILL_ONLY */,
431
+ InternalDealNumber: `health_check_${Date.now()}`
432
+ };
433
+ const response = await this.makeRequest(
434
+ CARDCOM_ENDPOINTS.LOW_PROFILE_CREATE,
435
+ request
436
+ );
437
+ const healthy = response.ResponseCode === 0 || response.ResponseCode === 1;
438
+ return {
439
+ provider: "cardcom",
440
+ healthy,
441
+ lastChecked: /* @__PURE__ */ new Date(),
442
+ avgLatencyMs: Date.now() - start,
443
+ circuitBreakerOpen: false
444
+ };
445
+ } catch {
446
+ return {
447
+ provider: "cardcom",
448
+ healthy: false,
449
+ lastChecked: /* @__PURE__ */ new Date(),
450
+ circuitBreakerOpen: false
451
+ };
452
+ }
453
+ }
454
+ validateWebhookSignature(payload, signature) {
455
+ if (!this.config.webhookSecret) {
456
+ return false;
457
+ }
458
+ try {
459
+ const expectedSignature = crypto.createHmac("sha256", this.config.webhookSecret).update(payload).digest("hex");
460
+ return crypto.timingSafeEqual(
461
+ Buffer.from(signature),
462
+ Buffer.from(expectedSignature)
463
+ );
464
+ } catch {
465
+ return false;
466
+ }
467
+ }
468
+ async getPaymentIntentStatus(providerIntentId) {
469
+ try {
470
+ const result = await this.getLowProfileStatus(providerIntentId);
471
+ if (!result.success || !result.data) {
472
+ return {
473
+ status: "unknown",
474
+ error: result.error
475
+ };
476
+ }
477
+ const status = mapCardcomDealResponseToStatus(
478
+ result.data.DealResponse ?? 0
479
+ );
480
+ return { status };
481
+ } catch (error) {
482
+ return {
483
+ status: "unknown",
484
+ error: error instanceof Error ? error.message : "Unknown error"
485
+ };
486
+ }
487
+ }
488
+ // ==========================================================================
489
+ // Helper Methods
490
+ // ==========================================================================
491
+ async makeRequest(endpoint, data) {
492
+ const url = `${CARDCOM_API_BASE}${endpoint}`;
493
+ const response = await fetch(url, {
494
+ method: "POST",
495
+ headers: {
496
+ "Content-Type": "application/json"
497
+ },
498
+ body: JSON.stringify(data)
499
+ });
500
+ if (!response.ok) {
501
+ throw new Error(`Cardcom API error: ${response.status} ${response.statusText}`);
502
+ }
503
+ return response.json();
504
+ }
505
+ async getLowProfileStatus(lowProfileCode) {
506
+ try {
507
+ const params = new URLSearchParams({
508
+ terminalnumber: this.config.terminalNumber,
509
+ lowprofilecode: lowProfileCode,
510
+ username: this.config.apiName
511
+ });
512
+ const url = `${CARDCOM_API_BASE}${CARDCOM_ENDPOINTS.LOW_PROFILE_STATUS}?${params}`;
513
+ const response = await fetch(url, {
514
+ method: "GET"
515
+ });
516
+ if (!response.ok) {
517
+ return {
518
+ success: false,
519
+ error: `Status check failed: ${response.status}`
520
+ };
521
+ }
522
+ const data = await response.json();
523
+ if (data.ResponseCode !== 0) {
524
+ return {
525
+ success: false,
526
+ error: mapCardcomError(data.ResponseCode)
527
+ };
528
+ }
529
+ return { success: true, data };
530
+ } catch (error) {
531
+ return {
532
+ success: false,
533
+ error: error instanceof Error ? error.message : "Status check failed"
534
+ };
535
+ }
536
+ }
537
+ handleError(error) {
538
+ const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
539
+ return {
540
+ success: false,
541
+ error: errorMessage
542
+ };
543
+ }
544
+ };
545
+
546
+ // src/providers/cardcom/cardcom-webhook-handler.ts
547
+ var CardcomWebhookHandler = class {
548
+ provider = "cardcom";
549
+ supportedEventTypes = CARDCOM_WEBHOOK_EVENTS;
550
+ parseEvent(rawPayload) {
551
+ try {
552
+ const params = rawPayload;
553
+ const responseCode = parseInt(params.ResponseCode ?? "1", 10);
554
+ const dealResponse = parseInt(params.DealResponse ?? "0", 10);
555
+ const lowProfileCode = params.LowProfileCode ?? "";
556
+ const internalDealNumber = params.InternalDealNumber ?? "";
557
+ if (!lowProfileCode && !internalDealNumber) {
558
+ return {
559
+ success: false,
560
+ error: "Missing LowProfileCode or InternalDealNumber in callback"
561
+ };
562
+ }
563
+ let eventType;
564
+ if (dealResponse === 1) {
565
+ eventType = "payment.completed";
566
+ } else if (dealResponse === 2) {
567
+ eventType = "payment.declined";
568
+ } else if (dealResponse === 0 && responseCode === 0) {
569
+ eventType = "payment.authorized";
570
+ } else {
571
+ eventType = "payment.declined";
572
+ }
573
+ const status = mapCardcomDealResponseToStatus(dealResponse);
574
+ const amountString = params.Amount ?? "0";
575
+ const amountMajor = parseFloat(amountString);
576
+ const amountMinor = Math.round(amountMajor * 100);
577
+ const parsed = {
578
+ provider: "cardcom",
579
+ eventId: `${lowProfileCode}_${internalDealNumber}_${Date.now()}`,
580
+ eventType,
581
+ providerTransactionId: internalDealNumber || lowProfileCode,
582
+ timestamp: /* @__PURE__ */ new Date(),
583
+ rawPayload,
584
+ newStatus: status,
585
+ amountMinor,
586
+ currency: params.Currency ?? "ILS"
587
+ };
588
+ if (dealResponse === 2 || responseCode !== 0) {
589
+ parsed.error = {
590
+ code: String(responseCode),
591
+ message: CARDCOM_DEAL_RESPONSE_ACTIONS[dealResponse] ?? "Payment failed"
592
+ };
593
+ }
594
+ return { success: true, event: parsed };
595
+ } catch (error) {
596
+ return {
597
+ success: false,
598
+ error: error instanceof Error ? error.message : "Parse error"
599
+ };
600
+ }
601
+ }
602
+ async processEvent(event) {
603
+ const action = this.getActionForEvent(event.eventType);
604
+ if (action === "ignored") {
605
+ return {
606
+ success: true,
607
+ action: "ignored_event_type"
608
+ };
609
+ }
610
+ return {
611
+ success: true,
612
+ transactionId: event.providerTransactionId,
613
+ action: "status_updated"
614
+ };
615
+ }
616
+ canHandle(eventType) {
617
+ return this.supportedEventTypes.includes(
618
+ eventType
619
+ );
620
+ }
621
+ async reconcile(_transactionId, _providerTransactionId) {
622
+ return {
623
+ reconciled: false,
624
+ finalStatus: "created",
625
+ source: "provider_query",
626
+ statusChanged: false
627
+ };
628
+ }
629
+ mapEventType(providerEventType) {
630
+ return providerEventType;
631
+ }
632
+ mapStatus(providerStatus) {
633
+ const dealResponse = parseInt(providerStatus, 10);
634
+ if (isNaN(dealResponse)) {
635
+ return null;
636
+ }
637
+ return mapCardcomDealResponseToStatus(dealResponse);
638
+ }
639
+ getActionForEvent(eventType) {
640
+ switch (eventType) {
641
+ case "payment.completed":
642
+ case "payment.declined":
643
+ case "payment.authorized":
644
+ return "status_update";
645
+ default:
646
+ return "ignored";
647
+ }
648
+ }
649
+ };
650
+ function validateCardcomCallback(params) {
651
+ const requiredFields = ["ResponseCode", "LowProfileCode"];
652
+ for (const field of requiredFields) {
653
+ if (!params[field]) {
654
+ return {
655
+ valid: false,
656
+ error: `Missing required field: ${field}`
657
+ };
658
+ }
659
+ }
660
+ const responseCode = parseInt(String(params.ResponseCode), 10);
661
+ if (isNaN(responseCode)) {
662
+ return {
663
+ valid: false,
664
+ error: "Invalid ResponseCode format"
665
+ };
666
+ }
667
+ return { valid: true };
668
+ }
669
+ function parseCardcomCallbackUrl(url) {
670
+ try {
671
+ const urlObj = new URL(url);
672
+ const params = {};
673
+ params.ResponseCode = urlObj.searchParams.get("ResponseCode") ?? void 0;
674
+ params.LowProfileCode = urlObj.searchParams.get("LowProfileCode") ?? void 0;
675
+ params.DealResponse = urlObj.searchParams.get("DealResponse") ?? void 0;
676
+ params.OperationResponse = urlObj.searchParams.get("OperationResponse") ?? void 0;
677
+ params.InternalDealNumber = urlObj.searchParams.get("InternalDealNumber") ?? void 0;
678
+ params.Amount = urlObj.searchParams.get("Amount") ?? void 0;
679
+ params.Currency = urlObj.searchParams.get("Currency") ?? void 0;
680
+ params.CardMask = urlObj.searchParams.get("CardMask") ?? void 0;
681
+ params.Token = urlObj.searchParams.get("Token") ?? void 0;
682
+ return params;
683
+ } catch {
684
+ return {};
685
+ }
686
+ }
687
+ function isCardcomCallbackSuccess(params) {
688
+ const responseCode = parseInt(params.ResponseCode ?? "1", 10);
689
+ const dealResponse = parseInt(params.DealResponse ?? "0", 10);
690
+ return responseCode === 0 && dealResponse === 1;
691
+ }
692
+ function isCardcomCallbackAuthorized(params) {
693
+ const responseCode = parseInt(params.ResponseCode ?? "1", 10);
694
+ const dealResponse = parseInt(params.DealResponse ?? "0", 10);
695
+ return responseCode === 0 && (dealResponse === 0 || dealResponse === 1);
696
+ }
697
+ function getCardcomCallbackError(params) {
698
+ const responseCode = parseInt(params.ResponseCode ?? "1", 10);
699
+ const dealResponse = parseInt(params.DealResponse ?? "0", 10);
700
+ if (responseCode === 0 && dealResponse === 1) {
701
+ return null;
702
+ }
703
+ if (dealResponse === 2) {
704
+ return "Payment declined by card issuer";
705
+ }
706
+ if (responseCode !== 0) {
707
+ return `Payment failed with code ${responseCode}`;
708
+ }
709
+ return "Payment processing error";
710
+ }
711
+ // Annotate the CommonJS export names for ESM import in node:
712
+ 0 && (module.exports = {
713
+ CARDCOM_API_BASE,
714
+ CARDCOM_CURRENCY_CODES,
715
+ CARDCOM_DEAL_RESPONSE_ACTIONS,
716
+ CARDCOM_ENDPOINTS,
717
+ CARDCOM_LANGUAGE_CODES,
718
+ CARDCOM_RESPONSE_CODE_MAP,
719
+ CARDCOM_SUPPORTED_CURRENCIES,
720
+ CARDCOM_WEBHOOK_EVENTS,
721
+ CardcomOperation,
722
+ CardcomProvider,
723
+ CardcomTransactionType,
724
+ CardcomWebhookHandler,
725
+ getCardcomCallbackError,
726
+ getCurrencyCode,
727
+ isCardcomCallbackAuthorized,
728
+ isCardcomCallbackSuccess,
729
+ mapCardcomDealResponseToStatus,
730
+ mapCardcomError,
731
+ parseCardcomCallbackUrl,
732
+ validateCardcomCallback
733
+ });
734
+ //# sourceMappingURL=index.cjs.map