globalpayments-api 3.12.0 → 3.13.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.
Files changed (26) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/README.md +0 -18
  3. package/lib/src/Terminals/Builders/TerminalAuthBuilder.d.ts +2 -0
  4. package/lib/src/Terminals/Builders/TerminalAuthBuilder.js +5 -1
  5. package/lib/src/Terminals/Builders/TerminalAuthBuilder.js.map +1 -1
  6. package/lib/src/Terminals/Builders/TerminalBuilder.d.ts +0 -1
  7. package/lib/src/Terminals/Builders/TerminalBuilder.js +0 -1
  8. package/lib/src/Terminals/Builders/TerminalBuilder.js.map +1 -1
  9. package/lib/src/Terminals/Builders/TerminalManageBuilder.d.ts +5 -0
  10. package/lib/src/Terminals/Builders/TerminalManageBuilder.js +14 -0
  11. package/lib/src/Terminals/Builders/TerminalManageBuilder.js.map +1 -1
  12. package/lib/src/Terminals/TerminalResponse.d.ts +4 -0
  13. package/lib/src/Terminals/TerminalResponse.js +4 -0
  14. package/lib/src/Terminals/TerminalResponse.js.map +1 -1
  15. package/lib/src/Terminals/UPA/Reponses/TransactionResponse.d.ts +4 -1
  16. package/lib/src/Terminals/UPA/Reponses/TransactionResponse.js +15 -1
  17. package/lib/src/Terminals/UPA/Reponses/TransactionResponse.js.map +1 -1
  18. package/lib/src/Terminals/UPA/UpaController.js +11 -4
  19. package/lib/src/Terminals/UPA/UpaController.js.map +1 -1
  20. package/lib/test/Integration/Gateways/GpApiConnector/GpApiMMAAccount.test.js +29 -1
  21. package/lib/test/Integration/Gateways/GpApiConnector/GpApiMMAAccount.test.js.map +1 -1
  22. package/lib/test/Unit/Terminals/UPA/UpaAdmin.test.js +2233 -388
  23. package/lib/test/Unit/Terminals/UPA/UpaAdmin.test.js.map +1 -1
  24. package/lib/test/Unit/Terminals/UPA/UpaCredit.test.js +504 -1
  25. package/lib/test/Unit/Terminals/UPA/UpaCredit.test.js.map +1 -1
  26. package/package.json +1 -1
@@ -11,6 +11,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
11
11
  */
12
12
  const src_1 = require("../../../../src");
13
13
  const UpaHelpertest_1 = require("./UpaHelpertest");
14
+ const AcquisitionType_1 = require("../../../../src/Entities/Enums/AcquisitionType");
14
15
  jest.setTimeout(240000);
15
16
  function sleep(delayMs) {
16
17
  return new Promise((resolve) => setTimeout(resolve, delayMs));
@@ -429,6 +430,302 @@ afterEach(async () => {
429
430
  console.warn(`updateLodginDetail() ERR010 scenario not reproduced: device accepted the malformed amount with status="${response?.status}" code="${response?.deviceResponseCode}". Per UPA doc an amount missing the leading zero SHOULD be rejected — the current firmware may be tolerating the drift.`);
430
431
  });
431
432
  });
433
+ (0, UpaHelpertest_1.describeUpaLive)("UPA void test case void support and response parsing ", () => {
434
+ let device;
435
+ beforeEach(() => {
436
+ device = (0, UpaHelpertest_1.createTestDevice)();
437
+ });
438
+ test("void support ", async () => {
439
+ const saleResponse = (await device
440
+ .sale(75.0)
441
+ .withEcrId(12)
442
+ .withClerkId(789)
443
+ .execute());
444
+ expect(saleResponse.status).toBe("Success");
445
+ const voidResponse = (await device
446
+ .void()
447
+ .withEcrId(12)
448
+ .withTerminalRefNumber(saleResponse.terminalRefNumber)
449
+ .withTransactionId(saleResponse.transactionId)
450
+ .withAmount(saleResponse.transactionAmount)
451
+ .execute());
452
+ expect(voidResponse).not.toBeNull();
453
+ expect(voidResponse.status).toBe("Success");
454
+ });
455
+ });
456
+ (0, UpaHelpertest_1.describeUpaLive)("UPA test for capture/Authcompletion ", () => {
457
+ let device;
458
+ beforeEach(() => {
459
+ device = (0, UpaHelpertest_1.createTestDevice)();
460
+ });
461
+ /**
462
+ * Test 1: Basic Capture
463
+ * Per UPA Spec §12.4.16 - AuthCompletion with mandatory fields
464
+ * Mandatory: referenceNumber, amount
465
+ */
466
+ test("UPA Capture - Basic (Auth → Capture)", async () => {
467
+ const authAmount = 10.0;
468
+ const captureAmount = 10.0;
469
+ const ecrId = "1";
470
+ // Step 1: Authorize to get transaction ID
471
+ const authResponse = await device
472
+ .authorize(authAmount)
473
+ .withEcrId(ecrId)
474
+ .execute();
475
+ expect(authResponse).toBeDefined();
476
+ expect(authResponse.status).toBe("Success");
477
+ expect(authResponse.transactionId).toBeTruthy();
478
+ await settleDevice();
479
+ // Step 2: Capture the authorized amount
480
+ const captureResponse = (await device
481
+ .capture(captureAmount)
482
+ .withEcrId(ecrId)
483
+ .withTransactionId(authResponse.transactionId)
484
+ .execute());
485
+ expect(captureResponse).toBeDefined();
486
+ expect(captureResponse.status).toBe("Success");
487
+ expect(captureResponse.deviceResponseCode).toBe("00");
488
+ expect(captureResponse.cardType).toBeDefined();
489
+ expect(captureResponse.transactionId).toBeTruthy();
490
+ // Note: transactionAmount may include device surcharges
491
+ expect(captureResponse.transactionAmount).toBeGreaterThanOrEqual(captureAmount);
492
+ console.log(`[Capture Basic] TransId: ${captureResponse.transactionId}, Amount: ${captureResponse.transactionAmount}`);
493
+ });
494
+ /**
495
+ * Test 2: Capture with Tax and Tip
496
+ * Per UPA Spec §12.4.16 - Optional fields: taxAmount, tipAmount
497
+ * Verifies proper amount aggregation
498
+ */
499
+ test("UPA Capture - with Tax and Tip", async () => {
500
+ const authAmount = 50.0;
501
+ const taxAmount = 5.0;
502
+ const tipAmount = 10.0;
503
+ const ecrId = "1";
504
+ // Step 1: Authorize
505
+ const authResponse = await device
506
+ .authorize(authAmount)
507
+ .withEcrId(ecrId)
508
+ .execute();
509
+ expect(authResponse).toBeDefined();
510
+ expect(authResponse.status).toBe("Success");
511
+ expect(authResponse.transactionId).toBeTruthy();
512
+ await settleDevice();
513
+ // Step 2: Capture with tax and tip
514
+ const captureResponse = (await device
515
+ .capture(authAmount)
516
+ .withEcrId(ecrId)
517
+ .withTransactionId(authResponse.transactionId)
518
+ .withTaxAmount(taxAmount)
519
+ .withGratuity(tipAmount)
520
+ .execute());
521
+ expect(captureResponse).toBeDefined();
522
+ expect(captureResponse.status).toBe("Success");
523
+ expect(captureResponse.deviceResponseCode).toBe("00");
524
+ // Verify amounts
525
+ // Note: Device may or may not aggregate tax and tip into total amount
526
+ // At minimum, should have at least the base authorized amount
527
+ expect(captureResponse.transactionAmount).toBeGreaterThanOrEqual(authAmount);
528
+ // Log actual values received for debugging
529
+ console.log(`[Capture Tax+Tip] Amount: ${captureResponse.transactionAmount}, Tax: ${captureResponse.taxAmount}, Tip: ${captureResponse.tipAmount}`);
530
+ // Verify tax and tip if populated (may be undefined depending on device response format)
531
+ if (captureResponse.taxAmount !== undefined) {
532
+ expect(captureResponse.taxAmount).toBeCloseTo(taxAmount, 2);
533
+ }
534
+ if (captureResponse.tipAmount !== undefined) {
535
+ expect(captureResponse.tipAmount).toBeCloseTo(tipAmount, 2);
536
+ }
537
+ });
538
+ /**
539
+ * Test 3: Capture with Tax Indicator (Tax Exempt)
540
+ * Per UPA Spec §12.4.16 - taxIndicator: 0 or 1
541
+ * 0 = tax applicable, 1 = tax exempt
542
+ */
543
+ test("UPA Capture - with Tax Indicator (Tax Exempt)", async () => {
544
+ const authAmount = 30.0;
545
+ const ecrId = "1";
546
+ const taxIndicator = 1; // 1 = tax exempt
547
+ // Step 1: Authorize
548
+ const authResponse = await device
549
+ .authorize(authAmount)
550
+ .withEcrId(ecrId)
551
+ .execute();
552
+ expect(authResponse).toBeDefined();
553
+ expect(authResponse.status).toBe("Success");
554
+ await settleDevice();
555
+ // Step 2: Capture with tax exempt indicator
556
+ const captureResponse = (await device
557
+ .capture(authAmount)
558
+ .withEcrId(ecrId)
559
+ .withTransactionId(authResponse.transactionId)
560
+ .withTaxIndicator(taxIndicator)
561
+ .execute());
562
+ expect(captureResponse).toBeDefined();
563
+ expect(captureResponse.status).toBe("Success");
564
+ // Note: Device may add surcharges, so check for >= base amount
565
+ expect(captureResponse.transactionAmount).toBeGreaterThanOrEqual(authAmount);
566
+ console.log(`[Capture TaxExempt] Amount: ${captureResponse.transactionAmount}, TaxIndicator: ${taxIndicator}`);
567
+ });
568
+ /**
569
+ * Test 4: Capture with Invoice Number
570
+ * Per UPA Spec §12.4.16 - invoiceNbr: AN(1-16)
571
+ */
572
+ test("UPA Capture - with Invoice Number", async () => {
573
+ const authAmount = 25.0;
574
+ const ecrId = "1";
575
+ const invoiceNum = "INV-" + Date.now().toString().slice(-8);
576
+ // Step 1: Authorize
577
+ const authResponse = await device
578
+ .authorize(authAmount)
579
+ .withEcrId(ecrId)
580
+ .execute();
581
+ expect(authResponse).toBeDefined();
582
+ expect(authResponse.status).toBe("Success");
583
+ await settleDevice();
584
+ // Step 2: Capture with invoice number
585
+ const captureResponse = (await device
586
+ .capture(authAmount)
587
+ .withEcrId(ecrId)
588
+ .withTransactionId(authResponse.transactionId)
589
+ .withInvoiceNumber(invoiceNum)
590
+ .execute());
591
+ expect(captureResponse).toBeDefined();
592
+ expect(captureResponse.status).toBe("Success");
593
+ // Invoice number may not be returned in response - if it is, verify it matches
594
+ if (captureResponse.invoiceNumber !== undefined &&
595
+ captureResponse.invoiceNumber !== "") {
596
+ expect(captureResponse.invoiceNumber).toBe(invoiceNum);
597
+ }
598
+ // Amount check (with device surcharges allowance)
599
+ expect(captureResponse.transactionAmount).toBeGreaterThanOrEqual(authAmount);
600
+ console.log(`[Capture Invoice] Invoice: ${captureResponse.invoiceNumber}, Amount: ${captureResponse.transactionAmount}`);
601
+ });
602
+ /**
603
+ * Test 5: Capture with Processing CPC (Commercial Card Processing)
604
+ * Per UPA Spec §12.4.16 - processCPC: 0 or 1
605
+ * 0 = No, 1 = Yes
606
+ */
607
+ test("UPA Capture - with Processing CPC", async () => {
608
+ const authAmount = 100.0;
609
+ const ecrId = "1";
610
+ // Step 1: Authorize
611
+ const authResponse = await device
612
+ .authorize(authAmount)
613
+ .withEcrId(ecrId)
614
+ .execute();
615
+ expect(authResponse).toBeDefined();
616
+ expect(authResponse.status).toBe("Success");
617
+ await settleDevice();
618
+ // Step 2: Capture with CPC processing
619
+ const captureResponse = (await device
620
+ .capture(authAmount)
621
+ .withEcrId(ecrId)
622
+ .withTransactionId(authResponse.transactionId)
623
+ .withProcessCPC(true)
624
+ .execute());
625
+ expect(captureResponse).toBeDefined();
626
+ expect(captureResponse.status).toBe("Success");
627
+ // Device may add surcharges, so check for >= base amount
628
+ expect(captureResponse.transactionAmount).toBeGreaterThanOrEqual(authAmount);
629
+ console.log(`[Capture CPC] Amount: ${captureResponse.transactionAmount}, ProcessCPC: true`);
630
+ });
631
+ /**
632
+ * Test 6: Capture with All Fields
633
+ * Per UPA Spec §12.4.16 - Comprehensive test with all optional fields
634
+ * Fields: amount, preAuthAmount, taxAmount, tipAmount, taxIndicator, processCPC
635
+ */
636
+ test("UPA Capture - with All Fields", async () => {
637
+ const authAmount = 75.0;
638
+ const taxAmount = 7.5;
639
+ const tipAmount = 15.0;
640
+ const ecrId = "1";
641
+ const invoiceNum = "FULL-" + Date.now().toString().slice(-6);
642
+ const taxIndicator = 0; // 0 = tax applicable
643
+ // Step 1: Authorize
644
+ const authResponse = await device
645
+ .authorize(authAmount)
646
+ .withEcrId(ecrId)
647
+ .execute();
648
+ expect(authResponse).toBeDefined();
649
+ expect(authResponse.status).toBe("Success");
650
+ await settleDevice();
651
+ // Step 2: Capture with all fields
652
+ const captureResponse = (await device
653
+ .capture(authAmount)
654
+ .withEcrId(ecrId)
655
+ .withTransactionId(authResponse.transactionId)
656
+ .withTaxAmount(taxAmount)
657
+ .withGratuity(tipAmount)
658
+ .withTaxIndicator(taxIndicator)
659
+ .withInvoiceNumber(invoiceNum)
660
+ .withProcessCPC(true)
661
+ .execute());
662
+ expect(captureResponse).toBeDefined();
663
+ expect(captureResponse.status).toBe("Success");
664
+ expect(captureResponse.deviceResponseCode).toBe("00");
665
+ // Verify all fields
666
+ expect(captureResponse.transactionId).toBeTruthy();
667
+ // Device may not aggregate all tax/tip components into total - at minimum check base amount
668
+ expect(captureResponse.transactionAmount).toBeGreaterThanOrEqual(authAmount);
669
+ // Tax and tip may be undefined or may be populated
670
+ if (captureResponse.taxAmount !== undefined &&
671
+ captureResponse.taxAmount > 0) {
672
+ expect(captureResponse.taxAmount).toBeGreaterThanOrEqual(0);
673
+ }
674
+ if (captureResponse.tipAmount !== undefined &&
675
+ captureResponse.tipAmount > 0) {
676
+ expect(captureResponse.tipAmount).toBeGreaterThanOrEqual(0);
677
+ }
678
+ expect(captureResponse.cardType).toBeDefined();
679
+ expect(captureResponse.maskedCardNumber).toBeDefined();
680
+ console.log(`[Capture AllFields] Amount: ${captureResponse.transactionAmount}, Tax: ${captureResponse.taxAmount}, Tip: ${captureResponse.tipAmount}, Invoice: ${captureResponse.invoiceNumber}, ClerkId: ${captureResponse.clerkId}`);
681
+ });
682
+ /**
683
+ * Test 7: Capture Response Field Parsing
684
+ * Per UPA Spec §12.4.16.5 - Validates all output parameters
685
+ * Verifies proper response parsing from device
686
+ */
687
+ test("UPA Capture - Response Field Parsing", async () => {
688
+ const authAmount = 40.0;
689
+ const ecrId = "1";
690
+ // Step 1: Authorize
691
+ const authResponse = await device
692
+ .authorize(authAmount)
693
+ .withEcrId(ecrId)
694
+ .execute();
695
+ expect(authResponse).toBeDefined();
696
+ expect(authResponse.status).toBe("Success");
697
+ await settleDevice();
698
+ // Step 2: Capture to validate response parsing
699
+ const captureResponse = (await device
700
+ .capture(authAmount)
701
+ .withEcrId(ecrId)
702
+ .withTransactionId(authResponse.transactionId)
703
+ .execute());
704
+ // Core transaction identifiers (per §12.4.16.5)
705
+ expect(captureResponse.transactionId).toBeTruthy(); // responseId: N16
706
+ expect(captureResponse.terminalRefNumber).toBeTruthy(); // tranNo: N4
707
+ expect(captureResponse.approvalCode).toBeTruthy(); // approvalCode: AN6
708
+ // Response codes (per §12.4.16.5)
709
+ expect(typeof captureResponse.responseCode).toBe("string");
710
+ expect(typeof captureResponse.responseText).toBe("string");
711
+ expect(typeof captureResponse.deviceResponseCode).toBe("string");
712
+ expect(typeof captureResponse.deviceResponseText).toBe("string");
713
+ // Card information (per §12.4.16.5)
714
+ expect(typeof captureResponse.cardType).toBe("string");
715
+ expect(typeof captureResponse.maskedCardNumber).toBe("string");
716
+ expect(captureResponse.maskedCardNumber).toMatch(/^\d{0,25}$/);
717
+ // Status validation
718
+ expect(captureResponse.status).toBe("Success");
719
+ expect(captureResponse.deviceResponseCode).toBe("00"); // "00" = Success
720
+ // Amount validation
721
+ expect(captureResponse.transactionAmount).toBeCloseTo(authAmount, 2);
722
+ expect(typeof captureResponse.transactionAmount).toBe("number");
723
+ // Gateway response info (per §12.4.16.5)
724
+ expect(typeof captureResponse.gatewayResponseCode).toBe("string");
725
+ expect(typeof captureResponse.gatewayResponseMessage).toBe("string");
726
+ console.log(`[Capture ResponseParsing] TransId: ${captureResponse.transactionId}, RefNum: ${captureResponse.terminalRefNumber}, ApprovalCode: ${captureResponse.approvalCode}, CardType: ${captureResponse.cardType}`);
727
+ });
728
+ });
432
729
  // ===========================================================================
433
730
  // COMPREHENSIVE INTEGRATED TEST SCENARIOS FROM SPEC
434
731
  // ===========================================================================
@@ -530,7 +827,6 @@ afterEach(async () => {
530
827
  .withPrescriptionAmount(25.5)
531
828
  .withClinicAmount(35.75)
532
829
  .withDentalAmount(40.25);
533
- //
534
830
  const request = controller
535
831
  .buildProcessTransaction(builder)
536
832
  .getJsonRequest();
@@ -544,6 +840,7 @@ afterEach(async () => {
544
840
  expect(request.data.data.transaction.dentalAmount).toBe("40.25");
545
841
  });
546
842
  });
843
+ // ===========================================================================
547
844
  // sale() with enhanced field support
548
845
  // ===========================================================================
549
846
  (0, UpaHelpertest_1.describeUpaLive)("UPA Credit – sale() with enhanced fields", () => {
@@ -615,6 +912,212 @@ afterEach(async () => {
615
912
  });
616
913
  });
617
914
  // ===========================================================================
915
+ // JIRA Story Requirements – Field Validation
916
+ // ===========================================================================
917
+ describe("JIRA Story: UPA Transaction Processing – Field Validation", () => {
918
+ let device;
919
+ beforeEach(() => {
920
+ device = (0, UpaHelpertest_1.createTestDevice)();
921
+ });
922
+ /**
923
+ * Requirement: clerkId
924
+ * Status: withClerkId() method should be available on builder
925
+ */
926
+ test("[Requirement:clerkId] Builder has withClerkId method", async () => {
927
+ const builder = device.sale(10.0);
928
+ expect(builder).toHaveProperty("withClerkId");
929
+ expect(typeof builder.withClerkId).toBe("function");
930
+ // Should be chainable
931
+ const chained = builder.withClerkId(123);
932
+ const result = await chained.withEcrId("13").execute();
933
+ expect(result.status).toBe("Success");
934
+ expect(chained).toBeDefined();
935
+ expect(chained).toEqual(builder); // Returns self for chaining
936
+ });
937
+ /**
938
+ * Requirement: cardBrandTransId
939
+ * Status: withCardBrandTransId() method should exist and work
940
+ */
941
+ test("[Requirement:cardBrandTransId] Builder has withCardBrandTransId method", async () => {
942
+ const builder = device.sale(10.0).withEcrId("13");
943
+ const transId = "ABC123XYZ";
944
+ expect(builder).toHaveProperty("withCardBrandTransId");
945
+ expect(typeof builder.withCardBrandTransId).toBe("function");
946
+ // Should be chainable and store value
947
+ const chained = builder.withCardBrandTransId(transId);
948
+ const response = await chained.execute();
949
+ expect(response.status).toBe("Success");
950
+ expect(chained).toBeDefined();
951
+ expect(chained).toEqual(builder);
952
+ expect(builder.cardBrandTransId).toBe(transId);
953
+ });
954
+ /**
955
+ * Requirement: cardOnFileIndicator
956
+ * Status: Should support CardHolder ('C'), Merchant ('M')
957
+ * Note: R (Recurring) and I (Installment) may require additional enum values
958
+ */
959
+ test("[Requirement:cardOnFileIndicator] Builder supports CardHolder and Merchant indicators", async () => {
960
+ const builderCH = device
961
+ .sale(10.0)
962
+ .withCardOnFileIndicator(src_1.StoredCredentialInitiator.CardHolder);
963
+ const builderM = device
964
+ .sale(10.0)
965
+ .withCardOnFileIndicator(src_1.StoredCredentialInitiator.Merchant);
966
+ expect(builderCH.cardOnFileIndicator).toBe(src_1.StoredCredentialInitiator.CardHolder);
967
+ expect(builderM.cardOnFileIndicator).toBe(src_1.StoredCredentialInitiator.Merchant);
968
+ const responseCH = await builderCH.withEcrId("13").execute();
969
+ const responseM = await builderM.withEcrId("13").execute();
970
+ expect(responseCH.status).toBe("Success");
971
+ expect(responseM.status).toBe("Success");
972
+ });
973
+ /**
974
+ * Requirement: preAuthAmount
975
+ * Status: withPreAuthAmount() should exist and use proper formatting
976
+ */
977
+ test("[Requirement:preAuthAmount] Builder has withPreAuthAmount with proper formatting", async () => {
978
+ const builder = device.authorize(15.0);
979
+ const preAuthAmt = 25.99;
980
+ expect(builder).toHaveProperty("withPreAuthAmount");
981
+ expect(typeof builder.withPreAuthAmount).toBe("function");
982
+ builder.withPreAuthAmount(preAuthAmt);
983
+ expect(builder.preAuthAmount).toBe(preAuthAmt);
984
+ const response = await builder.withEcrId("13").execute();
985
+ expect(response.status).toBe("Success");
986
+ });
987
+ /**
988
+ * Requirement: Processing Indicators
989
+ * Status: Builder should support quickChip, checkLuhn, securityCode
990
+ */
991
+ test("[Requirement:processingIndicators] Builder supports processing indicator flags", async () => {
992
+ const builder = device.sale(10.0);
993
+ // These should be properties on the builder
994
+ expect(builder).toHaveProperty("isQuickChip");
995
+ expect(builder).toHaveProperty("hasCheckLuhn");
996
+ expect(builder).toHaveProperty("hasSecurityCode");
997
+ const response = await builder.withEcrId("13").execute();
998
+ expect(response.status).toBe("Success");
999
+ });
1000
+ });
1001
+ // ===========================================================================
1002
+ // JIRA Story Requirements – Method Chaining
1003
+ // ===========================================================================
1004
+ describe("JIRA Story: UPA Transaction Processing – Method Chaining", () => {
1005
+ let device;
1006
+ beforeEach(() => {
1007
+ device = (0, UpaHelpertest_1.createTestDevice)();
1008
+ });
1009
+ /**
1010
+ * All required methods should be chainable
1011
+ */
1012
+ test("[MethodChaining] All required methods are chainable", () => {
1013
+ const result = device
1014
+ .sale(25.0)
1015
+ .withClerkId(101)
1016
+ .withCardOnFileIndicator(src_1.StoredCredentialInitiator.CardHolder)
1017
+ .withCardBrandTransId("TransID123")
1018
+ .withLineItemLeft("Item Description")
1019
+ .withLineItemRight("$25.00")
1020
+ .withLanguage("en")
1021
+ .withMerchantDecision("Approve")
1022
+ .withAcquisitionTypes([AcquisitionType_1.AcquisitionType.Contact])
1023
+ .withPreAuthAmount(50.0);
1024
+ // Verify all values are set
1025
+ expect(result.amount).toBe(25.0);
1026
+ expect(result.clerkId).toBe(101);
1027
+ expect(result.cardOnFileIndicator).toBe(src_1.StoredCredentialInitiator.CardHolder);
1028
+ expect(result.cardBrandTransId).toBe("TransID123");
1029
+ expect(result.lineItemLeft).toBe("Item Description");
1030
+ expect(result.lineItemRight).toBe("$25.00");
1031
+ expect(result.language).toBe("en");
1032
+ expect(result.merchantDecision).toBe("Approve");
1033
+ expect(result.acquisitionTypes).toEqual([AcquisitionType_1.AcquisitionType.Contact]);
1034
+ expect(result.preAuthAmount).toBe(50.0);
1035
+ });
1036
+ });
1037
+ // ===========================================================================
1038
+ // JIRA Story Requirements – Comprehensive Integration Test
1039
+ // ===========================================================================
1040
+ describe("JIRA Story: UPA Transaction Processing – Comprehensive Integration", () => {
1041
+ let device;
1042
+ beforeEach(() => {
1043
+ device = (0, UpaHelpertest_1.createTestDevice)();
1044
+ });
1045
+ /**
1046
+ * Complete transaction with all fields
1047
+ */
1048
+ test("[Integration:Complete] Sale with all JIRA story requirements", async () => {
1049
+ // Build complete sale transaction matching JIRA requirements
1050
+ const builder = device
1051
+ .sale(99.99)
1052
+ .withClerkId(42)
1053
+ .withCardOnFileIndicator(src_1.StoredCredentialInitiator.CardHolder)
1054
+ .withCardBrandTransId("BrandTxnId-2026-001")
1055
+ .withPreAuthAmount(150.0)
1056
+ .withInvoiceNumber("INV-2026-0001")
1057
+ .withRequestMultiUseToken(true);
1058
+ // Verify all properties are accessible (without execution)
1059
+ const builderAsAny = builder;
1060
+ expect(builderAsAny.amount).toBe(99.99);
1061
+ expect(builderAsAny.clerkId).toBe(42);
1062
+ expect(builderAsAny.cardOnFileIndicator).toBe(src_1.StoredCredentialInitiator.CardHolder);
1063
+ expect(builderAsAny.cardBrandTransId).toBe("BrandTxnId-2026-001");
1064
+ expect(builderAsAny.preAuthAmount).toBe(150.0);
1065
+ expect(builderAsAny.invoiceNumber).toBe("INV-2026-0001");
1066
+ expect(builderAsAny.requestMultiUseToken).toBe(true);
1067
+ const response = await builder.withEcrId("13").execute();
1068
+ expect(response.status).toBe("Success");
1069
+ });
1070
+ /**
1071
+ * Refund with cardOnFileIndicator - Merchant initiated
1072
+ *
1073
+ * NOTE: Refund-by-reference with GP-API has a limitation:
1074
+ * - UPA spec requires referenceNumber as AN(4-16)
1075
+ * - Device reference numbers are 12 digits (valid for UPA)
1076
+ * - But GP-API's validation layer expects GatewayTxnId (29 chars)
1077
+ * - This creates a constraint where refund-by-reference through GP-API fails
1078
+ *
1079
+ * Solution: Use refund without reference (card-on-file without transaction ID)
1080
+ * This requires either:
1081
+ * 1. CardData for manual refund
1082
+ * 2. Token from previous tokenized transaction
1083
+ * 3. Or wait for GP-API to support device reference numbers
1084
+ */
1085
+ test("[Integration:Refund] Refund with Merchant cardOnFileIndicator", async () => {
1086
+ // For now, test that refund builder supports cardOnFileIndicator properly
1087
+ // Full refund-by-reference will work once GP-API layer is fixed
1088
+ const refundBuilder = device
1089
+ .refund(50.0)
1090
+ .withClerkId(101)
1091
+ .withCardOnFileIndicator(src_1.StoredCredentialInitiator.Merchant)
1092
+ .withEcrId("13");
1093
+ const builderAsAny = refundBuilder;
1094
+ expect(builderAsAny.amount).toBe(50.0);
1095
+ expect(builderAsAny.clerkId).toBe(101);
1096
+ expect(builderAsAny.cardOnFileIndicator).toBe(src_1.StoredCredentialInitiator.Merchant);
1097
+ const response = await refundBuilder.execute();
1098
+ expect(response.status).toBe("Success");
1099
+ // Note: Actual refund execution requires CardData or reference that GP-API accepts
1100
+ // This test verifies the builder supports the JIRA requirements
1101
+ });
1102
+ /**
1103
+ * Pre-Authorization with all fields
1104
+ */
1105
+ test("[Integration:PreAuth] Pre-Auth with preAuthAmount and processing indicators", async () => {
1106
+ const builder = device
1107
+ .authorize(200.0)
1108
+ .withClerkId(55)
1109
+ .withCardBrandTransId("PreAuthBrandId")
1110
+ .withPreAuthAmount(250.0);
1111
+ const builderAsAny = builder;
1112
+ expect(builderAsAny.amount).toBe(200.0);
1113
+ expect(builderAsAny.clerkId).toBe(55);
1114
+ expect(builderAsAny.cardBrandTransId).toBe("PreAuthBrandId");
1115
+ expect(builderAsAny.preAuthAmount).toBe(250.0);
1116
+ const response = await builder.withEcrId("13").execute();
1117
+ expect(response.status).toBe("Success");
1118
+ });
1119
+ });
1120
+ // ===========================================================================
618
1121
  // processCPC serialization for Sale and PreAuth
619
1122
  // ===========================================================================
620
1123
  (0, UpaHelpertest_1.describeUpaLive)("UPA Credit – processCPC serialization", () => {