Payfast.component.ts - before create payment

PHOTO EMBED

Sat Jul 27 2024 18:12:32 GMT+0000 (Coordinated Universal Time)

Saved by @iamkatmakhafola

//ts
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';

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 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();
              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() {
    if (this.memberId === undefined) {
      this.snackBar.open('Member ID is not available', 'Close', { duration: 5000 });
      return;
    }
    
    this.orderService.getCartItems().subscribe(cartItems => {
      const order  = this.prepareOrderDetails(cartItems);

      this.orderService.createOrder(order ).subscribe({
        next: (orderResponse) => {
          this.snackBar.open('Order Created Successfully', 'Close', { duration: 5000 });
          this.router.navigate(['/orders']);
          console.log("Order Creation Successful: ", orderResponse)
        },
        error: (error) => {
          console.error('Error creating order:', error);
          this.snackBar.open('Failed to create order', 'Close', { duration: 5000 });
          this.router.navigate(['/cart']);
        }
      });
    });
  }

  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);
  }
  
    
  }
content_copyCOPY