I am working on an payment gateway API to process refunds.
On successful operation, the API returns a json array like this
{
"currencyCode" : "GBP",
"amount" : 100,
"originalMerchantRefNum" : "MERCHANTREF12346",
"mode" : "live",
"confirmationNumber" : 1997160616609792,
"authType" : "refund",
"id" : "25TWPTLHRR81AIG1LF"
}
On error the array returned is
{
"error": {
"code": "400",
"message": "Amount exceeds refundable amount"
}
}
I need to decode the json output and then show it to the user. But since the structure of the json array is different in both cases, how do I go arnd parsing the json array, so as to give relevant readable data to the end user.
My code which, does all the talking and fetching data from the gateway processor is given below
<?php
include('lock.php');
$flag=0;
$oid=$_POST['oid'];
if(isset($_POST['amount']))
{
$amount=$_POST['amount'];
$amount = $amount*100;
$flag=1;
}
// generate random number
$merchantref=mt_rand(10,9999999999);
//API Url
$url = 'https://api.netbanx.com/hosted/v1/orders/'.$oid.'/refund';
//Initiate cURL.
$ch = curl_init($url);
//The JSON data.
if($flag==1)
{
$jsonData = array(
"amount" => $amount,
'merchantRefNum' => $merchantref
);
}
else
{
$jsonData = array(
'merchantRefNum' => $merchantref
);
}
//Encode the array into JSON.
$jsonDataEncoded = json_encode($jsonData);
//Tell cURL that we want to send a POST request.
curl_setopt($ch, CURLOPT_POST, 1);
//Attach our encoded JSON string to the POST fields.
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
//Set the content type to application/json and HTTP Authorization code
$headers = array(
'Content-Type:application/json',
'Authorization: Basic '. base64_encode("..") //Base 64 encoding and appending Authorization: Basic
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//Execute the request
$result = curl_exec($ch);
$jdata=$result;
//decode the json output and store it in a variable
$jfo = json_decode($jdata);
//Handle decision making based on json output
?>
Basically something as simple as:
$response = json_decode(..., true);
if (isset($response['error'])) {
echo 'Sorry, ', $response['error']['message'];
} else {
echo 'Yay!';
}
What exactly you need to check for depends on the possible values the API may return. Most APIs specify something along the lines of "status will be set to 'success' or 'error'", or maybe "if the error key is present, this indicates an error, otherwise a success".
Related
I'm sending some data with the fetch API to a translate.php file, here is my JS code:
const translation = {
word: 'Hello'
};
fetch('http://yandex.local/translate.php', {
method: 'POST',
body: JSON.stringify(translation),
headers: {
'Content-Type': 'application/json'
}
}).then(res => {
return res.text();
}).then(text => {
console.log(text);
})
Here is how I try to get the data on the translate.php:
$postData = json_decode(file_get_contents("php://input"), true);
$word = $postData['word'];
Here is my cURL request:
$word = $postData['word'];
$curl = curl_init();
$request = '{
"texts": "Hello",
"targetLanguageCode": "ru",
"sourceLanguageCode": "en"
}';
curl_setopt($curl, CURLOPT_URL, 'https://translate.api.cloud.yandex.net/translate/v2/translate');
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"Authorization: Api-Key 123456",
"Content-Type: application/json"
));
curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
$err = curl_error($curl);
if($err) {
echo 'Curl Error: ' . $err;
} else {
$response = json_decode($result, true);
print_r($response['translations']['0']['text']);
}
curl_close($curl);
When I'm runing this code I get the translation of Hello in russian which is Привет. But if I replace "Hello" in the request object by $word I got the error: Trying to access array offset on value of type null
Here is the way I rewrite the request object:
$request = '{
"texts": $word,
"targetLanguageCode": "ru",
"sourceLanguageCode": "en"
}';
When I check the XHR of my translate.php all seems ok, I have a status 200 and the request payload shows my data. Also the word "hello" displays correctly in the console of my index.php
Don't ever create JSON strings by hand (i.e. I mean by hard-coding the JSON text directly into a string variable). It can lead to all kinds of syntax issues accidentally.
Please replace
$request = '{
"texts": "Hello",
"targetLanguageCode": "ru",
"sourceLanguageCode": "en"
}';
with
$requestObj = array(
"texts" => $word,
"targetLanguageCode" => "ru",
"sourceLanguageCode" => "en"
);
$request = json_encode($requestObj);
This will produce a more reliable output, and also include the $word variable correctly.
P.S. Your actual issue was that in PHP, variables are not interpolated inside a string unless that string is double-quoted (see the manual). Your $request string is single-quoted.
Therefore $word inside your $request string was not changed into "Hello" but left as the literal string "$word". And also since you removed the quotes around it, when the remote server tries to parse that it will not be valid JSON, because a text variable in JSON must have quotes around it. This is exactly the kind of slip-up which is easy to make, and why I say not to build your JSON by hand!
Your version would output
{"texts":$word,"targetLanguageCode":"ru","sourceLanguageCode":"en"}
whereas my version will (correctly) output:
{"texts":"Hello","targetLanguageCode":"ru","sourceLanguageCode":"en"}
(Of course I should add, given the comment thread above, that regardless of my changes, none of this will ever work unless you send a correct POST request to translate.php containing the relevant data to populate $word in the first place.)
I'm new to JSON Code. I want to learn about the update function. Currently, I successfully can update data to the database. Below is the code.
<?php
require_once "../config/configPDO.php";
$photo_after = 'kk haha';
$report_id = 1;
$url = "http://172.20.0.45/TGWebService/TGWebService.asmx/ot_maintainReport?taskname=&reportStatus=&photoBefore=&photoAfter=". urlencode($photo_after) . "&reportID=$report_id";
$data = file_get_contents($url);
$json = json_decode($data);
$query = $json->otReportList;
if($query){
echo "Data Save!";
}else{
echo "Error!! Not Saved";
}
?>
the problem is, if the value of $photo_after is base64 string, which is too large string, it will give the error:
1) PHP Warning: file_get_contents.....
2) PHP Notice: Trying to get property 'otReportList' of non-object in C:
BUT
when I change the code to this,
<?php
require_once "../config/configPDO.php";
$photo_after = 'mama kk';
$report_id = 1;
$sql = "UPDATE ot_report SET photo_after ='$photo_after', time_photo_after = GETDATE(), ot_end = '20:30:00' WHERE report_id = '$report_id'";
$query = $conn->prepare($sql);
$query->execute();
if($query){
echo "Data Save!";
}else{
echo "Error!! Not Saved";
}
?>
The data will updated including when the value of $photo_after is in base 64 string.
Can I know what is the problem? Any solution to allow the base64 string update thru json link?
Thanks
// ...
// It's likely that the following line failed
$data = file_get_contents($url);
// ...
If the length of $url is more than 2048 bytes, that could cause file_get_contents($url) to fail. See What is the maximum length of a URL in different browsers?.
Consequent to such failure, you end up with a value of $json which is not an object. Ultimately, the property otReportList would not exist in $json hence the error: ...trying to get property 'otReportList' of non-object in C....
To surmount the URL length limitation, it would be best to embed the value of $photo_after in the request body. As requests made with GET method should not have a body, using POST method would be appropriate.
Below is a conceptual adjustment of your code to send the data with a POST method:
<?php
require_once "../config/configPDO.php";
# You must adapt backend behind this URL to be able to service the
# POST request
$url = "http://172.20.0.45/TGWebService/TGWebService.asmx/ot_maintainReport";
$report_id = 1;
$photo_after = 'very-long-base64-encoding-of-an-image';
$request_content = <<<CONTENT
{
"taskname": $taskname,
"report_id": $report_id,
"photoBefore": $photoBefore,
"photo_after": $photo_after,
"reportStatus": $reportStatus
}
CONTENT;
$request_content_length = strlen($request_content);
# Depending on your server configuration, you may need to set
# $request_headers as an associative array instead of a string.
$request_headers = <<<HEADERS
Content-type: application/json
Content-Length: $request_content_length
HEADERS;
$request_options = array(
'http' => array(
'method' => "POST",
'header' => $request_headers,
'content' => $request_content
)
);
$request_context = stream_context_create($request_options);
$data = file_get_contents($url, false, $request_context);
# The request may fail for whatever reason, you should handle that case.
if (!$data) {
throw new Exception('Request failed, data is invalid');
}
$json = json_decode($data);
$query = $json->otReportList;
if ($query) {
echo "Data Save!";
} else {
echo "Error!! Not Saved";
}
?>
sending a long GET URL is not a good practice. You need to use POST method with cURL. And your webservice should receive the data using post method.
Here's example sending post using PHP:
//
// A very simple PHP example that sends a HTTP POST to a remote site
//
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://www.example.com/tester.phtml");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
"postvar1=value1&postvar2=value2&postvar3=value3");
// In real life you should use something like:
// curl_setopt($ch, CURLOPT_POSTFIELDS,
// http_build_query(array('postvar1' => 'value1')));
// Receive server response ...
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
curl_close ($ch);
// Further processing ...
if ($server_output == "OK") { ... } else { ... }
Sample code from: PHP + curl, HTTP POST sample code?
And all output from the webservice will put in the curl_exec() method and from there you can decode the replied json string.
I recently work with kraken.io API and I'm trying to integrate this API wuth my PHP CodeIgniter framework. So I followed the documentation but I got stuck when I used curl
This is my source code below ..
require_once(APPPATH.'libraries/kraken-php-master/Kraken.php');
$kraken = new Kraken("SOME_KEY", "SOME_SECRET");
$params = array(
"file" => base_url()."include/".$dataIn['logo'],
"wait" => true
);
$dataj='{"auth":{"api_key": "SOME_KEY", "api_secret": "SOME_SECRET"},"file":'.base_url()."include/".$dataIn['logo'].',wait":true}';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.kraken.io/v1/upload");
curl_setopt($ch, CURLOPT_HTTPHEADER,array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataj);
$response = curl_exec($ch);
curl_close($ch);
$data = $kraken->upload($params);
print_r($response);exit();
And I got this result
"{"success":false,"message":"Incoming request body does not contain a valid JSON object"}1"
So can anyone please help me,
And thanks in advance,
DONT POST YOUR API_KEY AND API_SECRET
The error message is quite clear, your json object is not valid. For instance this would be a valid JSON object for your request:
{
"auth": {
"api_key": "SOME",
"api_secret": "SECRET"
},
"file": "somefile.txt",
"wait": true
}
In your php code you are setting up a $params array but then you don't use it. Try this:
$dataj='{"auth":{"api_key": "SOME_KEY", "api_secret": "SOME_SECRET"},"file":"' . $params["file"]. '", "wait":true}';
You can validate your JSON HERE
You should use json_encode function to generate your JSON data
$dataj = json_encode([
"auth" => [
"api_key" => "API_KEY",
"api_secret" => "API_SECRET"
],
"file" => base_url() . "include/" . $dataIn['logo'],
"wait" => true
]);
EDIT:
Here is an example from https://kraken.io/docs/upload-url so you don't need to use curl
require_once("Kraken.php");
$kraken = new Kraken("your-api-key", "your-api-secret");
$params = array(
"file" => "/path/to/image/file.jpg",
"wait" => true
);
$data = $kraken->upload($params);
if ($data["success"]) {
echo "Success. Optimized image URL: " . $data["kraked_url"];
} else {
echo "Fail. Error message: " . $data["message"];
}
I'm trying to write a PHP script based on the instructions here:
https://developers.facebook.com/ads/blog/post/2016/12/18/lead-ads-offline/
But I'm having issues with a json string passed as a parameter to curl in PHP. It looks like it's adding backslashes ("match_keys":"Invalid keys \"email\" etc.) which are causing the API call to fail.
I've tried playing around with:
json_encode($array,JSON_UNESCAPED_SLASHES);
I've tried a bunch of SO answers already like Curl add backslashes but no luck.
<?php
$email = hash('sha256', 'test#gmail.com');
$data = array("match_keys" => '{"email": $email}',
"event_time" =>1477632399,
"event_name"=> "Purchase",
"currency"=> "USD",
"value"=> 2.00);
$fields = [
// 'upload_tag'=>'2016-10-28-conversions',
'access_token'=>'#######',
'data'=> $data
];
$url = 'https://graph.facebook.com/v2.8/#######/events';
echo httpPost($url, $fields);
function httpPost($url, $fields)
{
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($fields));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
?>
This is the response:
Array{"error":{"message":"(#100) Invalid parameter","type":"OAuthException","code":100,"error_data":{"match_keys":"Invalid keys \"email\" were found in param \"data[match_keys]\".","event_time":"Out of bounds array access: invalid index match_keys","event_name":"Out of bounds array access: invalid index match_keys","currency":"Out of bounds array access: invalid index match_keys","value":"Out of bounds array access: invalid index match_keys"},"fbtrace_id":"BrVDnZPR99A"}}%
You are mixing JSON in with PHP arrays. I doubt it's actually JSON you intend using to send your data, since you're using http_build_query. Try this:
$data = array("match_keys" => ["email" => $email],
"event_time" =>1477632399,
"event_name"=> "Purchase",
"currency"=> "USD",
"value"=> 2.00
);
With this, you define your data as an array, and leave http_build_query to do the encoding for you.
I'm currently working on some automatization script in PHP (No HTML!).
I have two PHP files. One is executing the script, and another one receive $_POST data and returns information.
The question is how from one PHP script to send POST to another PHP script, get return variables and continue working on that first script without HTML form and no redirects.
I need to make requests a couple of times from first PHP file to another under different conditions and return different type of data, depending on request.
I have something like this:
<?php // action.php (first PHP script)
/*
doing some stuff
*/
$data = sendPost('get_info');// send POST to getinfo.php with attribute ['get_info'] and return data from another file
$mysqli->query("INSERT INTO domains (id, name, address, email)
VALUES('".$data['id']."', '".$data['name']."', '".$data['address']."', '".$data['email']."')") or die(mysqli_error($mysqli));
/*
continue doing some stuff
*/
$data2 = sendPost('what_is_the_time');// send POST to getinfo.php with attribute ['what_is_the_time'] and return time data from another file
sendPost('get_info' or 'what_is_the_time'){
//do post with desired attribute
return $data; }
?>
I think i need some function that will be called with an attribute, sending post request and returning data based on request.
And the second PHP file:
<?php // getinfo.php (another PHP script)
if($_POST['get_info']){
//do some actions
$data = anotherFunction();
return $data;
}
if($_POST['what_is_the_time']){
$time = time();
return $time;
}
function anotherFunction(){
//do some stuff
return $result;
}
?>
Thanks in advance guys.
Update: OK. the curl method is fetching the output of php file. How to just return a $data variable instead of whole output?
You should use curl. your function will be like this:
function sendPost($data) {
$ch = curl_init();
// you should put here url of your getinfo.php script
curl_setopt($ch, CURLOPT_URL, "getinfo.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$result = curl_exec ($ch);
curl_close ($ch);
return $result;
}
Then you should call it this way:
$data = sendPost( array('get_info'=>1) );
I will give you some example class , In the below example you can use this as a get and also post call as well. I hope this will help you.!
/*
for your reference . Please provide argument like this,
$requestBody = array(
'action' => $_POST['action'],
'method'=> $_POST['method'],
'amount'=> $_POST['amount'],
'description'=> $_POST['description']
);
$http = "http://localhost/test-folder/source/signup.php";
$resp = Curl::postAuth($http,$requestBody);
*/
class Curl {
// without header
public static function post($http,$requestBody){
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $http ,
CURLOPT_USERAGENT => 'From Front End',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $requestBody
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
return $resp;
}
// with authorization header
public static function postAuth($http,$requestBody,$token){
if(!isset($token)){
$resposne = new stdClass();
$resposne->code = 400;
$resposne-> message = "auth not found";
return json_encode($resposne);
}
$curl = curl_init();
$headers = array(
'auth-token: '.$token,
);
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_HTTPHEADER => $headers ,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $http ,
CURLOPT_USERAGENT => 'From Front End',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $requestBody
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
return $resp;
}
}