@miden-npm/angular 2.1.3 → 2.1.5

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.
@@ -1569,11 +1569,11 @@ class CardComponent {
1569
1569
  this.back.emit();
1570
1570
  }
1571
1571
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1572
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CardComponent, isStandalone: true, selector: "base-card", inputs: { showBackButton: "showBackButton", caller: "caller" }, outputs: { back: "back" }, ngImport: i0, template: "@if (caller === 'buzapay') {\n <div class=\"checkout-card w-full h-screen flex flex-col items-center justify-center text-white\">\n <div class=\"flex w-1/2\">\n @if (showBackButton) {\n <base-back (back)=\"goBack()\"></base-back>\n }\n\n <div class=\"flex gap-2 w-full\">\n <div class=\"flex flex-col gap-8 w-full\">\n <div class=\"bg-off-white rounded-xl\">\n <ng-content select=\"[buzapay]\"></ng-content>\n </div>\n\n <div class=\"flex items-center gap-2 justify-center\">\n <p class=\"text-light-white-100 text-body-2xs font-regular\">Powered by Buzapay</p>\n <icon-buzapay-icon color=\"#E8F4FF\"></icon-buzapay-icon>\n </div>\n </div>\n\n <!-- Close Icon -->\n <div\n class=\"close-icon flex flex-col items-center justify-center self-start cursor-pointer hover:bg-gray-500\"\n >\n <p class=\"text-white\">x</p>\n </div>\n </div>\n </div>\n </div>\n} @else {\n <div\n class=\"checkout-card-miden w-full h-screen flex flex-col items-center justify-center text-white\"\n >\n <div class=\"flex w-1/2\">\n @if (showBackButton) {\n <base-back (back)=\"goBack()\"></base-back>\n }\n\n <div class=\"flex gap-2 w-full\">\n <div class=\"flex flex-col gap-8 w-full\">\n <div class=\"bg-white rounded-xl\">\n <ng-content select=\"[miden]\"></ng-content>\n </div>\n\n <div class=\"flex items-center gap-4 justify-center\">\n <icon-lock color=\"#E8F4FF\"></icon-lock>\n <p class=\"text-light-white-100 text-body-2xs font-regular\">\n Secured by <span class=\"font-semibold\">Miden</span>\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n}\n", dependencies: [{ kind: "component", type: IconBuzapayIconComponent, selector: "icon-buzapay-icon", inputs: ["color", "width", "height"] }, { kind: "component", type: IconLockComponent, selector: "icon-lock", inputs: ["color", "width", "height"] }, { kind: "component", type: BackComponent, selector: "base-back", outputs: ["back"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1572
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CardComponent, isStandalone: true, selector: "base-card", inputs: { showBackButton: "showBackButton", caller: "caller" }, outputs: { back: "back" }, ngImport: i0, template: "@if (caller === 'buzapay') {\n <div class=\"checkout-card w-full h-screen flex flex-col items-center justify-center text-white\">\n <div class=\"flex w-[95%] sm:w-[85%] md:w-[70%] lg:w-[60%] xl:w-1/2\">\n @if (showBackButton) {\n <base-back (back)=\"goBack()\"></base-back>\n }\n\n <div class=\"flex gap-2 w-full\">\n <div class=\"flex flex-col gap-8 w-full\">\n <div class=\"bg-off-white rounded-xl\">\n <ng-content select=\"[buzapay]\"></ng-content>\n </div>\n\n <div class=\"flex items-center gap-2 justify-center\">\n <p class=\"text-light-white-100 text-body-2xs font-regular\">Powered by Buzapay</p>\n <icon-buzapay-icon color=\"#E8F4FF\"></icon-buzapay-icon>\n </div>\n </div>\n\n <!-- Close Icon -->\n <div\n class=\"hidden sm:flex close-icon flex-col items-center justify-center self-start cursor-pointer hover:bg-gray-500\"\n >\n <p class=\"text-white\">x</p>\n </div>\n </div>\n </div>\n </div>\n} @else {\n <div\n class=\"checkout-card-miden w-full h-screen flex flex-col items-center justify-center text-white\"\n >\n <div class=\"flex w-[95%] sm:w-[85%] md:w-[70%] lg:w-[60%] xl:w-1/2\">\n @if (showBackButton) {\n <base-back (back)=\"goBack()\"></base-back>\n }\n\n <div class=\"flex gap-2 w-full\">\n <div class=\"flex flex-col gap-8 w-full\">\n <div class=\"bg-white rounded-xl\">\n <ng-content select=\"[miden]\"></ng-content>\n </div>\n\n <div class=\"flex items-center gap-4 justify-center\">\n <icon-lock color=\"#E8F4FF\"></icon-lock>\n <p class=\"text-light-white-100 text-body-2xs font-regular\">\n Secured by <span class=\"font-semibold\">Miden</span>\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n}\n", dependencies: [{ kind: "component", type: IconBuzapayIconComponent, selector: "icon-buzapay-icon", inputs: ["color", "width", "height"] }, { kind: "component", type: IconLockComponent, selector: "icon-lock", inputs: ["color", "width", "height"] }, { kind: "component", type: BackComponent, selector: "base-back", outputs: ["back"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1573
1573
  }
1574
1574
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CardComponent, decorators: [{
1575
1575
  type: Component,
1576
- args: [{ selector: 'base-card', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [IconBuzapayIconComponent, IconLockComponent, BackComponent], template: "@if (caller === 'buzapay') {\n <div class=\"checkout-card w-full h-screen flex flex-col items-center justify-center text-white\">\n <div class=\"flex w-1/2\">\n @if (showBackButton) {\n <base-back (back)=\"goBack()\"></base-back>\n }\n\n <div class=\"flex gap-2 w-full\">\n <div class=\"flex flex-col gap-8 w-full\">\n <div class=\"bg-off-white rounded-xl\">\n <ng-content select=\"[buzapay]\"></ng-content>\n </div>\n\n <div class=\"flex items-center gap-2 justify-center\">\n <p class=\"text-light-white-100 text-body-2xs font-regular\">Powered by Buzapay</p>\n <icon-buzapay-icon color=\"#E8F4FF\"></icon-buzapay-icon>\n </div>\n </div>\n\n <!-- Close Icon -->\n <div\n class=\"close-icon flex flex-col items-center justify-center self-start cursor-pointer hover:bg-gray-500\"\n >\n <p class=\"text-white\">x</p>\n </div>\n </div>\n </div>\n </div>\n} @else {\n <div\n class=\"checkout-card-miden w-full h-screen flex flex-col items-center justify-center text-white\"\n >\n <div class=\"flex w-1/2\">\n @if (showBackButton) {\n <base-back (back)=\"goBack()\"></base-back>\n }\n\n <div class=\"flex gap-2 w-full\">\n <div class=\"flex flex-col gap-8 w-full\">\n <div class=\"bg-white rounded-xl\">\n <ng-content select=\"[miden]\"></ng-content>\n </div>\n\n <div class=\"flex items-center gap-4 justify-center\">\n <icon-lock color=\"#E8F4FF\"></icon-lock>\n <p class=\"text-light-white-100 text-body-2xs font-regular\">\n Secured by <span class=\"font-semibold\">Miden</span>\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n}\n" }]
1576
+ args: [{ selector: 'base-card', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [IconBuzapayIconComponent, IconLockComponent, BackComponent], template: "@if (caller === 'buzapay') {\n <div class=\"checkout-card w-full h-screen flex flex-col items-center justify-center text-white\">\n <div class=\"flex w-[95%] sm:w-[85%] md:w-[70%] lg:w-[60%] xl:w-1/2\">\n @if (showBackButton) {\n <base-back (back)=\"goBack()\"></base-back>\n }\n\n <div class=\"flex gap-2 w-full\">\n <div class=\"flex flex-col gap-8 w-full\">\n <div class=\"bg-off-white rounded-xl\">\n <ng-content select=\"[buzapay]\"></ng-content>\n </div>\n\n <div class=\"flex items-center gap-2 justify-center\">\n <p class=\"text-light-white-100 text-body-2xs font-regular\">Powered by Buzapay</p>\n <icon-buzapay-icon color=\"#E8F4FF\"></icon-buzapay-icon>\n </div>\n </div>\n\n <!-- Close Icon -->\n <div\n class=\"hidden sm:flex close-icon flex-col items-center justify-center self-start cursor-pointer hover:bg-gray-500\"\n >\n <p class=\"text-white\">x</p>\n </div>\n </div>\n </div>\n </div>\n} @else {\n <div\n class=\"checkout-card-miden w-full h-screen flex flex-col items-center justify-center text-white\"\n >\n <div class=\"flex w-[95%] sm:w-[85%] md:w-[70%] lg:w-[60%] xl:w-1/2\">\n @if (showBackButton) {\n <base-back (back)=\"goBack()\"></base-back>\n }\n\n <div class=\"flex gap-2 w-full\">\n <div class=\"flex flex-col gap-8 w-full\">\n <div class=\"bg-white rounded-xl\">\n <ng-content select=\"[miden]\"></ng-content>\n </div>\n\n <div class=\"flex items-center gap-4 justify-center\">\n <icon-lock color=\"#E8F4FF\"></icon-lock>\n <p class=\"text-light-white-100 text-body-2xs font-regular\">\n Secured by <span class=\"font-semibold\">Miden</span>\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n}\n" }]
1577
1577
  }], propDecorators: { showBackButton: [{
1578
1578
  type: Input
1579
1579
  }], caller: [{
@@ -1662,6 +1662,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
1662
1662
 
1663
1663
  class PhoneNumberInputComponent {
1664
1664
  phoneCodeOptions = [];
1665
+ /**
1666
+ * This is the phone number value from the parent.
1667
+ * We'll keep the internal input in sync with it.
1668
+ */
1665
1669
  value;
1666
1670
  valueChange = new EventEmitter();
1667
1671
  codeChange = new EventEmitter();
@@ -1684,6 +1688,8 @@ class PhoneNumberInputComponent {
1684
1688
  selectedCode = '+1';
1685
1689
  ngOnInit() {
1686
1690
  this.initSelectedCode();
1691
+ // ✅ hydrate internal input from parent value on first mount
1692
+ this.syncPhoneNumberFromInput(this.value);
1687
1693
  }
1688
1694
  ngOnChanges(changes) {
1689
1695
  if (changes['defaultCountryCode'] && !changes['defaultCountryCode'].firstChange) {
@@ -1692,6 +1698,11 @@ class PhoneNumberInputComponent {
1692
1698
  if (changes['phoneCodeOptions'] && !changes['phoneCodeOptions'].firstChange) {
1693
1699
  this.ensureValidSelection();
1694
1700
  }
1701
+ // ✅ whenever parent value changes (or component remounts with an existing value),
1702
+ // update the internal form control so the UI shows it.
1703
+ if (changes['value']) {
1704
+ this.syncPhoneNumberFromInput(changes['value'].currentValue);
1705
+ }
1695
1706
  }
1696
1707
  get safeDefaultCode() {
1697
1708
  return this.phoneCodeOptions?.[0]?.value ?? '+1';
@@ -1710,21 +1721,36 @@ class PhoneNumberInputComponent {
1710
1721
  initSelectedCode() {
1711
1722
  const nextValue = this.defaultCountryCode ?? this.safeDefaultCode;
1712
1723
  this.selectedCode = nextValue;
1724
+ // keep form select in sync
1725
+ this.phoneNumberInputForm.patchValue({ phoneNumberExt: nextValue }, { emitEvent: false });
1726
+ // emit formatted code to parent
1713
1727
  this.codeChange.emit(this.getFormattedCode(nextValue));
1714
- this.phoneNumberInputForm.patchValue({ phoneNumberExt: nextValue });
1715
1728
  }
1716
1729
  ensureValidSelection() {
1717
1730
  const exists = this.phoneCodeOptions.some((o) => o.value === this.selectedCode);
1718
1731
  if (!exists) {
1719
1732
  this.selectedCode = this.defaultCountryCode ?? this.safeDefaultCode;
1733
+ this.phoneNumberInputForm.patchValue({ phoneNumberExt: this.selectedCode }, { emitEvent: false });
1720
1734
  this.codeChange.emit(this.getFormattedCode(this.selectedCode));
1721
1735
  }
1722
1736
  }
1737
+ syncPhoneNumberFromInput(val) {
1738
+ const current = this.phoneNumberInputForm.get('phoneNumber')?.value ?? '';
1739
+ const next = val ?? '';
1740
+ if (current !== next) {
1741
+ this.phoneNumberInputForm.patchValue({ phoneNumber: next }, { emitEvent: false });
1742
+ }
1743
+ }
1723
1744
  onCountryChange(e) {
1724
1745
  this.selectedCode = e;
1725
- this.codeChange.emit(this.getFormattedCode(e));
1746
+ // keep internal form control in sync
1747
+ this.phoneNumberInputForm.patchValue({ phoneNumberExt: this.selectedCode }, { emitEvent: false });
1748
+ this.codeChange.emit(this.getFormattedCode(this.selectedCode));
1726
1749
  }
1727
1750
  onPhoneChange(e) {
1751
+ // keep internal form control in sync
1752
+ this.phoneNumberInputForm.patchValue({ phoneNumber: e }, { emitEvent: false });
1753
+ // emit to parent
1728
1754
  this.valueChange.emit(e);
1729
1755
  }
1730
1756
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PhoneNumberInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -2265,182 +2291,181 @@ class PayByCardComponent {
2265
2291
  }
2266
2292
  else {
2267
2293
  if (this.payForm && this.payForm.valid) {
2268
- try {
2269
- this.isMakingPayment = true;
2270
- // Create card details object for encryption
2271
- const cardDetails = {
2272
- pan: this.payForm.value.cardNo ? this.payForm.value.cardNo.replaceAll(' ', '') : '',
2273
- expiryDate: this.payForm.value.expireDate ?? '',
2274
- cvv: this.payForm.value.cvv ?? '',
2275
- cardScheme: this.cardType,
2276
- nameOnCard: this.payForm.value.customerName ?? '',
2277
- ...(this.cardType === 'Verve' && { pin: this.payForm.value.cardPin ?? '' }),
2294
+ this.isMakingPayment = true;
2295
+ // Create card details object for encryption
2296
+ const cardDetails = {
2297
+ pan: this.payForm.value.cardNo ? this.payForm.value.cardNo.replaceAll(' ', '') : '',
2298
+ expiryDate: this.payForm.value.expireDate ?? '',
2299
+ cvv: this.payForm.value.cvv ?? '',
2300
+ cardScheme: this.cardType,
2301
+ nameOnCard: this.payForm.value.customerName ?? '',
2302
+ ...(this.cardType === 'Verve' && { pin: this.payForm.value.cardPin ?? '' }),
2303
+ };
2304
+ // Get billing details from the form control
2305
+ const billingDetails = {
2306
+ address2: this.billingForm.value.address2 ?? '',
2307
+ address1: this.billingForm.value.address1 ?? '',
2308
+ postalCode: this.billingForm.value.postalCode ?? '',
2309
+ state: this.billingForm.value.state ?? '',
2310
+ city: this.billingForm.value.city ?? '',
2311
+ country: this.billingForm.value.country ?? '',
2312
+ emailAddress: this.billingForm.value.emailAddress ?? '',
2313
+ phoneNumber: this.billingForm.value.phoneNumber
2314
+ ? `${this.billingForm.value.phoneNumberExt}${this.billingForm.value.phoneNumber}`
2315
+ : '',
2316
+ };
2317
+ // Encrypt card details using payload encryption method
2318
+ const encryptedCardDetails = this.encryptService.encryptPayload(this.secretKey, cardDetails);
2319
+ // Test: Decrypt to verify encryption works
2320
+ // const decryptedTest = this.encryptService.decryptPayload(
2321
+ // this.environment,
2322
+ // encryptedCardDetails.requestParam,
2323
+ // );
2324
+ let payload = null;
2325
+ let payloadMiden = null;
2326
+ if (this.caller === 'buzapay') {
2327
+ payload = {
2328
+ customerId: this.paymentObject?.email || this.payForm.value.customerName || '',
2329
+ amount: this.paymentObject?.amount.toString(),
2330
+ currency: this.paymentObject?.currency || 'USD',
2331
+ narration: this.paymentObject?.narration || 'Test transaction',
2332
+ encryptedCardDetails: encryptedCardDetails.requestParam, // Use the encrypted card details
2333
+ billingDetails: billingDetails,
2334
+ redirectUrl: this.paymentObject?.redirectUrl || `${this.baseAppUrl}/account/three-ds-status`,
2335
+ paymentReference: this.transactionReference,
2336
+ isCheckout: true,
2278
2337
  };
2279
- // Get billing details from the form control
2280
- const billingDetails = {
2281
- address2: this.billingForm.value.address2 ?? '',
2282
- address1: this.billingForm.value.address1 ?? '',
2283
- postalCode: this.billingForm.value.postalCode ?? '',
2284
- state: this.billingForm.value.state ?? '',
2285
- city: this.billingForm.value.city ?? '',
2286
- country: this.billingForm.value.country ?? '',
2287
- emailAddress: this.billingForm.value.emailAddress ?? '',
2288
- phoneNumber: this.billingForm.value.phoneNumber
2289
- ? `${this.billingForm.value.phoneNumberExt}${this.billingForm.value.phoneNumber}`
2290
- : '',
2338
+ }
2339
+ else {
2340
+ const deviceInformation = buildDeviceInformation();
2341
+ payloadMiden = {
2342
+ customerId: this.paymentObject?.email || this.payForm.value.customerName || '',
2343
+ amount: this.paymentObject?.amount.toString(),
2344
+ currency: this.paymentObject?.currency || 'USD',
2345
+ narration: this.paymentObject?.narration || 'Test transaction',
2346
+ encryptedCardDetails: encryptedCardDetails.requestParam, // Use the encrypted card details
2347
+ billingDetails: billingDetails,
2348
+ redirectUrl: this.paymentObject?.redirectUrl || `${this.baseAppUrl}/pay/verification`,
2349
+ paymentReference: this.transactionReference,
2350
+ isCheckout: true,
2351
+ postBackUrl: '',
2352
+ saveCard: false,
2353
+ deviceInformation,
2291
2354
  };
2292
- // Encrypt card details using payload encryption method
2293
- const encryptedCardDetails = this.encryptService.encryptPayload(this.secretKey, cardDetails);
2294
- // Test: Decrypt to verify encryption works
2295
- // const decryptedTest = this.encryptService.decryptPayload(
2296
- // this.environment,
2297
- // encryptedCardDetails.requestParam,
2298
- // );
2299
- let payload = null;
2300
- let payloadMiden = null;
2301
- if (this.caller === 'buzapay') {
2302
- payload = {
2303
- customerId: this.paymentObject?.email || this.payForm.value.customerName || '',
2304
- amount: this.paymentObject?.amount.toString(),
2305
- currency: this.paymentObject?.currency || 'USD',
2306
- narration: this.paymentObject?.narration || 'Test transaction',
2307
- encryptedCardDetails: encryptedCardDetails.requestParam, // Use the encrypted card details
2308
- billingDetails: billingDetails,
2309
- redirectUrl: this.paymentObject?.redirectUrl || `${this.baseAppUrl}/account/three-ds-status`,
2310
- paymentReference: this.transactionReference,
2311
- isCheckout: true,
2312
- };
2313
- }
2314
- else {
2315
- const deviceInformation = buildDeviceInformation();
2316
- payloadMiden = {
2317
- customerId: this.paymentObject?.email || this.payForm.value.customerName || '',
2318
- amount: this.paymentObject?.amount.toString(),
2319
- currency: this.paymentObject?.currency || 'USD',
2320
- narration: this.paymentObject?.narration || 'Test transaction',
2321
- encryptedCardDetails: encryptedCardDetails.requestParam, // Use the encrypted card details
2322
- billingDetails: billingDetails,
2323
- redirectUrl: this.paymentObject?.redirectUrl || `${this.baseAppUrl}/pay/verification`,
2324
- paymentReference: this.transactionReference,
2325
- isCheckout: true,
2326
- postBackUrl: '',
2327
- saveCard: false,
2328
- deviceInformation,
2329
- };
2355
+ }
2356
+ this.checkout
2357
+ .authorizeCardPayment(this.environment, this.caller === 'buzapay'
2358
+ ? {
2359
+ ...payload,
2360
+ merchantId: this.secretKey,
2330
2361
  }
2331
- this.checkout
2332
- .authorizeCardPayment(this.environment, this.caller === 'buzapay'
2333
- ? {
2334
- ...payload,
2335
- merchantId: this.secretKey,
2362
+ : {
2363
+ ...payloadMiden,
2364
+ merchantId: this.secretKey,
2365
+ }, this.caller)
2366
+ .subscribe({
2367
+ next: async (response) => {
2368
+ let processedResponse = response;
2369
+ // Check if response is encrypted (has responseParam)
2370
+ if (response?.responseParam) {
2371
+ // Decrypt the response
2372
+ processedResponse = this.encryptService.decryptPayload(this.environment, response.responseParam);
2336
2373
  }
2337
- : {
2338
- ...payloadMiden,
2339
- merchantId: this.secretKey,
2340
- }, this.caller)
2341
- .subscribe({
2342
- next: async (response) => {
2343
- let processedResponse = response;
2344
- // Check if response is encrypted (has responseParam)
2345
- if (response?.responseParam) {
2346
- // Decrypt the response
2347
- processedResponse = this.encryptService.decryptPayload(this.environment, response.responseParam);
2374
+ if (processedResponse?.isSuccessful) {
2375
+ // Miden flow
2376
+ if (this.caller === 'miden') {
2377
+ this.handleMidenCard(processedResponse);
2378
+ return;
2348
2379
  }
2349
- if (processedResponse?.isSuccessful) {
2350
- // Miden flow
2351
- if (this.caller === 'miden') {
2352
- this.handleMidenCard(processedResponse);
2353
- return;
2354
- }
2355
- // Check for 3DS authentication requirement
2356
- if (processedResponse.threeDsInteractionRequired === true) {
2357
- // Store 3DS data for the authentication page
2358
- const threeDsData = {
2359
- transactionReference: processedResponse.transactionReference,
2360
- threeDsHtml: processedResponse.threeDsHtml,
2361
- amount: processedResponse.amount,
2362
- responseMessage: processedResponse.responseMessage,
2363
- // Pass all 3DS details
2364
- paReq: processedResponse.threeDsHtml?.paReq,
2365
- termUrl: processedResponse.threeDsHtml?.termUrl,
2366
- action: processedResponse.threeDsHtml?.action,
2367
- acsUrl: processedResponse.threeDsHtml?.acsUrl,
2368
- md: processedResponse.threeDsHtml?.md,
2369
- };
2370
- // Encrypt 3DS data to pass as url param
2371
- const stringifiedThreeDsData = btoa(JSON.stringify(threeDsData));
2372
- // Open 3DS authentication page in a new tab
2373
- const threeDsUrl = `${this.baseAppUrl}/account/three-ds-confirm?threeDsData=${encodeURIComponent(stringifiedThreeDsData)}&paymentReference=${processedResponse.transactionReference}`;
2374
- window.open(threeDsUrl, '_self', 'noopener,noreferrer');
2375
- this.message =
2376
- '3D Secure authentication opened in new tab. Please complete the verification';
2377
- this.isMakingPayment = false;
2378
- return;
2379
- }
2380
- // Fallback check: if response message indicates 3DS is required
2381
- if (processedResponse.responseMessage === 'Payer Interaction Required' &&
2382
- processedResponse.threeDsHtml) {
2383
- // Store 3DS data for the authentication page
2384
- const threeDsData = {
2385
- transactionReference: processedResponse.transactionReference,
2386
- threeDsHtml: processedResponse.threeDsHtml,
2387
- amount: processedResponse.amount,
2388
- responseMessage: processedResponse.responseMessage,
2389
- // Pass all 3DS details
2390
- paReq: processedResponse.threeDsHtml?.paReq,
2391
- termUrl: processedResponse.threeDsHtml?.termUrl,
2392
- action: processedResponse.threeDsHtml?.action,
2393
- acsUrl: processedResponse.threeDsHtml?.acsUrl,
2394
- md: processedResponse.threeDsHtml?.md,
2395
- };
2396
- // Encrypt 3DS data to pass as url param
2397
- const stringifiedThreeDsData = btoa(JSON.stringify(threeDsData));
2398
- // Open 3DS authentication page in a new tab
2399
- const threeDsUrl = `${this.baseAppUrl}/account/three-ds-confirm?threeDsData=${encodeURIComponent(stringifiedThreeDsData)}&paymentReference=${processedResponse.transactionReference}`;
2400
- window.open(threeDsUrl, '_self', 'noopener,noreferrer');
2401
- this.message =
2402
- '3D Secure authentication opened in new tab. Please complete the verification';
2403
- this.isMakingPayment = false;
2404
- return;
2405
- }
2406
- // Emit the transaction reference to parent component
2407
- if (processedResponse.transactionReference &&
2408
- processedResponse.transactionReference.trim() !== '') {
2409
- this.paymentAuthorized.emit({
2410
- paymentId: processedResponse.transactionReference,
2411
- paymentDate: response?.data?.updatedAt ?? new Date().toISOString(),
2412
- paymentStatus: 'authorized',
2413
- message: this.message,
2414
- });
2415
- }
2416
- this.message = 'Card payment authorized successfully';
2380
+ // Check for 3DS authentication requirement
2381
+ if (processedResponse.threeDsInteractionRequired === true) {
2382
+ // Store 3DS data for the authentication page
2383
+ const threeDsData = {
2384
+ transactionReference: processedResponse.transactionReference,
2385
+ threeDsHtml: processedResponse.threeDsHtml,
2386
+ amount: processedResponse.amount,
2387
+ responseMessage: processedResponse.responseMessage,
2388
+ // Pass all 3DS details
2389
+ paReq: processedResponse.threeDsHtml?.paReq,
2390
+ termUrl: processedResponse.threeDsHtml?.termUrl,
2391
+ action: processedResponse.threeDsHtml?.action,
2392
+ acsUrl: processedResponse.threeDsHtml?.acsUrl,
2393
+ md: processedResponse.threeDsHtml?.md,
2394
+ };
2395
+ // Encrypt 3DS data to pass as url param
2396
+ const stringifiedThreeDsData = btoa(JSON.stringify(threeDsData));
2397
+ // Open 3DS authentication page in a new tab
2398
+ const threeDsUrl = `${this.baseAppUrl}/account/three-ds-confirm?threeDsData=${encodeURIComponent(stringifiedThreeDsData)}&paymentReference=${processedResponse.transactionReference}`;
2399
+ window.open(threeDsUrl, '_self', 'noopener,noreferrer');
2400
+ this.message =
2401
+ '3D Secure authentication opened in new tab. Please complete the verification';
2417
2402
  this.isMakingPayment = false;
2403
+ return;
2418
2404
  }
2419
- else {
2405
+ // Fallback check: if response message indicates 3DS is required
2406
+ if (processedResponse.responseMessage === 'Payer Interaction Required' &&
2407
+ processedResponse.threeDsHtml) {
2408
+ // Store 3DS data for the authentication page
2409
+ const threeDsData = {
2410
+ transactionReference: processedResponse.transactionReference,
2411
+ threeDsHtml: processedResponse.threeDsHtml,
2412
+ amount: processedResponse.amount,
2413
+ responseMessage: processedResponse.responseMessage,
2414
+ // Pass all 3DS details
2415
+ paReq: processedResponse.threeDsHtml?.paReq,
2416
+ termUrl: processedResponse.threeDsHtml?.termUrl,
2417
+ action: processedResponse.threeDsHtml?.action,
2418
+ acsUrl: processedResponse.threeDsHtml?.acsUrl,
2419
+ md: processedResponse.threeDsHtml?.md,
2420
+ };
2421
+ // Encrypt 3DS data to pass as url param
2422
+ const stringifiedThreeDsData = btoa(JSON.stringify(threeDsData));
2423
+ // Open 3DS authentication page in a new tab
2424
+ const threeDsUrl = `${this.baseAppUrl}/account/three-ds-confirm?threeDsData=${encodeURIComponent(stringifiedThreeDsData)}&paymentReference=${processedResponse.transactionReference}`;
2425
+ window.open(threeDsUrl, '_self', 'noopener,noreferrer');
2426
+ this.message =
2427
+ '3D Secure authentication opened in new tab. Please complete the verification';
2420
2428
  this.isMakingPayment = false;
2421
- this.message = processedResponse.responseMessage || 'Payment failed';
2422
- this.onError.emit({ errorMessage: this.message });
2423
- }
2424
- },
2425
- error: (err) => {
2426
- this.isMakingPayment = false;
2427
- if (err.error?.responseParam) {
2428
- // Decrypt error response
2429
- const decryptedErrorResponse = this.encryptService.decryptPayload(this.environment, err.error.responseParam);
2430
- this.message = decryptedErrorResponse.responseMessage || 'Payment failed';
2429
+ return;
2431
2430
  }
2432
- else {
2433
- this.message = err.error.message || err.error.responseMessage || 'Payment failed';
2431
+ // Emit the transaction reference to parent component
2432
+ if (processedResponse.transactionReference &&
2433
+ processedResponse.transactionReference.trim() !== '') {
2434
+ this.paymentAuthorized.emit({
2435
+ paymentId: processedResponse.transactionReference,
2436
+ paymentDate: response?.data?.updatedAt ?? new Date().toISOString(),
2437
+ paymentStatus: 'authorized',
2438
+ message: this.message,
2439
+ });
2434
2440
  }
2441
+ this.message = 'Card payment authorized successfully';
2442
+ this.isMakingPayment = false;
2443
+ }
2444
+ // Failure path for miden
2445
+ if (processedResponse && !processedResponse.isSuccessful && this.caller === 'miden') {
2446
+ this.message = processedResponse.responseMessage;
2435
2447
  this.onError.emit({ errorMessage: this.message });
2436
- },
2437
- });
2438
- }
2439
- catch (error) {
2440
- this.isMakingPayment = false;
2441
- this.message = 'An unexpected error occurred';
2442
- this.onError.emit({ errorMessage: this.message });
2443
- }
2448
+ }
2449
+ // Failure path for buzapay
2450
+ if (processedResponse && processedResponse.message && this.caller === 'buzapay') {
2451
+ this.message = response.message;
2452
+ this.onError.emit({ errorMessage: this.message });
2453
+ }
2454
+ this.isMakingPayment = false;
2455
+ },
2456
+ error: (err) => {
2457
+ this.isMakingPayment = false;
2458
+ if (err.error?.responseParam) {
2459
+ // Decrypt error response
2460
+ const decryptedErrorResponse = this.encryptService.decryptPayload(this.environment, err.error.responseParam);
2461
+ this.message = decryptedErrorResponse.responseMessage || 'Payment failed';
2462
+ }
2463
+ else {
2464
+ this.message = err.error.message || err.error.responseMessage || 'Payment failed';
2465
+ }
2466
+ this.onError.emit({ errorMessage: this.message });
2467
+ },
2468
+ });
2444
2469
  }
2445
2470
  else {
2446
2471
  this.payForm.markAllAsTouched();
@@ -2463,7 +2488,7 @@ class PayByCardComponent {
2463
2488
  }).sort((a, b) => a.label.localeCompare(b.label));
2464
2489
  }
2465
2490
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PayByCardComponent, deps: [{ token: ResourceService }, { token: i0.ChangeDetectorRef }, { token: CheckoutService }, { token: EncryptService }, { token: i4.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
2466
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: PayByCardComponent, isStandalone: true, selector: "pay-by-card", inputs: { secretKey: "secretKey", environment: "environment", caller: "caller", paymentObject: "paymentObject" }, outputs: { paymentAuthorized: "paymentAuthorized", onError: "onError" }, ngImport: i0, template: "@if (threeDSOpen) {\n <div class=\"fixed inset-0 z-50 flex items-center justify-center bg-white p-4\">\n <iframe\n title=\"Miden 3DS\"\n [src]=\"threeDSIframeSrc\"\n class=\"w-full h-full\"\n sandbox=\"allow-forms allow-scripts allow-same-origin allow-top-navigation\"\n ></iframe>\n </div>\n} @else {\n <div class=\"flex flex-col gap-6\">\n <!-- Billing Details -->\n @if (formIndex === 0) {\n <form [formGroup]=\"billingForm\">\n <div class=\"grid grid-cols-2 gap-6 overflow-y-auto\">\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"address1\"\n label=\"Address Line 1\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'address1', 'Address Line 1') || ''\"\n ></base-input>\n </div>\n <div class=\"col-span-2\">\n <base-input formControlName=\"address2\" label=\"Address Line 2\"></base-input>\n </div>\n <base-select\n formControlName=\"country\"\n label=\"Select Country\"\n [required]=\"true\"\n [options]=\"countries\"\n [loading]=\"loadingCountries\"\n [validationError]=\"getError('billing', 'country', 'Country') || ''\"\n (onSelectChange)=\"getCountryStates($event)\"\n ></base-select>\n <base-select\n formControlName=\"state\"\n label=\"Select State\"\n [required]=\"true\"\n [options]=\"countryStates\"\n [loading]=\"loadingStates\"\n [validationError]=\"getError('billing', 'state', 'State') || ''\"\n ></base-select>\n <base-input\n formControlName=\"city\"\n label=\"City\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'city', 'City') || ''\"\n ></base-input>\n <base-input\n formControlName=\"postalCode\"\n label=\"Postal Code\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'postalCode', 'Postal Code') || ''\"\n ></base-input>\n\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"emailAddress\"\n label=\"Email\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'emailAddress', 'Email Address') || ''\"\n ></base-input>\n </div>\n\n <div class=\"col-span-2\">\n <base-phone-number-input\n [phoneCodeOptions]=\"phoneCodeOptions\"\n [defaultCountryCode]=\"defaultCountryCode\"\n label=\"Phone number\"\n [preventPaste]=\"true\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'phoneNumber', 'Phone Number') || ''\"\n (codeChange)=\"onCodeChange($event)\"\n (valueChange)=\"onPhoneChange($event)\"\n ></base-phone-number-input>\n </div>\n </div>\n </form>\n }\n\n <!-- Card Details -->\n @if (formIndex === 1) {\n <form [formGroup]=\"payForm\">\n <div class=\"grid grid-cols-2 gap-6 overflow-y-auto\" style=\"max-height: 320px\">\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"customerName\"\n label=\"Card Name\"\n [required]=\"true\"\n [validationError]=\"getError('pay', 'customerName', 'Customer Name') || ''\"\n ></base-input>\n </div>\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"cardNo\"\n label=\"Card Number\"\n [required]=\"true\"\n mask=\"0000 0000 0000 0000\"\n placeholder=\"0000 0000 0000 0000\"\n [preventPaste]=\"false\"\n [validationError]=\"getError('pay', 'cardNo', 'Card Number') || ''\"\n (onInputChange)=\"cardNumberInputHandler($event)\"\n ></base-input>\n </div>\n <base-input\n formControlName=\"expireDate\"\n label=\"Expiry Date\"\n [required]=\"true\"\n mask=\"00/00\"\n placeholder=\"00/00\"\n [validationError]=\"getError('pay', 'expireDate', 'Expiry Date') || ''\"\n ></base-input>\n <base-input\n formControlName=\"cvv\"\n label=\"CVV\"\n [required]=\"true\"\n mask=\"000\"\n placeholder=\"000\"\n [validationError]=\"getError('pay', 'cvv', 'CVV') || ''\"\n ></base-input>\n\n @if (cardType === 'Verve') {\n <base-input\n formControlName=\"cardPin\"\n label=\"Card Pin\"\n type=\"password\"\n placeholder=\"0000\"\n mask=\"0000\"\n [required]=\"true\"\n [validationError]=\"getError('pay', 'cardPin', 'Card Pin') || ''\"\n ></base-input>\n <div class=\"text-sm text-blue-600 mb-4\">\n <i class=\"fas fa-info-circle mr-1\"></i>\n Pin is required for Verve cards\n </div>\n }\n </div>\n </form>\n }\n\n <div class=\"flex items-center justify-between gap-4 mt-6 w-full\">\n @if (formIndex > 0) {\n <div class=\"w-1/2\">\n <base-button\n label=\"Previous\"\n type=\"secondary\"\n [caller]=\"caller\"\n (onClick)=\"goBack()\"\n ></base-button>\n </div>\n }\n <div [class]=\"formIndex === 0 ? 'w-full' : 'w-1/2'\">\n <base-button\n [label]=\"formIndex === 0 ? 'Proceed' : 'Pay ' + formatAmountHandler\"\n type=\"primary\"\n [caller]=\"caller\"\n [loading]=\"isMakingPayment\"\n (onClick)=\"proceedHandler()\"\n ></base-button>\n </div>\n </div>\n </div>\n}\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "base-button", inputs: ["label", "type", "caller", "size", "paddingClassX", "disabled", "loading", "customClass"], outputs: ["onClick"] }, { kind: "component", type: InputComponent, selector: "base-input", inputs: ["label", "type", "placeholder", "validationError", "hint", "mask", "rules", "isAmountInput", "required", "disabled", "loading", "showCopyIcon", "preventPaste", "showBottomText"], outputs: ["onInputChange", "onInputBlur"] }, { kind: "component", type: SelectComponent, selector: "base-select", inputs: ["options", "placeholder", "hasSearch", "disabled", "loading", "validationError", "label", "hint", "required", "itemImageType", "showBottomText"], outputs: ["onSelectChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: PhoneNumberInputComponent, selector: "base-phone-number-input", inputs: ["phoneCodeOptions", "value", "label", "required", "disabled", "loading", "validationError", "hint", "defaultCountryCode", "preventPaste", "showCopyIcon", "containerClassName", "inputClassName", "placeholder"], outputs: ["valueChange", "codeChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2491
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: PayByCardComponent, isStandalone: true, selector: "pay-by-card", inputs: { secretKey: "secretKey", environment: "environment", caller: "caller", paymentObject: "paymentObject" }, outputs: { paymentAuthorized: "paymentAuthorized", onError: "onError" }, ngImport: i0, template: "@if (threeDSOpen) {\n <div class=\"fixed inset-0 z-50 flex items-center justify-center bg-white p-4\">\n <iframe\n title=\"Miden 3DS\"\n [src]=\"threeDSIframeSrc\"\n class=\"w-full h-full\"\n sandbox=\"allow-forms allow-scripts allow-same-origin allow-top-navigation\"\n ></iframe>\n </div>\n} @else {\n <div class=\"flex flex-col gap-6\">\n <!-- Billing Details -->\n @if (formIndex === 0) {\n <form [formGroup]=\"billingForm\">\n <div class=\"grid grid-cols-2 gap-6 overflow-y-auto\">\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"address1\"\n label=\"Address Line 1\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'address1', 'Address Line 1') || ''\"\n ></base-input>\n </div>\n <div class=\"col-span-2\">\n <base-input formControlName=\"address2\" label=\"Address Line 2\"></base-input>\n </div>\n <div class=\"col-span-2 sm:col-span-1\">\n <base-select\n formControlName=\"country\"\n label=\"Select Country\"\n [required]=\"true\"\n [options]=\"countries\"\n [loading]=\"loadingCountries\"\n [validationError]=\"getError('billing', 'country', 'Country') || ''\"\n (onSelectChange)=\"getCountryStates($event)\"\n ></base-select>\n </div>\n <div class=\"col-span-2 sm:col-span-1\">\n <base-select\n formControlName=\"state\"\n label=\"Select State\"\n [required]=\"true\"\n [options]=\"countryStates\"\n [loading]=\"loadingStates\"\n [validationError]=\"getError('billing', 'state', 'State') || ''\"\n ></base-select>\n </div>\n <div class=\"col-span-2 sm:col-span-1\">\n <base-input\n formControlName=\"city\"\n label=\"City\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'city', 'City') || ''\"\n ></base-input>\n </div>\n <div class=\"col-span-2 sm:col-span-1\">\n <base-input\n formControlName=\"postalCode\"\n label=\"Postal Code\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'postalCode', 'Postal Code') || ''\"\n ></base-input>\n </div>\n\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"emailAddress\"\n label=\"Email\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'emailAddress', 'Email Address') || ''\"\n ></base-input>\n </div>\n\n <div class=\"col-span-2\">\n <base-phone-number-input\n [value]=\"billingForm.get('phoneNumber')?.value ?? ''\"\n [phoneCodeOptions]=\"phoneCodeOptions\"\n [defaultCountryCode]=\"defaultCountryCode\"\n label=\"Phone number\"\n [preventPaste]=\"true\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'phoneNumber', 'Phone Number') || ''\"\n (codeChange)=\"onCodeChange($event)\"\n (valueChange)=\"onPhoneChange($event)\"\n ></base-phone-number-input>\n </div>\n </div>\n </form>\n }\n\n <!-- Card Details -->\n @if (formIndex === 1) {\n <form [formGroup]=\"payForm\">\n <div class=\"grid grid-cols-2 gap-6 overflow-y-auto\" style=\"max-height: 320px\">\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"customerName\"\n label=\"Card Name\"\n [required]=\"true\"\n [validationError]=\"getError('pay', 'customerName', 'Customer Name') || ''\"\n ></base-input>\n </div>\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"cardNo\"\n label=\"Card Number\"\n [required]=\"true\"\n mask=\"0000 0000 0000 0000 000\"\n placeholder=\"0000 0000 0000 0000\"\n [preventPaste]=\"true\"\n [validationError]=\"getError('pay', 'cardNo', 'Card Number') || ''\"\n (onInputChange)=\"cardNumberInputHandler($event)\"\n ></base-input>\n </div>\n <base-input\n formControlName=\"expireDate\"\n label=\"Expiry Date\"\n [required]=\"true\"\n mask=\"00/00\"\n placeholder=\"00/00\"\n [validationError]=\"getError('pay', 'expireDate', 'Expiry Date') || ''\"\n ></base-input>\n <base-input\n formControlName=\"cvv\"\n label=\"CVV\"\n [required]=\"true\"\n mask=\"000\"\n placeholder=\"000\"\n [validationError]=\"getError('pay', 'cvv', 'CVV') || ''\"\n ></base-input>\n\n @if (cardType === 'Verve') {\n <base-input\n formControlName=\"cardPin\"\n label=\"Card Pin\"\n type=\"password\"\n placeholder=\"0000\"\n mask=\"0000\"\n [required]=\"true\"\n [validationError]=\"getError('pay', 'cardPin', 'Card Pin') || ''\"\n ></base-input>\n <!-- <div class=\"text-sm text-blue-600 mb-4\">\n <i class=\"fas fa-info-circle mr-1\"></i>\n Pin is required for Verve cards\n </div> -->\n }\n </div>\n </form>\n }\n\n <div class=\"flex items-center justify-between gap-4 mt-6 w-full\">\n @if (formIndex > 0) {\n <div class=\"w-1/2\">\n <base-button\n label=\"Previous\"\n type=\"secondary\"\n [caller]=\"caller\"\n (onClick)=\"goBack()\"\n ></base-button>\n </div>\n }\n <div [class]=\"formIndex === 0 ? 'w-full' : 'w-1/2'\">\n <base-button\n [label]=\"formIndex === 0 ? 'Proceed' : 'Pay ' + formatAmountHandler\"\n type=\"primary\"\n [caller]=\"caller\"\n [loading]=\"isMakingPayment\"\n (onClick)=\"proceedHandler()\"\n ></base-button>\n </div>\n </div>\n </div>\n}\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "base-button", inputs: ["label", "type", "caller", "size", "paddingClassX", "disabled", "loading", "customClass"], outputs: ["onClick"] }, { kind: "component", type: InputComponent, selector: "base-input", inputs: ["label", "type", "placeholder", "validationError", "hint", "mask", "rules", "isAmountInput", "required", "disabled", "loading", "showCopyIcon", "preventPaste", "showBottomText"], outputs: ["onInputChange", "onInputBlur"] }, { kind: "component", type: SelectComponent, selector: "base-select", inputs: ["options", "placeholder", "hasSearch", "disabled", "loading", "validationError", "label", "hint", "required", "itemImageType", "showBottomText"], outputs: ["onSelectChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: PhoneNumberInputComponent, selector: "base-phone-number-input", inputs: ["phoneCodeOptions", "value", "label", "required", "disabled", "loading", "validationError", "hint", "defaultCountryCode", "preventPaste", "showCopyIcon", "containerClassName", "inputClassName", "placeholder"], outputs: ["valueChange", "codeChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2467
2492
  }
2468
2493
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PayByCardComponent, decorators: [{
2469
2494
  type: Component,
@@ -2473,7 +2498,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2473
2498
  SelectComponent,
2474
2499
  ReactiveFormsModule,
2475
2500
  PhoneNumberInputComponent,
2476
- ], template: "@if (threeDSOpen) {\n <div class=\"fixed inset-0 z-50 flex items-center justify-center bg-white p-4\">\n <iframe\n title=\"Miden 3DS\"\n [src]=\"threeDSIframeSrc\"\n class=\"w-full h-full\"\n sandbox=\"allow-forms allow-scripts allow-same-origin allow-top-navigation\"\n ></iframe>\n </div>\n} @else {\n <div class=\"flex flex-col gap-6\">\n <!-- Billing Details -->\n @if (formIndex === 0) {\n <form [formGroup]=\"billingForm\">\n <div class=\"grid grid-cols-2 gap-6 overflow-y-auto\">\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"address1\"\n label=\"Address Line 1\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'address1', 'Address Line 1') || ''\"\n ></base-input>\n </div>\n <div class=\"col-span-2\">\n <base-input formControlName=\"address2\" label=\"Address Line 2\"></base-input>\n </div>\n <base-select\n formControlName=\"country\"\n label=\"Select Country\"\n [required]=\"true\"\n [options]=\"countries\"\n [loading]=\"loadingCountries\"\n [validationError]=\"getError('billing', 'country', 'Country') || ''\"\n (onSelectChange)=\"getCountryStates($event)\"\n ></base-select>\n <base-select\n formControlName=\"state\"\n label=\"Select State\"\n [required]=\"true\"\n [options]=\"countryStates\"\n [loading]=\"loadingStates\"\n [validationError]=\"getError('billing', 'state', 'State') || ''\"\n ></base-select>\n <base-input\n formControlName=\"city\"\n label=\"City\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'city', 'City') || ''\"\n ></base-input>\n <base-input\n formControlName=\"postalCode\"\n label=\"Postal Code\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'postalCode', 'Postal Code') || ''\"\n ></base-input>\n\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"emailAddress\"\n label=\"Email\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'emailAddress', 'Email Address') || ''\"\n ></base-input>\n </div>\n\n <div class=\"col-span-2\">\n <base-phone-number-input\n [phoneCodeOptions]=\"phoneCodeOptions\"\n [defaultCountryCode]=\"defaultCountryCode\"\n label=\"Phone number\"\n [preventPaste]=\"true\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'phoneNumber', 'Phone Number') || ''\"\n (codeChange)=\"onCodeChange($event)\"\n (valueChange)=\"onPhoneChange($event)\"\n ></base-phone-number-input>\n </div>\n </div>\n </form>\n }\n\n <!-- Card Details -->\n @if (formIndex === 1) {\n <form [formGroup]=\"payForm\">\n <div class=\"grid grid-cols-2 gap-6 overflow-y-auto\" style=\"max-height: 320px\">\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"customerName\"\n label=\"Card Name\"\n [required]=\"true\"\n [validationError]=\"getError('pay', 'customerName', 'Customer Name') || ''\"\n ></base-input>\n </div>\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"cardNo\"\n label=\"Card Number\"\n [required]=\"true\"\n mask=\"0000 0000 0000 0000\"\n placeholder=\"0000 0000 0000 0000\"\n [preventPaste]=\"false\"\n [validationError]=\"getError('pay', 'cardNo', 'Card Number') || ''\"\n (onInputChange)=\"cardNumberInputHandler($event)\"\n ></base-input>\n </div>\n <base-input\n formControlName=\"expireDate\"\n label=\"Expiry Date\"\n [required]=\"true\"\n mask=\"00/00\"\n placeholder=\"00/00\"\n [validationError]=\"getError('pay', 'expireDate', 'Expiry Date') || ''\"\n ></base-input>\n <base-input\n formControlName=\"cvv\"\n label=\"CVV\"\n [required]=\"true\"\n mask=\"000\"\n placeholder=\"000\"\n [validationError]=\"getError('pay', 'cvv', 'CVV') || ''\"\n ></base-input>\n\n @if (cardType === 'Verve') {\n <base-input\n formControlName=\"cardPin\"\n label=\"Card Pin\"\n type=\"password\"\n placeholder=\"0000\"\n mask=\"0000\"\n [required]=\"true\"\n [validationError]=\"getError('pay', 'cardPin', 'Card Pin') || ''\"\n ></base-input>\n <div class=\"text-sm text-blue-600 mb-4\">\n <i class=\"fas fa-info-circle mr-1\"></i>\n Pin is required for Verve cards\n </div>\n }\n </div>\n </form>\n }\n\n <div class=\"flex items-center justify-between gap-4 mt-6 w-full\">\n @if (formIndex > 0) {\n <div class=\"w-1/2\">\n <base-button\n label=\"Previous\"\n type=\"secondary\"\n [caller]=\"caller\"\n (onClick)=\"goBack()\"\n ></base-button>\n </div>\n }\n <div [class]=\"formIndex === 0 ? 'w-full' : 'w-1/2'\">\n <base-button\n [label]=\"formIndex === 0 ? 'Proceed' : 'Pay ' + formatAmountHandler\"\n type=\"primary\"\n [caller]=\"caller\"\n [loading]=\"isMakingPayment\"\n (onClick)=\"proceedHandler()\"\n ></base-button>\n </div>\n </div>\n </div>\n}\n" }]
2501
+ ], template: "@if (threeDSOpen) {\n <div class=\"fixed inset-0 z-50 flex items-center justify-center bg-white p-4\">\n <iframe\n title=\"Miden 3DS\"\n [src]=\"threeDSIframeSrc\"\n class=\"w-full h-full\"\n sandbox=\"allow-forms allow-scripts allow-same-origin allow-top-navigation\"\n ></iframe>\n </div>\n} @else {\n <div class=\"flex flex-col gap-6\">\n <!-- Billing Details -->\n @if (formIndex === 0) {\n <form [formGroup]=\"billingForm\">\n <div class=\"grid grid-cols-2 gap-6 overflow-y-auto\">\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"address1\"\n label=\"Address Line 1\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'address1', 'Address Line 1') || ''\"\n ></base-input>\n </div>\n <div class=\"col-span-2\">\n <base-input formControlName=\"address2\" label=\"Address Line 2\"></base-input>\n </div>\n <div class=\"col-span-2 sm:col-span-1\">\n <base-select\n formControlName=\"country\"\n label=\"Select Country\"\n [required]=\"true\"\n [options]=\"countries\"\n [loading]=\"loadingCountries\"\n [validationError]=\"getError('billing', 'country', 'Country') || ''\"\n (onSelectChange)=\"getCountryStates($event)\"\n ></base-select>\n </div>\n <div class=\"col-span-2 sm:col-span-1\">\n <base-select\n formControlName=\"state\"\n label=\"Select State\"\n [required]=\"true\"\n [options]=\"countryStates\"\n [loading]=\"loadingStates\"\n [validationError]=\"getError('billing', 'state', 'State') || ''\"\n ></base-select>\n </div>\n <div class=\"col-span-2 sm:col-span-1\">\n <base-input\n formControlName=\"city\"\n label=\"City\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'city', 'City') || ''\"\n ></base-input>\n </div>\n <div class=\"col-span-2 sm:col-span-1\">\n <base-input\n formControlName=\"postalCode\"\n label=\"Postal Code\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'postalCode', 'Postal Code') || ''\"\n ></base-input>\n </div>\n\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"emailAddress\"\n label=\"Email\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'emailAddress', 'Email Address') || ''\"\n ></base-input>\n </div>\n\n <div class=\"col-span-2\">\n <base-phone-number-input\n [value]=\"billingForm.get('phoneNumber')?.value ?? ''\"\n [phoneCodeOptions]=\"phoneCodeOptions\"\n [defaultCountryCode]=\"defaultCountryCode\"\n label=\"Phone number\"\n [preventPaste]=\"true\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'phoneNumber', 'Phone Number') || ''\"\n (codeChange)=\"onCodeChange($event)\"\n (valueChange)=\"onPhoneChange($event)\"\n ></base-phone-number-input>\n </div>\n </div>\n </form>\n }\n\n <!-- Card Details -->\n @if (formIndex === 1) {\n <form [formGroup]=\"payForm\">\n <div class=\"grid grid-cols-2 gap-6 overflow-y-auto\" style=\"max-height: 320px\">\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"customerName\"\n label=\"Card Name\"\n [required]=\"true\"\n [validationError]=\"getError('pay', 'customerName', 'Customer Name') || ''\"\n ></base-input>\n </div>\n <div class=\"col-span-2\">\n <base-input\n formControlName=\"cardNo\"\n label=\"Card Number\"\n [required]=\"true\"\n mask=\"0000 0000 0000 0000 000\"\n placeholder=\"0000 0000 0000 0000\"\n [preventPaste]=\"true\"\n [validationError]=\"getError('pay', 'cardNo', 'Card Number') || ''\"\n (onInputChange)=\"cardNumberInputHandler($event)\"\n ></base-input>\n </div>\n <base-input\n formControlName=\"expireDate\"\n label=\"Expiry Date\"\n [required]=\"true\"\n mask=\"00/00\"\n placeholder=\"00/00\"\n [validationError]=\"getError('pay', 'expireDate', 'Expiry Date') || ''\"\n ></base-input>\n <base-input\n formControlName=\"cvv\"\n label=\"CVV\"\n [required]=\"true\"\n mask=\"000\"\n placeholder=\"000\"\n [validationError]=\"getError('pay', 'cvv', 'CVV') || ''\"\n ></base-input>\n\n @if (cardType === 'Verve') {\n <base-input\n formControlName=\"cardPin\"\n label=\"Card Pin\"\n type=\"password\"\n placeholder=\"0000\"\n mask=\"0000\"\n [required]=\"true\"\n [validationError]=\"getError('pay', 'cardPin', 'Card Pin') || ''\"\n ></base-input>\n <!-- <div class=\"text-sm text-blue-600 mb-4\">\n <i class=\"fas fa-info-circle mr-1\"></i>\n Pin is required for Verve cards\n </div> -->\n }\n </div>\n </form>\n }\n\n <div class=\"flex items-center justify-between gap-4 mt-6 w-full\">\n @if (formIndex > 0) {\n <div class=\"w-1/2\">\n <base-button\n label=\"Previous\"\n type=\"secondary\"\n [caller]=\"caller\"\n (onClick)=\"goBack()\"\n ></base-button>\n </div>\n }\n <div [class]=\"formIndex === 0 ? 'w-full' : 'w-1/2'\">\n <base-button\n [label]=\"formIndex === 0 ? 'Proceed' : 'Pay ' + formatAmountHandler\"\n type=\"primary\"\n [caller]=\"caller\"\n [loading]=\"isMakingPayment\"\n (onClick)=\"proceedHandler()\"\n ></base-button>\n </div>\n </div>\n </div>\n}\n" }]
2477
2502
  }], ctorParameters: () => [{ type: ResourceService }, { type: i0.ChangeDetectorRef }, { type: CheckoutService }, { type: EncryptService }, { type: i4.DomSanitizer }], propDecorators: { secretKey: [{
2478
2503
  type: Input
2479
2504
  }], environment: [{
@@ -2842,7 +2867,7 @@ class PayByTransferComponent {
2842
2867
  await this.checkout.generatePaymentAccount(this.environment, payload, this.caller).subscribe({
2843
2868
  next: async (response) => {
2844
2869
  if (response?.isSuccessful) {
2845
- this.paymentAccountDetails = response;
2870
+ this.paymentAccountDetails = this.caller === 'buzapay' ? response.data : response;
2846
2871
  this.startTimer();
2847
2872
  this.message = 'Virtual account generated successfully for payment.';
2848
2873
  this.isMakingPayment = false;
@@ -2866,13 +2891,14 @@ class PayByTransferComponent {
2866
2891
  .subscribe({
2867
2892
  next: async (response) => {
2868
2893
  if (response?.isSuccessful) {
2869
- this.paymentReferenceDetails = response.data;
2894
+ this.paymentReferenceDetails =
2895
+ this.caller === 'buzapay' ? response.data : response;
2870
2896
  // Check if payment has been made (paymentStatus is "Payment Received")
2871
- if (response.data?.paymentStatus === 'Payment Received') {
2897
+ if (this.paymentReferenceDetails?.paymentStatus === 'Payment Received') {
2872
2898
  this.paymentMade = true;
2873
2899
  }
2874
- if (response.data?.finalTransactionStatus === null ||
2875
- response.data?.paymentStatus === null) {
2900
+ if (this.paymentReferenceDetails?.finalTransactionStatus === null ||
2901
+ this.paymentReferenceDetails?.paymentStatus === null) {
2876
2902
  if (this.isConfirmCall) {
2877
2903
  this.message = 'Transaction not confirmed !!';
2878
2904
  }
@@ -2881,7 +2907,7 @@ class PayByTransferComponent {
2881
2907
  this.paymentReferenceStatus = 'pending';
2882
2908
  this.paymentAuthorized.emit({
2883
2909
  paymentId: this.transactionReference,
2884
- paymentDate: response?.data?.updatedAt ?? new Date().toISOString(),
2910
+ paymentDate: this.paymentReferenceDetails?.updatedAt ?? new Date().toISOString(),
2885
2911
  paymentStatus: this.paymentReferenceStatus,
2886
2912
  message: this.message,
2887
2913
  });
@@ -2890,18 +2916,18 @@ class PayByTransferComponent {
2890
2916
  this.paymentReferenceStatus = 'confirmed';
2891
2917
  this.paymentAuthorized.emit({
2892
2918
  paymentId: this.transactionReference,
2893
- paymentDate: response?.data?.updatedAt ?? new Date().toISOString(),
2919
+ paymentDate: this.paymentReferenceDetails?.updatedAt ?? new Date().toISOString(),
2894
2920
  paymentStatus: this.paymentReferenceStatus,
2895
2921
  message: this.message,
2896
2922
  });
2897
2923
  }
2898
2924
  }
2899
- else if (response.data?.finalTransactionStatus === 'Success' ||
2900
- response.data?.paymentStatus === 'Received' ||
2901
- response.data?.paymentStatus === 'Payment Received') {
2925
+ else if (this.paymentReferenceDetails?.finalTransactionStatus === 'Success' ||
2926
+ this.paymentReferenceDetails?.paymentStatus === 'Received' ||
2927
+ this.paymentReferenceDetails?.paymentStatus === 'Payment Received') {
2902
2928
  this.paymentAuthorized.emit({
2903
2929
  paymentId: this.transactionReference,
2904
- paymentDate: response?.data?.updatedAt ?? new Date().toISOString(),
2930
+ paymentDate: this.paymentReferenceDetails?.updatedAt ?? new Date().toISOString(),
2905
2931
  paymentStatus: this.paymentReferenceStatus,
2906
2932
  message: this.message,
2907
2933
  });
@@ -2915,7 +2941,7 @@ class PayByTransferComponent {
2915
2941
  this.message = response.responseMessage;
2916
2942
  this.paymentAuthorized.emit({
2917
2943
  paymentId: this.transactionReference,
2918
- paymentDate: null,
2944
+ paymentDate: new Date().toISOString(),
2919
2945
  paymentStatus: this.paymentReferenceStatus,
2920
2946
  message: this.message,
2921
2947
  });