I have been recently trying to make an API request using PHP to PayPal to pay multiple accounts but so far I have no luck.
`
class PayPal
{
public $_headers = array();
public $_config = array();
public $_data = array();
public function __construct()
{
if (!in_array('curl', get_loaded_extensions()))
{
trigger_error("CURL extension is not installed or enabled", E_USER_ERROR);
}
}
public function update_headers(array $credentails)
{
$this->_headers = $credentails;
return $this;
}
public function update_config(array $config)
{
$this->_config = $config;
return $this;
}
public function pay($data, $call)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->get_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, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->_headers);
return curl_exec($ch);
}
public function split_pay()
{
// create the pay request
$this->_data = array(
"actionType" =>"PAY",
"currencyCode" => "USD",
"receiverList" => array(
"receiver" => array(
array(
"amount"=> "1.00",
"email"=>"******#gmail.com"
),
array(
"amount"=> "2.00",
"email"=>"*********.co.uk"
),
),
),
"returnUrl" => "http://test.local/payments/confirm",
"cancelUrl" => "http://test.local/payments/cancel",
"requestEnvelope" => array(
"errorLanguage" => "en_US",
"detailLevel" => "ReturnAll",
),
);
return $this->pay($this->_data, "PAY");
}
private function get_url()
{
if (empty($this->_config))
{
trigger_error("You have not setup the config", E_USER_ERROR);
}
return $this->_config['url'];
}
public function call_headers()
{
if (empty($this->_headers))
{
trigger_error("You have not set any headers", E_USER_ERROR);
}
print_r($this->_headers);
}
}
?>`
This is a class file which I have created, it is very rough but its not working. Here is some more code.
`load->library('paypal');
$pp = new PayPal();
//Bring me the money!
//Headers for paypal
$headers = array(
"X-PAYPAL-SECURITY-USERID: ********",
"X-PAYPAL-SECURITY-PASSWORD: *********",
"X-PAYPAL-SECURITY-SIGNATURE: **********",
"X-PAYPAL-REQUEST-DATA-FORMAT: NV",
"X-PAYPAL-RESPONSE-DATA-FORMAT: NV",
"X-PAYPAL-APPLICATION-ID: APP-80W284485P519543T"
);
$config = array(
'url' => 'https://svcs.sandbox.paypal.com/AdaptivePayments/Pay',
'username' => '********',
'password' => '********',
'signature' => '********',
'app_id' => 'APP-80W284485P519543T',
);
$pp->update_headers($headers)->update_config($config);
print_r($pp->split_pay());
?>
`
I am being returned with this response.
responseEnvelope.timestamp=2014-04-22T06%3A15%3A49.821-07%3A00&responseEnvelope.ack=Failure&responseEnvelope.correlationId=b3d05fe547e22&responseEnvelope.build=10680030&error(0).errorId=580001&error(0).domain=PLATFORM&error(0).subdomain=Application&error(0).severity=Error&error(0).category=Application&error(0).message=Invalid+request%3A+%7B0%7D
Does anyone have any ideas why this might be
Related
I got method in getting the access token and here it is
public $token; //I declare global var to read in every func
public function getToken(){
$key = 'xxxxxxxxxxxxxx';
$secret = 'xxxxxxxxxxxxxxxxxx';
$data = array(
'key' => 'xxxxxxxxxxxxxxxxxx',
'secret' => 'xxxxxxxxxxxxxxx'
);
$payload = json_encode($data);
$ch = curl_init('https://cgi.singmap.com/token?key='.$key.'&secret='.$secret.'');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded',
'Accept: application/json',
'Content-Length: ' . strlen($payload))
);
// Submit the POST request
$response = json_decode(curl_exec($ch), true);
$trimmed = $response['datas'];
$token = $trimmed['access_token'];
curl_close($ch);
$this->token = $token;
}
The token only lasts for 5 minutes to use. But in my other method like this which uses token
public function propertyUnitDetails(){
$unitId = \DB::table('property_unit_list')
->select('projectId','unitId')
->get();
foreach($unitId as $res){
$this->getToken();
$final_token = $this->token;
// dd($final_token);
$request_time = Carbon::now()->format('YmdHis');
$sign = md5($final_token.$request_time);
$pageNo = 1;
$pageSize = 200;
$url = 'https://cgi.singmap.com/unit/queryUnitDetail?request_time='.$request_time.
'&token='.$final_token.'&sign='.$sign.'&projectId='.$res->projectId.'&unitId='.$res->unitId.'';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = json_decode(curl_exec($ch), true);
$trimmed = $response['datas'];
if(empty($trimmed)){
$this->getToken();
$final_token = $this->token;
}
foreach ($trimmed as $data){
$inserts[] = [
'projectId' => $res->projectId,
'stack' => $data['stack'],
'floorPlanId' => $data['floorPlanId'],
'soldBy' => $data['soldBy'],
'transactionPrice' => $data['transactionPrice'],
'type' => $data['type'],
'unitId' => $data['unitId'],
'floorPlanName' => $data['floorPlanName'],
'price1' => $data['price1'],
'price2' => $data['price2'],
'price3' => $data['price3'],
'price4' => $data['price4'],
'custom1' => $data['custom1'],
'custom2' => $data['custom2'],
'custom3' => $data['custom3'],
'custom4' => $data['custom4'],
'direction' => $data['direction'],
'area' => $data['area'],
'buildName' => $data['buildName'],
'unitName' => $data['unitName'],
'buildId' => $data['buildId'],
'bathrooms' => $data['bathrooms'],
'transactionDate' => $data['transactionDate'],
'bedrooms' => $data['bedrooms'],
'purchaseStatus' => $data['purchaseStatus'],
];
}
}
$chuncked = array_chunk($inserts, 10);
foreach($chuncked as $inserts){
\DB::table('property_project_details')->insert($inserts);
}
dd('record inserted');
}
When the function is not completely excecuted or the data is not fully inserted, maybe because it has a large amount of data. It throws an error of datas index is not found or something from the curl response. It is because I can only get the datas based on the token i get manually or declared manually. What I want is that if the token expires, it will run the function getToken() and pass the token to the running function in order to avoid interrupting it.
EDIT:
I added
$this->getToken();
$final_token = $this->token;
in my foreach statement because #user001232 said that in every unitId result query I got, a new token would be generated. But I still got an error every 5 mins that is because i cant get a new token even if i add that function in there.
Here you go, this will work:
<?php
class NameOfYourClass {
public $token;
public function refreshToken()
{
$key = 'xxxxxxxxxxxxxx';
$secret = 'xxxxxxxxxxxxxxxxxx';
$data = array(
'key' => 'xxxxxxxxxxxxxxxxxx',
'secret' => 'xxxxxxxxxxxxxxx'
);
$payload = json_encode($data);
$ch = curl_init('https://cgi.singmap.com/token?key='.$key.'&secret='.$secret.'');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded',
'Accept: application/json',
'Content-Length: ' . strlen($payload))
);
$response = json_decode(curl_exec($ch), true);
$trimmed = $response['datas'];
$this->token = $trimmed['access_token'];
curl_close($ch);
}
private function getUnitDetails($res, $attempts = 1)
{
// We only allow 5 attempts to avoid getting into infinite loops
if ($attempts > 5) {
throw new \Exception('Signmap API Issue');
}
$request_time = Carbon::now()->format('YmdHis');
$sign = md5($this->token.$request_time);
$pageNo = 1;
$pageSize = 200;
$url = 'https://cgi.singmap.com/unit/queryUnitDetail?request_time='.$request_time.
'&token='.$this->token.'&sign='.$sign.'&projectId='.$res->projectId.'&unitId='.$res->unitId.'';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = json_decode(curl_exec($ch), true);
$trimmed = $response['datas'] ?? null;
// If the response datas is empty, we're assuming it's because of a token error, so we retry
if(empty($trimmed)){
$attempts++;
$this->refreshToken();
return $this->getUnitDetails($res, $attempts);
}
return $trimmed;
}
public function propertyUnitDetails()
{
// Grab all of the units
$unitItds = \DB::table('property_unit_list')->select('projectId','unitId')->get();
foreach($unitId as $res) {
$trimmed = $this->getUnitDetails($res);
foreach ($trimmed as $data){
$inserts[] = [
'projectId' => $res->projectId,
'stack' => $data['stack'],
'floorPlanId' => $data['floorPlanId'],
'soldBy' => $data['soldBy'],
'transactionPrice' => $data['transactionPrice'],
'type' => $data['type'],
'unitId' => $data['unitId'],
'floorPlanName' => $data['floorPlanName'],
'price1' => $data['price1'],
'price2' => $data['price2'],
'price3' => $data['price3'],
'price4' => $data['price4'],
'custom1' => $data['custom1'],
'custom2' => $data['custom2'],
'custom3' => $data['custom3'],
'custom4' => $data['custom4'],
'direction' => $data['direction'],
'area' => $data['area'],
'buildName' => $data['buildName'],
'unitName' => $data['unitName'],
'buildId' => $data['buildId'],
'bathrooms' => $data['bathrooms'],
'transactionDate' => $data['transactionDate'],
'bedrooms' => $data['bedrooms'],
'purchaseStatus' => $data['purchaseStatus'],
];
}
}
$chuncked = array_chunk($inserts, 10);
foreach($chuncked as $inserts){
\DB::table('property_project_details')->insert($inserts);
}
dd('record inserted');
}
}
What if you call the method getToken() everytime you got a projectId in your loop. Its like this
foreach($project_id as $res){
$this->getToken();
$final_token = $this->token;
$request_time = Carbon::now()->format('YmdHis');
$sign = md5($final_token.$request_time);
//and so on ....
In that way. it will get a new token in every projectId. the only drawbacks is it will execute very slowly.
And if it is still got the error replace your code like this. Add a condition if empty
public function propertyBuildings(){
$project_id = \DB::table('project_list')
->select('projectId')
->get();
foreach($project_id as $res){
$this->getToken();
$final_token = $this->token;
$request_time = Carbon::now()->format('YmdHis');
$sign = md5($final_token.$request_time);
$url = 'https://cgi.singmap.com/project/queryBuilding?request_time='.$request_time.
'&token='.$token.'&sign='.$sign.'&projectId='.$res->projectId.'';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = json_decode(curl_exec($ch), true);
$trimmed = $response['datas'];
if(empty($trimmed)){
$this->getToken();
$final_token = $this->token;
}
// return $trimmed;
foreach($trimmed as $data){
$inserts[] = [
'projectId' => $res->projectId,
'buildId' => $data['buildId'],
'buildName' => $data['buildName'],
];
}
}
\DB::table('property_building')->insert($inserts);
dd('Data Inserted');
}
I need help to use the following code Paypal Adaptive Payment in WordPress Website.
I do not understand from where the CComponent class extend.
<?php
class PaypalTest extends CComponent{
public $api_user = "**********************";
public $api_pass = "***********";
public $api_sig = "**************************";
public $app_id = "APP-80W284485P519543T";
public $apiUrl = 'https://svcs.sandbox.paypal.com/AdaptivePayments/';
public $paypalUrl="https://www.paypal.com/webscr?cmd=_ap-payment&paykey=";
public $headers;
public function __construct(){
$this->headers = array(
"X-PAYPAL-SECURITY-USERID: ".$this->api_user,
"X-PAYPAL-SECURITY-PASSWORD: ".$this->api_pass,
"X-PAYPAL-SECURITY-SIGNATURE: ".$this->api_sig,
"X-PAYPAL-REQUEST-DATA-FORMAT: JSON",
"X-PAYPAL-RESPONSE-DATA-FORMAT: JSON",
"X-PAYPAL-APPLICATION-ID: ".$this->app_id,
);
}
public function getPaymentOptions($paykey){
}
public function setPaymentOptions(){
}
public function _paypalSend($data,$call){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->apiUrl.$call);
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, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
$response = json_decode(curl_exec($ch),true);
return $response;
}
public function splitPay(){
// create the pay request
$createPacket = array(
"actionType" =>"PAY",
"currencyCode" => "USD",
"receiverList" => array(
"receiver" => array(
array(
"amount"=> "1.00",
"email"=>"********#hotmail.com"
),
array(
"amount"=> "2.00",
"email"=>"********#gmail.ca"
),
),
),
"returnUrl" => "http://test.local/payments/confirm",
"cancelUrl" => "http://test.local/payments/cancel",
"requestEnvelope" => array(
"errorLanguage" => "en_US",
"detailLevel" => "ReturnAll",
),
);
$response = $this->_paypalSend($createPacket,"Pay");
}
}
?>
It looks like simple, but something I do not understand. And I'm not really familiar with Paypal Adaptive Payments. I'm in sandbox mode.
I am trying to implement PayPal Adaptive Payments, but as soon as I try to post with cURL, I get a NULL response and curl_error() gives the following error:
0NSS: client certificate not found (nickname not specified)
Here is the full PHP code, I am using sandbox. Some sensitive info is starred (*).
<?php
class PayPal {
public $API_USER = "*********.gmail.com";
public $API_PASSWORD = "********************";
public $API_SIGNATURE = "******************************";
public $API_APP_ID = "APP-80W284485P519543T";
public $apiUrl = "https://svcs.sandbox.paypal.com/AdaptivePayments/";
public $paypalUrl = "https://sandbox.paypal.com/webscr?cmd=ap-payment&paykey=";
public $headers = array();
function __construct() {
$this->headers = array(
"X-PAYPAL-SECURITY-USERID : " . $this->API_USER,
"X-PAYPAL-SECURITY-PASSWORD : " . $this->API_PASSWORD,
"X-PAYPAL-SECURITY-SIGNATURE : " . $this->API_SIGNATURE,
"X-PAYPAL-REQUEST-DATA-FORMAT : JSON",
"X-PAYPAL-RESPONSE-DATA-FORMAT : JSON",
"X-PAYPAL-APPLICATION-ID : " . $this->API_APP_ID
);
}
function paypalSend($data, $call) {
$ch = curl_init();
$curl_params = array(
CURLOPT_URL => $this->apiUrl . $call,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_SSL_VERIFYHOST => FALSE,
CURLOPT_HTTPHEADER => $this->headers,
CURLOPT_POSTFIELDS => json_encode($data)
);
curl_setopt_array($ch, $curl_params);
$result = curl_exec($ch);
echo(curl_errno($ch));
echo(curl_error($ch));
curl_close($ch);
return json_decode($result, TRUE);
}
function getPayKey() {
$createPacket = array(
"actionType" => "PAY",
"currencyCode" => "USD",
"receiverList" => array(
"receiver" => array(
array(
"amount" => "5.00",
"email" => "*********#gmail.com"
)
)
),
"returnUrl" => "http://example.com/success",
"cancelUrl" => "http://example.com/failure",
"requestEnvelope" => array(
"errorLanguage" => "en_US",
"detailLevel" => "ReturnAll"
)
);
// paypal Send
$response = $this->paypalSend($createPacket, "Pay");
var_dump($response);
}
}
$pp = new Paypal();
$pp->getPayKey();
?>
I have this problem. I've follow this tutorial -> http://www.youtube.com/watch?v=rzRR1i-F_VA
and after setting everything, I have some problem with getting through the authentification process. And After some research on authentification, I've tested this -> https://developer.paypal.com/webapps/developer/docs/classic/lifecycle/ug_sandbox/
At some point in the process (Making test requests), I've tested it in a bash console, and my userid, password and signature worked. So I figure that the problem was in the code I was using.
So here's the code:
<?php
class PaypalTest extends CComponent{
public $api_user = "**********************";
public $api_pass = "***********";
public $api_sig = "**************************";
public $app_id = "APP-80W284485P519543T";
public $apiUrl = 'https://svcs.sandbox.paypal.com/AdaptivePayments/';
public $paypalUrl="https://www.paypal.com/webscr?cmd=_ap-payment&paykey=";
public $headers;
public function __construct(){
$this->headers = array(
"X-PAYPAL-SECURITY-USERID: ".$this->api_user,
"X-PAYPAL-SECURITY-PASSWORD: ".$this->api_pass,
"X-PAYPAL-SECURITY-SIGNATURE: ".$this->api_sig,
"X-PAYPAL-REQUEST-DATA-FORMAT: JSON",
"X-PAYPAL-RESPONSE-DATA-FORMAT: JSON",
"X-PAYPAL-APPLICATION-ID: ".$this->app_id,
);
}
public function getPaymentOptions($paykey){
}
public function setPaymentOptions(){
}
public function _paypalSend($data,$call){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->apiUrl.$call);
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, json_encode($data));
curl_setopt($ch, CURLOPT_HEADER, $this->headers);
$response = json_decode(curl_exec($ch),true);
return $response;
}
public function splitPay(){
// create the pay request
$createPacket = array(
"actionType" =>"PAY",
"currencyCode" => "USD",
"receiverList" => array(
"receiver" => array(
array(
"amount"=> "1.00",
"email"=>"********#hotmail.com"
),
array(
"amount"=> "2.00",
"email"=>"********#gmail.ca"
),
),
),
"returnUrl" => "http://test.local/payments/confirm",
"cancelUrl" => "http://test.local/payments/cancel",
"requestEnvelope" => array(
"errorLanguage" => "en_US",
"detailLevel" => "ReturnAll",
),
);
$response = $this->_paypalSend($createPacket,"Pay");
}
}
And here's the call:
$payment = new PaypalTest();
$payment->splitPay();
Quite simple, but something is not working. And I'm not really familiar with Curl so I thought you guys could help me
P.S: I'm in sandbox mode
Thanks
Carl
change CURLOPT_HEADER to CURLOPT_HTTPHEADER
I am new to curl so I am using code found on the Paypal Developer blog and I am having a hard time getting it to work for me. Here is the code I am using
class paypal {
private $access_token;
private $token_type;
/**
* Constructor
*
* Handles oauth 2 bearer token fetch
* #link https://developer.paypal.com/webapps/developer/docs/api/#authentication--headers
*/
public function __construct(){
$postvals = "grant_type=client_credentials";
$uri = PAYMENT_URI . "v1/oauth2/token";
$auth_response = self::curl($uri, 'POST', $postvals, true);
$this->access_token = $auth_response['body']->access_token;
$this->token_type = $auth_response['body']->token_type;
}
/**
* cURL
*
* Handles GET / POST requests for auth requests
* #link http://php.net/manual/en/book.curl.php
*/
private function curl($url, $method = 'GET', $postvals = null, $auth = false){
$ch = curl_init($url);
//if we are sending request to obtain bearer token
if ($auth){
$headers = array("Accept: application/json", "Accept-Language: en_US");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, CLIENT_ID . ":" .CLIENT_SECRET);
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
//if we are sending request with the bearer token for protected resources
} else {
$headers = array("Content-Type:application/json", "Authorization:{$this->token_type} {$this->access_token}");
}
$options = array(
CURLOPT_HEADER => true,
CURLINFO_HEADER_OUT => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_VERBOSE => true,
CURLOPT_TIMEOUT => 10
);
if ($method == 'POST'){
$options[CURLOPT_POSTFIELDS] = $postvals;
$options[CURLOPT_CUSTOMREQUEST] = $method;
}
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
$header = substr($response, 0, curl_getinfo($ch,CURLINFO_HEADER_SIZE));
$body = json_decode(substr($response, curl_getinfo($ch,CURLINFO_HEADER_SIZE)));
curl_close($ch);
return array('header' => $header, 'body' => $body);
}
// Function for Processing Payment
function process_payment($request) {
$postvals = $request;
$uri = PAYMENT_URI . "v1/payments/payment";
return self::curl($uri, 'POST', $postvals);
}
}
if (isset($_SESSION['payment_type']) && ($_SESSION['payment_type'] == 'paypal')) { // User has chosen to pay with Paypal.
// Retrive Shopping cart contents
$r = mysqli_query($dbc, "CALL get_shopping_cart_contents('$uid')");
$request = array(
'intent' => 'sale',
'redirect_urls' => array(
'return_url' =>'http://store.example.com/final',
'cancel_url' =>'http://store.example.com/payment'
),
'payer' => array(
'payment_method' =>'paypal'
),
'transactions' => array(
'amount' => array(
'total' =>''.number_format($order_total,2).'',
'currency' =>'USD',
'details' => array(
'subtotal' =>''.number_format($subtotal,2).'',
'shipping' =>''.number_format($shipping,2).''
),
'item_list' => array(
)
),
'description' =>'Mike and Maureen Photography - Order ID #'.$order_id.''
)
);
while ($items = mysqli_fetch_array($r, MYSQLI_ASSOC)) {
$newitems = array(
'quantity' =>''.$items['quantity'].'',
'name' =>''.$items['name'].'',
'price' =>''.get_price($items['price'],$items['sales_price']).'',
'currency' =>'USD'
);
$request['transactions']['amount']['item_list']['items'][] = $newitems;
}
$request = json_encode($request);
process_payment($request);
}
I am good with php but this whole class, public/private stuff is throwing me off. Can I use this code without that or will it open me up to trouble? How do I run the process_payment function without it throwing an error. I am getting "Fatal error: Call to undefined function process_payment()"
Didnt I just define the function in the paypal class? I have read through the documentation on paypal and I cant get a grasp on what I am doing wrong. Any help would be great.
The function process_payment() is part of the paypal class. To call it, you will have to do one of the ways outlined here: https://stackoverflow.com/a/4216347/1715048