Getting token works, but making payment not - paypal

I'm making a class to make a payment with paypal.
Getting a token via the function getToken() works and it spits out a good response (according to the documentation).
However, when I'm using that token to build up a payment with the same sendAPICall() used for the token; it only returns a empty string (according to var_dump() ).
If I copy the exact curl command from the api-information and paste the beare-token; it works. So something is wrong with my API call....
Clearly I'm missing something. Could anyone point me to the error?
The function which gets the Bearer-token:
public function getToken(){
$headers = array(
"Accept-Language" => 'en_US',
"Accept" => "application/json"
);
$t = json_decode($this->sendAPICall('grant_type=client_credentials', '/oauth2/token', $headers, true));
if($t->error){
$this->error = $t->error_description;
$this->token = NULL;
return false;
}else{
$this->token = $t;
return true;
}
}
The function which should make the payment after checking there is a token available.
public function makePayment(){
$this->getToken();
if($this->error){
return false;
}else{
$d = '{"intent":"sale",
"redirect_urls":{
"return_url":"'.$this->config['returnURL'].'",
"cancel_url":"'.$this->config['cancelURL'].'"
},
"payer":{
"payment_method":"paypal"
},
"transactions":[
{
"amount":{
"total":"'.$this->amount.'",
"currency":"'.$this->config['currency'].'"
},
"description":"'.$this->description.'"
}
]
}';
$headers = array( "Authorization" => $this->token->token_type . ' ' . $this->token->access_token,
"Content-type" => "application/json"
);
return $this->sendAPICall(urlencode($d), '/payments/payment', $headers, false);
}
}
And off course the connection with the paypal API, where I'm using the $auth boolean to make the difference between sending the userpwd or using the token:
private function sendAPICall($data, $url, $headers, $auth=true){
$ch = curl_init();
$options = array( CURLOPT_URL => $this->config['endpoint'].$url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $data,
CURLOPT_RETURNTRANSFER => true
);
if($auth){
$options[CURLOPT_USERPWD] = $this->config['client_id'].':'.$this->config['client_secret'];
};
curl_setopt_array($ch, $options);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
return curl_exec($ch);
}

It does not look like this code snippet is passing HTTP headers correctly. CURLOPT_HTTPHEADER takes a unideimensional array with values of the form "headername: value". You need
$headers = array(
"Authorization: " . $this->token->token_type . ' ' . $this->token->access_token,
"Content-type: application/json"
);
Also consider
Checking for curl_errno($ch) / curl_error($ch) and the HTTP response code (curl_getinfo($ch, CURLINFO_HTTP_CODE)) to see if the call was successful.
Creating the request data as an associative array and using json_encode($data) when calling sendAPICall(). This is far easier than manipulating JSON strings manually.

Related

What is this? (Facebook Offline Conversions API) Error #21009 - The data set upload is temporarily not ready

We have been uploading to Facebook's Offline Conversion API for the past 3 weeks with no issues. Suddenly, Facebook is returning this error:
(#21009) The data set upload is temporarily not ready.
See below code for full JSON payload.
Our Auth Token is still valid. (e.g. Not expired, still valid)
According to this tool: https://developers.facebook.com/tools/debug/accesstoken/
# I had to remove these fields for privacy reasons
define('FACEBOOK_APP_ACCESS_TOKEN', 'YOUR TOKEN HERE');
define('FACEBOOK_PIXEL_OFFLINE_EVENT_SET_ID', 'YOUR PIXEL ID HERE');
# Be sure to change the email/name fields accordingly
$event_name='test-upload';
$data = array();
$data["match_keys"] = array();
$data["match_keys"]['email'] = hash('sha256', 'bob.ross#example.com');
$data["match_keys"]['fn'] = hash('sha256', 'bob');
$data["match_keys"]['ln'] = hash('sha256', 'ross');
$data["match_keys"]['gen'] = hash('sha256', 'm');
$data["event_time"] = time();
$data["event_name"] = $event_name;
$data["currency"] = "USD";
$data["value"] = '0.00';
// Turn Data to JSON
$data_json = json_encode(array($data));
// Fill available fields
$fields = array();
$fields['access_token'] = FACEBOOK_APP_ACCESS_TOKEN;
$fields['upload_tag'] = $event_name . '-' . time(); // You should set a tag here (feel free to adjust)
$fields['data'] = $data_json;
$url = 'https://graph.facebook.com/v3.2/' . FACEBOOK_PIXEL_OFFLINE_EVENT_SET_ID . '/events';
$curl = curl_init($url);
curl_setopt_array($curl, array(
// Replace with your offline_event_set_id
CURLOPT_URL => 'https://graph.facebook.com/v3.2/' . FACEBOOK_PIXEL_OFFLINE_EVENT_SET_ID . '/events',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => http_build_query($fields),
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
//"content-type: multipart/form-data",
"Accept: application/json" ),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Expected result from Facebook:
{"id":"36485444079550","num_processed_entries":1}
Actual result from Facebook
{
"error": {
"message": "(#21009) The data set upload is temporarily not ready.",
"type": "OAuthException",
"code": 21009,
"fbtrace_id": "GeofD5QsXdI"
}
}
I would add a comment instead of an "answer" but I don't quite have the points yet. The commenters on the Facebook thread (https://developers.facebook.com/support/bugs/1052442614962359/) have had this magically resolve overnight, and I experienced the same (problem happening and no explanation, then magical resolution and no explanation). It seems like Facebook may have fixed whatever was causing the issue.

Consume a REST API in codeigniter controller

I have create a REST API and want to consume my own created API in codeigniter controller.
My created REST API
controller(example.php)
class Example extends REST_Controller {
public function __construct() {
parent::__construct();
$this->load->model('user');
}
public function user_fetch_post() {
//returns all rows if the id parameter doesn't exist,
//otherwise single row will be returned
$id = $this->input->post('id');
$users = $this->user->getRows($id);
//check if the user data exists
if(!empty($users)){
//set the response and exit
$this->response($users, REST_Controller::HTTP_OK);
}else{
//set the response and exit
$this->response([
'status' => FALSE,
'message' => 'No user were found.'
], REST_Controller::HTTP_NOT_FOUND);
}
}
model(user.php)
function getRows($id = ""){
if(!empty($id)){
$query = $this->db->get_where('users', array('id' => $id));
return $query->row_array();
}else{
$query = $this->db->get('users');
return $query->result_array();
}
}
Here i want to call my created api(from example.php)for fetch record in welcome.php controller with basic authentication(uname-admin,pwd-1234)
my controller welcome.php
public function index()
{
}
Can anybody help to me that how to call my api in controller welcome.php with basic authentication.
Using CURL you can consume any API/network call.
<?php
$headers = array(
'Content-Type:application/json',
'Authorization: Basic '. base64_encode("user:password") // place your auth details here
);
$payload = array(
'id' => 1,
);
$process = curl_init($host); //your API url
curl_setopt($process, CURLOPT_HTTPHEADER, $headers);
curl_setopt($process, CURLOPT_HEADER, 1);
curl_setopt($process, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($process, CURLOPT_TIMEOUT, 30);
curl_setopt($process, CURLOPT_POST, 1);
curl_setopt($process, CURLOPT_POSTFIELDS, $payload);
curl_setopt($process, CURLOPT_RETURNTRANSFER, TRUE);
$return = curl_exec($process);
curl_close($process);
//finally print your API response
print_r($return);
?>
But why are you calling your own API this way? You can simply call your API model and perform your operations
Add below to your curl options
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'APIKEY: admin#123',
'Content-Type: application/json',
));
also update
$config['rest_key_name'] = 'APIKEY';
in rest.php file inside config folder of your codeigniter settings. By default it is 'X-API-KEY'
This may help to somebody else looking for a solution, if OP has resolved it himself/herself.

How to Retrieve HTTP Status Code with Guzzle?

New to Guzzle/Http.
I have a API rest url login that answer with 401 code if not authorized, or 400 if missing values.
I would get the http status code to check if there is some issues, but cannot have only the code (integer or string).
This is my piece of code, I did use instruction here ( http://docs.guzzlephp.org/en/stable/quickstart.html#exceptions )
namespace controllers;
use GuzzleHttp\Psr7;
use GuzzleHttp\Exception\ClientException;
$client = new \GuzzleHttp\Client();
$url = $this->getBaseDomain().'/api/v1/login';
try {
$res = $client->request('POST', $url, [
'form_params' => [
'username' => 'abc',
'password' => '123'
]
]);
} catch (ClientException $e) {
//echo Psr7\str($e->getRequest());
echo Psr7\str($e->getResponse());
}
You can use the getStatusCode function.
$response = $client->request('GET', $url);
$statusCode = $response->getStatusCode();
Note: If your URL redirects to some other URL then you need to set false value for allow_redirects property to be able to detect initial status code for parent URL.
// On client creation
$client = new GuzzleHttp\Client([
'allow_redirects' => false
]);
// Using with request function
$client->request('GET', '/url/with/redirect', ['allow_redirects' => false]);
If you want to check status code in catch block, then you need to use $exception->getCode()
More about responses
More about allow_redirects
you can also use this code :
$client = new \GuzzleHttp\Client(['base_uri' 'http://...', 'http_errors' => false]);
hope help you

IPP CustomerAgg 401 on getAccountTransactions

The user flow I'm building for my application is that users can click on myAccounts and I'll display the getCustomerAccounts Results. That works perfectly. Then for each account I have a hyperlink called get transactions. That takes the user to a new page that should list out the transactions for that account. For some reason I'm always getting a 401 Code:ApplicationAuthenticationFailed when I call getAccountTransactions even though the previous call of getCustomerAccounts worked fine.
I'm confused as I imagine the authentication that is failing for the 401 is the exact same that works for the earlier call. Here is my code:
function get_transactions($accountID)
{
IntuitAggCatHelpers::GetOAuthTokens( $oauth_token, $oauth_token_secret);
$signatures = array( 'consumer_key' => OAUTH_CONSUMER_KEY,
'shared_secret' => OAUTH_SHARED_SECRET,
'oauth_token' => $oauth_token,
'oauth_secret' => $oauth_token_secret);
$txnStartDate = '2014-06-01'; // YYYY-MM-DD
$url = FINANCIAL_FEED_URL ."v1/accounts/$accountID/transactions?txnStartDate=$txnStartDate";
$action = 'GET';
$oauthObject = new OAuthSimple();
$oauthObject->setAction( $action );
$oauthObject->reset();
$result = $oauthObject->sign(
array
(
'path' => $url,
'parameters'=>
array
(
'oauth_signature_method' => 'HMAC-SHA1',
'Host' => FINANCIAL_FEED_HOST
),
'signatures'=> $signatures
)
);
$options = array();
$curlError = fopen('php://temp', 'rw+');
$options[CURLOPT_STDERR] = $curlError;
$options[CURLOPT_CUSTOMREQUEST] = $action;
$options[CURLOPT_URL] = $result['signed_url'];
$options[CURLOPT_HEADER] = 1;
$options[CURLOPT_VERBOSE] = 1;
$options[CURLOPT_RETURNTRANSFER] = 1;
$options[CURLOPT_SSL_VERIFYPEER] = true;
$options[CURLOPT_HTTPHEADER] = array
(
'Accept:application/json',
'Content-Type:application/json',
//'Content-Length:' . strlen( $postData ),
'Host:'. FINANCIAL_FEED_HOST,
//'Authorization:' . $result['header']
);
$curlError = fopen('php://temp', 'rw+');
$options[CURLOPT_STDERR] = $curlError;
$ch = curl_init();
curl_setopt_array( $ch, $options );
$responseText = urldecode( curl_exec( $ch ) );
echo $responseText;
//display curl http conversation
rewind( $curlError );
stream_get_contents( $curlError );
fclose( $curlError );
$httpCode = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
curl_close( $ch );
return $responseText;
}
Using same certificate(.p12) please try the above getAccountTransaction call from APIExplorer tool.
https://developer.intuit.com/apiexplorer?apiname=CustomerAccountData
Usage Ref - https://developer.intuit.com/docs/0020_customeraccountdata/007_firstrequest
If that works well, then compare the request header and URL with the same from your above code. 401 suggests authentication error which comes when your OAuth header is not properly formed/incorrect. Above comparison should sort this out.
PN - While uploading .p12 file(SAML) in ApiExplorer, sometiems, I get the following error msg.
"Your certificate is invalid. Please use base64 encoded CER format and make sure that the file is not empty". If you get the same then this can't be tested in ApiExplorer.
Thanks
This worked for me:
$result = $oauthObject->sign(array(
'path' => FINANCIAL_FEED_URL . 'v1/accounts/400037865348',
'parameters'=> array('oauth_signature_method' => 'HMAC-SHA1',
'Host'=> FINANCIAL_FEED_HOST,
'txnStartDate' => '2014-01-01',
'txnEndDate' => '2014-08-29'),
'signatures'=> $signatures));
Found at https://intuitpartnerplatform.lc.intuit.com/questions/797819-how-to-get-txnstartdate-into-my-url-without-breaking-oauth-authentication.

REST Api for Sugarcrm

Sugarcrm is providing Restful API support.So how can i check json response using rest client(browser plugin to check restful web services)?.
I am developing a web-app using spring MVC(Restful API).I want to use sugarcrm as my crm module.how can i integrate both?.
I have gone through sugar's documentation about the same ,but I do not have any idea about php biased programming.
can anyone please help me?
Thanks.
run below code, if you have any problem then let me know.
<?php
//Put your Base url
$url = 'yoursugarcrm_url/service/v4_1/rest.php';
// Open a curl session for making the call
$curl = curl_init($url);
// Tell curl to use HTTP POST
curl_setopt($curl, CURLOPT_POST, true);
// Tell curl not to return headers, but do return the response
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
// Set the POST arguments to pass to the Sugar server
$parameters = array(
'user_auth' => array(
'user_name' => 'admin',
'password' => md5('uDje9ceUo89nBrM'),
),
);
$json = json_encode($parameters);
$postArgs = array(
'method' => 'login',
'input_type' => 'JSON',
'response_type' => 'JSON',
'rest_data' => $json,
);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postArgs);
// Make the REST call, returning the result
$response = curl_exec($curl);
// Convert the result from JSON format to a PHP array
$result = json_decode($response);
if ( !is_object($result) ) {
die("Error handling result.\n");
}
if ( !isset($result->id) ) {
die("Error: {$result->name} - {$result->description}\n.");
}
// Get the session id
$sessionId = $result->id;
//echo json_encode(array("sessionId"=>$sessionId));
//Your moduel parameter
//Parameter of the customer
$fullname = $_POST['fullname'];
$password = md5($_POST['password']);
$email_address = $_POST['email_address'];
// My moduel
$parameters = array(
'session' => $sessionId, //Session ID get from session.php
'module' => 'custo_Customers', // Your PackageKey_ModuleName
'name_value_list' => array (
array('name' => 'fullname', 'value' => $fullname),
array('name' => 'email_address', 'value' => $email_address),
array('name' => 'password', 'value' => $password),
),
);
$json = json_encode($parameters); // Json strgin
$postArgs = 'method=set_entry&input_type=JSON&response_type=JSON&rest_data=' . $json;
curl_setopt($curl, CURLOPT_POSTFIELDS, $postArgs);
// Make the REST call, returning the result
$response = curl_exec($curl);
// Convert the result from JSON format to a PHP array
$result = json_decode($response,true);
echo $response;
?>