service-provider-app/src/app/carnet/checkout/checkout.component.ts

162 lines
6.2 KiB
TypeScript
Raw Normal View History

2025-08-21 06:37:56 -03:00
import { Component, ElementRef, inject, ViewChild } from '@angular/core';
import { PaymentService } from '../../core/services/carnet/payment.service';
import { CommonModule } from '@angular/common';
import { Fees } from '../../core/models/carnet/fee';
import { CarnetService } from '../../core/services/carnet/carnet.service';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { NavigationService } from '../../core/services/common/navigation.service';
import { NotificationService } from '../../core/services/common/notification.service';
import { StorageService } from '../../core/services/common/storage.service';
import { finalize } from 'rxjs';
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
// This is necessary to tell TypeScript that a global 'paypal' object exists.
declare var paypal: any;
@Component({
selector: 'app-checkout',
imports: [CommonModule, AngularMaterialModule],
templateUrl: './checkout.component.html',
styleUrl: './checkout.component.scss'
})
export class CheckoutComponent {
paymentCompleted: boolean = false;
paymentError: boolean = false;
isLoading: boolean = false;
paymentDetails: any = null;
currentApplicationDetails: { headerid: number, applicationName: string, applicationType: string } | null = null;
changeInProgress: boolean = false;
estimatedFees: Fees = {};
@ViewChild('paypalcontrol', { static: true }) paypalElement!: ElementRef;
orderDetails = {
price: '',
description: '',
};
orderTotal = 0.00;
currency = 'USD';
private paymentService = inject(PaymentService);
private notificationService = inject(NotificationService);
private errorHandler = inject(ApiErrorHandlerService);
private storageService = inject(StorageService);
private navigationService = inject(NavigationService);
private carnetService = inject(CarnetService);
constructor() {
this.currentApplicationDetails = this.storageService.get<{ headerid: number, applicationName: string, applicationType: string }>('currentapplication')
this.orderDetails.description = ` 'Carnet Application - ${this.currentApplicationDetails?.applicationName}`
}
ngOnInit(): void {
if (this.currentApplicationDetails?.headerid) {
this.carnetService.getEstimatedFees(this.currentApplicationDetails?.headerid).subscribe({
next: (data: Fees) => {
if (data) {
this.estimatedFees = data;
this.calculateTotal();
}
},
error: (error: any) => {
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to get estimated fees');
this.notificationService.showError(errorMessage);
console.error('Error getting estimated fees:', error);
}
});
}
}
ngAfterViewInit(): void {
this.initConfig();
}
initConfig(): void {
paypal
.Buttons({
style: {
layout: 'vertical', // or 'horizontal'
color: 'gold',
shape: 'pill',
label: 'pay',
height: 35 // Height in pixels (default is ~35-45px)
// 'paypal' Standard PayPal button [defoult]
// 'checkout' "Checkout with PayPal"
// 'buynow' "Buy Now with PayPal"
// 'pay' "Pay with PayPal"
// 'installment' Displays installment information
// 'subscribe' For subscriptions
// 'donate' For donations
// pay : Pay with [PayPal]
// buynow : [PayPal] Buy Now
// Error: Expected style.height to be between 25px and 55px - got 10px
// width width usually doesnt need to be set or must be reasonable.
},
// 1. Call your server to set up the transaction
createOrder: async (data: any, actions: any) => {
try {
// Call the createOrder method from your service
const orderId = await this.paymentService.createOrder(this.orderDetails);
// console.log('Order ID created by server:', orderId);
return orderId;
} catch (error) {
this.notificationService.showError('Failed to initiate the payment');
console.error('Error creating order:', error);
return;
}
},
// 2. Call your server to finalize the transaction
onApprove: async (data: any, actions: any) => {
try {
// data.orderID is the ID of the transaction from PayPal
const captureDetails = await this.paymentService.completePayment(data.orderID);
// console.log('Capture details:', captureDetails);
// You can now redirect the user or update the UI
this.changeInProgress = true;
this.carnetService.submitApplication(this.currentApplicationDetails?.headerid!).pipe(finalize(() => {
this.changeInProgress = false;
})).subscribe({
next: () => {
this.notificationService.showSuccess('Application submitted successfully');
this.storageService.removeItem('currentapplication');
this.navigationService.navigate(["home"]);
},
error: (error) => {
this.notificationService.showError('Failed to submit application');
console.error('Error submitting the application', error);
}
});
} catch (error) {
this.notificationService.showError('Failed to complete the payment');
console.error('Error completing the payment:', error);
return;
}
},
// 3. Handle errors
onError: (error: any) => {
this.notificationService.showError('Payment transaction failed');
console.error('An error occurred during the transaction:', error);
},
// 4. Handle cancellation
onCancel: (data: any) => {
}
}).render(this.paypalElement.nativeElement)
.catch((error: any) => {
console.error('Failed to render PayPal Buttons:', error);
});
}
calculateTotal(): void {
const validFees = Object.values(this.estimatedFees).filter(
(fee): fee is number => typeof fee === 'number'
);
this.orderTotal = validFees.reduce((total, fee) => total + fee, 0);
}
}