PHP E-commerce Payment System | Paypal

Created At: 2023-05-12 21:53:26 Updated At: 2023-05-13 00:06:11

Here I will explain step by step process how PHP Paypal SDK works in terms payment and our app e-commerce app. Let's take a look at the constructor function.

     public function __construct()
    {

        $paypal_conf = Config::get('paypal');
        
        $this->_api_context =  new \PayPal\Rest\ApiContext(new OAuthTokenCredential(
                $paypal_conf['client_id'],
                $paypal_conf['secret'])
        );
        $this->_api_context->setConfig($paypal_conf['settings']);
    }

In the PayPal PHP SDK, an API context is a configuration object that contains information required to make API calls to PayPal servers, such as client ID, client secret, API endpoints, authentication tokens, and other settings.

When making an API call, the SDK needs an API context object to authenticate the client and authorize the transaction. The API context manages the authentication and authorization details so that the developer doesn't need to include them in every API call.

The __construct() function in the provided code snippet creates a new API context object and initializes it with the client ID, secret, and other settings from the paypal configuration file. The API context object is then stored in the $this->_api_context property, which can be used to make API calls to PayPal throughout the lifetime of the object.

See the diagram below

Let's see our payWithpaypal() function

    public function payWithpaypal(Request $request)
    {
       
        $order = Order::with(['details'])->where(['id' => session('order_id')])->first();
       
 
        $tr_ref = Str::random(6) . '-' . rand(1, 1000);

        $payer = new Payer();
        $payer->setPaymentMethod('paypal');

        $items_array = [];
        $item = new Item();
        $number = sprintf("%0.2f", $order['order_amount']); 
       
        
        $item->setName(session('f_name'))
            ->setCurrency(Helpers::currency_code())
            ->setQuantity(1)
            ->setPrice($number);
       
        array_push($items_array, $item);

        $item_list = new ItemList();
        $item_list->setItems($items_array);

        $amount = new Amount();
     
        $amount->setCurrency(Helpers::currency_code())
            ->setTotal($number);
        \session()->put('transaction_reference', $tr_ref);
        $transaction = new Transaction();
        $transaction->setAmount($amount)
            ->setItemList($item_list)
            ->setDescription($tr_ref);
       
        $redirect_urls = new RedirectUrls();
        $redirect_urls->setReturnUrl(URL::route('paypal-status'))
        ->setCancelUrl(URL::route('payment-fail'));

        $payment = new Payment();
        $payment->setIntent('Sale')
            ->setPayer($payer)
            ->setRedirectUrls($redirect_urls)
            ->setTransactions(array($transaction));
         
        try {
            
            $payment->create($this->_api_context);
             
           
             /**
         * Get redirect url
         * The API response provides the url that you must redirect
         * the buyer to. Retrieve the url from the $payment->getLinks() method
         *
         */
    
        foreach ($payment->getLinks() as $key => $link) {
            
            if ($link->getRel() == 'approval_url') {
                
                $redirectUrl = $link->getHref();
                
                break;
            }
    
        }
     
            //$status = OrderTrack::where('success', 'success')->first();
            //dd($status);
            DB::table('orders')
                ->where('id', $order->id)
                ->update([
                    'transaction_reference' => $payment->getId(),
                    'payment_method' => 'paypal',
                    'order_status' => 'success',
                    'failed' => now(),
                    //'status_id'=>$status->id,
                    'updated_at' => now()
                ]);
       
            Session::put('paypal_payment_id', $payment->getId());
             
            if (isset($redirectUrl)) {
                
                return Redirect::away($redirectUrl);
            }else{
                dd("bye");
            }

        } catch (\Exception $ex) {
          // dd($ex->getData()["error_description"]);
            Toastr::error(trans($ex->getData()));

            //Toastr::error(trans('messages.your_currency_is_not_supported',['method'=>trans('messages.paypal')]));
            return back();
        }

        Session::put('error', trans('messages.config_your_account',['method'=>trans('messages.paypal')]));
        return back();
    }

This code is a PHP function that processes a payment through PayPal using the PayPal REST API.

The payWithpaypal() function begins by retrieving the order details from the database based on the order_id saved in the session data. It then generates a unique transaction reference number using the Str::random() and rand() functions.

Next, the function creates a new instance of the Payer class and sets the payment method to "paypal". It then creates an array of Item objects representing the items being purchased and sets the price and currency for each item.

The function then creates an Amount object representing the total amount of the payment, sets the transaction description using the transaction reference number generated earlier, and creates a Transaction object using the Amount and ItemList objects.

The function then creates a RedirectUrls object with URLs for PayPal to redirect the user after payment is complete or if the payment is cancelled. It then creates a Payment object with the intent of "Sale" and the Payer, RedirectUrls, and Transaction objects.

The function then tries to create the payment using the _api_context object, which is an instance of the ApiContext class that contains the PayPal API credentials and settings. If the payment is created successfully, the function retrieves the redirect URL from the payment's links and redirects the user to PayPal to complete the payment.

If an exception is thrown during the payment creation process, the function catches the exception and displays an error message to the user. If the payment creation is unsuccessful for any other reason, the function displays a generic error message to the user.

See the diagram

Let's see getPaymentStatus()

    public function getPaymentStatus(Request $request)
    {
        $payment_id = Session::get('paypal_payment_id');
        if (empty($request['PayerID']) || empty($request['token'])) {
            Session::put('error', trans('messages.payment_failed'));
            return Redirect::back();
        }

        $payment = Payment::get($payment_id, $this->_api_context);
        $execution = new PaymentExecution();
        $execution->setPayerId($request['PayerID']);

        /**Execute the payment **/
        $result = $payment->execute($execution, $this->_api_context);
        $order = Order::where('transaction_reference', $payment_id)->first();
        
        if ($result->getState() == 'approved') {

            $order->transaction_reference = $payment_id;
            $order->payment_method = 'paypal';
            $order->payment_status = 'paid';
            $order->order_status = 'confirmed';
            $status = OrderTrack::where('order_status', $order->order_status)->first();
            $order->status_id=$status->id;
            $order->confirmed = now();
            $order->save();
            /*try {
                Helpers::send_order_notification($order);
            } catch (\Exception $e) {
            } */


            return redirect('&status=success');
            /*if ($order->callback != null) {
                return redirect($order->callback . '&status=success');
            }else{
                return \redirect()->route('payment-success');
            }*/
        }
        $order->order_status = 'failed';
        $status = OrderTrack::where('order_status', $order->order_status)->first();

        $order->status_id=$status->id;
        $order->failed = now();
        $order->save();
        return redirect('&status=fail');
        /*if ($order->callback != null) {
            return redirect($order->callback . '&status=fail');
        }else{
            return \redirect()->route('payment-fail');
        }*/
    }

The code is for a function named getPaymentStatus that accepts an HTTP request object as a parameter. The purpose of this function is to handle the response from PayPal after the user completes the payment process.

The function first retrieves the paypal_payment_id from the session and checks if the PayerID and token parameters are present in the request object. If either of these parameters is missing, the function sets an error message in the session and redirects the user back to the previous page.

If the PayerID and token parameters are present, the function uses the PayPal PHP SDK to execute the payment and retrieve the payment status. It retrieves the order object with the transaction reference ID from the database and updates its payment and order status accordingly.

If the payment is approved, the function updates the order's payment status, order status, and sets the confirmed timestamp. It also sets a status ID by retrieving the first order track with the same order status as the updated order. Finally, it redirects the user to a success page.

If the payment is not approved, the function updates the order status to 'failed', sets the failed timestamp, and redirects the user to a fail page.

There are some commented out lines of code that seem to be related to sending a notification or redirecting the user to a callback URL, but they are not currently being used in the function.

Comment

Add Reviews