PayPal Rest API for Payments returns NULL in the sandbox

api, payment, paypal, php, rest

Solution

turns out the solutions was to add a header, Content-Type: application/json. For some reason, php guessed the correct Content-type in the token request (presumably because of the Accepts header) but when passed the json-array changed the content-type to application/xml. All good now!

Problem

I've a sandbox account with PayPal. I can retrieve the token via the api using curl on PHP, however processing a test card just returns null. Anyone see a problem with the code? Is this a known problem with the PayPal sandbox? The client in the below snippet are fabricated, however, as mentioned before, using my real credentials I can successfully make a call to retrieve the token. The PHP to generate the request: ``` <?php class psPayPal { private $tokenUrl = 'https://api.sandbox.paypal.com/v1/oauth2/token'; private $paymentUrl = 'https://api.sandbox.paypal.com/v1/payments/payment'; private $client = 'dlkjasdfkja;skdjfaksdjfkajsdkfjaejkjefkekjakdjfaksjdfadjf;ja'; private $secret = 'klj;akjdfjeieiadfaldkjfelkajsdfkjaejeiejisadif;alkdsfj;kjjie'; private $token; private $tokenHandle; private $paymentHandle; public function __construct() { $this->tokenHandle = curl_init($this->tokenUrl); $this->buildTokenRequest(); } public function buildTokenRequest() { $header = array( 'Accept: application/json', 'Accept-Language: en_US' ); $user = $this->client . ':' . $this->secret; $data = 'grant_type=client_credentials'; curl_setopt($this->tokenHandle, CURLOPT_HTTPHEADER, $header); curl_setopt($this->tokenHandle, CURLOPT_USERPWD, $user); curl_setopt($this->tokenHandle, CURLOPT_POSTFIELDS, $data); curl_setopt($this->tokenHandle, CURLOPT_RETURNTRANSFER, true); $this->commitTokenRequest(); } public function commitTokenRequest() { $response = json_decode(curl_exec($this->tokenHandle)); $this->token = $response->access_token; curl_close($this->tokenHandle); } public function buildPaymentRequest($cost = '', $description = '') { $this->paymentHandle = curl_init($this->paymentUrl); $header = array( 'Accept: application/json', 'Accept-Language: en_US', 'Authorization:Bearer ' . $this->token ); $data = array( 'intent' => 'sale', 'payer' => array( 'payment_method' => 'credit_card', 'funding_instruments' => array( array( 'credit_card' => array( 'number' => '5500005555555559', 'type' => 'mastercard', 'expire_year'=> '2018', 'cvv2'=> '111', 'first_name'=> 'Joe', 'last_name' => 'Shopper' ) ) ) ), 'transactions' => array( array( 'amount' => array( 'total' => '39.54', 'currency' => 'USD' ), 'description' => 'This is my descrription for hats' ) ) ); $d = json_encode($data); curl_setopt($this->paymentHandle, CURLOPT_HTTPHEADER, $header); curl_setopt($this->paymentHandle, CURLOPT_POSTFIELDS, $d); curl_setopt($this->paymentHandle, CURLOPT_RETURNTRANSFER, true); $this->commitPaymentRequest(); } public function commitPaymentRequest() { $response = json_decode(curl_exec($this->paymentHandle)); var_dump($response); curl_close($this->paymentHandle); } } ?> ``` I've tried with a variety of options, although I believe the code above to be complete. I've also validated the jSON I'm sending with JSON Lint. The JSON follows: ``` { "intent": "sale", "payer": { "payment_method": "credit_card", "funding_instruments": [ { "credit_card": { "number": "5500005555555559", "type": "mastercard", "expire_year": "2018", "cvv2": "111", "first_name": "Joe", "last_name": "Shopper" } } ] }, "transactions": [ { "amount": { "total": "39.54", "currency": "USD" }, "description": "This is my descrription for hats" } ] ``` } Any suggestions greatly appreciated!

Original source