@miden-npm/angular 0.0.37 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,800 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { EventEmitter, Output, Input, ChangeDetectionStrategy, Component, ViewChild } from '@angular/core';
3
3
  import * as i1 from '@miden-npm/angular';
4
- import { getValidationErrorMessage, formatAmount, cardType, checkObjectTruthy, getQueryParams, ButtonComponent, InputComponent, SelectComponent, 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
- import { tap, finalize } from 'rxjs';
8
- import * as i2$1 from '@angular/common';
4
+ import { formatAmount, RadioGroupComponent, ImageComponent, PayByCardComponent, PayByTransferComponent, PayByStableCoinComponent, SuccessComponent, CardComponent, checkObjectTruthy, IconLoaderComponent, ButtonComponent, InputErrorComponent } from '@miden-npm/angular';
5
+ import * as i2 from '@angular/common';
9
6
  import { CommonModule } from '@angular/common';
10
-
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 = 'sandbox';
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
- rawCountries = [];
42
- countries = [];
43
- countryStates = [];
44
- formIndex = 0;
45
- setFormIndex(index) {
46
- this.formIndex = index;
47
- }
48
- billingForm = new FormGroup({
49
- address1: new FormControl('', [Validators.required]),
50
- address2: new FormControl(''),
51
- postalCode: new FormControl('', [Validators.required]),
52
- state: new FormControl('', [Validators.required]),
53
- city: new FormControl('', [Validators.required]),
54
- country: new FormControl('', [Validators.required]),
55
- emailAddress: new FormControl('', [Validators.required, Validators.email]),
56
- phoneNumber: new FormControl('', [Validators.required]),
57
- });
58
- payForm = new FormGroup({
59
- customerName: new FormControl('', [Validators.required]),
60
- cardNo: new FormControl('', [Validators.required]),
61
- expireDate: new FormControl('', [Validators.required]),
62
- cvv: new FormControl('', [Validators.required]),
63
- cardPin: new FormControl(''), // Only required for Verve cards
64
- });
65
- getError(formKey, controlName, label) {
66
- const control = formKey === 'billing' ? this.billingForm.get(controlName) : this.payForm.get(controlName);
67
- return getValidationErrorMessage(control, label);
68
- }
69
- get formatAmountHandler() {
70
- return formatAmount(this.paymentObject.amount, this.paymentObject.currency);
71
- }
72
- cardNumberInputHandler(event) {
73
- this.cardType = cardType(event);
74
- this.updatePinValidation();
75
- }
76
- updatePinValidation() {
77
- const cardPinControl = this.payForm.get('cardPin');
78
- if (this.cardType === 'Verve') {
79
- cardPinControl?.setValidators([Validators.required]);
80
- }
81
- else {
82
- cardPinControl?.clearValidators();
83
- }
84
- cardPinControl?.updateValueAndValidity();
85
- }
86
- async getAllCountries() {
87
- this.loadingCountries = true;
88
- this.cdr.markForCheck();
89
- this.resources
90
- .getCountries(this.environment, this.secretKey)
91
- .pipe(tap((res) => {
92
- if (res?.isSuccessful) {
93
- this.rawCountries = res.data ?? [];
94
- this.countries = (res.data ?? []).map((c) => {
95
- return { label: c.countryName, value: c.iso2 };
96
- });
97
- }
98
- }), finalize(() => {
99
- this.loadingCountries = false;
100
- this.cdr.markForCheck();
101
- }))
102
- .subscribe();
103
- }
104
- async getCountryStates(countryIso2) {
105
- const country = this.rawCountries.filter((c) => c.iso2 === countryIso2);
106
- this.loadingStates = true;
107
- this.cdr.markForCheck();
108
- this.resources
109
- .getCountryStates(country[0].iso3, this.environment, this.secretKey)
110
- .pipe(tap((res) => {
111
- if (res?.isSuccessful) {
112
- this.countryStates = (res.data ?? []).map((s) => {
113
- return { label: s.name, value: s.name };
114
- });
115
- }
116
- }), finalize(() => {
117
- this.loadingStates = false;
118
- this.cdr.markForCheck();
119
- }))
120
- .subscribe();
121
- }
122
- async generatePaymentLinkHandler() {
123
- if (!this.secretKey) {
124
- return (this.message = 'Secret key is required.');
125
- }
126
- if (!checkObjectTruthy(this.paymentObject)) {
127
- return (this.message = 'Kindly ensure you are passing all the required data.');
128
- }
129
- this.loading = true;
130
- this.cdr.markForCheck();
131
- this.checkout
132
- .createPaymentLink(this.paymentObject, this.environment, this.secretKey)
133
- .pipe(tap((res) => {
134
- if (res?.isSuccessful) {
135
- this.message = 'Payment link created successfully';
136
- const queryParams = getQueryParams(res.launchUrl ?? '');
137
- this.transactionReference = queryParams['paymentReference'];
138
- }
139
- else {
140
- this.message = 'Failed to create payment link';
141
- }
142
- }), finalize(() => {
143
- this.loading = false;
144
- this.cdr.markForCheck();
145
- }))
146
- .subscribe();
147
- }
148
- async proceedHandler() {
149
- if (this.formIndex === 0) {
150
- if (this.billingForm && this.billingForm.valid) {
151
- this.checkout.setBillingInfo({ ...this.billingForm.value });
152
- this.setFormIndex(1);
153
- }
154
- else {
155
- this.billingForm.markAllAsTouched();
156
- }
157
- }
158
- else {
159
- if (this.payForm && this.payForm.valid) {
160
- try {
161
- this.isMakingPayment = true;
162
- // Create card details object for encryption
163
- const cardDetails = {
164
- pan: this.payForm.value.cardNo ?? '',
165
- expiryDate: this.payForm.value.expireDate ?? '',
166
- cvv: this.payForm.value.cvv ?? '',
167
- cardScheme: this.cardType,
168
- nameOnCard: this.payForm.value.customerName ?? '',
169
- ...(this.cardType === 'Verve' && { pin: this.payForm.value.cardPin ?? '' }),
170
- };
171
- // Get billing details from the form control
172
- const billingDetails = {
173
- address2: this.billingForm.value.address2 ?? '',
174
- address1: this.billingForm.value.address1 ?? '',
175
- postalCode: this.billingForm.value.postalCode ?? '',
176
- state: this.billingForm.value.state ?? '',
177
- city: this.billingForm.value.city ?? '',
178
- country: this.billingForm.value.country ?? '',
179
- emailAddress: this.billingForm.value.emailAddress ?? '',
180
- phoneNumber: this.billingForm.value.phoneNumber ?? '',
181
- };
182
- // Encrypt card details using payload encryption method
183
- const encryptedCardDetails = this.encryptService.encryptPayload(this.secretKey, cardDetails);
184
- // Test: Decrypt to verify encryption works
185
- // const decryptedTest = this.encryptService.decryptPayload(
186
- // this.environment,
187
- // encryptedCardDetails.requestParam,
188
- // );
189
- const payload = {
190
- customerId: this.paymentObject?.email || this.payForm.value.customerName || '',
191
- amount: this.paymentObject?.amount.toString(),
192
- currency: this.paymentObject?.currency || 'USD',
193
- narration: this.paymentObject?.narration || 'Test transaction',
194
- encryptedCardDetails: encryptedCardDetails.requestParam, // Use the encrypted card details
195
- billingDetails: billingDetails,
196
- redirectUrl: this.paymentObject?.redirectUrl || '',
197
- paymentReference: this.transactionReference,
198
- isCheckout: true,
199
- };
200
- this.checkout
201
- .authorizeCardPayment(this.environment, {
202
- ...payload,
203
- merchantId: this.secretKey,
204
- })
205
- .subscribe({
206
- next: async (response) => {
207
- let processedResponse = response;
208
- // Check if response is encrypted (has responseParam)
209
- if (response?.responseParam) {
210
- // Decrypt the response
211
- processedResponse = this.encryptService.decryptPayload(this.environment, response.responseParam);
212
- }
213
- if (processedResponse?.isSuccessful) {
214
- // Check for 3DS authentication requirement
215
- if (processedResponse.threeDsInteractionRequired === true) {
216
- // Store 3DS data for the authentication page
217
- const threeDsData = {
218
- transactionReference: processedResponse.transactionReference,
219
- threeDsHtml: processedResponse.threeDsHtml,
220
- amount: processedResponse.amount,
221
- responseMessage: processedResponse.responseMessage,
222
- // Pass all 3DS details
223
- paReq: processedResponse.threeDsHtml?.paReq,
224
- termUrl: processedResponse.threeDsHtml?.termUrl,
225
- action: processedResponse.threeDsHtml?.action,
226
- acsUrl: processedResponse.threeDsHtml?.acsUrl,
227
- md: processedResponse.threeDsHtml?.md,
228
- };
229
- // Encrypt 3DS data to pass as url param
230
- const stringifiedThreeDsData = btoa(JSON.stringify(threeDsData));
231
- // Open 3DS authentication page in a new tab
232
- const threeDsUrl = `https://sandbox-merchant.buzapay.com/account/three-ds-confirm?threeDsData=${encodeURIComponent(stringifiedThreeDsData)}&paymentReference=${processedResponse.transactionReference}`;
233
- window.open(threeDsUrl, '_self', 'noopener,noreferrer');
234
- this.message =
235
- '3D Secure authentication opened in new tab. Please complete the verification';
236
- this.isMakingPayment = false;
237
- return;
238
- }
239
- // Fallback check: if response message indicates 3DS is required
240
- if (processedResponse.responseMessage === 'Payer Interaction Required' &&
241
- processedResponse.threeDsHtml) {
242
- // Store 3DS data for the authentication page
243
- const threeDsData = {
244
- transactionReference: processedResponse.transactionReference,
245
- threeDsHtml: processedResponse.threeDsHtml,
246
- amount: processedResponse.amount,
247
- responseMessage: processedResponse.responseMessage,
248
- // Pass all 3DS details
249
- paReq: processedResponse.threeDsHtml?.paReq,
250
- termUrl: processedResponse.threeDsHtml?.termUrl,
251
- action: processedResponse.threeDsHtml?.action,
252
- acsUrl: processedResponse.threeDsHtml?.acsUrl,
253
- md: processedResponse.threeDsHtml?.md,
254
- };
255
- // Encrypt 3DS data to pass as url param
256
- const stringifiedThreeDsData = btoa(JSON.stringify(threeDsData));
257
- // Open 3DS authentication page in a new tab
258
- const threeDsUrl = `https://sandbox-merchant.buzapay.com/account/three-ds-confirm?threeDsData=${encodeURIComponent(stringifiedThreeDsData)}&paymentReference=${processedResponse.transactionReference}`;
259
- window.open(threeDsUrl, '_self', 'noopener,noreferrer');
260
- this.message =
261
- '3D Secure authentication opened in new tab. Please complete the verification';
262
- this.isMakingPayment = false;
263
- return;
264
- }
265
- // Emit the transaction reference to parent component
266
- if (processedResponse.transactionReference &&
267
- processedResponse.transactionReference.trim() !== '') {
268
- this.paymentAuthorized.emit({
269
- paymentId: processedResponse.transactionReference,
270
- paymentDate: response.data.updatedAt,
271
- paymentStatus: 'Authorized',
272
- });
273
- }
274
- this.message = 'Card payment authorized successfully';
275
- // Handle legacy 3DS logic for backward compatibility
276
- // if (processedResponse.provider === 'myRoute2') {
277
- // if (processedResponse.requires3DS === true) {
278
- // this.router.navigateByUrl('account/visa-card-payment-confirm');
279
- // } else {
280
- // if (processedResponse.responseCode === 'T00') {
281
- // } else if (processedResponse.responseCode === '000') {
282
- // this.message = 'Please confirm transaction !!';
283
- // } else {
284
- // this.message = processedResponse.responseMessage;
285
- // }
286
- // }
287
- // } else if (processedResponse.provider === 'myRoute1') {
288
- // if (processedResponse.requires3DS === true) {
289
- // this.router.navigateByUrl('account/visa-card-payment-confirm2');
290
- // }
291
- // }
292
- this.isMakingPayment = false;
293
- }
294
- else {
295
- this.isMakingPayment = false;
296
- this.message = processedResponse.responseMessage || 'Payment failed';
297
- this.paymentAuthorized.emit({
298
- paymentId: processedResponse.transactionReference,
299
- paymentDate: response.data.updatedAt,
300
- paymentStatus: 'Payment failed',
301
- });
302
- }
303
- },
304
- error: (err) => {
305
- this.isMakingPayment = false;
306
- if (err.error?.responseParam) {
307
- // Decrypt error response
308
- const decryptedErrorResponse = this.encryptService.decryptPayload(this.environment, err.error.responseParam);
309
- this.message = decryptedErrorResponse.responseMessage || 'Payment failed';
310
- }
311
- else {
312
- this.message = err.error.responseMessage || err.error.message || 'Payment failed';
313
- }
314
- },
315
- });
316
- }
317
- catch (error) {
318
- this.isMakingPayment = false;
319
- this.message = 'An unexpected error occurred';
320
- }
321
- }
322
- else {
323
- this.payForm.markAllAsTouched();
324
- }
325
- }
326
- }
327
- async ngOnInit() {
328
- await this.generatePaymentLinkHandler();
329
- await this.getAllCountries();
330
- }
331
- 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 });
332
- 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 [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 <base-button\n [label]=\"formIndex === 0 ? 'Proceed' : 'Pay ' + formatAmountHandler\"\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", "preventPaste"], 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 });
333
- }
334
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: PayByCardComponent, decorators: [{
335
- type: Component,
336
- 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 [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 <base-button\n [label]=\"formIndex === 0 ? 'Proceed' : 'Pay ' + formatAmountHandler\"\n type=\"primary\"\n customClass=\"w-full\"\n [loading]=\"isMakingPayment\"\n (onClick)=\"proceedHandler()\"\n ></base-button>\n</div>\n" }]
337
- }], ctorParameters: () => [{ type: i1.ResourceService }, { type: i0.ChangeDetectorRef }, { type: i1.CheckoutService }, { type: i1.EncryptService }], propDecorators: { secretKey: [{
338
- type: Input
339
- }], environment: [{
340
- type: Input
341
- }], paymentObject: [{
342
- type: Input
343
- }], paymentAuthorized: [{
344
- type: Output
345
- }] } });
346
-
347
- class PayByTransferComponent {
348
- checkout;
349
- cdr;
350
- constructor(checkout, cdr) {
351
- this.checkout = checkout;
352
- this.cdr = cdr;
353
- }
354
- secretKey = '';
355
- environment = '';
356
- paymentObject = {
357
- merchantName: '',
358
- amount: 0,
359
- currency: '',
360
- email: '',
361
- phoneNumber: '',
362
- narration: '',
363
- redirectUrl: '',
364
- };
365
- paymentAuthorized = new EventEmitter();
366
- message = '';
367
- generatingLink = false;
368
- isMakingPayment = false;
369
- isFetchingPaymentDetails = false;
370
- isConfirmCall = false;
371
- paymentMade = false;
372
- isPaymentConfirmed = false;
373
- paymentAccountDetails = null;
374
- paymentReferenceDetails = null;
375
- transactionReference = '';
376
- paymentReferenceStatus = '';
377
- countDownTime = '';
378
- remainingSeconds = 30 * 60;
379
- intervalId = null;
380
- updateDisplay() {
381
- const minutes = Math.floor(this.remainingSeconds / 60);
382
- const seconds = this.remainingSeconds % 60;
383
- this.countDownTime = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
384
- this.cdr.markForCheck(); // 👈 notify OnPush to re-render
385
- }
386
- transferForm = new FormGroup({
387
- customerName: new FormControl('', [Validators.required]),
388
- });
389
- getError(controlName, label) {
390
- const control = this.transferForm.get(controlName);
391
- return getValidationErrorMessage(control, label);
392
- }
393
- get formatAmountHandler() {
394
- return formatAmount(this.paymentObject.amount, this.paymentObject.currency);
395
- }
396
- startTimer() {
397
- if (this.intervalId) {
398
- clearInterval(this.intervalId);
399
- this.intervalId = null;
400
- }
401
- this.updateDisplay();
402
- this.intervalId = setInterval(() => {
403
- this.remainingSeconds--;
404
- if (this.remainingSeconds < 0) {
405
- clearInterval(this.intervalId);
406
- this.intervalId = null;
407
- this.countDownTime = '00:00';
408
- this.cdr.markForCheck();
409
- return;
410
- }
411
- this.updateDisplay();
412
- }, 1000);
413
- }
414
- async generatePaymentLinkHandler() {
415
- if (!this.secretKey) {
416
- return (this.message = 'Secret key is required.');
417
- }
418
- if (!checkObjectTruthy(this.paymentObject)) {
419
- return (this.message = 'Kindly ensure you are passing all the required data.');
420
- }
421
- this.generatingLink = true;
422
- this.cdr.markForCheck();
423
- this.checkout
424
- .createPaymentLink(this.paymentObject, this.environment, this.secretKey)
425
- .pipe(tap((res) => {
426
- if (res?.isSuccessful) {
427
- this.message = 'Payment link created successfully';
428
- const queryParams = getQueryParams(res.launchUrl ?? '');
429
- this.transactionReference = queryParams['paymentReference'];
430
- }
431
- else {
432
- this.message = 'Failed to create payment link';
433
- }
434
- }), finalize(() => {
435
- this.generatingLink = false;
436
- this.cdr.markForCheck();
437
- }))
438
- .subscribe();
439
- }
440
- async payHandler() {
441
- if (this.transferForm && this.transferForm.valid) {
442
- const payload = {
443
- paymentReference: this.transactionReference,
444
- channel: 'virtual_account',
445
- customerName: this.transferForm.value.customerName ?? '',
446
- merchantId: this.secretKey,
447
- };
448
- this.isMakingPayment = true;
449
- await this.checkout.generatePaymentAccount(this.environment, payload).subscribe({
450
- next: async (response) => {
451
- if (response?.isSuccessful) {
452
- this.paymentAccountDetails = response.data;
453
- this.startTimer();
454
- this.message = 'Virtual account generated successfully for payment.';
455
- this.isMakingPayment = false;
456
- }
457
- },
458
- error: (err) => {
459
- this.isMakingPayment = false;
460
- this.message = err.error.responseMessage || err.error.message;
461
- },
462
- });
463
- }
464
- else {
465
- this.transferForm?.markAllAsTouched();
466
- }
467
- }
468
- async getReferenceDetails() {
469
- this.isFetchingPaymentDetails = true;
470
- await this.checkout
471
- .getPaymentReferenceDetails(this.environment, this.transactionReference)
472
- .subscribe({
473
- next: async (response) => {
474
- if (response?.isSuccessful) {
475
- this.paymentReferenceDetails = response.data;
476
- // Check if payment has been made (paymentStatus is "Payment Received")
477
- if (response.data?.paymentStatus === 'Payment Received') {
478
- this.paymentMade = true;
479
- }
480
- if (response.data?.finalTransactionStatus === null ||
481
- response.data?.paymentStatus === null) {
482
- if (this.isConfirmCall) {
483
- this.message = 'Transaction not confirmed !!';
484
- }
485
- // Only set to pending if payment hasn't been confirmed locally or made locally
486
- if (!this.isPaymentConfirmed && !this.paymentMade) {
487
- this.paymentReferenceStatus = 'pending';
488
- this.paymentAuthorized.emit({
489
- paymentId: this.transactionReference,
490
- paymentDate: response.data.updatedAt,
491
- paymentStatus: this.paymentReferenceStatus,
492
- });
493
- }
494
- else {
495
- this.paymentReferenceStatus = 'confirmed';
496
- this.paymentAuthorized.emit({
497
- paymentId: this.transactionReference,
498
- paymentDate: response.data.updatedAt,
499
- paymentStatus: this.paymentReferenceStatus,
500
- });
501
- }
502
- }
503
- else if (response.data?.finalTransactionStatus === 'Success' ||
504
- response.data?.paymentStatus === 'Received' ||
505
- response.data?.paymentStatus === 'Payment Received') {
506
- this.paymentAuthorized.emit({
507
- paymentId: this.transactionReference,
508
- paymentDate: response.data.updatedAt,
509
- paymentStatus: this.paymentReferenceStatus,
510
- });
511
- this.message = 'Transaction confirmed !!';
512
- this.paymentReferenceStatus = 'confirmed';
513
- this.isPaymentConfirmed = true;
514
- }
515
- }
516
- else if (!response?.isSuccessful && response?.responseCode === '119') {
517
- this.paymentReferenceStatus = 'used';
518
- this.message = response.responseMessage;
519
- this.paymentAuthorized.emit({
520
- paymentId: this.transactionReference,
521
- paymentDate: null,
522
- paymentStatus: this.paymentReferenceStatus,
523
- });
524
- }
525
- this.isFetchingPaymentDetails = false;
526
- },
527
- error: (err) => {
528
- this.paymentReferenceStatus = '';
529
- this.isFetchingPaymentDetails = false;
530
- this.message = err.error.responseMessage || err.error.message;
531
- },
532
- });
533
- }
534
- async ngOnInit() {
535
- this.startTimer();
536
- await this.generatePaymentLinkHandler();
537
- }
538
- ngOnDestroy() {
539
- if (this.intervalId) {
540
- clearInterval(this.intervalId);
541
- this.intervalId = null;
542
- }
543
- }
544
- 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 });
545
- 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=\"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 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", "preventPaste"], outputs: ["onInputChange", "onInputBlur"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
546
- }
547
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: PayByTransferComponent, decorators: [{
548
- type: Component,
549
- args: [{ selector: 'pay-by-transfer', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
550
- LabelInfoComponent,
551
- CopyComponent,
552
- ButtonComponent,
553
- ReactiveFormsModule,
554
- InputComponent,
555
- ], 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 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" }]
556
- }], ctorParameters: () => [{ type: i1.CheckoutService }, { type: i0.ChangeDetectorRef }], propDecorators: { secretKey: [{
557
- type: Input
558
- }], environment: [{
559
- type: Input
560
- }], paymentObject: [{
561
- type: Input
562
- }], paymentAuthorized: [{
563
- type: Output
564
- }] } });
565
-
566
- class PayByStableCoinComponent {
567
- resource;
568
- checkout;
569
- cdr;
570
- constructor(resource, checkout, cdr) {
571
- this.resource = resource;
572
- this.checkout = checkout;
573
- this.cdr = cdr;
574
- }
575
- secretKey = '';
576
- environment = '';
577
- paymentObject = {
578
- merchantName: '',
579
- amount: 0,
580
- currency: '',
581
- email: '',
582
- phoneNumber: '',
583
- narration: '',
584
- redirectUrl: '',
585
- };
586
- paymentAuthorized = new EventEmitter();
587
- message = '';
588
- transactionReference = '';
589
- paymentReferenceStatus = '';
590
- generateAddressPayload = null;
591
- addressDetails = null;
592
- paymentReferenceDetails = null;
593
- stableCoins = [];
594
- networkList = [];
595
- loadingStableCoins = false;
596
- generatingAddress = false;
597
- isConfirmingPayment = false;
598
- loading = false;
599
- loadingStableCoinNetworks = false;
600
- formIndex = 0;
601
- setFormIndex(index) {
602
- this.formIndex = index;
603
- }
604
- stableCoinForm = new FormGroup({
605
- stableCoin: new FormControl('', [Validators.required]),
606
- network: new FormControl('', [Validators.required]),
607
- });
608
- getError(controlName, label) {
609
- const control = this.stableCoinForm.get(controlName);
610
- return getValidationErrorMessage(control, label);
611
- }
612
- get formatAmountHandler() {
613
- return formatAmount(this.paymentObject.amount, this.paymentObject.currency);
614
- }
615
- get amountPlusNetworkFee() {
616
- return this.addressDetails
617
- ? Number(this.addressDetails.transactionAmount) + this.addressDetails.networkFee
618
- : 0;
619
- }
620
- async generatePaymentLinkHandler() {
621
- if (!this.secretKey) {
622
- return (this.message = 'Secret key is required.');
623
- }
624
- if (!checkObjectTruthy(this.paymentObject)) {
625
- return (this.message = 'Kindly ensure you are passing all the required data.');
626
- }
627
- this.loading = true;
628
- this.cdr.markForCheck();
629
- this.checkout
630
- .createPaymentLink(this.paymentObject, this.environment, this.secretKey)
631
- .pipe(tap((res) => {
632
- if (res?.isSuccessful) {
633
- this.message = 'Payment link created successfully';
634
- const queryParams = getQueryParams(res.launchUrl ?? '');
635
- this.transactionReference = queryParams['paymentReference'];
636
- }
637
- else {
638
- this.message = 'Failed to create payment link';
639
- }
640
- }), finalize(() => {
641
- this.loading = false;
642
- this.cdr.markForCheck();
643
- }))
644
- .subscribe();
645
- }
646
- generateAddress() {
647
- if (!this.generateAddressPayload)
648
- return;
649
- this.generatingAddress = true;
650
- this.cdr.markForCheck();
651
- this.checkout
652
- .generateStableCoinAddress(this.environment, this.generateAddressPayload)
653
- .pipe(tap((response) => {
654
- if (response?.isSuccessful) {
655
- this.addressDetails = response.data;
656
- this.setFormIndex(1);
657
- }
658
- }), finalize(() => {
659
- this.generatingAddress = false;
660
- this.cdr.markForCheck();
661
- }))
662
- .subscribe({
663
- error: (err) => {
664
- this.message = err.error.responseMessage || err.error.message;
665
- },
666
- });
667
- }
668
- async payHandler() {
669
- if (this.stableCoinForm && this.stableCoinForm.valid) {
670
- this.generateAddressPayload = {
671
- paymentReference: this.transactionReference,
672
- currency: this.stableCoinForm.get('stableCoin')?.value ?? '',
673
- chain: this.stableCoinForm.get('network')?.value ?? '',
674
- transactionAmount: this.paymentObject?.amount,
675
- merchantId: this.secretKey,
676
- };
677
- await this.generateAddress();
678
- }
679
- else {
680
- this.stableCoinForm?.markAllAsTouched();
681
- }
682
- }
683
- async getStableCoins() {
684
- this.loadingStableCoins = true;
685
- await this.resource.getStableCoins(this.environment).subscribe({
686
- next: async (response) => {
687
- if (response?.isSuccessful) {
688
- this.stableCoins =
689
- response.data?.map((c) => ({
690
- label: c.name,
691
- value: c.name,
692
- })) ?? [];
693
- this.loadingStableCoins = false;
694
- }
695
- },
696
- error: (err) => {
697
- this.loadingStableCoins = false;
698
- this.message = err.error.responseMessage || err.error.message;
699
- },
700
- });
701
- }
702
- async getStableCoinNetworks() {
703
- const stableCoin = this.stableCoinForm.get('stableCoin')?.value;
704
- this.loadingStableCoinNetworks = true;
705
- await this.resource.getStableCoinNetworks(this.environment, stableCoin ?? '').subscribe({
706
- next: async (response) => {
707
- if (response?.isSuccessful) {
708
- this.networkList =
709
- response.networks?.map((n) => ({
710
- label: n,
711
- value: n,
712
- })) ?? [];
713
- this.loadingStableCoinNetworks = false;
714
- }
715
- },
716
- error: (err) => {
717
- this.loadingStableCoinNetworks = false;
718
- this.message = err.error.responseMessage || err.error.message;
719
- },
720
- });
721
- }
722
- async confirmPaymentHandler() {
723
- this.isConfirmingPayment = true;
724
- await this.checkout
725
- .getPaymentReferenceDetails(this.environment, this.transactionReference)
726
- .subscribe({
727
- next: async (response) => {
728
- if (response?.isSuccessful) {
729
- this.paymentReferenceDetails = response.data;
730
- if (response.data?.finalTransactionStatus === null ||
731
- response.data?.paymentStatus === null) {
732
- this.message = 'Transaction not confirmed !!';
733
- this.paymentReferenceStatus = 'pending';
734
- this.paymentAuthorized.emit({
735
- paymentId: this.transactionReference,
736
- paymentDate: response.data.updatedAt,
737
- paymentStatus: this.paymentReferenceStatus,
738
- });
739
- }
740
- else if (response.data?.finalTransactionStatus === 'Success' ||
741
- response.data?.paymentStatus === 'Payment Received') {
742
- this.message = 'Transaction confirmed !!';
743
- this.paymentReferenceStatus = 'confirmed';
744
- this.paymentAuthorized.emit({
745
- paymentId: this.transactionReference,
746
- paymentDate: response.data.updatedAt,
747
- paymentStatus: this.paymentReferenceStatus,
748
- });
749
- }
750
- }
751
- else if (!response?.isSuccessful && response?.responseCode === '119') {
752
- this.paymentReferenceStatus = 'used';
753
- this.message = response.responseMessage;
754
- this.paymentAuthorized.emit({
755
- paymentId: this.transactionReference,
756
- paymentDate: null,
757
- paymentStatus: this.paymentReferenceStatus,
758
- });
759
- }
760
- this.isConfirmingPayment = false;
761
- },
762
- error: (err) => {
763
- this.paymentReferenceStatus = '';
764
- this.isConfirmingPayment = false;
765
- this.message = err.error.responseMessage || err.error.message;
766
- },
767
- });
768
- }
769
- async ngOnInit() {
770
- await this.generatePaymentLinkHandler();
771
- await this.getStableCoins();
772
- }
773
- 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 });
774
- 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 ' + formatAmountHandler\"\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\">\n {{ generateAddressPayload?.currency }}\n </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:
775
- // ImageComponent,
776
- 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 });
777
- }
778
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: PayByStableCoinComponent, decorators: [{
779
- type: Component,
780
- args: [{ selector: 'pay-by-stable-coin', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
781
- SelectComponent,
782
- ButtonComponent,
783
- // ImageComponent,
784
- CurrencyAmountComponent,
785
- CopyComponent,
786
- IconArrowSwapComponent,
787
- ReactiveFormsModule,
788
- ], 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 ' + formatAmountHandler\"\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\">\n {{ generateAddressPayload?.currency }}\n </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" }]
789
- }], ctorParameters: () => [{ type: i1.ResourceService }, { type: i1.CheckoutService }, { type: i0.ChangeDetectorRef }], propDecorators: { secretKey: [{
790
- type: Input
791
- }], environment: [{
792
- type: Input
793
- }], paymentObject: [{
794
- type: Input
795
- }], paymentAuthorized: [{
796
- type: Output
797
- }] } });
7
+ import { tap, finalize } from 'rxjs';
798
8
 
799
9
  class CheckoutCardComponent {
800
10
  options = null;
@@ -812,6 +22,8 @@ class CheckoutCardComponent {
812
22
  ready = new EventEmitter();
813
23
  validityChange = new EventEmitter();
814
24
  tokenize = new EventEmitter();
25
+ paymentAuthorized = new EventEmitter();
26
+ onError = new EventEmitter();
815
27
  successObject = {
816
28
  paymentDate: '',
817
29
  paymentId: '',
@@ -855,10 +67,10 @@ class CheckoutCardComponent {
855
67
  }
856
68
  setSuccess(event) {
857
69
  this.successObject = { ...event };
858
- if (this.successObject.paymentStatus === 'Authorized') {
70
+ if (this.successObject.paymentStatus === 'authorized') {
859
71
  this.checkoutState = 'SUCCESS';
860
72
  }
861
- else if (this.successObject.paymentStatus === 'Payment failed') {
73
+ else if (this.successObject.paymentStatus === 'payment failed') {
862
74
  this.checkoutState = 'PENDING';
863
75
  }
864
76
  else if (this.successObject.paymentStatus === 'used') {
@@ -867,9 +79,13 @@ class CheckoutCardComponent {
867
79
  else {
868
80
  this.checkoutState = 'PENDING';
869
81
  }
82
+ this.paymentAuthorized.emit(event);
83
+ }
84
+ onErrorHandler(e) {
85
+ this.onError.emit(e);
870
86
  }
871
87
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: CheckoutCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
872
- 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 });
88
+ 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", paymentAuthorized: "paymentAuthorized", onError: "onError" }, ngImport: i0, template: "<base-card>\n <div class=\"grid grid-cols-3\" buzapay>\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=\"max-h-[32rem] 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 caller=\"buzapay\"\n (paymentAuthorized)=\"setSuccess($event)\"\n (onError)=\"onErrorHandler($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 caller=\"buzapay\"\n (paymentAuthorized)=\"setSuccess($event)\"\n (onError)=\"onErrorHandler($event)\"\n ></pay-by-transfer>\n } @else {\n <pay-by-stable-coin\n [environment]=\"environment\"\n [secretKey]=\"secretKey\"\n [paymentObject]=\"paymentObject\"\n caller=\"buzapay\"\n (paymentAuthorized)=\"setSuccess($event)\"\n (onError)=\"onErrorHandler($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: ["caller", "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", "caller", "paymentObject"], outputs: ["paymentAuthorized", "onError"] }, { kind: "component", type: PayByTransferComponent, selector: "pay-by-transfer", inputs: ["secretKey", "environment", "caller", "paymentObject"], outputs: ["paymentAuthorized", "onError"] }, { kind: "component", type: PayByStableCoinComponent, selector: "pay-by-stable-coin", inputs: ["secretKey", "environment", "caller", "paymentObject"], outputs: ["paymentAuthorized", "onError"] }, { kind: "component", type: SuccessComponent, selector: "base-success", inputs: ["successObject", "caller", "amount", "currency", "redirectUrl"] }, { kind: "component", type: CardComponent, selector: "base-card", inputs: ["showBackButton", "caller"], outputs: ["back"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
873
89
  }
874
90
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: CheckoutCardComponent, decorators: [{
875
91
  type: Component,
@@ -881,7 +97,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
881
97
  PayByStableCoinComponent,
882
98
  SuccessComponent,
883
99
  CardComponent,
884
- ], 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" }]
100
+ ], template: "<base-card>\n <div class=\"grid grid-cols-3\" buzapay>\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=\"max-h-[32rem] 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 caller=\"buzapay\"\n (paymentAuthorized)=\"setSuccess($event)\"\n (onError)=\"onErrorHandler($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 caller=\"buzapay\"\n (paymentAuthorized)=\"setSuccess($event)\"\n (onError)=\"onErrorHandler($event)\"\n ></pay-by-transfer>\n } @else {\n <pay-by-stable-coin\n [environment]=\"environment\"\n [secretKey]=\"secretKey\"\n [paymentObject]=\"paymentObject\"\n caller=\"buzapay\"\n (paymentAuthorized)=\"setSuccess($event)\"\n (onError)=\"onErrorHandler($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" }]
885
101
  }], propDecorators: { options: [{
886
102
  type: Input
887
103
  }], secretKey: [{
@@ -896,6 +112,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
896
112
  type: Output
897
113
  }], tokenize: [{
898
114
  type: Output
115
+ }], paymentAuthorized: [{
116
+ type: Output
117
+ }], onError: [{
118
+ type: Output
899
119
  }] } });
900
120
 
901
121
  class CheckoutIframeComponent {
@@ -931,6 +151,7 @@ class CheckoutIframeComponent {
931
151
  redirectUrl: 'https://sandbox-merchant.buzapay.com/account/three-ds-status',
932
152
  };
933
153
  container;
154
+ onError = new EventEmitter();
934
155
  get blockStyle() {
935
156
  return {
936
157
  ...(this.style || {}),
@@ -963,7 +184,7 @@ class CheckoutIframeComponent {
963
184
  this.loading = true;
964
185
  this.cdr.markForCheck();
965
186
  this.checkout
966
- .createPaymentLink(this.paymentObject, this.environment, this.secretKey)
187
+ .createPaymentLink(this.paymentObject, this.environment, this.secretKey, 'buzapay')
967
188
  .pipe(tap((res) => {
968
189
  if (res?.isSuccessful) {
969
190
  this.launchUrl = res.launchUrl ?? '';
@@ -974,18 +195,23 @@ class CheckoutIframeComponent {
974
195
  }
975
196
  else {
976
197
  this.errorMessage = 'Failed to create payment link';
198
+ this.onError.emit({ errorMessage: this.errorMessage });
977
199
  }
978
200
  }), finalize(() => {
979
201
  this.loading = false;
980
202
  this.cdr.markForCheck();
981
203
  }))
982
- .subscribe();
204
+ .subscribe({
205
+ error: (err) => {
206
+ this.onError.emit({ errorMessage: this.errorMessage });
207
+ },
208
+ });
983
209
  }
984
210
  async ngAfterViewInit() {
985
211
  await this.generatePaymentLinkHandler();
986
212
  }
987
213
  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 });
988
- 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 });
214
+ 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" }, outputs: { onError: "onError" }, 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 });
989
215
  }
990
216
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: CheckoutIframeComponent, decorators: [{
991
217
  type: Component,
@@ -1003,6 +229,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
1003
229
  }], container: [{
1004
230
  type: ViewChild,
1005
231
  args: ['container', { static: false }]
232
+ }], onError: [{
233
+ type: Output
1006
234
  }] } });
1007
235
 
1008
236
  class CheckoutButtonComponent {
@@ -1029,6 +257,10 @@ class CheckoutButtonComponent {
1029
257
  narration: '',
1030
258
  redirectUrl: 'https://sandbox-merchant.buzapay.com/account/three-ds-status',
1031
259
  };
260
+ onError = new EventEmitter();
261
+ get formatAmountHandler() {
262
+ return formatAmount(this.paymentObject.amount, this.paymentObject.currency);
263
+ }
1032
264
  async generatePaymentLinkHandler() {
1033
265
  if (!this.secretKey) {
1034
266
  return (this.errorMessage = 'Secret key is required.');
@@ -1039,7 +271,7 @@ class CheckoutButtonComponent {
1039
271
  this.loading = true;
1040
272
  this.cdr.markForCheck();
1041
273
  this.checkout
1042
- .createPaymentLink(this.paymentObject, this.environment, this.secretKey)
274
+ .createPaymentLink(this.paymentObject, this.environment, this.secretKey, 'buzapay')
1043
275
  .pipe(tap((res) => {
1044
276
  if (res?.isSuccessful) {
1045
277
  this.launchUrl = res.launchUrl ?? '';
@@ -1051,19 +283,24 @@ class CheckoutButtonComponent {
1051
283
  }
1052
284
  else {
1053
285
  this.errorMessage = 'Failed to create payment link';
286
+ this.onError.emit({ errorMessage: this.errorMessage });
1054
287
  }
1055
288
  }), finalize(() => {
1056
289
  this.loading = false;
1057
290
  this.cdr.markForCheck();
1058
291
  }))
1059
- .subscribe();
292
+ .subscribe({
293
+ error: (err) => {
294
+ this.onError.emit({ errorMessage: this.errorMessage });
295
+ },
296
+ });
1060
297
  }
1061
298
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: CheckoutButtonComponent, deps: [{ token: i1.CheckoutService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1062
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: CheckoutButtonComponent, isStandalone: true, selector: "bzp-checkout-button", inputs: { secretKey: "secretKey", timeout: "timeout", environment: "environment", mode: "mode", paymentObject: "paymentObject" }, ngImport: i0, template: "@if (urlLaunchUrl && mode === 'iframe') {\n <bzp-checkout-iframe\n [url]=\"urlLaunchUrl\"\n [secretKey]=\"secretKey\"\n [environment]=\"environment\"\n ></bzp-checkout-iframe>\n} @else {\n <base-button\n label=\"Pay\"\n type=\"primary\"\n customClass=\"w-full\"\n [loading]=\"loading\"\n (onClick)=\"generatePaymentLinkHandler()\"\n ></base-button>\n <base-input-error [errorMessage]=\"errorMessage\"></base-input-error>\n}\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "base-button", inputs: ["label", "type", "size", "paddingClassX", "disabled", "loading", "customClass"], outputs: ["onClick"] }, { kind: "component", type: InputErrorComponent, selector: "base-input-error", inputs: ["errorMessage"] }, { kind: "component", type: CheckoutIframeComponent, selector: "bzp-checkout-iframe", inputs: ["secretKey", "url", "style", "environment", "paymentObject"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
299
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: CheckoutButtonComponent, isStandalone: true, selector: "bzp-checkout-button", inputs: { secretKey: "secretKey", timeout: "timeout", environment: "environment", mode: "mode", paymentObject: "paymentObject" }, outputs: { onError: "onError" }, ngImport: i0, template: "@if (urlLaunchUrl && mode === 'iframe') {\n <bzp-checkout-iframe\n [url]=\"urlLaunchUrl\"\n [secretKey]=\"secretKey\"\n [environment]=\"environment\"\n ></bzp-checkout-iframe>\n} @else {\n <base-button\n [label]=\"'Pay ' + formatAmountHandler\"\n type=\"primary\"\n customClass=\"w-full\"\n [loading]=\"loading\"\n (onClick)=\"generatePaymentLinkHandler()\"\n ></base-button>\n <base-input-error [errorMessage]=\"errorMessage\"></base-input-error>\n}\n", dependencies: [{ kind: "component", type: ButtonComponent, selector: "base-button", inputs: ["label", "type", "caller", "size", "paddingClassX", "disabled", "loading", "customClass"], outputs: ["onClick"] }, { kind: "component", type: InputErrorComponent, selector: "base-input-error", inputs: ["errorMessage"] }, { kind: "component", type: CheckoutIframeComponent, selector: "bzp-checkout-iframe", inputs: ["secretKey", "url", "style", "environment", "paymentObject"], outputs: ["onError"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1063
300
  }
1064
301
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: CheckoutButtonComponent, decorators: [{
1065
302
  type: Component,
1066
- args: [{ selector: 'bzp-checkout-button', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ButtonComponent, InputErrorComponent, InputErrorComponent, CheckoutIframeComponent], template: "@if (urlLaunchUrl && mode === 'iframe') {\n <bzp-checkout-iframe\n [url]=\"urlLaunchUrl\"\n [secretKey]=\"secretKey\"\n [environment]=\"environment\"\n ></bzp-checkout-iframe>\n} @else {\n <base-button\n label=\"Pay\"\n type=\"primary\"\n customClass=\"w-full\"\n [loading]=\"loading\"\n (onClick)=\"generatePaymentLinkHandler()\"\n ></base-button>\n <base-input-error [errorMessage]=\"errorMessage\"></base-input-error>\n}\n" }]
303
+ args: [{ selector: 'bzp-checkout-button', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ButtonComponent, InputErrorComponent, InputErrorComponent, CheckoutIframeComponent], template: "@if (urlLaunchUrl && mode === 'iframe') {\n <bzp-checkout-iframe\n [url]=\"urlLaunchUrl\"\n [secretKey]=\"secretKey\"\n [environment]=\"environment\"\n ></bzp-checkout-iframe>\n} @else {\n <base-button\n [label]=\"'Pay ' + formatAmountHandler\"\n type=\"primary\"\n customClass=\"w-full\"\n [loading]=\"loading\"\n (onClick)=\"generatePaymentLinkHandler()\"\n ></base-button>\n <base-input-error [errorMessage]=\"errorMessage\"></base-input-error>\n}\n" }]
1067
304
  }], ctorParameters: () => [{ type: i1.CheckoutService }, { type: i0.ChangeDetectorRef }], propDecorators: { secretKey: [{
1068
305
  type: Input
1069
306
  }], timeout: [{
@@ -1074,11 +311,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
1074
311
  type: Input
1075
312
  }], paymentObject: [{
1076
313
  type: Input
314
+ }], onError: [{
315
+ type: Output
1077
316
  }] } });
1078
317
 
1079
318
  /**
1080
319
  * Generated bundle index. Do not edit.
1081
320
  */
1082
321
 
1083
- export { CheckoutButtonComponent, CheckoutCardComponent, CheckoutIframeComponent, PayByCardComponent, PayByStableCoinComponent, PayByTransferComponent };
322
+ export { CheckoutButtonComponent, CheckoutCardComponent, CheckoutIframeComponent };
1084
323
  //# sourceMappingURL=miden-npm-angular-buzapay-checkout.mjs.map