0

I am integrating paypal for the first time in laravel 5.2. I am using the PayPal SDK as the api but I have reached a point where I am stuck. when I submit a payment form I get the following error.

"PayPalConnectionException in PayPalHttpConnection.php line 176: Got Http response code 400 when accessing https://api.sandbox.paypal.com/v1/payments/payment."

I got the tutorial from this website and here is the code from my controller

<?php
namespace App\Http\Controllers; 
use Illuminate\Http\Request;
use App\Http\Requests;
use PayPal\Rest\ApiContext; 
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\RedirectUrls;
use PayPal\Api\ExecutePayment;
use PayPal\Api\PaymentExecution;
use PayPal\Api\Transaction;
use Session;
use Redirect;
use Config;
use URL; 
use Redirects;

class IndexController extends Controller

{

private $_api_context;

public function __construct()
{

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

public function paypalform()
{
   return view('sponsors.paypalform'); 
}



public function postPayment()
{
    $input = \Request::all();
    $product = $input['product'];
    $price = $input['price'];
    $shipping = 2;

    $total = $price + $shipping;



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

    $item_1 = new Item();
    $item_1->setName($product) // item name
        ->setCurrency('USD')
        ->setQuantity(2)
        ->setPrice($price); // unit price




    $item_list = new ItemList();
    $item_list->setItems([$item_1]);

    $details = new Details();
    $details->setShipping($shipping)
            ->setSubtotal($price);

    $amount = new Amount();
    $amount->setCurrency('USD')
           ->setTotal($total)
           ->setDetails($details);


     $transaction = new Transaction();
     $transaction->setAmount($amount)
         ->setItemList($item_list)
         ->setDescription('Your transaction description')
           ->setInvoiceNumber(uniqid()); // added




     $redirect_urls = new RedirectUrls();
     $redirect_urls->setReturnUrl(URL::route('payment.status'))
         ->setCancelUrl(URL::route('payment.status'));

     $payment = new Payment();
     $payment->setIntent('Sale')
         ->setPayer($payer)
         ->setRedirectUrls($redirect_urls)
         ->setTransactions(array($transaction));


     try {
    $payment->create($this->_api_context);
} catch (\PayPal\Exception\PPConnectionException $ex) {
    if (\Config::get('app.debug')) {
        echo "Exception: " . $ex->getMessage() . PHP_EOL;
        $err_data = json_decode($ex->getData(), true);
        exit;
    } else {
        die('Some error occur, sorry for inconvenient');
    }
}



     foreach($payment->getLinks() as $link) {
         if($link->getRel() == 'approval_url') {
             $redirect_url = $link->getHref();
             break;
         }
     }

     // add payment ID to session
     Session::put('paypal_payment_id', $payment->getId());

     if(isset($redirect_url)) {
         // redirect to paypal
         return Redirect::away($redirect_url);
    }

    return Redirect::route('original.route')
        ->with('error', 'Unknown error occurred');
}

}

I think the problems comes when redireciting to paypal website but I can't figure out what exactly is going wrong.

5
  • Try dd($payment->getId()); before Session::put('paypal_payment_id', $payment->getId()); and see what's its response. Commented May 2, 2016 at 13:18
  • second thing is to make sure you provide all the data to paypal, otherwise it will throw same exception. Commented May 2, 2016 at 13:27
  • Hi Muhammad thanks for the reply. i am getting the same error of "PayPalConnectionException in PayPalHttpConnection.php line 176: Got Http response code 400 when accessing api.sandbox.paypal.com/v1/payments/payment." . how can to check to see if i am providing all the data to paypal. Commented May 2, 2016 at 15:54
  • Have look in your /logs/paypal.log which path you can find in $paypal_conf['settings']. That will help to find out what exactly missing Commented May 2, 2016 at 16:07
  • Are you testing on local or online sources? Commented May 3, 2016 at 5:36

1 Answer 1

2

I also faced this problem - in my case it I actually sent falsy data to paypal.

In a first step try to catch the Exception and get the actualy errormessage

// For testing purpose use the general exception (failed to catch with paypal for me)
catch (Exception $ex) {
  if (\Config::get('app.debug')) {
    echo "Exception: " . $ex->getMessage() . PHP_EOL;
    $err_data = json_decode($ex->getData(), true);
    exit;
  } else {
    die('Some error occur, sorry for inconvenient');
  }
}

The resulting message should give you enough information to solve what you got wrong.

Below i paste you my code which is working for me using paypal REST api. You will need 3 routes

  • /payments/create (create payment)
  • /payments/success (validate payment was successful & redirect from paypal)
  • /payments/cancel (handle cancellation of paypal)

You will also need to add you paypal config and initialize it in your controller. If you do not have a paypal config file yet you can set the client id and secret directly in the function. The settings should be like this

 'settings' => array(
    /**
     * Available option 'sandbox' or 'live'
     */
    'mode' => 'sandbox',

    /**
     * Specify the max request time in seconds
     */
    'http.ConnectionTimeOut' => 30,

    /**
     * Whether want to log to a file
     */
    'log.LogEnabled' => true,

    /**
     * Specify the file that want to write on
     */
    'log.FileName' => storage_path() . '/logs/paypal.log',

    /**
     * Available option 'FINE', 'INFO', 'WARN' or 'ERROR'
     *
     * Logging is most verbose in the 'FINE' level and decreases as you
     * proceed towards ERROR
     */
    'log.LogLevel' => 'FINE'
)

Constructor of Controller

    $paypal_conf = config('paypal');
    $this->_api_context = new ApiContext(new OAuthTokenCredential($paypal_conf['client_id'], $paypal_conf['secret']));
    $this->_api_context->setConfig($paypal_conf['settings']);

Create Route

    // create a payment
    public function create(Request $request)
    {
        $payer = new Payer();
        $payer->setPaymentMethod('paypal');

        $price = '10.00'; // 10 € for example

        if($price == 0) { // ensure a price above 0
            return Redirect::to('/');
        }

        // Set Item
        $item_1 = new Item();
        $item_1->setName('My Item')
            ->setCurrency('EUR')
            ->setQuantity(1)
            ->setPrice($price);

        // add item to list
        $item_list = new ItemList();
        $item_list->setItems(array($item_1));

        $amount = new Amount();
        $amount->setCurrency('EUR')
            ->setTotal($price); // price of all items together

        $transaction = new Transaction();
        $transaction->setAmount($amount)
            ->setItemList($item_list)
            ->setDescription('Fitondo Fitnessplan');

        $redirect_urls = new RedirectUrls();
        $redirect_urls->setReturnUrl(URL::to('/payment/status'))
            ->setCancelUrl(URL::to('/payments/cancel'));

        $payment = new Payment();
        $payment->setIntent('Sale')
            ->setPayer($payer)
            ->setRedirectUrls($redirect_urls)
            ->setTransactions(array($transaction));

        try {
            $payment->create($this->_api_context);
        } catch (\PayPal\Exception\PayPalConnectionException $ex) {
            if (config('app.debug')) {
                echo "Exception: " . $ex->getMessage() . PHP_EOL;
                $err_data = json_decode($ex->getData(), true);
                exit;
            } else {
                die('Error.');
            }
        }

        foreach($payment->getLinks() as $link) {
            if($link->getRel() == 'approval_url') {
                $redirect_url = $link->getHref();
                break;
            }
        }

        /* here you could already add a database entry that a person started buying stuff (not finished of course) */

        if(isset($redirect_url)) {
            // redirect to paypal
            return Redirect::away($redirect_url);
        }

        die('Error.');
    }

Success Route

public function get(Request $request)
{
    // Get the payment ID before session clear
    $payment_id = $request->paymentId;

    if (empty($request->PayerID) || empty($request->token)) {
       die('error');
    }

    $payment = Payment::get($payment_id, $this->_api_context);

    // PaymentExecution object includes information necessary 
    // to execute a PayPal account payment. 
    // The payer_id is added to the request query parameters
    // when the user is redirected from paypal back to your site
    $execution = new PaymentExecution();
    $execution->setPayerId($request->PayerID);

    //Execute the payment
    $result = $payment->execute($execution, $this->_api_context);

    if ($result->getState() == 'approved') { // payment made

        /* here you should update your db that the payment was succesful */

        return Redirect::to('/this-is-what-you-bought')
            ->with(['success' => 'Payment success']);
    }

    return Redirect::to('/')
        ->with(['error' => 'Payment failed']);
}

I hope I got everything - I had to clean up my code a little to simplify it.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.