Search code examples
phplaravelpaypalpaypal-rest-sdk

PayPal-PHP-SDK not working using single item in list


I'm following this example and using it in a Laravel application. During tests I have noticed that when I pass an array of only single item to $itemList->setItems($items); I get the following error: Got Http response code 400 when accessing https://api.sandbox.paypal.com/v1/payments/payment

Here's the piece of code I'm using:

    $card = new CreditCard();
    $card->setType("visa")
        ->setNumber("4669424246660779")
        ->setExpireMonth("11")
        ->setExpireYear("2019")
        ->setCvv2("012")
        ->setFirstName("Joe")
        ->setLastName("Shopper");
    $fi = new FundingInstrument();
    $fi->setCreditCard($card);
    $payer = new Payer();
    $payer->setPaymentMethod("credit_card")
        ->setFundingInstruments(array($fi));
    $items[0] = new Item();
    $items[0]->setName('Ground Coffee 40 oz')
        ->setDescription('Ground Coffee 40 oz')
        ->setCurrency('USD')
        ->setQuantity(1)
        ->setTax(0.3)
        ->setPrice(7.50);
   /* 
    Removing this comment makes this code work
   $items[1] = new Item();
    $items[1]->setName('Granola bars')
        ->setDescription('Granola Bars with Peanuts')
        ->setCurrency('USD')
        ->setQuantity(5)
        ->setTax(0.2)
        ->setPrice(2); */

    $itemList = new ItemList();
    $itemList->setItems($items);
    $details = new Details();
    $details->setShipping(1.2)
        ->setTax(1.3)
        ->setSubtotal(17.5);
    $amount = new Amount();
    $amount->setCurrency("USD")
        ->setTotal(20)
        ->setDetails($details);
    $transaction = new Transaction();
    $transaction->setAmount($amount)
        ->setItemList($itemList)
        ->setDescription("Payment description")
        ->setInvoiceNumber(uniqid());
    $payment = new Payment();
    $payment->setIntent("sale")
        ->setPayer($payer)
        ->setTransactions(array($transaction));
    $request = clone $payment;
    try {
        $payment->create($apiContext);
    } catch (Exception $ex) {
        ResultPrinter::printError('Create Payment Using Credit Card. If 500 Exception, try creating a new Credit Card using <a href="https://ppmts.custhelp.com/app/answers/detail/a_id/750">Step 4, on this link</a>, and using it.', 'Payment', null, $request, $ex);
        exit(1);
    }
     //ResultPrinter::printResult('Create Payment Using Credit Card', 'Payment', $payment->getId(), $request, $payment);

    return $payment;

Where, if I uncomment the $items[1] part, it works fine. Why does this happen?


Solution

  • It is throwing 400 exception because the totals are not matching. You can catch proper exception with proper message as shown here: https://github.com/paypal/PayPal-PHP-SDK/wiki/exception-%27PayPal%5CException%5CPayPalConnectionException%27-with-message-%27Got-Http-response-code-400-when-accessing

    try {
        $payment->create($apiContext);
    } catch (PayPal\Exception\PayPalConnectionException $ex) {
        echo $ex->getCode(); // Prints the Error Code
        echo $ex->getData(); // Prints the detailed error message 
        die($ex);
    } catch (Exception $ex) {
        die($ex);
    }
    

    In your case, because you deleted the second item, the total does not match up. Replace below code with proper values and it should work.

       $details->setShipping(1.2)
            ->setTax(1.3)
            ->setSubtotal(7.8);
        $amount = new Amount();
        $amount->setCurrency("USD")
            ->setTotal(10.3)