import { HttpClient } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; import { FormBuilder } from '@angular/forms'; import { Router } from '@angular/router'; import { Md5 } from 'ts-md5'; import { environment } from '../../environments/environment'; import { OrderService } from '../Services/order.service'; import { MatSnackBar } from '@angular/material/snack-bar'; import { UserService } from '../Services/userprofile.service'; import { CartItemViewModel, OrderViewModel } from '../shared/order'; import { PaymentViewModel } from '../shared/payment'; import { PaymentService } from '../Services/payment.service'; declare global { interface Window { payfast_do_onsite_payment: (param1: any, callback: any) => any; } } @Component({ selector: 'app-payfast', standalone: true, imports: [], templateUrl: './payfast.component.html', styleUrl: './payfast.component.css' }) export class PayfastComponent implements OnInit { memberId!: number; constructor(private router : Router, private orderService : OrderService, private paymentService : PaymentService , private userService: UserService, private formBuilder: FormBuilder, private snackBar: MatSnackBar) { } ngOnInit(): void { this.fetchMemberId(); } getSignature(data : Map<string, string>) : string { let tmp = new URLSearchParams(); data.forEach((v, k)=> { tmp.append(k, v) }); let queryString = tmp.toString(); let sig = Md5.hashStr(queryString); return sig; } async doOnSitePayment() { await this.fetchMemberId(); let onSiteUserData = new Map<string, string>(); onSiteUserData.set("merchant_id", "10033427") onSiteUserData.set("merchant_key", "mu83ipbgas9p7") onSiteUserData.set('return_url', window.location.origin + '/payment-success') onSiteUserData.set('cancel_url', window.location.origin + '/payment-cancel') // Gather required user data from orderService or other sources const userData = this.orderService.getUserData(); onSiteUserData.set("email_address", userData.email); // Set amount and item_name this.orderService.getTotalAmount().subscribe(amount => { onSiteUserData.set('amount', amount.toString()); onSiteUserData.set('item_name', 'Cart Purchase'); // Optional passphrase for added security onSiteUserData.set('passphrase', 'HelloWorldHello'); // Use if you have a passphrase let signature = this.getSignature(onSiteUserData); onSiteUserData.set('signature', signature); let formData = new FormData(); onSiteUserData.forEach((val, key) => { formData.append(key, val); }); fetch(environment.payfastOnsiteEndpoint, { method: 'POST', body: formData, redirect: 'follow' }) .then(response => response.json()) .then(respJson => { let uuid = respJson['uuid']; window.payfast_do_onsite_payment({ 'uuid': uuid }, (res: any) => { if (res == true) { this.createOrder().then((orderResponse) => { this.createPayment(orderResponse); this.snackBar.open('Payment Successful', 'Close', { duration: 5000 }); }); } else { this.snackBar.open('Payment Failed', 'Close', { duration: 5000 }); } }); }) .catch(error => { console.error('Error processing payment:', error); this.router.navigate(['/cancel']); }); }); } //order private fetchMemberId() { const user = localStorage.getItem('User'); if (user) { const userData = JSON.parse(user); this.memberId = userData.userId; // Optional: Fetch and validate member details if needed this.userService.getMemberByUserId(this.memberId).subscribe({ next: (member) => { if (member && member.member_ID) { this.memberId = member.member_ID; console.log('Member ID:', this.memberId); // Check if this logs the correct ID } else { console.error('Member ID is undefined in the response'); this.snackBar.open('Failed to retrieve member information', 'Close', { duration: 5000 }); } }, error: (error) => { console.error('Error fetching member:', error); this.snackBar.open('Failed to retrieve member information', 'Close', { duration: 5000 }); } }); } else { this.snackBar.open('User not logged in', 'Close', { duration: 5000 }); this.router.navigate(['/login']); } } private createOrder(): Promise<OrderViewModel> { return new Promise((resolve, reject) => { if (this.memberId === undefined) { this.snackBar.open('Member ID is not available', 'Close', { duration: 5000 }); reject('Member ID is not available'); } else { this.orderService.getCartItems().subscribe({ next: (cartItems) => { const order = this.prepareOrderDetails(cartItems); this.orderService.createOrder(order).subscribe({ next: (orderResponse) => { this.snackBar.open('Order Created Successfully', 'Close', { duration: 5000 }); resolve(orderResponse); }, error: (error) => { console.error('Error creating order:', error); this.snackBar.open('Failed to create order', 'Close', { duration: 5000 }); reject(error); } }); }, error: (error) => { console.error('Error fetching cart items:', error); this.snackBar.open('Failed to fetch cart items', 'Close', { duration: 5000 }); reject(error); } }); } }); } private prepareOrderDetails(cartItems: CartItemViewModel[]): OrderViewModel { const order: OrderViewModel = { order_ID: 0, // ID will be generated by backend member_ID: this.memberId, order_Date: new Date().toISOString(), total_Price: this.calculateTotalPrice(cartItems), order_Status_ID: 1, // Ready for Collection isCollected: false, orderLines: cartItems.map(item => ({ order_Line_ID: 0, // ID will be generated by backend product_ID: item.product_ID, product_Name: item.product_Name, quantity: item.quantity, unit_Price: item.unit_Price })) }; console.log('Prepared order details:', order); return order; } // Helper method to calculate the total price private calculateTotalPrice(cartItems: CartItemViewModel[]): number { return cartItems.reduce((total, item) => total + (item.unit_Price * item.quantity), 0); } private createPayment(order: OrderViewModel) { const paymentData: PaymentViewModel = { payment_ID: 0, amount: order.total_Price, payment_Date: new Date().toISOString(), order_ID: order.order_ID, payment_Type_ID: 1 // Default to 1 }; this.paymentService.createPayment(paymentData).subscribe({ next: (response) => { console.log('Payment record created successfully:', response); this.router.navigate(['/orders']); }, error: (error) => { console.error('Error creating payment record:', error); } }); } }
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter