@miden-npm/angular 2.1.4 → 2.1.6

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.
@@ -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 });
@@ -1879,6 +1905,40 @@ class CheckoutService {
1879
1905
  headers,
1880
1906
  });
1881
1907
  }
1908
+ validateCardPaymentOtp(environment, { merchantId, ...rest }, caller = 'buzapay') {
1909
+ const baseUrl = getBaseUrl(environment, caller);
1910
+ if (!merchantId || merchantId.trim() === '') {
1911
+ throw new Error('merchantId is required for authorizeCardPayment');
1912
+ }
1913
+ const headers = new HttpHeaders({
1914
+ merchantId: merchantId.trim(),
1915
+ uniqueKey: merchantId.trim(),
1916
+ });
1917
+ const apiKey = {
1918
+ buzapay: 'api/v1/checkout/card-payment/validate-otp',
1919
+ miden: '',
1920
+ };
1921
+ return this.http.post(`${baseUrl}/${apiKey[caller]}`, rest, {
1922
+ headers,
1923
+ });
1924
+ }
1925
+ resendCardPaymentOtp(environment, { merchantId, ...rest }, caller = 'buzapay') {
1926
+ const baseUrl = getBaseUrl(environment, caller);
1927
+ if (!merchantId || merchantId.trim() === '') {
1928
+ throw new Error('merchantId is required for authorizeCardPayment');
1929
+ }
1930
+ const headers = new HttpHeaders({
1931
+ merchantId: merchantId.trim(),
1932
+ uniqueKey: merchantId.trim(),
1933
+ });
1934
+ const apiKey = {
1935
+ buzapay: 'api/v1/checkout/card-payment/resend-otp',
1936
+ miden: '',
1937
+ };
1938
+ return this.http.post(`${baseUrl}/${apiKey[caller]}`, rest, {
1939
+ headers,
1940
+ });
1941
+ }
1882
1942
  getPaymentReferenceDetails(environment, paymentReference, caller = 'buzapay') {
1883
1943
  const baseUrl = getBaseUrl(environment, caller);
1884
1944
  const apiKey = {
@@ -2001,6 +2061,8 @@ class PayByCardComponent {
2001
2061
  loadingCountries = false;
2002
2062
  loadingStates = false;
2003
2063
  isMakingPayment = false;
2064
+ isValidatingOtp = false;
2065
+ isSendingOtp = false;
2004
2066
  cardType = '';
2005
2067
  message = '';
2006
2068
  transactionReference = '';
@@ -2033,6 +2095,9 @@ class PayByCardComponent {
2033
2095
  cvv: new FormControl('', [Validators.required]),
2034
2096
  cardPin: new FormControl(''), // Only required for Verve cards
2035
2097
  });
2098
+ otpForm = new FormGroup({
2099
+ otp: new FormControl('', [Validators.required]),
2100
+ });
2036
2101
  onCodeChange(e) {
2037
2102
  this.billingForm.patchValue({ phoneNumberExt: e });
2038
2103
  }
@@ -2040,7 +2105,11 @@ class PayByCardComponent {
2040
2105
  this.billingForm.patchValue({ phoneNumber: e });
2041
2106
  }
2042
2107
  getError(formKey, controlName, label) {
2043
- const control = formKey === 'billing' ? this.billingForm.get(controlName) : this.payForm.get(controlName);
2108
+ const control = formKey === 'billing'
2109
+ ? this.billingForm.get(controlName)
2110
+ : formKey === 'pay'
2111
+ ? this.payForm.get(controlName)
2112
+ : this.otpForm.get(controlName);
2044
2113
  return getValidationErrorMessage(control, label);
2045
2114
  }
2046
2115
  get formatAmountHandler() {
@@ -2263,189 +2332,250 @@ class PayByCardComponent {
2263
2332
  this.billingForm.markAllAsTouched();
2264
2333
  }
2265
2334
  }
2266
- else {
2335
+ else if (this.formIndex === 1) {
2267
2336
  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 ?? '' }),
2337
+ this.isMakingPayment = true;
2338
+ // Create card details object for encryption
2339
+ const cardDetails = {
2340
+ pan: this.payForm.value.cardNo ? this.payForm.value.cardNo.replaceAll(' ', '') : '',
2341
+ expiryDate: this.payForm.value.expireDate ?? '',
2342
+ cvv: this.payForm.value.cvv ?? '',
2343
+ cardScheme: this.cardType,
2344
+ nameOnCard: this.payForm.value.customerName ?? '',
2345
+ ...(this.cardType === 'Verve' && { pin: this.payForm.value.cardPin ?? '' }),
2346
+ };
2347
+ // Get billing details from the form control
2348
+ const billingDetails = {
2349
+ address2: this.billingForm.value.address2 ?? '',
2350
+ address1: this.billingForm.value.address1 ?? '',
2351
+ postalCode: this.billingForm.value.postalCode ?? '',
2352
+ state: this.billingForm.value.state ?? '',
2353
+ city: this.billingForm.value.city ?? '',
2354
+ country: this.billingForm.value.country ?? '',
2355
+ emailAddress: this.billingForm.value.emailAddress ?? '',
2356
+ phoneNumber: this.billingForm.value.phoneNumber
2357
+ ? `${this.billingForm.value.phoneNumberExt}${this.billingForm.value.phoneNumber}`
2358
+ : '',
2359
+ };
2360
+ // Encrypt card details using payload encryption method
2361
+ const encryptedCardDetails = this.encryptService.encryptPayload(this.secretKey, cardDetails);
2362
+ // Test: Decrypt to verify encryption works
2363
+ // const decryptedTest = this.encryptService.decryptPayload(
2364
+ // this.environment,
2365
+ // encryptedCardDetails.requestParam,
2366
+ // );
2367
+ let payload = null;
2368
+ let payloadMiden = null;
2369
+ if (this.caller === 'buzapay') {
2370
+ payload = {
2371
+ customerId: this.paymentObject?.email || this.payForm.value.customerName || '',
2372
+ amount: this.paymentObject?.amount.toString(),
2373
+ currency: this.paymentObject?.currency || 'USD',
2374
+ narration: this.paymentObject?.narration || 'Test transaction',
2375
+ encryptedCardDetails: encryptedCardDetails.requestParam, // Use the encrypted card details
2376
+ billingDetails: billingDetails,
2377
+ redirectUrl: this.paymentObject?.redirectUrl || `${this.baseAppUrl}/account/three-ds-status`,
2378
+ paymentReference: this.transactionReference,
2379
+ isCheckout: true,
2278
2380
  };
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
- : '',
2381
+ }
2382
+ else {
2383
+ const deviceInformation = buildDeviceInformation();
2384
+ payloadMiden = {
2385
+ customerId: this.paymentObject?.email || this.payForm.value.customerName || '',
2386
+ amount: this.paymentObject?.amount.toString(),
2387
+ currency: this.paymentObject?.currency || 'USD',
2388
+ narration: this.paymentObject?.narration || 'Test transaction',
2389
+ encryptedCardDetails: encryptedCardDetails.requestParam, // Use the encrypted card details
2390
+ billingDetails: billingDetails,
2391
+ redirectUrl: this.paymentObject?.redirectUrl || `${this.baseAppUrl}/pay/verification`,
2392
+ paymentReference: this.transactionReference,
2393
+ isCheckout: true,
2394
+ postBackUrl: '',
2395
+ saveCard: false,
2396
+ deviceInformation,
2291
2397
  };
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
- };
2398
+ }
2399
+ this.checkout
2400
+ .authorizeCardPayment(this.environment, this.caller === 'buzapay'
2401
+ ? {
2402
+ ...payload,
2403
+ merchantId: this.secretKey,
2330
2404
  }
2331
- this.checkout
2332
- .authorizeCardPayment(this.environment, this.caller === 'buzapay'
2333
- ? {
2334
- ...payload,
2335
- merchantId: this.secretKey,
2405
+ : {
2406
+ ...payloadMiden,
2407
+ merchantId: this.secretKey,
2408
+ }, this.caller)
2409
+ .subscribe({
2410
+ next: async (response) => {
2411
+ let processedResponse = response;
2412
+ // Check if response is encrypted (has responseParam)
2413
+ if (response?.responseParam) {
2414
+ // Decrypt the response
2415
+ processedResponse = this.encryptService.decryptPayload(this.environment, response.responseParam);
2336
2416
  }
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);
2348
- }
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';
2417
+ if (processedResponse?.isSuccessful) {
2418
+ // Verve OTPValidationRequired flow
2419
+ if (processedResponse?.otpValidationRequired) {
2417
2420
  this.isMakingPayment = false;
2421
+ this.setFormIndex(2);
2422
+ this.cdr.markForCheck();
2423
+ return;
2418
2424
  }
2419
- else {
2425
+ // Miden flow
2426
+ if (this.caller === 'miden') {
2427
+ this.handleMidenCard(processedResponse);
2428
+ return;
2429
+ }
2430
+ // Check for 3DS authentication requirement
2431
+ if (processedResponse.threeDsInteractionRequired === true) {
2432
+ // Store 3DS data for the authentication page
2433
+ const threeDsData = {
2434
+ transactionReference: processedResponse.transactionReference,
2435
+ threeDsHtml: processedResponse.threeDsHtml,
2436
+ amount: processedResponse.amount,
2437
+ responseMessage: processedResponse.responseMessage,
2438
+ // Pass all 3DS details
2439
+ paReq: processedResponse.threeDsHtml?.paReq,
2440
+ termUrl: processedResponse.threeDsHtml?.termUrl,
2441
+ action: processedResponse.threeDsHtml?.action,
2442
+ acsUrl: processedResponse.threeDsHtml?.acsUrl,
2443
+ md: processedResponse.threeDsHtml?.md,
2444
+ };
2445
+ // Encrypt 3DS data to pass as url param
2446
+ const stringifiedThreeDsData = btoa(JSON.stringify(threeDsData));
2447
+ // Open 3DS authentication page in a new tab
2448
+ const threeDsUrl = `${this.baseAppUrl}/account/three-ds-confirm?threeDsData=${encodeURIComponent(stringifiedThreeDsData)}&paymentReference=${processedResponse.transactionReference}`;
2449
+ window.open(threeDsUrl, '_self', 'noopener,noreferrer');
2450
+ this.message =
2451
+ '3D Secure authentication opened in new tab. Please complete the verification';
2420
2452
  this.isMakingPayment = false;
2421
- this.message = processedResponse.responseMessage || 'Payment failed';
2422
- this.onError.emit({ errorMessage: this.message });
2453
+ return;
2423
2454
  }
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';
2455
+ // Fallback check: if response message indicates 3DS is required
2456
+ if (processedResponse.responseMessage === 'Payer Interaction Required' &&
2457
+ processedResponse.threeDsHtml) {
2458
+ // Store 3DS data for the authentication page
2459
+ const threeDsData = {
2460
+ transactionReference: processedResponse.transactionReference,
2461
+ threeDsHtml: processedResponse.threeDsHtml,
2462
+ amount: processedResponse.amount,
2463
+ responseMessage: processedResponse.responseMessage,
2464
+ // Pass all 3DS details
2465
+ paReq: processedResponse.threeDsHtml?.paReq,
2466
+ termUrl: processedResponse.threeDsHtml?.termUrl,
2467
+ action: processedResponse.threeDsHtml?.action,
2468
+ acsUrl: processedResponse.threeDsHtml?.acsUrl,
2469
+ md: processedResponse.threeDsHtml?.md,
2470
+ };
2471
+ // Encrypt 3DS data to pass as url param
2472
+ const stringifiedThreeDsData = btoa(JSON.stringify(threeDsData));
2473
+ // Open 3DS authentication page in a new tab
2474
+ const threeDsUrl = `${this.baseAppUrl}/account/three-ds-confirm?threeDsData=${encodeURIComponent(stringifiedThreeDsData)}&paymentReference=${processedResponse.transactionReference}`;
2475
+ window.open(threeDsUrl, '_self', 'noopener,noreferrer');
2476
+ this.message =
2477
+ '3D Secure authentication opened in new tab. Please complete the verification';
2478
+ this.isMakingPayment = false;
2479
+ return;
2431
2480
  }
2432
- else {
2433
- this.message = err.error.message || err.error.responseMessage || 'Payment failed';
2481
+ // Emit the transaction reference to parent component
2482
+ if (processedResponse.transactionReference &&
2483
+ processedResponse.transactionReference.trim() !== '') {
2484
+ this.paymentAuthorized.emit({
2485
+ paymentId: processedResponse.transactionReference,
2486
+ paymentDate: response?.data?.updatedAt ?? new Date().toISOString(),
2487
+ paymentStatus: 'authorized',
2488
+ message: this.message,
2489
+ });
2434
2490
  }
2491
+ this.message = 'Card payment authorized successfully';
2492
+ this.isMakingPayment = false;
2493
+ }
2494
+ // Failure path for miden
2495
+ if (processedResponse && !processedResponse.isSuccessful && this.caller === 'miden') {
2496
+ this.message = processedResponse.responseMessage;
2435
2497
  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
- }
2498
+ }
2499
+ // Failure path for buzapay
2500
+ if (processedResponse && processedResponse.message && this.caller === 'buzapay') {
2501
+ this.message = response.message;
2502
+ this.onError.emit({ errorMessage: this.message });
2503
+ }
2504
+ this.isMakingPayment = false;
2505
+ },
2506
+ error: (err) => {
2507
+ this.isMakingPayment = false;
2508
+ if (err.error?.responseParam) {
2509
+ // Decrypt error response
2510
+ const decryptedErrorResponse = this.encryptService.decryptPayload(this.environment, err.error.responseParam);
2511
+ this.message = decryptedErrorResponse.responseMessage || 'Payment failed';
2512
+ }
2513
+ else {
2514
+ this.message = err.error.message || err.error.responseMessage || 'Payment failed';
2515
+ }
2516
+ this.onError.emit({ errorMessage: this.message });
2517
+ },
2518
+ });
2444
2519
  }
2445
2520
  else {
2446
2521
  this.payForm.markAllAsTouched();
2447
2522
  }
2448
2523
  }
2524
+ else {
2525
+ if (this.otpForm && this.otpForm.valid) {
2526
+ this.isValidatingOtp = true;
2527
+ this.checkout
2528
+ .validateCardPaymentOtp(this.environment, {
2529
+ transactionReference: this.transactionReference,
2530
+ otp: this.otpForm.value.otp,
2531
+ merchantId: this.secretKey,
2532
+ }, this.caller)
2533
+ .subscribe({
2534
+ next: async (response) => {
2535
+ this.isValidatingOtp = false;
2536
+ this.paymentAuthorized.emit({
2537
+ paymentId: response.transactionReference,
2538
+ paymentDate: response?.data?.updatedAt ?? new Date().toISOString(),
2539
+ paymentStatus: 'authorized',
2540
+ message: response?.responseMessage,
2541
+ });
2542
+ },
2543
+ error: (err) => {
2544
+ this.isValidatingOtp = false;
2545
+ this.message =
2546
+ err.error.message || err.error.responseMessage || 'Validate OTP Failed';
2547
+ this.onError.emit({ errorMessage: this.message });
2548
+ },
2549
+ });
2550
+ }
2551
+ else {
2552
+ this.otpForm.markAllAsTouched();
2553
+ }
2554
+ }
2555
+ }
2556
+ async resendOtp() {
2557
+ this.isSendingOtp = true;
2558
+ this.checkout
2559
+ .resendCardPaymentOtp(this.environment, {
2560
+ transactionReference: this.transactionReference,
2561
+ merchantId: this.secretKey,
2562
+ }, this.caller)
2563
+ .subscribe({
2564
+ next: async (response) => {
2565
+ if (response?.isSuccessful) {
2566
+ this.isSendingOtp = false;
2567
+ this.notyf.success({
2568
+ message: 'OTP Sent Successfully.',
2569
+ ...toastConfig,
2570
+ });
2571
+ }
2572
+ },
2573
+ error: (err) => {
2574
+ this.isSendingOtp = false;
2575
+ this.message = err.error.message || err.error.responseMessage || 'OTP Sending Failed';
2576
+ this.onError.emit({ errorMessage: this.message });
2577
+ },
2578
+ });
2449
2579
  }
2450
2580
  async ngOnInit() {
2451
2581
  this.notyf = new Notyf();
@@ -2463,7 +2593,7 @@ class PayByCardComponent {
2463
2593
  }).sort((a, b) => a.label.localeCompare(b.label));
2464
2594
  }
2465
2595
  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 <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 [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 });
2596
+ 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 <!-- Verve OTP Verification -->\n @if (formIndex === 2) {\n <form [formGroup]=\"otpForm\">\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=\"otp\"\n label=\"OTP\"\n [required]=\"true\"\n [validationError]=\"getError('otp', 'otp', 'OTP') || ''\"\n ></base-input>\n </div>\n </div>\n <p class=\"text-primary text-sm mt-2\">\n Didn't get OTP?\n <span\n [class]=\"isSendingOtp ? '' : 'underline cursor-pointer'\"\n (click)=\"isSendingOtp ? null : resendOtp()\"\n >{{ isSendingOtp ? 'Sending...' : 'Resend OTP' }}</span\n >\n </p>\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 @if (formIndex < 2) {\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 }\n @if (formIndex === 2) {\n <div class=\"w-1/2\">\n <base-button\n label=\"Validate OTP\"\n type=\"primary\"\n [caller]=\"caller\"\n [loading]=\"isValidatingOtp\"\n (onClick)=\"proceedHandler()\"\n ></base-button>\n </div>\n }\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
2597
  }
2468
2598
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PayByCardComponent, decorators: [{
2469
2599
  type: Component,
@@ -2473,7 +2603,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2473
2603
  SelectComponent,
2474
2604
  ReactiveFormsModule,
2475
2605
  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 <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 [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" }]
2606
+ ], 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 <!-- Verve OTP Verification -->\n @if (formIndex === 2) {\n <form [formGroup]=\"otpForm\">\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=\"otp\"\n label=\"OTP\"\n [required]=\"true\"\n [validationError]=\"getError('otp', 'otp', 'OTP') || ''\"\n ></base-input>\n </div>\n </div>\n <p class=\"text-primary text-sm mt-2\">\n Didn't get OTP?\n <span\n [class]=\"isSendingOtp ? '' : 'underline cursor-pointer'\"\n (click)=\"isSendingOtp ? null : resendOtp()\"\n >{{ isSendingOtp ? 'Sending...' : 'Resend OTP' }}</span\n >\n </p>\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 @if (formIndex < 2) {\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 }\n @if (formIndex === 2) {\n <div class=\"w-1/2\">\n <base-button\n label=\"Validate OTP\"\n type=\"primary\"\n [caller]=\"caller\"\n [loading]=\"isValidatingOtp\"\n (onClick)=\"proceedHandler()\"\n ></base-button>\n </div>\n }\n </div>\n </div>\n}\n" }]
2477
2607
  }], ctorParameters: () => [{ type: ResourceService }, { type: i0.ChangeDetectorRef }, { type: CheckoutService }, { type: EncryptService }, { type: i4.DomSanitizer }], propDecorators: { secretKey: [{
2478
2608
  type: Input
2479
2609
  }], environment: [{
@@ -2776,6 +2906,10 @@ class PayByTransferComponent {
2776
2906
  this.countDownTime = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
2777
2907
  this.cdr.markForCheck(); // 👈 notify OnPush to re-render
2778
2908
  }
2909
+ resetPaymentAccountDetails() {
2910
+ this.paymentAccountDetails = null;
2911
+ this.cdr.markForCheck();
2912
+ }
2779
2913
  transferForm = new FormGroup({
2780
2914
  customerName: new FormControl('', [Validators.required]),
2781
2915
  });
@@ -2842,7 +2976,7 @@ class PayByTransferComponent {
2842
2976
  await this.checkout.generatePaymentAccount(this.environment, payload, this.caller).subscribe({
2843
2977
  next: async (response) => {
2844
2978
  if (response?.isSuccessful) {
2845
- this.paymentAccountDetails = response;
2979
+ this.paymentAccountDetails = this.caller === 'buzapay' ? response.data : response;
2846
2980
  this.startTimer();
2847
2981
  this.message = 'Virtual account generated successfully for payment.';
2848
2982
  this.isMakingPayment = false;
@@ -2866,13 +3000,14 @@ class PayByTransferComponent {
2866
3000
  .subscribe({
2867
3001
  next: async (response) => {
2868
3002
  if (response?.isSuccessful) {
2869
- this.paymentReferenceDetails = response.data;
3003
+ this.paymentReferenceDetails =
3004
+ this.caller === 'buzapay' ? response.data : response;
2870
3005
  // Check if payment has been made (paymentStatus is "Payment Received")
2871
- if (response.data?.paymentStatus === 'Payment Received') {
3006
+ if (this.paymentReferenceDetails?.paymentStatus === 'Payment Received') {
2872
3007
  this.paymentMade = true;
2873
3008
  }
2874
- if (response.data?.finalTransactionStatus === null ||
2875
- response.data?.paymentStatus === null) {
3009
+ if (this.paymentReferenceDetails?.finalTransactionStatus === null ||
3010
+ this.paymentReferenceDetails?.paymentStatus === null) {
2876
3011
  if (this.isConfirmCall) {
2877
3012
  this.message = 'Transaction not confirmed !!';
2878
3013
  }
@@ -2881,7 +3016,7 @@ class PayByTransferComponent {
2881
3016
  this.paymentReferenceStatus = 'pending';
2882
3017
  this.paymentAuthorized.emit({
2883
3018
  paymentId: this.transactionReference,
2884
- paymentDate: response?.data?.updatedAt ?? new Date().toISOString(),
3019
+ paymentDate: this.paymentReferenceDetails?.updatedAt ?? new Date().toISOString(),
2885
3020
  paymentStatus: this.paymentReferenceStatus,
2886
3021
  message: this.message,
2887
3022
  });
@@ -2890,18 +3025,18 @@ class PayByTransferComponent {
2890
3025
  this.paymentReferenceStatus = 'confirmed';
2891
3026
  this.paymentAuthorized.emit({
2892
3027
  paymentId: this.transactionReference,
2893
- paymentDate: response?.data?.updatedAt ?? new Date().toISOString(),
3028
+ paymentDate: this.paymentReferenceDetails?.updatedAt ?? new Date().toISOString(),
2894
3029
  paymentStatus: this.paymentReferenceStatus,
2895
3030
  message: this.message,
2896
3031
  });
2897
3032
  }
2898
3033
  }
2899
- else if (response.data?.finalTransactionStatus === 'Success' ||
2900
- response.data?.paymentStatus === 'Received' ||
2901
- response.data?.paymentStatus === 'Payment Received') {
3034
+ else if (this.paymentReferenceDetails?.finalTransactionStatus === 'Success' ||
3035
+ this.paymentReferenceDetails?.paymentStatus === 'Received' ||
3036
+ this.paymentReferenceDetails?.paymentStatus === 'Payment Received') {
2902
3037
  this.paymentAuthorized.emit({
2903
3038
  paymentId: this.transactionReference,
2904
- paymentDate: response?.data?.updatedAt ?? new Date().toISOString(),
3039
+ paymentDate: this.paymentReferenceDetails?.updatedAt ?? new Date().toISOString(),
2905
3040
  paymentStatus: this.paymentReferenceStatus,
2906
3041
  message: this.message,
2907
3042
  });
@@ -2915,7 +3050,7 @@ class PayByTransferComponent {
2915
3050
  this.message = response.responseMessage;
2916
3051
  this.paymentAuthorized.emit({
2917
3052
  paymentId: this.transactionReference,
2918
- paymentDate: null,
3053
+ paymentDate: new Date().toISOString(),
2919
3054
  paymentStatus: this.paymentReferenceStatus,
2920
3055
  message: this.message,
2921
3056
  });
@@ -2941,7 +3076,7 @@ class PayByTransferComponent {
2941
3076
  }
2942
3077
  }
2943
3078
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PayByTransferComponent, deps: [{ token: CheckoutService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
2944
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: PayByTransferComponent, isStandalone: true, selector: "pay-by-transfer", inputs: { secretKey: "secretKey", environment: "environment", caller: "caller", paymentObject: "paymentObject" }, outputs: { paymentAuthorized: "paymentAuthorized", onError: "onError" }, ngImport: i0, template: "<div class=\"flex flex-col gap-10\">\n @if (!paymentAccountDetails) {\n <form [formGroup]=\"transferForm\">\n <div class=\"flex flex-col gap-10\">\n <base-input\n formControlName=\"customerName\"\n label=\"Customer Name\"\n [required]=\"true\"\n [validationError]=\"getError('customerName', 'Customer Name') || ''\"\n ></base-input>\n\n <base-button\n [label]=\"'Pay ' + formatAmountHandler\"\n type=\"primary\"\n [caller]=\"caller\"\n customClass=\"w-full\"\n [loading]=\"isMakingPayment\"\n (onClick)=\"payHandler()\"\n ></base-button>\n </div>\n </form>\n }\n\n @if (paymentAccountDetails) {\n <div class=\"flex flex-col gap-10\">\n <div\n class=\"p-4 rounded-lg flex flex-col gap-6\"\n [ngClass]=\"{\n 'bg-[#FAFDFF] border border-[#F0FAFF]': caller === 'miden',\n 'bg-[#EFF7FF]': caller === 'buzapay',\n }\"\n >\n <base-label-info label=\"Bank Name\" [value]=\"paymentAccountDetails.bank\"></base-label-info>\n <base-label-info\n label=\"Account Name\"\n [value]=\"paymentAccountDetails.accountName\"\n ></base-label-info>\n <div class=\"flex items-center justify-between\">\n <base-label-info\n label=\"Account Number\"\n [value]=\"paymentAccountDetails.accountNumber\"\n ></base-label-info>\n <base-copy color=\"#9DBFDE\" [copyText]=\"paymentAccountDetails.accountNumber\"></base-copy>\n </div>\n <div class=\"flex items-center justify-between\">\n <base-label-info label=\"Amount\" [value]=\"formatAmountHandler\"></base-label-info>\n <base-copy color=\"#9DBFDE\" [copyText]=\"formatAmountHandler\"></base-copy>\n </div>\n </div>\n\n @if (caller === 'buzapay') {\n <p class=\"w-2/3 mx-auto text-center text-body-2xs font-medium text-sub-copy\">\n This account is for this transaction only and expires in\n <span class=\"text-orange-500\">{{ countDownTime }}</span>\n </p>\n } @else {\n <div class=\"p-4 rounded-lg bg-[#FAFDFF] flex items-center gap-3\">\n <base-circle-countdown\n [value]=\"remainingSeconds\"\n [total]=\"1800\"\n [middleText]=\"countDownTime\"\n [size]=\"40\"\n [stroke]=\"2\"\n style=\"color: #3b82f6\"\n ></base-circle-countdown>\n <p class=\"text-body-3xs font-medium text-light-copy\">\n This account is for this transaction only and expires in\n <span class=\"text-[#1383E8]\">{{ countDownTime }}...</span>\n </p>\n </div>\n }\n\n <div class=\"flex flex-col gap-4\">\n <base-button\n label=\"I have paid the money\"\n type=\"primary\"\n [caller]=\"caller\"\n customClass=\"w-full\"\n [loading]=\"isFetchingPaymentDetails\"\n (onClick)=\"getReferenceDetails()\"\n ></base-button>\n <p class=\"text-heading-text text-body-2xs font-medium text-center py-2 cursor-pointer\">\n Cancel Payment\n </p>\n </div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "component", type: LabelInfoComponent, selector: "base-label-info", inputs: ["type", "label", "labelCustomClass", "valueImageSrc", "valueImageCustomClass", "valueImagePosition", "hasValueCopy", "value", "valueCustomClass", "alignRight"] }, { kind: "component", type: CopyComponent, selector: "base-copy", inputs: ["copyText", "color"] }, { kind: "component", type: ButtonComponent, selector: "base-button", inputs: ["label", "type", "caller", "size", "paddingClassX", "disabled", "loading", "customClass"], outputs: ["onClick"] }, { 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: InputComponent, selector: "base-input", inputs: ["label", "type", "placeholder", "validationError", "hint", "mask", "rules", "isAmountInput", "required", "disabled", "loading", "showCopyIcon", "preventPaste", "showBottomText"], outputs: ["onInputChange", "onInputBlur"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: CircleCountdownComponent, selector: "base-circle-countdown", inputs: ["value", "total", "middleText", "size", "stroke"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3079
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: PayByTransferComponent, isStandalone: true, selector: "pay-by-transfer", inputs: { secretKey: "secretKey", environment: "environment", caller: "caller", paymentObject: "paymentObject" }, outputs: { paymentAuthorized: "paymentAuthorized", onError: "onError" }, ngImport: i0, template: "<div class=\"flex flex-col gap-10\">\n @if (!paymentAccountDetails) {\n <form [formGroup]=\"transferForm\">\n <div class=\"flex flex-col gap-10\">\n <base-input\n formControlName=\"customerName\"\n label=\"Customer Name\"\n [required]=\"true\"\n [validationError]=\"getError('customerName', 'Customer Name') || ''\"\n ></base-input>\n\n <base-button\n [label]=\"'Pay ' + formatAmountHandler\"\n type=\"primary\"\n [caller]=\"caller\"\n customClass=\"w-full\"\n [loading]=\"isMakingPayment\"\n (onClick)=\"payHandler()\"\n ></base-button>\n </div>\n </form>\n }\n\n @if (paymentAccountDetails) {\n <div class=\"flex flex-col gap-10\">\n <div\n class=\"p-4 rounded-lg flex flex-col gap-6\"\n [ngClass]=\"{\n 'bg-[#FAFDFF] border border-[#F0FAFF]': caller === 'miden',\n 'bg-[#EFF7FF]': caller === 'buzapay',\n }\"\n >\n <base-label-info label=\"Bank Name\" [value]=\"paymentAccountDetails.bank\"></base-label-info>\n <base-label-info\n label=\"Account Name\"\n [value]=\"paymentAccountDetails.accountName\"\n ></base-label-info>\n <div class=\"flex items-center justify-between\">\n <base-label-info\n label=\"Account Number\"\n [value]=\"paymentAccountDetails.accountNumber\"\n ></base-label-info>\n <base-copy color=\"#9DBFDE\" [copyText]=\"paymentAccountDetails.accountNumber\"></base-copy>\n </div>\n <div class=\"flex items-center justify-between\">\n <base-label-info label=\"Amount\" [value]=\"formatAmountHandler\"></base-label-info>\n <base-copy color=\"#9DBFDE\" [copyText]=\"formatAmountHandler\"></base-copy>\n </div>\n </div>\n\n @if (caller === 'buzapay') {\n <p class=\"w-2/3 mx-auto text-center text-body-2xs font-medium text-sub-copy\">\n This account is for this transaction only and expires in\n <span class=\"text-orange-500\">{{ countDownTime }}</span>\n </p>\n } @else {\n <div class=\"p-4 rounded-lg bg-[#FAFDFF] flex items-center gap-3\">\n <base-circle-countdown\n [value]=\"remainingSeconds\"\n [total]=\"1800\"\n [middleText]=\"countDownTime\"\n [size]=\"40\"\n [stroke]=\"2\"\n style=\"color: #3b82f6\"\n ></base-circle-countdown>\n <p class=\"text-body-3xs font-medium text-light-copy\">\n This account is for this transaction only and expires in\n <span class=\"text-[#1383E8]\">{{ countDownTime }}...</span>\n </p>\n </div>\n }\n\n <div class=\"flex flex-col gap-4\">\n <base-button\n label=\"I have paid the money\"\n type=\"primary\"\n [caller]=\"caller\"\n customClass=\"w-full\"\n [loading]=\"isFetchingPaymentDetails\"\n (onClick)=\"getReferenceDetails()\"\n ></base-button>\n <p\n class=\"text-heading-text text-body-2xs font-medium text-center py-2 cursor-pointer\"\n (click)=\"resetPaymentAccountDetails()\"\n >\n Cancel Payment\n </p>\n </div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "component", type: LabelInfoComponent, selector: "base-label-info", inputs: ["type", "label", "labelCustomClass", "valueImageSrc", "valueImageCustomClass", "valueImagePosition", "hasValueCopy", "value", "valueCustomClass", "alignRight"] }, { kind: "component", type: CopyComponent, selector: "base-copy", inputs: ["copyText", "color"] }, { kind: "component", type: ButtonComponent, selector: "base-button", inputs: ["label", "type", "caller", "size", "paddingClassX", "disabled", "loading", "customClass"], outputs: ["onClick"] }, { 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: InputComponent, selector: "base-input", inputs: ["label", "type", "placeholder", "validationError", "hint", "mask", "rules", "isAmountInput", "required", "disabled", "loading", "showCopyIcon", "preventPaste", "showBottomText"], outputs: ["onInputChange", "onInputBlur"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: CircleCountdownComponent, selector: "base-circle-countdown", inputs: ["value", "total", "middleText", "size", "stroke"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2945
3080
  }
2946
3081
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PayByTransferComponent, decorators: [{
2947
3082
  type: Component,
@@ -2953,7 +3088,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2953
3088
  InputComponent,
2954
3089
  CommonModule,
2955
3090
  CircleCountdownComponent,
2956
- ], template: "<div class=\"flex flex-col gap-10\">\n @if (!paymentAccountDetails) {\n <form [formGroup]=\"transferForm\">\n <div class=\"flex flex-col gap-10\">\n <base-input\n formControlName=\"customerName\"\n label=\"Customer Name\"\n [required]=\"true\"\n [validationError]=\"getError('customerName', 'Customer Name') || ''\"\n ></base-input>\n\n <base-button\n [label]=\"'Pay ' + formatAmountHandler\"\n type=\"primary\"\n [caller]=\"caller\"\n customClass=\"w-full\"\n [loading]=\"isMakingPayment\"\n (onClick)=\"payHandler()\"\n ></base-button>\n </div>\n </form>\n }\n\n @if (paymentAccountDetails) {\n <div class=\"flex flex-col gap-10\">\n <div\n class=\"p-4 rounded-lg flex flex-col gap-6\"\n [ngClass]=\"{\n 'bg-[#FAFDFF] border border-[#F0FAFF]': caller === 'miden',\n 'bg-[#EFF7FF]': caller === 'buzapay',\n }\"\n >\n <base-label-info label=\"Bank Name\" [value]=\"paymentAccountDetails.bank\"></base-label-info>\n <base-label-info\n label=\"Account Name\"\n [value]=\"paymentAccountDetails.accountName\"\n ></base-label-info>\n <div class=\"flex items-center justify-between\">\n <base-label-info\n label=\"Account Number\"\n [value]=\"paymentAccountDetails.accountNumber\"\n ></base-label-info>\n <base-copy color=\"#9DBFDE\" [copyText]=\"paymentAccountDetails.accountNumber\"></base-copy>\n </div>\n <div class=\"flex items-center justify-between\">\n <base-label-info label=\"Amount\" [value]=\"formatAmountHandler\"></base-label-info>\n <base-copy color=\"#9DBFDE\" [copyText]=\"formatAmountHandler\"></base-copy>\n </div>\n </div>\n\n @if (caller === 'buzapay') {\n <p class=\"w-2/3 mx-auto text-center text-body-2xs font-medium text-sub-copy\">\n This account is for this transaction only and expires in\n <span class=\"text-orange-500\">{{ countDownTime }}</span>\n </p>\n } @else {\n <div class=\"p-4 rounded-lg bg-[#FAFDFF] flex items-center gap-3\">\n <base-circle-countdown\n [value]=\"remainingSeconds\"\n [total]=\"1800\"\n [middleText]=\"countDownTime\"\n [size]=\"40\"\n [stroke]=\"2\"\n style=\"color: #3b82f6\"\n ></base-circle-countdown>\n <p class=\"text-body-3xs font-medium text-light-copy\">\n This account is for this transaction only and expires in\n <span class=\"text-[#1383E8]\">{{ countDownTime }}...</span>\n </p>\n </div>\n }\n\n <div class=\"flex flex-col gap-4\">\n <base-button\n label=\"I have paid the money\"\n type=\"primary\"\n [caller]=\"caller\"\n customClass=\"w-full\"\n [loading]=\"isFetchingPaymentDetails\"\n (onClick)=\"getReferenceDetails()\"\n ></base-button>\n <p class=\"text-heading-text text-body-2xs font-medium text-center py-2 cursor-pointer\">\n Cancel Payment\n </p>\n </div>\n </div>\n }\n</div>\n" }]
3091
+ ], template: "<div class=\"flex flex-col gap-10\">\n @if (!paymentAccountDetails) {\n <form [formGroup]=\"transferForm\">\n <div class=\"flex flex-col gap-10\">\n <base-input\n formControlName=\"customerName\"\n label=\"Customer Name\"\n [required]=\"true\"\n [validationError]=\"getError('customerName', 'Customer Name') || ''\"\n ></base-input>\n\n <base-button\n [label]=\"'Pay ' + formatAmountHandler\"\n type=\"primary\"\n [caller]=\"caller\"\n customClass=\"w-full\"\n [loading]=\"isMakingPayment\"\n (onClick)=\"payHandler()\"\n ></base-button>\n </div>\n </form>\n }\n\n @if (paymentAccountDetails) {\n <div class=\"flex flex-col gap-10\">\n <div\n class=\"p-4 rounded-lg flex flex-col gap-6\"\n [ngClass]=\"{\n 'bg-[#FAFDFF] border border-[#F0FAFF]': caller === 'miden',\n 'bg-[#EFF7FF]': caller === 'buzapay',\n }\"\n >\n <base-label-info label=\"Bank Name\" [value]=\"paymentAccountDetails.bank\"></base-label-info>\n <base-label-info\n label=\"Account Name\"\n [value]=\"paymentAccountDetails.accountName\"\n ></base-label-info>\n <div class=\"flex items-center justify-between\">\n <base-label-info\n label=\"Account Number\"\n [value]=\"paymentAccountDetails.accountNumber\"\n ></base-label-info>\n <base-copy color=\"#9DBFDE\" [copyText]=\"paymentAccountDetails.accountNumber\"></base-copy>\n </div>\n <div class=\"flex items-center justify-between\">\n <base-label-info label=\"Amount\" [value]=\"formatAmountHandler\"></base-label-info>\n <base-copy color=\"#9DBFDE\" [copyText]=\"formatAmountHandler\"></base-copy>\n </div>\n </div>\n\n @if (caller === 'buzapay') {\n <p class=\"w-2/3 mx-auto text-center text-body-2xs font-medium text-sub-copy\">\n This account is for this transaction only and expires in\n <span class=\"text-orange-500\">{{ countDownTime }}</span>\n </p>\n } @else {\n <div class=\"p-4 rounded-lg bg-[#FAFDFF] flex items-center gap-3\">\n <base-circle-countdown\n [value]=\"remainingSeconds\"\n [total]=\"1800\"\n [middleText]=\"countDownTime\"\n [size]=\"40\"\n [stroke]=\"2\"\n style=\"color: #3b82f6\"\n ></base-circle-countdown>\n <p class=\"text-body-3xs font-medium text-light-copy\">\n This account is for this transaction only and expires in\n <span class=\"text-[#1383E8]\">{{ countDownTime }}...</span>\n </p>\n </div>\n }\n\n <div class=\"flex flex-col gap-4\">\n <base-button\n label=\"I have paid the money\"\n type=\"primary\"\n [caller]=\"caller\"\n customClass=\"w-full\"\n [loading]=\"isFetchingPaymentDetails\"\n (onClick)=\"getReferenceDetails()\"\n ></base-button>\n <p\n class=\"text-heading-text text-body-2xs font-medium text-center py-2 cursor-pointer\"\n (click)=\"resetPaymentAccountDetails()\"\n >\n Cancel Payment\n </p>\n </div>\n </div>\n }\n</div>\n" }]
2957
3092
  }], ctorParameters: () => [{ type: CheckoutService }, { type: i0.ChangeDetectorRef }], propDecorators: { secretKey: [{
2958
3093
  type: Input
2959
3094
  }], environment: [{