@miden-npm/angular 0.0.17 → 0.0.19

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.
@@ -1,47 +1,400 @@
1
1
  import * as i0 from '@angular/core';
2
- import { ChangeDetectionStrategy, Component, EventEmitter, Output, Input, ViewChild } from '@angular/core';
2
+ import { EventEmitter, Output, Input, ChangeDetectionStrategy, Component, ViewChild } from '@angular/core';
3
3
  import * as i1 from '@miden-npm/angular';
4
- import { ButtonComponent, InputComponent, SelectComponent, LabelInfoComponent, CopyComponent, ImageComponent, CurrencyAmountComponent, IconArrowSwapComponent, formatAmount, RadioGroupComponent, SuccessComponent, CardComponent, checkObjectTruthy, IconLoaderComponent, InputErrorComponent } from '@miden-npm/angular';
5
- import * as i2 from '@angular/common';
6
- import { CommonModule } from '@angular/common';
4
+ import { getValidationErrorMessage, cardType, checkObjectTruthy, getQueryParams, ButtonComponent, InputComponent, SelectComponent, formatAmount, LabelInfoComponent, CopyComponent, CurrencyAmountComponent, IconArrowSwapComponent, RadioGroupComponent, ImageComponent, SuccessComponent, CardComponent, IconLoaderComponent, InputErrorComponent } from '@miden-npm/angular';
5
+ import * as i2 from '@angular/forms';
6
+ import { FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
7
7
  import { tap, finalize } from 'rxjs';
8
+ import * as i2$1 from '@angular/common';
9
+ import { CommonModule } from '@angular/common';
8
10
 
9
11
  class PayByCardComponent {
12
+ resources;
13
+ cdr;
14
+ checkout;
15
+ encryptService;
16
+ constructor(resources, cdr, checkout, encryptService) {
17
+ this.resources = resources;
18
+ this.cdr = cdr;
19
+ this.checkout = checkout;
20
+ this.encryptService = encryptService;
21
+ }
22
+ secretKey = '';
23
+ environment = '';
24
+ paymentObject = {
25
+ merchantName: '',
26
+ amount: 0,
27
+ currency: '',
28
+ email: '',
29
+ phoneNumber: '',
30
+ narration: '',
31
+ redirectUrl: '',
32
+ };
33
+ paymentAuthorized = new EventEmitter();
34
+ loading = false;
35
+ loadingCountries = false;
36
+ loadingStates = false;
37
+ isMakingPayment = false;
38
+ cardType = '';
39
+ message = '';
40
+ transactionReference = '';
41
+ countries = [];
42
+ countryStates = [];
10
43
  formIndex = 0;
11
44
  setFormIndex(index) {
12
45
  this.formIndex = index;
13
46
  }
14
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: PayByCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
15
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: PayByCardComponent, isStandalone: true, selector: "pay-by-card", ngImport: i0, template: "<div class=\"flex flex-col gap-6\">\n <!-- Billing Details -->\n @if (formIndex === 0) {\n <div class=\"grid grid-cols-2 gap-6 overflow-y-auto\">\n <base-input label=\"First Name\" [required]=\"true\"></base-input>\n <base-input label=\"Last Name\" [required]=\"true\"></base-input>\n <base-input label=\"Email\"></base-input>\n <base-input label=\"Phone Number\"></base-input>\n <base-select\n label=\"Select Country\"\n [required]=\"true\"\n [options]=\"[\n { label: 'United States', value: 'US' },\n { label: 'Canada', value: 'CA' },\n { label: 'United Kingdom', value: 'UK' },\n ]\"\n ></base-select>\n <base-select\n label=\"Select State\"\n [required]=\"true\"\n [options]=\"[\n { label: 'California', value: 'CA' },\n { label: 'Texas', value: 'TX' },\n { label: 'New York', value: 'NY' },\n ]\"\n ></base-select>\n <base-input label=\"City\" [required]=\"true\"></base-input>\n <base-input label=\"Postal Code\" [required]=\"true\"></base-input>\n <div class=\"col-span-2\">\n <base-input label=\"Street Address\" [required]=\"true\"></base-input>\n </div>\n </div>\n }\n\n <!-- Card Details -->\n @if (formIndex === 1) {\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 label=\"Card Name\" [required]=\"true\"></base-input>\n </div>\n <div class=\"col-span-2\">\n <base-input label=\"Card Number\" [required]=\"true\"></base-input>\n </div>\n <base-input label=\"Expiry Date\" [required]=\"true\"></base-input>\n <base-input label=\"CVV\" [required]=\"true\"></base-input>\n </div>\n }\n\n <base-button\n [label]=\"formIndex === 0 ? 'Proceed' : 'Pay'\"\n type=\"primary\"\n customClass=\"w-full\"\n (onClick)=\"formIndex === 0 ? setFormIndex(1) : null\"\n ></base-button>\n</div>\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "base-button", inputs: ["label", "type", "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"], outputs: ["onInputChange", "onInputBlur"] }, { kind: "component", type: SelectComponent, selector: "base-select", inputs: ["options", "placeholder", "hasSearch", "disabled", "loading", "validationError", "label", "hint", "required", "itemImageType"], outputs: ["onSelectChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
47
+ billingForm = new FormGroup({
48
+ address1: new FormControl('', [Validators.required]),
49
+ address2: new FormControl(''),
50
+ postalCode: new FormControl('', [Validators.required]),
51
+ state: new FormControl('', [Validators.required]),
52
+ city: new FormControl('', [Validators.required]),
53
+ country: new FormControl('', [Validators.required]),
54
+ emailAddress: new FormControl('', [Validators.required, Validators.email]),
55
+ phoneNumber: new FormControl('', [Validators.required]),
56
+ });
57
+ payForm = new FormGroup({
58
+ customerName: new FormControl('', [Validators.required]),
59
+ cardNo: new FormControl('', [Validators.required]),
60
+ expireDate: new FormControl('', [Validators.required]),
61
+ cvv: new FormControl('', [Validators.required]),
62
+ cardPin: new FormControl(''), // Only required for Verve cards
63
+ });
64
+ getError(formKey, controlName, label) {
65
+ const control = formKey === 'billing' ? this.billingForm.get(controlName) : this.payForm.get(controlName);
66
+ return getValidationErrorMessage(control, label);
67
+ }
68
+ cardNumberInputHandler(event) {
69
+ this.cardType = cardType(event);
70
+ this.updatePinValidation();
71
+ }
72
+ updatePinValidation() {
73
+ const cardPinControl = this.payForm.get('cardPin');
74
+ if (this.cardType === 'Verve') {
75
+ cardPinControl?.setValidators([Validators.required]);
76
+ }
77
+ else {
78
+ cardPinControl?.clearValidators();
79
+ }
80
+ cardPinControl?.updateValueAndValidity();
81
+ }
82
+ async getAllCountries() {
83
+ this.loadingCountries = true;
84
+ this.cdr.markForCheck();
85
+ this.resources
86
+ .getCountries(this.environment, this.secretKey)
87
+ .pipe(tap((res) => {
88
+ if (res?.isSuccessful) {
89
+ this.countries = (res.data ?? []).map((c) => {
90
+ return { label: c.countryName, value: c.iso3 };
91
+ });
92
+ }
93
+ }), finalize(() => {
94
+ this.loadingCountries = false;
95
+ this.cdr.markForCheck();
96
+ }))
97
+ .subscribe();
98
+ }
99
+ async getCountryStates(countryIso3) {
100
+ this.loadingStates = true;
101
+ this.cdr.markForCheck();
102
+ this.resources
103
+ .getCountryStates(countryIso3, this.environment, this.secretKey)
104
+ .pipe(tap((res) => {
105
+ if (res?.isSuccessful) {
106
+ this.countryStates = (res.data ?? []).map((s) => {
107
+ return { label: s.name, value: s.name };
108
+ });
109
+ }
110
+ }), finalize(() => {
111
+ this.loadingStates = false;
112
+ this.cdr.markForCheck();
113
+ }))
114
+ .subscribe();
115
+ }
116
+ async generatePaymentLinkHandler() {
117
+ if (!this.secretKey) {
118
+ return (this.message = 'Secret key is required.');
119
+ }
120
+ if (!checkObjectTruthy(this.paymentObject)) {
121
+ return (this.message = 'Kindly ensure you are passing all the required data.');
122
+ }
123
+ this.loading = true;
124
+ this.cdr.markForCheck();
125
+ this.checkout
126
+ .createPaymentLink(this.paymentObject, this.environment, this.secretKey)
127
+ .pipe(tap((res) => {
128
+ if (res?.isSuccessful) {
129
+ this.message = 'Payment link created successfully';
130
+ const queryParams = getQueryParams(res.launchUrl ?? '');
131
+ this.transactionReference = queryParams['paymentReference'];
132
+ }
133
+ else {
134
+ this.message = 'Failed to create payment link';
135
+ }
136
+ }), finalize(() => {
137
+ this.loading = false;
138
+ this.cdr.markForCheck();
139
+ }))
140
+ .subscribe();
141
+ }
142
+ async proceedHandler() {
143
+ if (this.formIndex === 0) {
144
+ if (this.billingForm && this.billingForm.valid) {
145
+ this.checkout.setBillingInfo({ ...this.billingForm.value });
146
+ this.setFormIndex(1);
147
+ }
148
+ else {
149
+ this.billingForm.markAllAsTouched();
150
+ }
151
+ }
152
+ else {
153
+ if (this.payForm && this.payForm.valid) {
154
+ try {
155
+ this.isMakingPayment = true;
156
+ // Create card details object for encryption
157
+ const cardDetails = {
158
+ pan: this.payForm.value.cardNo ?? '',
159
+ expiryDate: this.payForm.value.expireDate ?? '',
160
+ cvv: this.payForm.value.cvv ?? '',
161
+ cardScheme: this.cardType,
162
+ nameOnCard: this.payForm.value.customerName ?? '',
163
+ ...(this.cardType === 'Verve' && { pin: this.payForm.value.cardPin ?? '' }),
164
+ };
165
+ // Get billing details from the form control
166
+ const billingDetails = {
167
+ address2: this.billingForm.value.address2 ?? '',
168
+ address1: this.billingForm.value.address1 ?? '',
169
+ postalCode: this.billingForm.value.postalCode ?? '',
170
+ state: this.billingForm.value.state ?? '',
171
+ city: this.billingForm.value.city ?? '',
172
+ country: this.billingForm.value.country ?? '',
173
+ emailAddress: this.billingForm.value.emailAddress ?? '',
174
+ phoneNumber: this.billingForm.value.phoneNumber ?? '',
175
+ };
176
+ // Encrypt card details using payload encryption method
177
+ const encryptedCardDetails = this.encryptService.encryptPayload(this.environment, cardDetails);
178
+ // Test: Decrypt to verify encryption works
179
+ const decryptedTest = this.encryptService.decryptPayload(this.environment, encryptedCardDetails.requestParam);
180
+ const payload = {
181
+ customerId: this.paymentObject?.email || this.payForm.value.customerName || '',
182
+ amount: this.paymentObject?.amount.toString(),
183
+ currency: this.paymentObject?.currency || 'USD',
184
+ narration: this.paymentObject?.narration || 'Test transaction',
185
+ encryptedCardDetails: encryptedCardDetails.requestParam, // Use the encrypted card details
186
+ billingDetails: billingDetails,
187
+ redirectUrl: this.paymentObject?.redirectUrl || '',
188
+ paymentReference: this.transactionReference,
189
+ isCheckout: true,
190
+ };
191
+ this.checkout
192
+ .authorizeCardPayment(this.environment, {
193
+ ...payload,
194
+ merchantId: this.secretKey,
195
+ })
196
+ .subscribe({
197
+ next: async (response) => {
198
+ let processedResponse = response;
199
+ // Check if response is encrypted (has responseParam)
200
+ if (response?.responseParam) {
201
+ // Decrypt the response
202
+ processedResponse = this.encryptService.decryptPayload(this.environment, response.responseParam);
203
+ }
204
+ if (processedResponse?.isSuccessful) {
205
+ // Check for 3DS authentication requirement
206
+ if (processedResponse.threeDsInteractionRequired === true) {
207
+ // Store 3DS data for the authentication page
208
+ const threeDsData = {
209
+ transactionReference: processedResponse.transactionReference,
210
+ threeDsHtml: processedResponse.threeDsHtml,
211
+ amount: processedResponse.amount,
212
+ responseMessage: processedResponse.responseMessage,
213
+ // Pass all 3DS details
214
+ paReq: processedResponse.threeDsHtml?.paReq,
215
+ termUrl: processedResponse.threeDsHtml?.termUrl,
216
+ action: processedResponse.threeDsHtml?.action,
217
+ acsUrl: processedResponse.threeDsHtml?.acsUrl,
218
+ md: processedResponse.threeDsHtml?.md,
219
+ };
220
+ // Store 3DS data in localStorage for the new tab
221
+ localStorage.setItem('threeDsData', JSON.stringify(threeDsData));
222
+ // Open 3DS authentication page in a new tab
223
+ const threeDsUrl = `${window.location.origin}/account/three-ds-confirm`;
224
+ window.open(threeDsUrl, '_blank', 'noopener,noreferrer');
225
+ this.message =
226
+ '3D Secure authentication opened in new tab. Please complete the verification';
227
+ this.isMakingPayment = false;
228
+ return;
229
+ }
230
+ // Fallback check: if response message indicates 3DS is required
231
+ if (processedResponse.responseMessage === 'Payer Interaction Required' &&
232
+ processedResponse.threeDsHtml) {
233
+ // Store 3DS data for the authentication page
234
+ const threeDsData = {
235
+ transactionReference: processedResponse.transactionReference,
236
+ threeDsHtml: processedResponse.threeDsHtml,
237
+ amount: processedResponse.amount,
238
+ responseMessage: processedResponse.responseMessage,
239
+ // Pass all 3DS details
240
+ paReq: processedResponse.threeDsHtml?.paReq,
241
+ termUrl: processedResponse.threeDsHtml?.termUrl,
242
+ action: processedResponse.threeDsHtml?.action,
243
+ acsUrl: processedResponse.threeDsHtml?.acsUrl,
244
+ md: processedResponse.threeDsHtml?.md,
245
+ };
246
+ // Store 3DS data in localStorage for the new tab
247
+ localStorage.setItem('threeDsData', JSON.stringify(threeDsData));
248
+ // Open 3DS authentication page in a new tab
249
+ const threeDsUrl = `${window.location.origin}/account/three-ds-confirm`;
250
+ window.open(threeDsUrl, '_blank', 'noopener,noreferrer');
251
+ this.message =
252
+ '3D Secure authentication opened in new tab. Please complete the verification';
253
+ this.isMakingPayment = false;
254
+ return;
255
+ }
256
+ // Emit the transaction reference to parent component
257
+ if (processedResponse.transactionReference &&
258
+ processedResponse.transactionReference.trim() !== '') {
259
+ this.paymentAuthorized.emit({
260
+ paymentId: processedResponse.transactionReference,
261
+ paymentDate: response.data.updatedAt,
262
+ paymentStatus: 'Authorized',
263
+ });
264
+ }
265
+ this.message = 'Card payment authorized successfully';
266
+ // Handle legacy 3DS logic for backward compatibility
267
+ // if (processedResponse.provider === 'myRoute2') {
268
+ // if (processedResponse.requires3DS === true) {
269
+ // this.router.navigateByUrl('account/visa-card-payment-confirm');
270
+ // } else {
271
+ // if (processedResponse.responseCode === 'T00') {
272
+ // } else if (processedResponse.responseCode === '000') {
273
+ // this.message = 'Please confirm transaction !!';
274
+ // } else {
275
+ // this.message = processedResponse.responseMessage;
276
+ // }
277
+ // }
278
+ // } else if (processedResponse.provider === 'myRoute1') {
279
+ // if (processedResponse.requires3DS === true) {
280
+ // this.router.navigateByUrl('account/visa-card-payment-confirm2');
281
+ // }
282
+ // }
283
+ this.isMakingPayment = false;
284
+ }
285
+ else {
286
+ this.isMakingPayment = false;
287
+ this.message = processedResponse.responseMessage || 'Payment failed';
288
+ this.paymentAuthorized.emit({
289
+ paymentId: processedResponse.transactionReference,
290
+ paymentDate: response.data.updatedAt,
291
+ paymentStatus: 'Payment failed',
292
+ });
293
+ }
294
+ },
295
+ error: (err) => {
296
+ this.isMakingPayment = false;
297
+ if (err.error?.responseParam) {
298
+ // Decrypt error response
299
+ const decryptedErrorResponse = this.encryptService.decryptPayload(this.environment, err.error.responseParam);
300
+ this.message = decryptedErrorResponse.responseMessage || 'Payment failed';
301
+ }
302
+ else {
303
+ this.message = err.error.responseMessage || err.error.message || 'Payment failed';
304
+ }
305
+ },
306
+ });
307
+ }
308
+ catch (error) {
309
+ this.isMakingPayment = false;
310
+ this.message = 'An unexpected error occurred';
311
+ }
312
+ }
313
+ else {
314
+ this.payForm.markAllAsTouched();
315
+ }
316
+ }
317
+ }
318
+ async ngOnInit() {
319
+ await this.generatePaymentLinkHandler();
320
+ await this.getAllCountries();
321
+ }
322
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: PayByCardComponent, deps: [{ token: i1.ResourceService }, { token: i0.ChangeDetectorRef }, { token: i1.CheckoutService }, { token: i1.EncryptService }], target: i0.ɵɵFactoryTarget.Component });
323
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: PayByCardComponent, isStandalone: true, selector: "pay-by-card", inputs: { secretKey: "secretKey", environment: "environment", paymentObject: "paymentObject" }, outputs: { paymentAuthorized: "paymentAuthorized" }, ngImport: i0, template: "<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 <base-input\n formControlName=\"emailAddress\"\n label=\"Email\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'emailAddress', 'Email Address') || ''\"\n ></base-input>\n <base-input\n formControlName=\"phoneNumber\"\n label=\"Phone Number\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'phoneNumber', 'Phone Number') || ''\"\n ></base-input>\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 [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 <base-button\n [label]=\"formIndex === 0 ? 'Proceed' : 'Pay'\"\n type=\"primary\"\n customClass=\"w-full\"\n [loading]=\"isMakingPayment\"\n (onClick)=\"proceedHandler()\"\n ></base-button>\n</div>\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "base-button", inputs: ["label", "type", "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"], outputs: ["onInputChange", "onInputBlur"] }, { kind: "component", type: SelectComponent, selector: "base-select", inputs: ["options", "placeholder", "hasSearch", "disabled", "loading", "validationError", "label", "hint", "required", "itemImageType"], outputs: ["onSelectChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
16
324
  }
17
325
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: PayByCardComponent, decorators: [{
18
326
  type: Component,
19
- args: [{ selector: 'pay-by-card', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ButtonComponent, InputComponent, SelectComponent], template: "<div class=\"flex flex-col gap-6\">\n <!-- Billing Details -->\n @if (formIndex === 0) {\n <div class=\"grid grid-cols-2 gap-6 overflow-y-auto\">\n <base-input label=\"First Name\" [required]=\"true\"></base-input>\n <base-input label=\"Last Name\" [required]=\"true\"></base-input>\n <base-input label=\"Email\"></base-input>\n <base-input label=\"Phone Number\"></base-input>\n <base-select\n label=\"Select Country\"\n [required]=\"true\"\n [options]=\"[\n { label: 'United States', value: 'US' },\n { label: 'Canada', value: 'CA' },\n { label: 'United Kingdom', value: 'UK' },\n ]\"\n ></base-select>\n <base-select\n label=\"Select State\"\n [required]=\"true\"\n [options]=\"[\n { label: 'California', value: 'CA' },\n { label: 'Texas', value: 'TX' },\n { label: 'New York', value: 'NY' },\n ]\"\n ></base-select>\n <base-input label=\"City\" [required]=\"true\"></base-input>\n <base-input label=\"Postal Code\" [required]=\"true\"></base-input>\n <div class=\"col-span-2\">\n <base-input label=\"Street Address\" [required]=\"true\"></base-input>\n </div>\n </div>\n }\n\n <!-- Card Details -->\n @if (formIndex === 1) {\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 label=\"Card Name\" [required]=\"true\"></base-input>\n </div>\n <div class=\"col-span-2\">\n <base-input label=\"Card Number\" [required]=\"true\"></base-input>\n </div>\n <base-input label=\"Expiry Date\" [required]=\"true\"></base-input>\n <base-input label=\"CVV\" [required]=\"true\"></base-input>\n </div>\n }\n\n <base-button\n [label]=\"formIndex === 0 ? 'Proceed' : 'Pay'\"\n type=\"primary\"\n customClass=\"w-full\"\n (onClick)=\"formIndex === 0 ? setFormIndex(1) : null\"\n ></base-button>\n</div>\n" }]
20
- }] });
327
+ args: [{ selector: 'pay-by-card', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ButtonComponent, InputComponent, SelectComponent, ReactiveFormsModule], template: "<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 <base-input\n formControlName=\"emailAddress\"\n label=\"Email\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'emailAddress', 'Email Address') || ''\"\n ></base-input>\n <base-input\n formControlName=\"phoneNumber\"\n label=\"Phone Number\"\n [required]=\"true\"\n [validationError]=\"getError('billing', 'phoneNumber', 'Phone Number') || ''\"\n ></base-input>\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 [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 <base-button\n [label]=\"formIndex === 0 ? 'Proceed' : 'Pay'\"\n type=\"primary\"\n customClass=\"w-full\"\n [loading]=\"isMakingPayment\"\n (onClick)=\"proceedHandler()\"\n ></base-button>\n</div>\n" }]
328
+ }], ctorParameters: () => [{ type: i1.ResourceService }, { type: i0.ChangeDetectorRef }, { type: i1.CheckoutService }, { type: i1.EncryptService }], propDecorators: { secretKey: [{
329
+ type: Input
330
+ }], environment: [{
331
+ type: Input
332
+ }], paymentObject: [{
333
+ type: Input
334
+ }], paymentAuthorized: [{
335
+ type: Output
336
+ }] } });
21
337
 
22
338
  class PayByTransferComponent {
339
+ checkout;
23
340
  cdr;
341
+ constructor(checkout, cdr) {
342
+ this.checkout = checkout;
343
+ this.cdr = cdr;
344
+ }
345
+ secretKey = '';
346
+ environment = '';
347
+ paymentObject = {
348
+ merchantName: '',
349
+ amount: 0,
350
+ currency: '',
351
+ email: '',
352
+ phoneNumber: '',
353
+ narration: '',
354
+ redirectUrl: '',
355
+ };
356
+ paymentAuthorized = new EventEmitter();
357
+ message = '';
358
+ generatingLink = false;
359
+ isMakingPayment = false;
360
+ isFetchingPaymentDetails = false;
361
+ isConfirmCall = false;
362
+ paymentMade = false;
363
+ isPaymentConfirmed = false;
364
+ paymentAccountDetails = null;
365
+ paymentReferenceDetails = null;
366
+ transactionReference = '';
367
+ paymentReferenceStatus = '';
24
368
  countDownTime = '';
25
369
  remainingSeconds = 30 * 60;
26
370
  intervalId = null;
27
- constructor(cdr) {
28
- this.cdr = cdr;
29
- }
30
371
  updateDisplay() {
31
372
  const minutes = Math.floor(this.remainingSeconds / 60);
32
373
  const seconds = this.remainingSeconds % 60;
33
374
  this.countDownTime = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
34
375
  this.cdr.markForCheck(); // 👈 notify OnPush to re-render
35
376
  }
377
+ transferForm = new FormGroup({
378
+ customerName: new FormControl('', [Validators.required]),
379
+ });
380
+ getError(controlName, label) {
381
+ const control = this.transferForm.get(controlName);
382
+ return getValidationErrorMessage(control, label);
383
+ }
384
+ get formatAmountHandler() {
385
+ return formatAmount(this.paymentObject.amount, this.paymentObject.currency);
386
+ }
36
387
  startTimer() {
388
+ if (this.intervalId) {
389
+ clearInterval(this.intervalId);
390
+ this.intervalId = null;
391
+ }
37
392
  this.updateDisplay();
38
393
  this.intervalId = setInterval(() => {
39
394
  this.remainingSeconds--;
40
395
  if (this.remainingSeconds < 0) {
41
- if (this.intervalId) {
42
- clearInterval(this.intervalId);
43
- this.intervalId = null;
44
- }
396
+ clearInterval(this.intervalId);
397
+ this.intervalId = null;
45
398
  this.countDownTime = '00:00';
46
399
  this.cdr.markForCheck();
47
400
  return;
@@ -49,8 +402,129 @@ class PayByTransferComponent {
49
402
  this.updateDisplay();
50
403
  }, 1000);
51
404
  }
52
- ngOnInit() {
405
+ async generatePaymentLinkHandler() {
406
+ if (!this.secretKey) {
407
+ return (this.message = 'Secret key is required.');
408
+ }
409
+ if (!checkObjectTruthy(this.paymentObject)) {
410
+ return (this.message = 'Kindly ensure you are passing all the required data.');
411
+ }
412
+ this.generatingLink = true;
413
+ this.cdr.markForCheck();
414
+ this.checkout
415
+ .createPaymentLink(this.paymentObject, this.environment, this.secretKey)
416
+ .pipe(tap((res) => {
417
+ if (res?.isSuccessful) {
418
+ this.message = 'Payment link created successfully';
419
+ const queryParams = getQueryParams(res.launchUrl ?? '');
420
+ this.transactionReference = queryParams['paymentReference'];
421
+ }
422
+ else {
423
+ this.message = 'Failed to create payment link';
424
+ }
425
+ }), finalize(() => {
426
+ this.generatingLink = false;
427
+ this.cdr.markForCheck();
428
+ }))
429
+ .subscribe();
430
+ }
431
+ async payHandler() {
432
+ if (this.transferForm && this.transferForm.valid) {
433
+ const payload = {
434
+ paymentReference: this.transactionReference,
435
+ channel: 'virtual_account',
436
+ customerName: this.transferForm.value.customerName ?? '',
437
+ merchantId: this.secretKey,
438
+ };
439
+ this.isMakingPayment = true;
440
+ await this.checkout.generatePaymentAccount(this.environment, payload).subscribe({
441
+ next: async (response) => {
442
+ if (response?.isSuccessful) {
443
+ this.paymentAccountDetails = response.data;
444
+ this.startTimer();
445
+ this.message = 'Virtual account generated successfully for payment.';
446
+ this.isMakingPayment = false;
447
+ }
448
+ },
449
+ error: (err) => {
450
+ this.isMakingPayment = false;
451
+ this.message = err.error.responseMessage || err.error.message;
452
+ },
453
+ });
454
+ }
455
+ else {
456
+ this.transferForm?.markAllAsTouched();
457
+ }
458
+ }
459
+ async getReferenceDetails() {
460
+ this.isFetchingPaymentDetails = true;
461
+ await this.checkout
462
+ .getPaymentReferenceDetails(this.environment, this.transactionReference)
463
+ .subscribe({
464
+ next: async (response) => {
465
+ if (response?.isSuccessful) {
466
+ this.paymentReferenceDetails = response.data;
467
+ // Check if payment has been made (paymentStatus is "Payment Received")
468
+ if (response.data?.paymentStatus === 'Payment Received') {
469
+ this.paymentMade = true;
470
+ }
471
+ if (response.data?.finalTransactionStatus === null ||
472
+ response.data?.paymentStatus === null) {
473
+ if (this.isConfirmCall) {
474
+ this.message = 'Transaction not confirmed !!';
475
+ }
476
+ // Only set to pending if payment hasn't been confirmed locally or made locally
477
+ if (!this.isPaymentConfirmed && !this.paymentMade) {
478
+ this.paymentReferenceStatus = 'pending';
479
+ this.paymentAuthorized.emit({
480
+ paymentId: this.transactionReference,
481
+ paymentDate: response.data.updatedAt,
482
+ paymentStatus: this.paymentReferenceStatus,
483
+ });
484
+ }
485
+ else {
486
+ this.paymentReferenceStatus = 'confirmed';
487
+ this.paymentAuthorized.emit({
488
+ paymentId: this.transactionReference,
489
+ paymentDate: response.data.updatedAt,
490
+ paymentStatus: this.paymentReferenceStatus,
491
+ });
492
+ }
493
+ }
494
+ else if (response.data?.finalTransactionStatus === 'Success' ||
495
+ response.data?.paymentStatus === 'Received' ||
496
+ response.data?.paymentStatus === 'Payment Received') {
497
+ this.paymentAuthorized.emit({
498
+ paymentId: this.transactionReference,
499
+ paymentDate: response.data.updatedAt,
500
+ paymentStatus: this.paymentReferenceStatus,
501
+ });
502
+ this.message = 'Transaction confirmed !!';
503
+ this.paymentReferenceStatus = 'confirmed';
504
+ this.isPaymentConfirmed = true;
505
+ }
506
+ }
507
+ else if (!response?.isSuccessful && response?.responseCode === '119') {
508
+ this.paymentReferenceStatus = 'used';
509
+ this.message = response.responseMessage;
510
+ this.paymentAuthorized.emit({
511
+ paymentId: this.transactionReference,
512
+ paymentDate: null,
513
+ paymentStatus: this.paymentReferenceStatus,
514
+ });
515
+ }
516
+ this.isFetchingPaymentDetails = false;
517
+ },
518
+ error: (err) => {
519
+ this.paymentReferenceStatus = '';
520
+ this.isFetchingPaymentDetails = false;
521
+ this.message = err.error.responseMessage || err.error.message;
522
+ },
523
+ });
524
+ }
525
+ async ngOnInit() {
53
526
  this.startTimer();
527
+ await this.generatePaymentLinkHandler();
54
528
  }
55
529
  ngOnDestroy() {
56
530
  if (this.intervalId) {
@@ -58,38 +532,255 @@ class PayByTransferComponent {
58
532
  this.intervalId = null;
59
533
  }
60
534
  }
61
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: PayByTransferComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
62
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.1", type: PayByTransferComponent, isStandalone: true, selector: "pay-by-transfer", ngImport: i0, template: "<div class=\"flex flex-col gap-10\">\n <p class=\"text-sub-copy text-sm font-semibold text-center\">Amount to Pay NGN 200,500.00</p>\n\n <div class=\"bg-[#EFF7FF] p-4 rounded-lg flex flex-col gap-6\">\n <base-label-info label=\"Bank Name\" value=\"Teerus MFB\"></base-label-info>\n <div class=\"flex items-center justify-between\">\n <base-label-info label=\"Account Number\" value=\"0001928940\"></base-label-info>\n <base-copy color=\"#9DBFDE\"></base-copy>\n </div>\n <div class=\"flex items-center justify-between\">\n <base-label-info label=\"Amount\" value=\"NGN 200,500.00\"></base-label-info>\n <base-copy color=\"#9DBFDE\"></base-copy>\n </div>\n </div>\n\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\n <div class=\"flex flex-col gap-4\">\n <base-button label=\"I have paid the money\" type=\"primary\" customClass=\"w-full\"></base-button>\n <p class=\"text-heading-text text-body-2xs font-medium text-center py-2 cursor-pointer\">Cancel Payment</p>\n </div>\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", "size", "paddingClassX", "disabled", "loading", "customClass"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
535
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: PayByTransferComponent, deps: [{ token: i1.CheckoutService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
536
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: PayByTransferComponent, isStandalone: true, selector: "pay-by-transfer", inputs: { secretKey: "secretKey", environment: "environment", paymentObject: "paymentObject" }, outputs: { paymentAuthorized: "paymentAuthorized" }, 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=\"Card 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 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 class=\"bg-[#EFF7FF] p-4 rounded-lg flex flex-col gap-6\">\n <base-label-info\n label=\"Bank Name\"\n [value]=\"paymentAccountDetails.bank + ' - ' + 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 <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\n <div class=\"flex flex-col gap-4\">\n <base-button\n label=\"I have paid the money\"\n type=\"primary\"\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", "size", "paddingClassX", "disabled", "loading", "customClass"], outputs: ["onClick"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.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"], outputs: ["onInputChange", "onInputBlur"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
63
537
  }
64
538
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: PayByTransferComponent, decorators: [{
65
539
  type: Component,
66
- args: [{ selector: 'pay-by-transfer', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [LabelInfoComponent, CopyComponent, ButtonComponent], template: "<div class=\"flex flex-col gap-10\">\n <p class=\"text-sub-copy text-sm font-semibold text-center\">Amount to Pay NGN 200,500.00</p>\n\n <div class=\"bg-[#EFF7FF] p-4 rounded-lg flex flex-col gap-6\">\n <base-label-info label=\"Bank Name\" value=\"Teerus MFB\"></base-label-info>\n <div class=\"flex items-center justify-between\">\n <base-label-info label=\"Account Number\" value=\"0001928940\"></base-label-info>\n <base-copy color=\"#9DBFDE\"></base-copy>\n </div>\n <div class=\"flex items-center justify-between\">\n <base-label-info label=\"Amount\" value=\"NGN 200,500.00\"></base-label-info>\n <base-copy color=\"#9DBFDE\"></base-copy>\n </div>\n </div>\n\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\n <div class=\"flex flex-col gap-4\">\n <base-button label=\"I have paid the money\" type=\"primary\" customClass=\"w-full\"></base-button>\n <p class=\"text-heading-text text-body-2xs font-medium text-center py-2 cursor-pointer\">Cancel Payment</p>\n </div>\n</div>\n" }]
67
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
540
+ args: [{ selector: 'pay-by-transfer', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
541
+ LabelInfoComponent,
542
+ CopyComponent,
543
+ ButtonComponent,
544
+ ReactiveFormsModule,
545
+ InputComponent,
546
+ ], 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=\"Card 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 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 class=\"bg-[#EFF7FF] p-4 rounded-lg flex flex-col gap-6\">\n <base-label-info\n label=\"Bank Name\"\n [value]=\"paymentAccountDetails.bank + ' - ' + 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 <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\n <div class=\"flex flex-col gap-4\">\n <base-button\n label=\"I have paid the money\"\n type=\"primary\"\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" }]
547
+ }], ctorParameters: () => [{ type: i1.CheckoutService }, { type: i0.ChangeDetectorRef }], propDecorators: { secretKey: [{
548
+ type: Input
549
+ }], environment: [{
550
+ type: Input
551
+ }], paymentObject: [{
552
+ type: Input
553
+ }], paymentAuthorized: [{
554
+ type: Output
555
+ }] } });
68
556
 
69
557
  class PayByStableCoinComponent {
70
- proceedToPay = new EventEmitter();
558
+ resource;
559
+ checkout;
560
+ cdr;
561
+ constructor(resource, checkout, cdr) {
562
+ this.resource = resource;
563
+ this.checkout = checkout;
564
+ this.cdr = cdr;
565
+ }
566
+ secretKey = '';
567
+ environment = '';
568
+ paymentObject = {
569
+ merchantName: '',
570
+ amount: 0,
571
+ currency: '',
572
+ email: '',
573
+ phoneNumber: '',
574
+ narration: '',
575
+ redirectUrl: '',
576
+ };
577
+ paymentAuthorized = new EventEmitter();
578
+ message = '';
579
+ transactionReference = '';
580
+ paymentReferenceStatus = '';
581
+ generateAddressPayload = null;
582
+ addressDetails = null;
583
+ paymentReferenceDetails = null;
584
+ stableCoins = [];
585
+ networkList = [];
586
+ loadingStableCoins = false;
587
+ generatingAddress = false;
588
+ isConfirmingPayment = false;
589
+ loading = false;
590
+ loadingStableCoinNetworks = false;
71
591
  formIndex = 0;
72
592
  setFormIndex(index) {
73
593
  this.formIndex = index;
74
594
  }
75
- payHandler() {
76
- this.setFormIndex(1);
77
- this.proceedToPay.emit();
595
+ stableCoinForm = new FormGroup({
596
+ stableCoin: new FormControl('', [Validators.required]),
597
+ network: new FormControl('', [Validators.required]),
598
+ });
599
+ getError(controlName, label) {
600
+ const control = this.stableCoinForm.get(controlName);
601
+ return getValidationErrorMessage(control, label);
78
602
  }
79
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: PayByStableCoinComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
80
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: PayByStableCoinComponent, isStandalone: true, selector: "pay-by-stable-coin", outputs: { proceedToPay: "proceedToPay" }, ngImport: i0, template: "<div class=\"flex flex-col gap-6\">\n @if (formIndex === 0) {\n <div class=\"grid grid-cols-1 gap-6\">\n <base-select\n label=\"Select Crypto\"\n [required]=\"true\"\n [options]=\"[\n { label: 'USDT', value: 'USDT' },\n { label: 'USDC', value: 'USDC' },\n { label: 'BUSD', value: 'BUSD' },\n ]\"\n ></base-select>\n <base-select\n label=\"Select Network\"\n [required]=\"true\"\n [options]=\"[\n { label: 'Ethereum', value: 'ETH' },\n { label: 'Binance Smart Chain', value: 'BSC' },\n { label: 'Polygon', value: 'MATIC' },\n ]\"\n ></base-select>\n </div>\n\n <base-button\n label=\"Pay\"\n type=\"primary\"\n customClass=\"w-full\"\n (onClick)=\"payHandler()\"\n ></base-button>\n }\n\n @if (formIndex === 1) {\n <div class=\"flex flex-col gap-6\">\n <div class=\"mx-auto\">\n <base-image\n src=\"../../../assets/images/stable-coin-qr-code.png\"\n alt=\"QR Code\"\n [width]=\"122\"\n [height]=\"122\"\n class=\"mb-1\"\n ></base-image>\n <p class=\"mb-0 text-body-4xs text-light-copy font-normal text-center\">USDC</p>\n </div>\n\n <div class=\"flex flex-col gap-6 border-c border-grey-100 p-4 rounded-2xl bg-light-white-50\">\n <div class=\"border-b border-grey-border pb-4 flex flex-col gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">Network</p>\n <div class=\"flex justify-between\">\n <div class=\"flex flex-col gap-1\">\n <p class=\"mb-0 text-body-2xs font-medium text-sub-copy\">BNB Smart Chain (BEP20)</p>\n <div class=\"flex items-center gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">*Est. arrival = 3 mins</p>\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">|</p>\n <base-currency-amount\n currency=\"USDC\"\n [amount]=\"10\"\n textClass=\"mb-0 text-body-3xs text-light-copy font-normal\"\n iconColorClass=\"#557591\"\n iconWidth=\"12\"\n iconHeight=\"12\"\n ></base-currency-amount>\n </div>\n </div>\n <icon-arrow-swap></icon-arrow-swap>\n </div>\n </div>\n\n <div class=\"pb-4 flex flex-col gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">Deposit Address ></p>\n <div class=\"flex justify-between\">\n <p class=\"mb-0 text-body-2xs font-medium text-sub-copy w-2/3 break-words\">\n 0j8938ysheeee8333c162883a4d4f5g6t111nhk8uey37777yt6\n </p>\n <base-copy copyText=\"0j8938ysheeee8333c162883a4d4f5g6t111nhk8uey37777yt6\"></base-copy>\n </div>\n </div>\n\n <!-- <div class=\"pb-4 flex flex-col gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">Memo ></p>\n <div class=\"flex justify-between\">\n <p\n class=\"mb-0 text-body-2xs font-medium text-sub-copy w-2/3 break-words\"\n >\n 0j8938ysheeee8333c162883a4d4f5g6t111nhk8uey37777yt6\n </p>\n <app-copy\n [isCopyIcon]=\"true\"\n [copyText]=\"'0j8938ysheeee8333c162883a4d4f5g6t111nhk8uey37777yt6'\"\n ></app-copy>\n </div>\n </div> -->\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <div class=\"flex items-center justify-between border-b border-grey-border py-3\">\n <p class=\"mb-0 text-body-2xs font-medium text-primary-black\">Network fee</p>\n <base-currency-amount\n currency=\"USDC\"\n [amount]=\"12\"\n textClass=\"mb-0 text-body-2xs font-extrabold text-primary-black\"\n iconColorClass=\"#231F20\"\n ></base-currency-amount>\n </div>\n\n <div class=\"flex items-center justify-between py-4\">\n <p class=\"mb-0 text-body-lg font-semibold text-primary-black\">Pay</p>\n <base-currency-amount\n currency=\"USDC\"\n [amount]=\"15\"\n textClass=\"mb-0 text-body-lg font-extrabold text-primary-black\"\n iconColorClass=\"#231F20\"\n iconWidth=\"20\"\n iconHeight=\"20\"\n ></base-currency-amount>\n </div>\n </div>\n\n <div class=\"flex flex-col gap-6\">\n <base-button label=\"Confirm Payment\" type=\"primary\" customClass=\"w-full\"></base-button>\n </div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "component", type: SelectComponent, selector: "base-select", inputs: ["options", "placeholder", "hasSearch", "disabled", "loading", "validationError", "label", "hint", "required", "itemImageType"], outputs: ["onSelectChange"] }, { kind: "component", type: ButtonComponent, selector: "base-button", inputs: ["label", "type", "size", "paddingClassX", "disabled", "loading", "customClass"], outputs: ["onClick"] }, { kind: "component", type: ImageComponent, selector: "base-image", inputs: ["src", "alt", "isFullWidth", "width", "height", "customClass"], outputs: ["onClick"] }, { kind: "component", type: CurrencyAmountComponent, selector: "base-currency-amount", inputs: ["currency", "amount", "textClass", "iconColorClass", "iconWidth", "iconHeight"] }, { kind: "component", type: CopyComponent, selector: "base-copy", inputs: ["copyText", "color"] }, { kind: "component", type: IconArrowSwapComponent, selector: "icon-arrow-swap", inputs: ["color", "width", "height"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
603
+ get amountPlusNetworkFee() {
604
+ return this.addressDetails
605
+ ? Number(this.addressDetails.transactionAmount) + this.addressDetails.networkFee
606
+ : 0;
607
+ }
608
+ async generatePaymentLinkHandler() {
609
+ if (!this.secretKey) {
610
+ return (this.message = 'Secret key is required.');
611
+ }
612
+ if (!checkObjectTruthy(this.paymentObject)) {
613
+ return (this.message = 'Kindly ensure you are passing all the required data.');
614
+ }
615
+ this.loading = true;
616
+ this.cdr.markForCheck();
617
+ this.checkout
618
+ .createPaymentLink(this.paymentObject, this.environment, this.secretKey)
619
+ .pipe(tap((res) => {
620
+ if (res?.isSuccessful) {
621
+ this.message = 'Payment link created successfully';
622
+ const queryParams = getQueryParams(res.launchUrl ?? '');
623
+ this.transactionReference = queryParams['paymentReference'];
624
+ }
625
+ else {
626
+ this.message = 'Failed to create payment link';
627
+ }
628
+ }), finalize(() => {
629
+ this.loading = false;
630
+ this.cdr.markForCheck();
631
+ }))
632
+ .subscribe();
633
+ }
634
+ generateAddress() {
635
+ if (!this.generateAddressPayload)
636
+ return;
637
+ this.generatingAddress = true;
638
+ this.cdr.markForCheck();
639
+ this.checkout
640
+ .generateStableCoinAddress(this.environment, this.generateAddressPayload)
641
+ .pipe(tap((response) => {
642
+ if (response?.isSuccessful) {
643
+ this.addressDetails = response.data;
644
+ this.setFormIndex(1);
645
+ }
646
+ }), finalize(() => {
647
+ this.generatingAddress = false;
648
+ this.cdr.markForCheck();
649
+ }))
650
+ .subscribe({
651
+ error: (err) => {
652
+ this.message = err.error.responseMessage || err.error.message;
653
+ },
654
+ });
655
+ }
656
+ async payHandler() {
657
+ if (this.stableCoinForm && this.stableCoinForm.valid) {
658
+ this.generateAddressPayload = {
659
+ paymentReference: this.transactionReference,
660
+ currency: this.stableCoinForm.get('stableCoin')?.value ?? '',
661
+ chain: this.stableCoinForm.get('network')?.value ?? '',
662
+ transactionAmount: this.paymentObject?.amount,
663
+ merchantId: this.secretKey,
664
+ };
665
+ await this.generateAddress();
666
+ }
667
+ else {
668
+ this.stableCoinForm?.markAllAsTouched();
669
+ }
670
+ }
671
+ async getStableCoins() {
672
+ this.loadingStableCoins = true;
673
+ await this.resource.getStableCoins(this.environment).subscribe({
674
+ next: async (response) => {
675
+ if (response?.isSuccessful) {
676
+ this.stableCoins =
677
+ response.data?.map((c) => ({
678
+ label: c.name,
679
+ value: c.name,
680
+ })) ?? [];
681
+ this.loadingStableCoins = false;
682
+ }
683
+ },
684
+ error: (err) => {
685
+ this.loadingStableCoins = false;
686
+ this.message = err.error.responseMessage || err.error.message;
687
+ },
688
+ });
689
+ }
690
+ async getStableCoinNetworks() {
691
+ const stableCoin = this.stableCoinForm.get('stableCoin')?.value;
692
+ this.loadingStableCoinNetworks = true;
693
+ await this.resource.getStableCoinNetworks(this.environment, stableCoin ?? '').subscribe({
694
+ next: async (response) => {
695
+ if (response?.isSuccessful) {
696
+ this.networkList =
697
+ response.networks?.map((n) => ({
698
+ label: n,
699
+ value: n,
700
+ })) ?? [];
701
+ this.loadingStableCoinNetworks = false;
702
+ }
703
+ },
704
+ error: (err) => {
705
+ this.loadingStableCoinNetworks = false;
706
+ this.message = err.error.responseMessage || err.error.message;
707
+ },
708
+ });
709
+ }
710
+ async confirmPaymentHandler() {
711
+ this.isConfirmingPayment = true;
712
+ await this.checkout
713
+ .getPaymentReferenceDetails(this.environment, this.transactionReference)
714
+ .subscribe({
715
+ next: async (response) => {
716
+ if (response?.isSuccessful) {
717
+ this.paymentReferenceDetails = response.data;
718
+ if (response.data?.finalTransactionStatus === null ||
719
+ response.data?.paymentStatus === null) {
720
+ this.message = 'Transaction not confirmed !!';
721
+ this.paymentReferenceStatus = 'pending';
722
+ this.paymentAuthorized.emit({
723
+ paymentId: this.transactionReference,
724
+ paymentDate: response.data.updatedAt,
725
+ paymentStatus: this.paymentReferenceStatus,
726
+ });
727
+ }
728
+ else if (response.data?.finalTransactionStatus === 'Success' ||
729
+ response.data?.paymentStatus === 'Payment Received') {
730
+ this.message = 'Transaction confirmed !!';
731
+ this.paymentReferenceStatus = 'confirmed';
732
+ this.paymentAuthorized.emit({
733
+ paymentId: this.transactionReference,
734
+ paymentDate: response.data.updatedAt,
735
+ paymentStatus: this.paymentReferenceStatus,
736
+ });
737
+ }
738
+ }
739
+ else if (!response?.isSuccessful && response?.responseCode === '119') {
740
+ this.paymentReferenceStatus = 'used';
741
+ this.message = response.responseMessage;
742
+ this.paymentAuthorized.emit({
743
+ paymentId: this.transactionReference,
744
+ paymentDate: null,
745
+ paymentStatus: this.paymentReferenceStatus,
746
+ });
747
+ }
748
+ this.isConfirmingPayment = false;
749
+ },
750
+ error: (err) => {
751
+ this.paymentReferenceStatus = '';
752
+ this.isConfirmingPayment = false;
753
+ this.message = err.error.responseMessage || err.error.message;
754
+ },
755
+ });
756
+ }
757
+ async ngOnInit() {
758
+ await this.generatePaymentLinkHandler();
759
+ await this.getStableCoins();
760
+ }
761
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: PayByStableCoinComponent, deps: [{ token: i1.ResourceService }, { token: i1.CheckoutService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
762
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: PayByStableCoinComponent, isStandalone: true, selector: "pay-by-stable-coin", inputs: { secretKey: "secretKey", environment: "environment", paymentObject: "paymentObject" }, outputs: { paymentAuthorized: "paymentAuthorized" }, ngImport: i0, template: "<div class=\"flex flex-col gap-6\">\n @if (formIndex === 0) {\n <form [formGroup]=\"stableCoinForm\" class=\"grid grid-cols-1 gap-6\">\n <div class=\"grid grid-cols-1 gap-6\">\n <base-select\n formControlName=\"stableCoin\"\n label=\"Select Crypto\"\n [required]=\"true\"\n [options]=\"stableCoins\"\n [validationError]=\"getError('stableCoin', 'Select Crypto') ?? ''\"\n [loading]=\"loadingStableCoins\"\n (onSelectChange)=\"getStableCoinNetworks()\"\n ></base-select>\n <base-select\n formControlName=\"network\"\n label=\"Select Network\"\n [required]=\"true\"\n [options]=\"networkList\"\n [validationError]=\"getError('network', 'Network') ?? ''\"\n [loading]=\"loadingStableCoinNetworks\"\n ></base-select>\n </div>\n\n <base-button\n label=\"Pay\"\n type=\"primary\"\n customClass=\"w-full\"\n [loading]=\"generatingAddress\"\n (onClick)=\"payHandler()\"\n ></base-button>\n </form>\n }\n\n @if (formIndex === 1) {\n <div class=\"flex flex-col gap-6\">\n <div class=\"mx-auto\">\n <!-- <base-image\n src=\"../../../assets/images/stable-coin-qr-code.png\"\n alt=\"QR Code\"\n [width]=\"122\"\n [height]=\"122\"\n class=\"mb-1\"\n ></base-image> -->\n <p class=\"mb-0 text-body-4xs text-light-copy font-normal text-center\">USDC</p>\n </div>\n\n <div class=\"flex flex-col gap-6 border-c border-grey-100 p-4 rounded-2xl bg-light-white-50\">\n <div class=\"border-b border-grey-border pb-4 flex flex-col gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">Network</p>\n <div class=\"flex justify-between\">\n <div class=\"flex flex-col gap-1\">\n <p class=\"mb-0 text-body-2xs font-medium text-sub-copy\">\n {{ addressDetails?.chain }}\n </p>\n <div class=\"flex items-center gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">*Est. arrival = 3 mins</p>\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">|</p>\n <base-currency-amount\n [currency]=\"generateAddressPayload?.currency ?? ''\"\n [amount]=\"addressDetails?.networkFee ?? 0\"\n textClass=\"mb-0 text-body-3xs text-light-copy font-normal\"\n iconColorClass=\"#557591\"\n iconWidth=\"12\"\n iconHeight=\"12\"\n ></base-currency-amount>\n </div>\n </div>\n <icon-arrow-swap></icon-arrow-swap>\n </div>\n </div>\n\n <div class=\"pb-4 flex flex-col gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">Deposit Address ></p>\n <div class=\"flex justify-between\">\n <p class=\"mb-0 text-body-2xs font-medium text-sub-copy w-2/3 break-words\">\n {{ addressDetails?.walletAddress }}\n </p>\n <base-copy [copyText]=\"addressDetails?.walletAddress ?? ''\"></base-copy>\n </div>\n </div>\n\n <!-- <div class=\"pb-4 flex flex-col gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">Memo ></p>\n <div class=\"flex justify-between\">\n <p\n class=\"mb-0 text-body-2xs font-medium text-sub-copy w-2/3 break-words\"\n >\n 0j8938ysheeee8333c162883a4d4f5g6t111nhk8uey37777yt6\n </p>\n <app-copy\n [isCopyIcon]=\"true\"\n [copyText]=\"'0j8938ysheeee8333c162883a4d4f5g6t111nhk8uey37777yt6'\"\n ></app-copy>\n </div>\n </div> -->\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <div class=\"flex items-center justify-between border-b border-grey-border py-3\">\n <p class=\"mb-0 text-body-2xs font-medium text-primary-black\">Network fee</p>\n <base-currency-amount\n [currency]=\"generateAddressPayload?.currency ?? ''\"\n [amount]=\"addressDetails?.networkFee ?? 0\"\n textClass=\"mb-0 text-body-2xs font-extrabold text-primary-black\"\n iconColorClass=\"#231F20\"\n ></base-currency-amount>\n </div>\n\n <div class=\"flex items-center justify-between py-4\">\n <p class=\"mb-0 text-body-lg font-semibold text-primary-black\">Pay</p>\n <base-currency-amount\n [currency]=\"generateAddressPayload?.currency ?? ''\"\n [amount]=\"amountPlusNetworkFee\"\n textClass=\"mb-0 text-body-lg font-extrabold text-primary-black\"\n iconColorClass=\"#231F20\"\n iconWidth=\"20\"\n iconHeight=\"20\"\n ></base-currency-amount>\n </div>\n </div>\n\n <div class=\"flex flex-col gap-6\">\n <base-button\n label=\"Confirm Payment\"\n type=\"primary\"\n customClass=\"w-full\"\n [loading]=\"isConfirmingPayment\"\n (onClick)=\"confirmPaymentHandler()\"\n ></base-button>\n </div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "component", type: SelectComponent, selector: "base-select", inputs: ["options", "placeholder", "hasSearch", "disabled", "loading", "validationError", "label", "hint", "required", "itemImageType"], outputs: ["onSelectChange"] }, { kind: "component", type: ButtonComponent, selector: "base-button", inputs: ["label", "type", "size", "paddingClassX", "disabled", "loading", "customClass"], outputs: ["onClick"] }, { kind: "component", type:
763
+ // ImageComponent,
764
+ CurrencyAmountComponent, selector: "base-currency-amount", inputs: ["currency", "amount", "textClass", "iconColorClass", "iconWidth", "iconHeight"] }, { kind: "component", type: CopyComponent, selector: "base-copy", inputs: ["copyText", "color"] }, { kind: "component", type: IconArrowSwapComponent, selector: "icon-arrow-swap", inputs: ["color", "width", "height"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
81
765
  }
82
766
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: PayByStableCoinComponent, decorators: [{
83
767
  type: Component,
84
768
  args: [{ selector: 'pay-by-stable-coin', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
85
769
  SelectComponent,
86
770
  ButtonComponent,
87
- ImageComponent,
771
+ // ImageComponent,
88
772
  CurrencyAmountComponent,
89
773
  CopyComponent,
90
774
  IconArrowSwapComponent,
91
- ], template: "<div class=\"flex flex-col gap-6\">\n @if (formIndex === 0) {\n <div class=\"grid grid-cols-1 gap-6\">\n <base-select\n label=\"Select Crypto\"\n [required]=\"true\"\n [options]=\"[\n { label: 'USDT', value: 'USDT' },\n { label: 'USDC', value: 'USDC' },\n { label: 'BUSD', value: 'BUSD' },\n ]\"\n ></base-select>\n <base-select\n label=\"Select Network\"\n [required]=\"true\"\n [options]=\"[\n { label: 'Ethereum', value: 'ETH' },\n { label: 'Binance Smart Chain', value: 'BSC' },\n { label: 'Polygon', value: 'MATIC' },\n ]\"\n ></base-select>\n </div>\n\n <base-button\n label=\"Pay\"\n type=\"primary\"\n customClass=\"w-full\"\n (onClick)=\"payHandler()\"\n ></base-button>\n }\n\n @if (formIndex === 1) {\n <div class=\"flex flex-col gap-6\">\n <div class=\"mx-auto\">\n <base-image\n src=\"../../../assets/images/stable-coin-qr-code.png\"\n alt=\"QR Code\"\n [width]=\"122\"\n [height]=\"122\"\n class=\"mb-1\"\n ></base-image>\n <p class=\"mb-0 text-body-4xs text-light-copy font-normal text-center\">USDC</p>\n </div>\n\n <div class=\"flex flex-col gap-6 border-c border-grey-100 p-4 rounded-2xl bg-light-white-50\">\n <div class=\"border-b border-grey-border pb-4 flex flex-col gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">Network</p>\n <div class=\"flex justify-between\">\n <div class=\"flex flex-col gap-1\">\n <p class=\"mb-0 text-body-2xs font-medium text-sub-copy\">BNB Smart Chain (BEP20)</p>\n <div class=\"flex items-center gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">*Est. arrival = 3 mins</p>\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">|</p>\n <base-currency-amount\n currency=\"USDC\"\n [amount]=\"10\"\n textClass=\"mb-0 text-body-3xs text-light-copy font-normal\"\n iconColorClass=\"#557591\"\n iconWidth=\"12\"\n iconHeight=\"12\"\n ></base-currency-amount>\n </div>\n </div>\n <icon-arrow-swap></icon-arrow-swap>\n </div>\n </div>\n\n <div class=\"pb-4 flex flex-col gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">Deposit Address ></p>\n <div class=\"flex justify-between\">\n <p class=\"mb-0 text-body-2xs font-medium text-sub-copy w-2/3 break-words\">\n 0j8938ysheeee8333c162883a4d4f5g6t111nhk8uey37777yt6\n </p>\n <base-copy copyText=\"0j8938ysheeee8333c162883a4d4f5g6t111nhk8uey37777yt6\"></base-copy>\n </div>\n </div>\n\n <!-- <div class=\"pb-4 flex flex-col gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">Memo ></p>\n <div class=\"flex justify-between\">\n <p\n class=\"mb-0 text-body-2xs font-medium text-sub-copy w-2/3 break-words\"\n >\n 0j8938ysheeee8333c162883a4d4f5g6t111nhk8uey37777yt6\n </p>\n <app-copy\n [isCopyIcon]=\"true\"\n [copyText]=\"'0j8938ysheeee8333c162883a4d4f5g6t111nhk8uey37777yt6'\"\n ></app-copy>\n </div>\n </div> -->\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <div class=\"flex items-center justify-between border-b border-grey-border py-3\">\n <p class=\"mb-0 text-body-2xs font-medium text-primary-black\">Network fee</p>\n <base-currency-amount\n currency=\"USDC\"\n [amount]=\"12\"\n textClass=\"mb-0 text-body-2xs font-extrabold text-primary-black\"\n iconColorClass=\"#231F20\"\n ></base-currency-amount>\n </div>\n\n <div class=\"flex items-center justify-between py-4\">\n <p class=\"mb-0 text-body-lg font-semibold text-primary-black\">Pay</p>\n <base-currency-amount\n currency=\"USDC\"\n [amount]=\"15\"\n textClass=\"mb-0 text-body-lg font-extrabold text-primary-black\"\n iconColorClass=\"#231F20\"\n iconWidth=\"20\"\n iconHeight=\"20\"\n ></base-currency-amount>\n </div>\n </div>\n\n <div class=\"flex flex-col gap-6\">\n <base-button label=\"Confirm Payment\" type=\"primary\" customClass=\"w-full\"></base-button>\n </div>\n </div>\n }\n</div>\n" }]
92
- }], propDecorators: { proceedToPay: [{
775
+ ReactiveFormsModule,
776
+ ], template: "<div class=\"flex flex-col gap-6\">\n @if (formIndex === 0) {\n <form [formGroup]=\"stableCoinForm\" class=\"grid grid-cols-1 gap-6\">\n <div class=\"grid grid-cols-1 gap-6\">\n <base-select\n formControlName=\"stableCoin\"\n label=\"Select Crypto\"\n [required]=\"true\"\n [options]=\"stableCoins\"\n [validationError]=\"getError('stableCoin', 'Select Crypto') ?? ''\"\n [loading]=\"loadingStableCoins\"\n (onSelectChange)=\"getStableCoinNetworks()\"\n ></base-select>\n <base-select\n formControlName=\"network\"\n label=\"Select Network\"\n [required]=\"true\"\n [options]=\"networkList\"\n [validationError]=\"getError('network', 'Network') ?? ''\"\n [loading]=\"loadingStableCoinNetworks\"\n ></base-select>\n </div>\n\n <base-button\n label=\"Pay\"\n type=\"primary\"\n customClass=\"w-full\"\n [loading]=\"generatingAddress\"\n (onClick)=\"payHandler()\"\n ></base-button>\n </form>\n }\n\n @if (formIndex === 1) {\n <div class=\"flex flex-col gap-6\">\n <div class=\"mx-auto\">\n <!-- <base-image\n src=\"../../../assets/images/stable-coin-qr-code.png\"\n alt=\"QR Code\"\n [width]=\"122\"\n [height]=\"122\"\n class=\"mb-1\"\n ></base-image> -->\n <p class=\"mb-0 text-body-4xs text-light-copy font-normal text-center\">USDC</p>\n </div>\n\n <div class=\"flex flex-col gap-6 border-c border-grey-100 p-4 rounded-2xl bg-light-white-50\">\n <div class=\"border-b border-grey-border pb-4 flex flex-col gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">Network</p>\n <div class=\"flex justify-between\">\n <div class=\"flex flex-col gap-1\">\n <p class=\"mb-0 text-body-2xs font-medium text-sub-copy\">\n {{ addressDetails?.chain }}\n </p>\n <div class=\"flex items-center gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">*Est. arrival = 3 mins</p>\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">|</p>\n <base-currency-amount\n [currency]=\"generateAddressPayload?.currency ?? ''\"\n [amount]=\"addressDetails?.networkFee ?? 0\"\n textClass=\"mb-0 text-body-3xs text-light-copy font-normal\"\n iconColorClass=\"#557591\"\n iconWidth=\"12\"\n iconHeight=\"12\"\n ></base-currency-amount>\n </div>\n </div>\n <icon-arrow-swap></icon-arrow-swap>\n </div>\n </div>\n\n <div class=\"pb-4 flex flex-col gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">Deposit Address ></p>\n <div class=\"flex justify-between\">\n <p class=\"mb-0 text-body-2xs font-medium text-sub-copy w-2/3 break-words\">\n {{ addressDetails?.walletAddress }}\n </p>\n <base-copy [copyText]=\"addressDetails?.walletAddress ?? ''\"></base-copy>\n </div>\n </div>\n\n <!-- <div class=\"pb-4 flex flex-col gap-2\">\n <p class=\"mb-0 text-body-3xs text-light-copy font-normal\">Memo ></p>\n <div class=\"flex justify-between\">\n <p\n class=\"mb-0 text-body-2xs font-medium text-sub-copy w-2/3 break-words\"\n >\n 0j8938ysheeee8333c162883a4d4f5g6t111nhk8uey37777yt6\n </p>\n <app-copy\n [isCopyIcon]=\"true\"\n [copyText]=\"'0j8938ysheeee8333c162883a4d4f5g6t111nhk8uey37777yt6'\"\n ></app-copy>\n </div>\n </div> -->\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <div class=\"flex items-center justify-between border-b border-grey-border py-3\">\n <p class=\"mb-0 text-body-2xs font-medium text-primary-black\">Network fee</p>\n <base-currency-amount\n [currency]=\"generateAddressPayload?.currency ?? ''\"\n [amount]=\"addressDetails?.networkFee ?? 0\"\n textClass=\"mb-0 text-body-2xs font-extrabold text-primary-black\"\n iconColorClass=\"#231F20\"\n ></base-currency-amount>\n </div>\n\n <div class=\"flex items-center justify-between py-4\">\n <p class=\"mb-0 text-body-lg font-semibold text-primary-black\">Pay</p>\n <base-currency-amount\n [currency]=\"generateAddressPayload?.currency ?? ''\"\n [amount]=\"amountPlusNetworkFee\"\n textClass=\"mb-0 text-body-lg font-extrabold text-primary-black\"\n iconColorClass=\"#231F20\"\n iconWidth=\"20\"\n iconHeight=\"20\"\n ></base-currency-amount>\n </div>\n </div>\n\n <div class=\"flex flex-col gap-6\">\n <base-button\n label=\"Confirm Payment\"\n type=\"primary\"\n customClass=\"w-full\"\n [loading]=\"isConfirmingPayment\"\n (onClick)=\"confirmPaymentHandler()\"\n ></base-button>\n </div>\n </div>\n }\n</div>\n" }]
777
+ }], ctorParameters: () => [{ type: i1.ResourceService }, { type: i1.CheckoutService }, { type: i0.ChangeDetectorRef }], propDecorators: { secretKey: [{
778
+ type: Input
779
+ }], environment: [{
780
+ type: Input
781
+ }], paymentObject: [{
782
+ type: Input
783
+ }], paymentAuthorized: [{
93
784
  type: Output
94
785
  }] } });
95
786
 
@@ -98,6 +789,7 @@ class CheckoutCardComponent {
98
789
  secretKey = '';
99
790
  environment = 'sandbox';
100
791
  paymentObject = {
792
+ merchantName: '',
101
793
  amount: 0,
102
794
  currency: '',
103
795
  email: '',
@@ -108,7 +800,12 @@ class CheckoutCardComponent {
108
800
  ready = new EventEmitter();
109
801
  validityChange = new EventEmitter();
110
802
  tokenize = new EventEmitter();
111
- checkoutState = 'PAYMENT';
803
+ successObject = {
804
+ paymentDate: '',
805
+ paymentId: '',
806
+ paymentStatus: '',
807
+ };
808
+ checkoutState = 'PENDING';
112
809
  countryOptions = [
113
810
  {
114
811
  label: 'Nigeria',
@@ -137,11 +834,20 @@ class CheckoutCardComponent {
137
834
  paymentTypeHandler(event) {
138
835
  this.paymentType = event;
139
836
  }
140
- payStableCoinHandler() {
141
- this.checkoutState = 'STABLE_COIN_PAYMENT';
837
+ setSuccess(event) {
838
+ this.successObject = { ...event };
839
+ if (this.successObject.paymentStatus === 'pending') {
840
+ this.checkoutState = 'PENDING';
841
+ }
842
+ else if (this.successObject.paymentStatus === 'used') {
843
+ this.checkoutState = 'USED';
844
+ }
845
+ else {
846
+ this.checkoutState = 'SUCCESS';
847
+ }
142
848
  }
143
849
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: CheckoutCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
144
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: CheckoutCardComponent, isStandalone: true, selector: "bzp-checkout-card", inputs: { options: "options", secretKey: "secretKey", environment: "environment", paymentObject: "paymentObject" }, outputs: { ready: "ready", validityChange: "validityChange", tokenize: "tokenize" }, ngImport: i0, template: "<base-card [showBackButton]=\"checkoutState === 'STABLE_COIN_PAYMENT'\">\n <div class=\"grid grid-cols-3\">\n @if (checkoutState === 'PAYMENT') {\n <div class=\"bg-[#EFF7FF] px-6 py-8 flex flex-col gap-5 col-span-1 rounded-l-xl\">\n <p class=\"text-heading-text text-body-xs font-semibold\">Pay with</p>\n <base-radio-group\n [options]=\"filteredPaymentTypeOptions\"\n (selectedChange)=\"paymentTypeHandler($event)\"\n ></base-radio-group>\n </div>\n }\n\n <div class=\"col-span-2\">\n @if (checkoutState === 'PAYMENT' || checkoutState === 'STABLE_COIN_PAYMENT') {\n @if (checkoutState === 'PAYMENT') {\n <div class=\"flex items-center justify-between px-12 py-8\">\n @if (options?.imageUrl) {\n <base-image\n [src]=\"options?.imageUrl ?? ''\"\n alt=\"Merchant Logo\"\n [width]=\"52\"\n [height]=\"52\"\n class=\"rounded-lg\"\n ></base-image>\n } @else {\n <div\n class=\"bg-heading-text rounded flex flex-col justify-center\"\n style=\"width: 52px; height: 52px\"\n >\n <p class=\"text-white text-center text-body-2xs font-medium\">Logo</p>\n </div>\n }\n\n <div class=\"flex flex-col gap-1\">\n <p class=\"text-body-2xs font-regular text-sub-copy text-right\">\n Raymahni Merchant LLC\n </p>\n <p class=\"text-body-2xs font-regular text-sub-copy text-right\">\n Pay:\n <span class=\"text-orange-500 font-extrabold\">{{ formatAmountHandler }}</span>\n </p>\n </div>\n </div>\n }\n\n <div class=\"overflow-y-scroll px-10 pb-10 pt-2\">\n @if (paymentType === 'CARD') {\n <pay-by-card></pay-by-card>\n } @else if (paymentType === 'BANK_TRANSFER') {\n <pay-by-transfer></pay-by-transfer>\n } @else {\n <pay-by-stable-coin (proceedToPay)=\"payStableCoinHandler()\"></pay-by-stable-coin>\n }\n </div>\n } @else if (checkoutState === 'SUCCESS') {\n <base-success></base-success>\n }\n </div>\n </div>\n</base-card>\n", dependencies: [{ kind: "component", type: RadioGroupComponent, selector: "base-radio-group", inputs: ["options", "type"], outputs: ["selectedChange"] }, { kind: "component", type: ImageComponent, selector: "base-image", inputs: ["src", "alt", "isFullWidth", "width", "height", "customClass"], outputs: ["onClick"] }, { kind: "component", type: PayByCardComponent, selector: "pay-by-card" }, { kind: "component", type: PayByTransferComponent, selector: "pay-by-transfer" }, { kind: "component", type: PayByStableCoinComponent, selector: "pay-by-stable-coin", outputs: ["proceedToPay"] }, { kind: "component", type: SuccessComponent, selector: "base-success" }, { kind: "component", type: CardComponent, selector: "base-card", inputs: ["showBackButton"], outputs: ["back"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
850
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: CheckoutCardComponent, isStandalone: true, selector: "bzp-checkout-card", inputs: { options: "options", secretKey: "secretKey", environment: "environment", paymentObject: "paymentObject" }, outputs: { ready: "ready", validityChange: "validityChange", tokenize: "tokenize" }, ngImport: i0, template: "<base-card>\n <div class=\"grid grid-cols-3\">\n @if (checkoutState === 'PENDING') {\n <div class=\"bg-[#EFF7FF] px-6 py-8 flex flex-col gap-5 col-span-1 rounded-l-xl\">\n <p class=\"text-heading-text text-body-xs font-semibold\">Pay with</p>\n <base-radio-group\n [options]=\"filteredPaymentTypeOptions\"\n (selectedChange)=\"paymentTypeHandler($event)\"\n ></base-radio-group>\n </div>\n }\n\n <div [class]=\"checkoutState === 'SUCCESS' ? 'col-span-3' : 'col-span-2'\">\n @if (checkoutState === 'PENDING') {\n <div class=\"flex items-center justify-between px-12 py-8\">\n @if (options?.imageUrl) {\n <base-image\n [src]=\"options?.imageUrl ?? ''\"\n alt=\"Merchant Logo\"\n [width]=\"52\"\n [height]=\"52\"\n class=\"rounded-lg\"\n ></base-image>\n } @else {\n <div\n class=\"bg-heading-text rounded flex flex-col justify-center\"\n style=\"width: 52px; height: 52px\"\n >\n <p class=\"text-white text-center text-body-2xs font-medium\">Logo</p>\n </div>\n }\n\n <div class=\"flex flex-col gap-1\">\n <p class=\"text-body-2xs font-regular text-sub-copy text-right\">\n {{ paymentObject.merchantName }}\n </p>\n <p class=\"text-body-2xs font-regular text-sub-copy text-right\">\n Pay:\n <span class=\"text-orange-500 font-extrabold\">{{ formatAmountHandler }}</span>\n </p>\n </div>\n </div>\n\n <div class=\"overflow-y-scroll px-10 pb-10 pt-2\">\n @if (paymentType === 'CARD') {\n <pay-by-card\n [environment]=\"environment\"\n [secretKey]=\"secretKey\"\n [paymentObject]=\"paymentObject\"\n (paymentAuthorized)=\"setSuccess($event)\"\n ></pay-by-card>\n } @else if (paymentType === 'BANK_TRANSFER') {\n <pay-by-transfer\n [environment]=\"environment\"\n [secretKey]=\"secretKey\"\n [paymentObject]=\"paymentObject\"\n (paymentAuthorized)=\"setSuccess($event)\"\n ></pay-by-transfer>\n } @else {\n <pay-by-stable-coin\n [environment]=\"environment\"\n [secretKey]=\"secretKey\"\n [paymentObject]=\"paymentObject\"\n (paymentAuthorized)=\"setSuccess($event)\"\n ></pay-by-stable-coin>\n }\n </div>\n } @else if (checkoutState === 'SUCCESS') {\n <base-success\n [amount]=\"paymentObject.amount\"\n [currency]=\"paymentObject.currency\"\n [redirectUrl]=\"paymentObject.redirectUrl\"\n [successObject]=\"successObject\"\n ></base-success>\n }\n </div>\n </div>\n</base-card>\n", dependencies: [{ kind: "component", type: RadioGroupComponent, selector: "base-radio-group", inputs: ["options", "type"], outputs: ["selectedChange"] }, { kind: "component", type: ImageComponent, selector: "base-image", inputs: ["src", "alt", "isFullWidth", "width", "height", "customClass"], outputs: ["onClick"] }, { kind: "component", type: PayByCardComponent, selector: "pay-by-card", inputs: ["secretKey", "environment", "paymentObject"], outputs: ["paymentAuthorized"] }, { kind: "component", type: PayByTransferComponent, selector: "pay-by-transfer", inputs: ["secretKey", "environment", "paymentObject"], outputs: ["paymentAuthorized"] }, { kind: "component", type: PayByStableCoinComponent, selector: "pay-by-stable-coin", inputs: ["secretKey", "environment", "paymentObject"], outputs: ["paymentAuthorized"] }, { kind: "component", type: SuccessComponent, selector: "base-success", inputs: ["successObject", "amount", "currency", "redirectUrl"] }, { kind: "component", type: CardComponent, selector: "base-card", inputs: ["showBackButton"], outputs: ["back"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
145
851
  }
146
852
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: CheckoutCardComponent, decorators: [{
147
853
  type: Component,
@@ -153,7 +859,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
153
859
  PayByStableCoinComponent,
154
860
  SuccessComponent,
155
861
  CardComponent,
156
- ], template: "<base-card [showBackButton]=\"checkoutState === 'STABLE_COIN_PAYMENT'\">\n <div class=\"grid grid-cols-3\">\n @if (checkoutState === 'PAYMENT') {\n <div class=\"bg-[#EFF7FF] px-6 py-8 flex flex-col gap-5 col-span-1 rounded-l-xl\">\n <p class=\"text-heading-text text-body-xs font-semibold\">Pay with</p>\n <base-radio-group\n [options]=\"filteredPaymentTypeOptions\"\n (selectedChange)=\"paymentTypeHandler($event)\"\n ></base-radio-group>\n </div>\n }\n\n <div class=\"col-span-2\">\n @if (checkoutState === 'PAYMENT' || checkoutState === 'STABLE_COIN_PAYMENT') {\n @if (checkoutState === 'PAYMENT') {\n <div class=\"flex items-center justify-between px-12 py-8\">\n @if (options?.imageUrl) {\n <base-image\n [src]=\"options?.imageUrl ?? ''\"\n alt=\"Merchant Logo\"\n [width]=\"52\"\n [height]=\"52\"\n class=\"rounded-lg\"\n ></base-image>\n } @else {\n <div\n class=\"bg-heading-text rounded flex flex-col justify-center\"\n style=\"width: 52px; height: 52px\"\n >\n <p class=\"text-white text-center text-body-2xs font-medium\">Logo</p>\n </div>\n }\n\n <div class=\"flex flex-col gap-1\">\n <p class=\"text-body-2xs font-regular text-sub-copy text-right\">\n Raymahni Merchant LLC\n </p>\n <p class=\"text-body-2xs font-regular text-sub-copy text-right\">\n Pay:\n <span class=\"text-orange-500 font-extrabold\">{{ formatAmountHandler }}</span>\n </p>\n </div>\n </div>\n }\n\n <div class=\"overflow-y-scroll px-10 pb-10 pt-2\">\n @if (paymentType === 'CARD') {\n <pay-by-card></pay-by-card>\n } @else if (paymentType === 'BANK_TRANSFER') {\n <pay-by-transfer></pay-by-transfer>\n } @else {\n <pay-by-stable-coin (proceedToPay)=\"payStableCoinHandler()\"></pay-by-stable-coin>\n }\n </div>\n } @else if (checkoutState === 'SUCCESS') {\n <base-success></base-success>\n }\n </div>\n </div>\n</base-card>\n" }]
862
+ ], template: "<base-card>\n <div class=\"grid grid-cols-3\">\n @if (checkoutState === 'PENDING') {\n <div class=\"bg-[#EFF7FF] px-6 py-8 flex flex-col gap-5 col-span-1 rounded-l-xl\">\n <p class=\"text-heading-text text-body-xs font-semibold\">Pay with</p>\n <base-radio-group\n [options]=\"filteredPaymentTypeOptions\"\n (selectedChange)=\"paymentTypeHandler($event)\"\n ></base-radio-group>\n </div>\n }\n\n <div [class]=\"checkoutState === 'SUCCESS' ? 'col-span-3' : 'col-span-2'\">\n @if (checkoutState === 'PENDING') {\n <div class=\"flex items-center justify-between px-12 py-8\">\n @if (options?.imageUrl) {\n <base-image\n [src]=\"options?.imageUrl ?? ''\"\n alt=\"Merchant Logo\"\n [width]=\"52\"\n [height]=\"52\"\n class=\"rounded-lg\"\n ></base-image>\n } @else {\n <div\n class=\"bg-heading-text rounded flex flex-col justify-center\"\n style=\"width: 52px; height: 52px\"\n >\n <p class=\"text-white text-center text-body-2xs font-medium\">Logo</p>\n </div>\n }\n\n <div class=\"flex flex-col gap-1\">\n <p class=\"text-body-2xs font-regular text-sub-copy text-right\">\n {{ paymentObject.merchantName }}\n </p>\n <p class=\"text-body-2xs font-regular text-sub-copy text-right\">\n Pay:\n <span class=\"text-orange-500 font-extrabold\">{{ formatAmountHandler }}</span>\n </p>\n </div>\n </div>\n\n <div class=\"overflow-y-scroll px-10 pb-10 pt-2\">\n @if (paymentType === 'CARD') {\n <pay-by-card\n [environment]=\"environment\"\n [secretKey]=\"secretKey\"\n [paymentObject]=\"paymentObject\"\n (paymentAuthorized)=\"setSuccess($event)\"\n ></pay-by-card>\n } @else if (paymentType === 'BANK_TRANSFER') {\n <pay-by-transfer\n [environment]=\"environment\"\n [secretKey]=\"secretKey\"\n [paymentObject]=\"paymentObject\"\n (paymentAuthorized)=\"setSuccess($event)\"\n ></pay-by-transfer>\n } @else {\n <pay-by-stable-coin\n [environment]=\"environment\"\n [secretKey]=\"secretKey\"\n [paymentObject]=\"paymentObject\"\n (paymentAuthorized)=\"setSuccess($event)\"\n ></pay-by-stable-coin>\n }\n </div>\n } @else if (checkoutState === 'SUCCESS') {\n <base-success\n [amount]=\"paymentObject.amount\"\n [currency]=\"paymentObject.currency\"\n [redirectUrl]=\"paymentObject.redirectUrl\"\n [successObject]=\"successObject\"\n ></base-success>\n }\n </div>\n </div>\n</base-card>\n" }]
157
863
  }], propDecorators: { options: [{
158
864
  type: Input
159
865
  }], secretKey: [{
@@ -194,6 +900,7 @@ class CheckoutIframeComponent {
194
900
  };
195
901
  environment = 'sandbox';
196
902
  paymentObject = {
903
+ merchantName: '',
197
904
  amount: 0,
198
905
  currency: '',
199
906
  email: '',
@@ -256,7 +963,7 @@ class CheckoutIframeComponent {
256
963
  await this.generatePaymentLinkHandler();
257
964
  }
258
965
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: CheckoutIframeComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i1.CheckoutService }], target: i0.ɵɵFactoryTarget.Component });
259
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: CheckoutIframeComponent, isStandalone: true, selector: "bzp-checkout-iframe", inputs: { secretKey: "secretKey", url: "url", style: "style", environment: "environment", paymentObject: "paymentObject" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: "<div class=\"relative\" [ngStyle]=\"blockStyle\">\n <div #container class=\"w-full h-full\"></div>\n\n @if (loading) {\n <div class=\"absolute inset-0 grid place-items-center bg-white/60\">\n <icon-loader></icon-loader>\n </div>\n }\n</div>\n", dependencies: [{ kind: "component", type: IconLoaderComponent, selector: "icon-loader", inputs: ["color", "size"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
966
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: CheckoutIframeComponent, isStandalone: true, selector: "bzp-checkout-iframe", inputs: { secretKey: "secretKey", url: "url", style: "style", environment: "environment", paymentObject: "paymentObject" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: "<div class=\"relative\" [ngStyle]=\"blockStyle\">\n <div #container class=\"w-full h-full\"></div>\n\n @if (loading) {\n <div class=\"absolute inset-0 grid place-items-center bg-white/60\">\n <icon-loader></icon-loader>\n </div>\n }\n</div>\n", dependencies: [{ kind: "component", type: IconLoaderComponent, selector: "icon-loader", inputs: ["color", "size"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
260
967
  }
261
968
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: CheckoutIframeComponent, decorators: [{
262
969
  type: Component,
@@ -291,6 +998,7 @@ class CheckoutButtonComponent {
291
998
  environment = 'sandbox';
292
999
  mode = 'redirect';
293
1000
  paymentObject = {
1001
+ merchantName: '',
294
1002
  amount: 0,
295
1003
  currency: '',
296
1004
  email: '',