Reputation: 5197
I'm trying to work out why my Curl request is not working for the PayPal API. I have the following query working fine to get the auth token:
sub get_token {
my $curl = WWW::Curl::Easy->new();
my $fh = 'README';
$curl->setopt(CURLOPT_HEADER,0); # dont want the headers, or they will break the json reading!
$curl->setopt(CURLOPT_URL,"https://".$config->{$config->{mode}}->{transaction_endpoint}."/v1/oauth2/token");
$curl->setopt(CURLOPT_POSTFIELDS,"grant_type=client_credentials");
$curl->setopt(CURLOPT_USERPWD, $config->{$config->{mode}}->{system_client_id}.":".$config->{$config->{mode}}->{system_secret});
$curl->setopt(CURLOPT_SSL_VERIFYPEER,0);
$curl->setopt(CURLOPT_SSL_VERIFYHOST,0);
$curl->setopt('CURLOPT_RETURNTRANSFER',1);
$curl->setopt(CURLOPT_POST,1);
my $response_body;
open(my $fh, '>', \$response_body);
$curl->setopt(CURLOPT_WRITEDATA, $fh);
$curl->setopt(CURLOPT_VERBOSE,0);
my $retcode = $curl->perform();
if ($retcode != 0) {
warn "An error happened: ", $curl->strerror($retcode), " ($retcode)\n";
warn "errbuf: ", $curl->errbuf;
}
my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE);
use JSON;
my $json_vals = decode_json($response_body);
return $json_vals->{access_token};
}
..but then when I try and use the same logic below to get the transaction, it fails with a 500 IS Error:
sub get_proper_trans_id {
my $token = get_token($_[0]);
print $IN->header( 'utf8' );
my $curl = WWW::Curl::Easy->new();
my $fh = 'README';
my @headers = ("Authorization: Bearer $token","Content-Type: application/json; charset=utf-8");
print qq|Getting: https://$config->{$config->{mode}}->{transaction_endpoint}/v1/payments/payment/$_[0] \n|;
$curl->setopt(CURLOPT_HTTPHEADER,\@headers);
$curl->setopt(CURLOPT_HEADER,1);
$curl->setopt(CURLOPT_URL,"https://$config->{$config->{mode}}->{transaction_endpoint}/v1/payments/payment/$_[0]");
$curl->setopt(CURLOPT_SSL_VERIFYPEER,0);
$curl->setopt(CURLOPT_SSL_VERIFYHOST,0);
$curl->setopt('CURLOPT_RETURNTRANSFER',1);
$curl->setopt(CURLOPT_POST,1);
my $response_body;
open(my $fh, '>', \$response_body);
$curl->setopt(CURLOPT_WRITEDATA, $fh);
$curl->setopt(CURLOPT_VERBOSE,1);
my $retcode = $curl->perform();
if ($retcode != 0) {
warn "An error happened: ", $curl->strerror($retcode), " ($retcode)\n";
warn "errbuf: ", $curl->errbuf;
}
my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE);
}
The value of $_[0]
being passed into get_proper_trans_id()
is the PAY-xxxx transaction ID passed back from the PayPal-Checkout.JS system.
If I run this curl command manually, it works:
curl https://$config->{$config->{mode}}->{transaction_endpoint}/v1/payments/payment/$_[0] -H "Content-Type: application/json; charset=utf-8" -H "Authorization: Bearer $token"
The problem is that I'm having utf8 issues with that method, so I'm trying to find a module that will do the job for me.
Here is the output of the curl (with debugging and headers);
* Hostname was NOT found in DNS cache
* Trying 173.0.82.78...
* Connected to api.sandbox.paypal.com (173.0.82.78) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / AES256-SHA256
* Server certificate:
* subject: C=US; ST=California; L=San Jose; O=PayPal, Inc.; OU=PayPal Production; CN=api.sandbox.paypal.com
* start date: 2016-01-13 00:00:00 GMT
* expire date: 2018-01-13 23:59:59 GMT
* issuer: C=US; O=Symantec Corporation; OU=Symantec Trust Network; CN=Symantec Class 3 Secure Server CA - G4
* SSL certificate verify ok.
> POST /v1/payments/payment/PAY-6KY19646FF321593HLCVRQSY HTTP/1.1
Host: api.sandbox.paypal.com
Accept: */*
Authorization: Bearer MY_TOKEN_HERE
Content-Type: application/json; charset=utf-8
Expect: 100-continue
< HTTP/1.1 500 Internal Server Error
< Date: Tue, 21 Feb 2017 06:38:03 GMT
* Server Apache is not blacklisted
< Server: Apache
< paypal-debug-id: 217b14fc80976
< Connection: close
< X-SLR-RETRY: 500
< X-SLR-RETRY-API: /v1/payments/payment/{id}
< Connection: close
< Paypal-Debug-Id: 217b14fc80976
< Set-Cookie: X-PP-SILOVER=name%3DSANDBOX3.API.1%26silo_version%3D1880%26app%3Dplatformapiserv%26TIME%3D1273015128%26HTTP_X_PP_AZ_LOCATOR%3D; Expires=Tue, 21 Feb 2017 07:08:03 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
< Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT
< Vary: Authorization
< Content-Length: 196
< Content-Type: text/xml;charset=UTF-8
<
* Closing connection 0
GOT:
"HTTP/1.1 500 Internal Server Error
Date: Tue, 21 Feb 2017 06:38:03 GMT
Server: Apache
paypal-debug-id: 217b14fc80976
Connection: close
X-SLR-RETRY: 500
X-SLR-RETRY-API: /v1/payments/payment/{id}
Connection: close
Paypal-Debug-Id: 217b14fc80976
Set-Cookie: X-PP-SILOVER=name%3DSANDBOX3.API.1%26silo_version%3D1880%26app%3Dplatformapiserv%26TIME%3D1273015128%26HTTP_X_PP_AZ_LOCATOR%3D; Expires=Tue, 21 Feb 2017 07:08:03 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT
Vary: Authorization
Content-Length: 196
Content-Type: text/xml;charset=UTF-8
<ns1:XMLFault xmlns:ns1="http://cxf.apache.org/bindings/xformat"><ns1:faultstring xmlns:ns1="http://cxf.apache.org/bindings/xformat">java.lang.NullPointerException</ns1:faultstring></ns1:XMLFault>"
What am I missing? Thanks!
Upvotes: 1
Views: 175
Reputation: 5197
Ok, I just got a reply from the PayPal Tech's. It would seem that this particular function needs a GET instead of POST:
I see you are trying to use a POST where you need to use a GET (the REST API flow needs a GET for you to be able to get transaction details. GET https://api.sandbox.paypal.com/v1/payments/payment/ Can you try changing it for a GET? I hope this sorts it.
...and sure enough, that fixed it :)
For anyone wondering how I made that change, I just commented out:
$curl->setopt(CURLOPT_POST,1);
curl defaults to GET when sending requests.
Upvotes: 1