timoleary / F3-PYPL

F3-PYPL is a Fat-Free Framework plugin to help implement PayPal Express Checkout
21 stars 5 forks source link

Paypal Express checkout smart buttons #11

Closed t-book closed 4 years ago

t-book commented 4 years ago

Dear @timoleary,

could you kindly check if I do understand the different APIs correctly:

Your Plugin supports both Paypal express checkout and Paypal Plus. The Express Checkout API has evolved from classic API to smart buttons (< is that the correct name for it?). The newly covered smart buttons for express checkout are not covered by this plugin.

Correct? Thanks a lot for your guidance,

Toni

timoleary commented 4 years ago

The plugin is built on the Classic API using NVP.

Progression of the PayPal API's are as follows: Server side: Classic API (deprecated) -> REST Payments V1 (deprecated) -> REST Orders V2 Client side: Checkout.js (deprecated) -> PayPal JavaScript SDK

The PayPal JS SDK is capable of generating client side REST requests, as of right now it generates REST Orders V2 requests. It can be used in conjunction with a REST server side integration, there is also some backwards compatibility with the older API's.

You might loose some of the newer functionality like the alternative payment methods but you can launch & complete a wallet flow.

Details on how to use the JS SDK with the older API's is documented here https://developer.paypal.com/docs/checkout/reference/upgrade-integration/#nvp-integrations

https://timoleary.net/f3pypl/jssdk rough demo, needs error handling in the JS etc but you get the idea.

PHP

$f3->route('GET /jssdk',
    function ($f3) {
        $basket = new \Basket();
        $cartitems = $basket->find();

        $paypal = new PayPal;
        $subtotal = $paypal->copyBasket($cartitems);
        $options=array('LOGOIMG'=>'https://www.timoleary.net/f3pypl/images/logo.png');
        $result = $paypal->create("Sale", "EUR", $subtotal, $options);

        // Reroute buyer to PayPal with resulting transaction token
        if ($result['ACK'] != 'Success') {
            // Handle API error code
            die('Error with API call - ' . $result["L_ERRORCODE0"]);
        } else {

        // Extract EC Token from Redirect URL
        $redirect=$result['redirect'];
        if (preg_match('/EC-.{17}/', $redirect, $regs)) {
            $token = $regs[0];
        }

       // Pass token to template for use in the JS SDK
        $f3->set('token', $token);
        echo \Template::instance()->render('smartbuttons.html');
        }
    }
);

Template

<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <script
    src="https://www.paypal.com/sdk/js?client-id=sb&currency=EUR&disable-funding=credit,card,sepa">
  </script>
</head>
<body>
  <div id="paypal-button-container"></div>
    <script>
  paypal.Buttons({
    createOrder: function() {
        return '{{ @token }}';
    },
      onApprove: function (data) {
        //console.info(data);
        //console.info('PayerID: '+data.payerID);
        //console.info('EC TOKEN: '+data.orderID);
        window.location = 'complete?PayerID='+data.payerID+'&token='+data.orderID+''; 
    }
  }).render('#paypal-button-container');
</script>
</body>
</html>
t-book commented 4 years ago

Dear @timoleary Thanks a million! I was unsure which way to go. See if I can further use your plugin with some adjustments or if it's needed to start from scratch with smart buttons. Your answer helped a lot and for sure others as well. 👍

t-book commented 4 years ago

By the way : https://timoleary.net/f3pypl/jssdk : Error with API call - 10525 🤔

timoleary commented 4 years ago

By the way : https://timoleary.net/f3pypl/jssdk : Error with API call - 10525 🤔

Whoops I forgot to populate the basket when you visit the page directly, good spot!