1

I'm trying to figure out the Paypal API, and I have the following code, which should make a call, get an access token, and then make the API call. The first part works (up until the $accesstoken line), and returns the access token properly, but the second part doesn't return anything. The code this is supposed to mimic can be found here: Make Your First Call

$url = "https://api.sandbox.paypal.com/v1/oauth2/token";
$headers = array(
    'Accept' => 'application/json',
    'Accept-Language' => 'en_US',
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'grant_type=client_credentials');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERPWD, $clientID . ':' . $clientSecret);
$curl = curl_exec($ch);

$x = json_decode($curl, TRUE);
print_r($x);
$accesstoken = $x['access_token'];


$headers2 = array(
    'Content-Type' => 'application/json',
    'Authorization' => 'Bearer' . $accesstoken
);

$data = array(
    "intent" => "sale",
    "redirect_urls" => array(
        "return_url" => "http://example.com/your_redirect_url/",
        "cancel_url" => "http://example.com/your_cancel_url/"
    ),
    "payer" => array(
        "payment_method" => "paypal"
    ),
    "transactions" => array(
        "transactions" => array(
            "total" => ".99",
            "currency" => "USD"
        )
    )
);

$saleurl = "https://api.sandbox.paypal.com/v1/payments/payment";

$sale = curl_init();
curl_setopt($sale, CURLOPT_URL, $saleurl);
curl_setopt($sale, CURLOPT_VERBOSE, TRUE);
curl_setopt($sale, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($sale, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($sale, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($sale, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($sale, CURLOPT_HTTPHEADER, $headers2);
$finalsale = curl_exec($sale);

$verb = json_decode($finalsale, TRUE);
print_r($verb);

Curl doesn't make complete sense to me, any help would be appreciated.

UPDATE: I changed the format of the headers to:

$headers2 = array(
    'Content-Type: application/json',
    'Authorization: Bearer ' . $accesstoken
);

as per one of the answers. Now it is displaying:

[name] => MALFORMED_REQUEST
[message] => Incoming JSON request does not map to API request
[information_link] => https://developer.paypal.com/webapps/developer/docs/api/#MALFORMED_REQUEST
[debug_id] => f53a882702a04
7
  • 1
    In your production code always verify peer and verify host for security: docforge.com/wiki/PHP/Curl Commented Oct 7, 2013 at 18:09
  • 1
    never assume that an external call succeeded. You're not checking either return value from curl_exec() for a boolean false, which would indicate failure. You simply take the returned value and try to json_decode it. at minimum you should have something more like if (($result = $curl_exec($handle) === FALSE) { die(curl_error($handle)); } Commented Oct 7, 2013 at 18:12
  • @Matt, I'm testing right now, but of course SSL is a must once I'm online. Commented Oct 7, 2013 at 18:17
  • @Marc I tried: if (($result = curl_exec($sale)) === FALSE){ echo "Error."; die(curl_error($sale)); } but it didn't trigger. I'm looking into curl debugging commands now. Commented Oct 7, 2013 at 18:19
  • 1
    (Shameless plug) If you run it through Runscope you can see what the API is returning more easily. runscope.com/provider-guide/troubleshooting-api-requests Commented Oct 7, 2013 at 18:20

3 Answers 3

2

You are not setting your headers correctly ...

$headers = array(
    'Accept: application/json',
    'Accept-Language: en_US'
);

and

$headers2 = array(
    'Content-Type: application/json',
    'Authorization: Bearer ' . $accesstoken
);

Is the correct format.

Also note the (space) after Bearer inbetween your $accesstoken

Edit: Update for your JSON ( i think this is right but echo it out and check it against the reference, I might have one to many array()

$data = array(
    "intent" => "sale",
    "redirect_urls" => array(
        "return_url" => "http://example.com/your_redirect_url/",
        "cancel_url" => "http://example.com/your_cancel_url/"
    ),
    "payer" => array(
        "payment_method" => "paypal"
    ),
    "transactions" => array(array(
            "amount" => array(
                "total" => ".99",
                "currency" => "USD"
            )
        )
    )
);
Sign up to request clarification or add additional context in comments.

3 Comments

Now its giving an error about a Malformed request, "Incoming JSON request does not map to API request"
Now it's giving me: "Currency amount must be non-negative number, may optionally contain exactly 2 decimal places separated by '.', optional thousands separator ',', limited to 7 digits before the decimal point"
adding in a 0 (0.99 vs .99) fixed that.
1

You need a space here

$headers2 = array(
    'Content-Type' => 'application/json',
    'Authorization' => 'Bearer ' . $accesstoken // Added a space after Bearer
);

See if it works now

1 Comment

This doesn't seem to change anything, though you are right about the space, I meant to include it.
0

Change curl_setopt($sale, CURLOPT_POSTFIELDS, json_encode($data));

to curl_setopt($sale, CURLOPT_POSTFIELDS, $data);

The json encode function breaks it

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.