Search code examples
codeigniterauthenticationcurlpaypalexpress-checkout

PayPal express checkout server side, authentication failure


I searched a lot everywhere but I didn't find an answer for my problem.

I can't make it work. My PayPal button is using express checkout Server side Rest, but with client-side I tested, it's easy, and it works.

I am using CodeIgniter so here is my code.

Here is the javascript code in my views folder. CREATE_URL and EXECUTE_URL goes to a controller.

paypal.Button.render({

        env: 'sandbox', // sandbox | production

        // Show the buyer a 'Pay Now' button in the checkout flow
        commit: true,

        // payment() is called when the button is clicked
        payment: function() {

            // Set up a url on your server to create the payment
            var CREATE_URL = '/projects/createurl';

            // Make a call to your server to set up the payment
            return paypal.request.post(CREATE_URL)
                .then(function(res) {
                    return res.paymentID;
                });
        },

        // onAuthorize() is called when the buyer approves the payment
        onAuthorize: function(data, actions) {

            // Set up a url on your server to execute the payment
            var EXECUTE_URL = '/projects/executeurl';

            // Set up the data you need to pass to your server
            var data = {
                paymentID: data.paymentID,
                payerID: data.payerID
            };

            // Make a call to your server to execute the payment
            return paypal.request.post(EXECUTE_URL, data)
                .then(function (res) {
                    window.alert('Payment Complete!');
                });
        }

    }, '#paypal-button-container');

Here is CREATE_URL controller

public function createurl() {

            $ch = curl_init();
    $clientId = "something";
    $secret = "something";

    curl_setopt($ch, CURLOPT_URL, "https://api.sandbox.paypal.com/v1/oauth2/token");
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSLVERSION , 6); 
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($ch, CURLOPT_USERPWD, $clientId.":".$secret);
    curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=client_credentials");

    $result = curl_exec($ch);

    if(empty($result))die("Error: No response.");
    else
    {
        $json = json_decode($result, TRUE);
    }



    curl_close($ch); 


    $ch2 = curl_init();
    $token = $json['access_token'];
    $data = '{
            "transactions": [{
            "amount": {
                "currency":"EUR",
                "total":"12"
            },
            "description":"creating a payment"
            }],
            "payer": {
                "payment_method":"paypal"
            },
            "intent":"sale",
            "redirect_urls": {
                "cancel_url":"https://mysite.gr/projects/project/10",
                "return_url":"https://mysite.gr/projects/project/10"
            }
       }'; 


    curl_setopt($ch2, CURLOPT_URL, "https://api.sandbox.paypal.com/v1/payments/payment");
    curl_setopt($ch2, CURLOPT_VERBOSE, 1);
    curl_setopt($ch2, CURLOPT_HEADER, 0);
    curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch2, CURLOPT_HTTPHEADER , "Content-Type: application/json");
    curl_setopt($ch2, CURLOPT_HTTPHEADER , "Authorization: Bearer ".$token);
    curl_setopt($ch2, CURLOPT_POST, 1);
    curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch2, CURLOPT_POSTFIELDS, $data);

    $result = curl_exec($ch2);
    $json = json_decode($result, TRUE); 
    print_r($json);
    curl_close($ch2);
} 

So when I click the PayPal button - it fails. Logs from the console :

ppxo_no_token_passed_to_payment

ppxo_unhandled_error {stack: "Error: No value passed to payment↵ at https://w…://www.paypalobjects.com/api/checkout.js:3076:13)", errtype: "[object Error]"

Uncaught Error: No value passed to payment

And also when I enter the controller into the url to see the array it says this:

Array ( [name] => AUTHENTICATION_FAILURE [message] => Authentication failed due to invalid authentication credentials or a missing Authorization header. [links] => Array ( [0] => Array ( [href] => https://developer.paypal.com/docs/api/overview/#error [rel] => information_link ) ) )


Solution

  • OK i fixed my problem after 1 week of working on it i finally found the solution and now it works very good!

    The

    AUTHENTICATION_FAILURE [message] => Authentication failed due to invalid authentication credentials or a missing Authorization header.

    it was because i am sending two individual HTTPHEADERS instead of one, and the result is to overwrite one another. So the correct way to do it, is to pass an array in the third arguments of HTTPHEADER like this:

    curl_setopt($ch2, CURLOPT_HTTPHEADER , array("Content-Type: application/json", "Authorization: Bearer myaccesstokenishere"));
    

    After that i still had the problem:

    ppxo_no_token_passed_to_payment

    ppxo_unhandled_error {stack: "Error: No value passed to payment↵

    Uncaught Error: No value passed to payment

    To fix that problem i just echo the result without json_decode it like this:

    $result = curl_exec($ch2);
    
    echo $result;
    
    curl_close($ch2);
    

    And now everything works.

    The executeurl controller was easy enough, if anyone wants me to post it tell me.

    I hope i helped someone who had simiral issues.