Mefimefi
Mefimefi

Reputation: 123

Laravel 5.3 - Omnipay Paypal Express not returning success message

I'm new to Laravel. I've been struggling to implement Paypal Express Checkout in my website for a couple days in order to enable donations to a non-profit organization. Thanks to these explanations I've been able to install Omnipay, let the user input the amount (s)he wants to donate and go to Paypal. But, when I try to end the transaction (Pay), I'm not redirected to my succes message. My sandbox account does not show any transactions either, so it seems the payment is not completed correctly. I'm guessing there's something wrong with my "getSuccessPayment" function, but I can't figure out what it is...

Here's my Controller so far :

<?php namespace App\Http\Controllers;
use Omnipay\Omnipay;
use Session;
use App\Http\Requests\PaymentRequest;

class PaymentController extends Controller {

    public function postPayment(PaymentRequest $request)
    {
        $price = $request->get('price');

        $items[] = array('name' => 'Don', 'quantity' => 1, 'price' => $price);

        $params = array(
            'cancelUrl'=>url('/donner'),
            'returnUrl'=>url('/payment_success'),
            'amount' =>  $price,
            'currency' => 'EUR'
        );

        Session::put('params', $params);
        Session::save();

        $gateway = Omnipay::create('PayPal_Express');
        $gateway->setUsername('my sandbox email'); 
        $gateway->setPassword('my sandbox password');  
        $gateway->setSignature('my sandbox signature');
        $gateway->setTestMode(true);

       $response = $gateway->purchase($params)->setItems($items)->send();

        if ($response->isSuccessful()) {
            print_r($response);
        } elseif ($response->isRedirect()) {
            $response->redirect();
        } else {
            echo $response->getMessage();
        }
    }

     public function getSuccessPayment()
    {

        $gateway = Omnipay::create('PayPal_Express');
        $gateway->setUsername('my sandbox email'); 
        $gateway->setPassword('my sandbox password');  
        $gateway->setSignature('my sandbox signature');
        $gateway->setTestMode(true);

        $params = Session::get('params');
        $response = $gateway->completePurchase($params)->send();
        $paypalResponse = $response->getData(); 

        if(isset($paypalResponse['PAYMENTINFO_0_ACK']) && $paypalResponse['PAYMENTINFO_0_ACK'] === 'Success') {
            return redirect('/payment_success');

        } else {
            //payment fails
        return redirect('/payment_failure');

        }
    }
}
?>

And my Routes :

Route::post('donner',
    ['as' => 'payment', 'uses' => 'PaymentController@postPayment']);

Route::get('payment_success', 'PaymentController@getSuccessPayment');

Route::get('payment_failure', 'PaymentController@getSuccessPayment');

Upvotes: 1

Views: 1019

Answers (1)

cfreear
cfreear

Reputation: 1875

When creating your gateway parameters you are passing in /donner as the returnUrl, this is where your users are returned to after completing the PayPal express login and payment confirmation so Laravel would look Route::get('donner'... route which you don't have, changing this to 'returnUrl'=>url('/payment_success'), will bring your users back to your success route and allow you to file the completePurchase call.

Edit for further details based on edited question and comments:

Customers are returned to your returnUrl if the successfully complete the PayPal login and checkout screens, they go to the cancelUrl if for whatever reason they quit the process.

In your PaymentController@getSuccessPayment method paypal will send back a token and payerID in the query string (www.example.com/payment_success?token=EC-12345&PayerID=ABC123, omnipay-paypal will automatically pick up on this in the completePurchase call which is where you are effective confirming with PayPal that the customer completed the checkout correctly and that the transaction was successful.

To avoid confusion I would rename your current Route::get('payment_success', 'PaymentController@getSuccessPayment'); route to something like Route::get('complete_payment', 'PaymentController@getCompletePayment'); and create a new payment_success route that a user is sent to after you have confirmed the status of the payment with PayPal.

Upvotes: 0

Related Questions