Sending Authentication Header using Curl and PHP - php

I'm trying to use an API that requires authentication with a private key pair.
Here is the API documentation:
Authentication API Docs
SubmitOrder API Docs
This is my code. I'm not getting any errors, but no trades are being placed. My coding skills are not the sharpest and without errors, I'm stuck!
<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);
// Generate random amount between 28.00 and 30.00
$ran1 = mt_rand(2800, 3000);
$ran2 = $ran1/100;
// Config
$sAPIKey = "mykey"; // private key
$sAPISecret = "mysecret"; // api secret
$sPair = "GLD_BTC";
// $sAmount = "1.00";
$sRate = "0.0001";
$sNonce = time();
// Request
$sRequest = "https://tradesatoshi.com/api/private/submitorder?API_PUBLIC_KEY=" . $sAPIKey . "&Market=" . $sPair . "&Type=" . 'Buy' . "&Amount=" . $ran2 . "&Price=" . $sRate . "&nonce=" . $sNonce;
$sSign=hash_hmac('sha512', $sRequest, $sAPISecret);
$ch = curl_init($sRequest);
// disable cert validation
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // shouldn't need this
// curl_setopt($ch, CURLOPT_HTTPHEADER, array('apisign:' . $sSign));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('apisign:' . $sSign));
$execResult = curl_exec($ch);
?>
Any guidance would be sincerely appreciated.

Related

cant read data from epever to raspberry

I'm using Raspberry-pi to read data from epever by rs485 to usb.I'm using this PHP file to read data.
<?php
/*
* PHP EpSolar Tracer Class (PhpEpsolarTracer) v0.9
*
*/
//EPEver tracer php library
require_once 'PhpEpsolarTracer.php';
//influxDB php client library
require 'vendor/autoload.php';
//Define IP of influxDB
$host = 'localhost';
$tracer = new PhpEpsolarTracer('/dev/ttyUSBACM0');
$client = new InfluxDB\Client($host,8086,"root","root");
$db = $client->selectDB("logger");
//'http://localhost:8086/write?db=mydb' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000'
Print "\n Realtime Data\n";
if ($tracer->getRealtimeData()) {
for ($i = 0; $i < count($tracer->realtimeData); $i++) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost:8086/write?db=powerwall" );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$Item = $tracer->realtimeData[$i];
$Key_Name = str_replace(" ","-",$tracer->realtimeKey[$i]);
Print str_pad($i, 2, '0', STR_PAD_LEFT) . " " . $Key_Name . " " . $Item . "\n";
curl_setopt($ch, CURLOPT_POSTFIELDS, "$Key_Name,unit=Realtime value=$Item" );
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/plain'));
$result = curl_exec ($ch);
}
} else
print "Cannot get RealTime Data\n";
Print "\n Statistical Data\n";
if ($tracer->getStatData()) {
for ($i = 0; $i < count($tracer->statData); $i++) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost:8086/write?db=powerwall" );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$Item = $tracer->statData[$i];
$Key_Name = str_replace(" ","-",$tracer->statKey[$i]);
$Key_Name = 'Stat-' . $Key_Name;
Print str_pad($i, 2, '0', STR_PAD_LEFT) . " " . $Key_Name . " " . $Item . "\n";
curl_setopt($ch, CURLOPT_POSTFIELDS, "$Key_Name,unit=statData value=$Item" );
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/plain'));
$result = curl_exec ($ch);
}
} else
print "Cannot get Statistical Data\n";
?>
When I run this code I got the error message:
Cannot get Real Time Data
So then I followed the issue in here:
Modbus cant read data from epever tracer 1210a to raspberry
But I haven't do this, I got several errors.
Then I have checked the kernel version of my raspberry pi and it shows as
Linux raspberry pi 4.19.57-v7+ #1244 SMP Thu Jul 4 18:45:25 BST 2019 armv7l GNU/Linux

Workflow Max add job via API

I'm trying to add a job to the Workflow Max API. I seem to be hitting the API but I keep getting the error message:
Message not in expected format. The following required element was missing - Job/ClientID
I'm sure that the client ID is added but something seems to be wrong. This is the code:
function post_job_to_workflow_max($job_data) {
// configure our connection to the api
$api_token = 'API_KEY';
$acc_key = 'ACC_TOKEN';
$url = 'https://api.workflowmax.com/job.api/add?apiKey=' . $api_token . '&accountKey=' . $acc_key;
// Job data must match the format required by WorkflowMax
// currently accepts XML data
// see: https://www.workflowmax.com/api/job-methods#POST%20add
$xml = new SimpleXMLElement("<Job></Job>");
$xml->addChild('Name', $job_data[0]);
$xml->addChild('Description', $job_data[1]);
$xml->addChild('ClientID', 18754031);
// $clientID = $xml->addChild('Client');
// $clientID->addChild('ID', 18754031);
// $clientID->addChild('Name', "TEST CLIENT");
$xml->addChild('State', 'Planned');
$xml->addChild('StartDate', $job_data[2]);
$xml->addChild('DueDate', $job_data[3]);
// print_r($xml);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml->asXML());
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: text/xml',
'Content-Length: ' . strlen($xml->asXML()))
);
$output = curl_exec($ch);
curl_close($ch);
$result = simplexml_load_string($output);
print_r($result);
}
If there's anyone with experience of using WFM, would be good to hear how you approached it.
Thanks
So in answer to my own question, I did finally work this out.
The way I did this was to return the ID of the client from the function I used to post a client to WorkFlow Max. See code:
1) post the client
function post_client_to_workflowmax($client_data) {
// configure our connection to the api
$api_token = 'YOUR_TOKEN';
$acc_key = 'YOUR_KEY';
$url = 'https://api.workflowmax.com/client.api/add?apiKey=' . $api_token . '&accountKey=' . $acc_key;
// Client data must match the format required by WorkflowMax
// currently accepts XML data
// These indexes match up with how the data has been stored
// see: https://www.workflowmax.com/api/client-methods#POST%20add
$xml = new SimpleXMLElement("<Client></Client>");
$xml->addChild('Name', htmlspecialchars($client_data[2]));
$xml->addChild('Email', htmlspecialchars($client_data[9]));
$xml->addChild('Phone', htmlspecialchars($client_data[10]));
$xml->addChild('Address', htmlspecialchars($client_data[3]) . ' ' . htmlspecialchars($client_data[4]));
$xml->addChild('City', htmlspecialchars($client_data[5]));
$xml->addChild('Postcode', htmlspecialchars($client_data[7]));
$xml->addChild('Country', htmlspecialchars($client_data[8]));
$xml->addChild('IsProspect', 'No');
$contacts = $xml->addChild('Contacts');
$contact = $contacts->addChild('Contact');
$name = $contact->addChild('Name', htmlspecialchars($client_data[0]) . ' ' . htmlspecialchars($client_data[1]));
// POST request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml->asXML());
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: text/xml',
'Content-Length: ' . strlen($xml->asXML()))
);
$output = curl_exec($ch);
curl_close($ch);
// Create an array from the data that is sent back from the API
$result = simplexml_load_string($output);
$clientID = NULL;
// here we get the ID created for this client and pass it into the variable $clientID
foreach($result->Client as $k => $v) {
$clientID = $v->ID;
}
return $clientID;
}
We then get that ID passed into our job posting function like so:
2) post a job to WFM
function post_job_to_workflow_max($job_data, $clientID) {
// configure our connection to the api
$api_token = 'YOUR_TOKEN';
$acc_key = 'YOUR_KEY';
$url = 'https://api.workflowmax.com/job.api/add?apiKey=' . $api_token . '&accountKey=' . $acc_key;
// Job data must match the format required by WorkflowMax
// currently accepts XML data
// see: https://www.workflowmax.com/api/job-methods#POST%20add
$xml = new SimpleXMLElement("<Job></Job>");
$xml->addChild('ClientID', $clientID);
$xml->addChild('Name', htmlspecialchars($job_data[0]));
$xml->addChild('Description', htmlspecialchars($job_data[1]));
$xml->addChild('State', 'Planned');
$xml->addChild('StartDate', htmlspecialchars($job_data[2]));
$xml->addChild('DueDate', htmlspecialchars($job_data[3]));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml->asXML());
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: text/xml',
'Content-Length: ' . strlen($xml->asXML()))
);
$output = curl_exec($ch);
curl_close($ch);
$result = simplexml_load_string($output);
}
And then calling these functions looks something like this:
$id = post_client_to_workflowmax($client);
post_job_to_workflow_max($job, $id);
Where $client must be an array of data. This worked for my case but might not work for your particular case so you may need to edit the fields etc.
Hopefully this helps someone who is stuck with the same problem. Not the most elegant code but it gets the job done.

Adding a Mailchimp User via Notification Script after Wordpress User subscribes (Membermouse) PHP and API

I am working on a MemberMouse subscription Wordpress website. After a User signs up via a webform for a membership, I want to call a script that adds the User to a Mailchimp mailing list WITH a double opt-in. Membermouse offers an integration via Mailchimp, however only with a single opt-in. Therefore, due to government law, I am required to use a double opt-in.
I wrote the following script, that should be called under the condition that once the member is added it sends the following php sript:
<?php
require_once("wp-load.php");
require_once("wp-content/plugins/membermouse/includes/mm-constants.php");
require_once("wp-content/plugins/membermouse/includes/init.php");
// Your Membermouse API URL
$apiUrl = "MYDOMAIN/wp-content/plugins/membermouse/api/request.php";
// Your API key
$apiKey = "my API key";
// Your API secret
$apiSecret = "my API secret";
// ---- GET EVENT TYPE ----
if(!isset($_GET["mm_member_add"]))
{
// event type was not found, so exit
exit;
}
// ---- ACCESS DATA ----
// member data
$username = $_GET["username"];
$email = $_GET["email"];
$apiKey1 = 'my Mailchimp API key';
$listID1 = 'my Mailchimp list ID';
// MailChimp API URL
$memberID1 = md5(strtolower($email));
$dataCenter1 = substr($apiKey1,strpos($apiKey1,'-')+1);
$url1 = 'https://' . $dataCenter1 . '.api.mailchimp.com/3.0/lists/' . $listID1 . '/members/' . $memberID1;
// member information
$json = json_encode([
'email_address' => $email,
'status' => 'pending',
]);
// send a HTTP POST request with curl
$ch1 = curl_init($url1);
curl_setopt($ch1, CURLOPT_USERPWD, 'user:' . $apiKey1);
curl_setopt($ch1, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_TIMEOUT, 10);
curl_setopt($ch1, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch1, CURLOPT_POSTFIELDS, $json);
$result1 = curl_exec($ch1);
$httpCode = curl_getinfo($ch1, CURLINFO_HTTP_CODE);
curl_close($ch1);
break;
echo "<pre>".print_r($result1, true)."</pre>";
?>
However, it will not respond. The script will be executed.
So far so good. However, I am trying since a couple of days how to write this PHP to get this be working. Additionally, I am not sure if the PHP code is even correct. This was just an assumption.
For references I found this script from membermouse: https://dl.dropboxusercontent.com/u/265387542/files/member_notification_script.php
And this script for Mailchimp: https://www.codexworld.com/add-subscriber-to-list-mailchimp-api-php/
I tried to combine these two, however so far without success.
Thanks for the fast reply #scottcwilson, however I get not responds from this php file.
This is how it looks now:
<?php
require_once("wp-load.php");
require_once("wp-content/plugins/membermouse/includes/mm-constants.php");
require_once("wp-content/plugins/membermouse/includes/init.php");
// Your API URL
$apiUrl = "MYDOMAIN/wp-content/plugins/membermouse/api/request.php";
// Your API key
$apiKey = "My API key";
// Your API secret
$apiSecret = "My API secret";
// ---- GET EVENT TYPE ----
if(!isset($_GET["mm_member_add"]))
{
// event type was not found, so exit
exit;
}
// ---- ACCESS DATA ----
// member data
$username = $_GET["username"];
$email = $_GET["email"];
$apiKey1 = 'Mailchimp API';
$listID1 = 'Mailchimp List ID';
// MailChimp API URL
$memberID1 = md5(strtolower($email));
$dataCenter1 = substr($apiKey1,strpos($apiKey1,'-')+1);
$url1 = 'https://' . $dataCenter1 . '.api.mailchimp.com/3.0/lists/' . $listID1 . '/members/';
// member information
$json = json_encode([
'email_address' => $email,
'status' => 'pending',
]);
// send a HTTP POST request with curl
$ch1 = curl_init($url1);
curl_setopt($ch1, CURLOPT_USERPWD, 'api_v3:' . $apiKey1);
curl_setopt($ch1, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_TIMEOUT, 10);
curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch1, CURLOPT_POSTFIELDS, $json);
$result1 = curl_exec($ch1);
$httpCode = curl_getinfo($ch1, CURLINFO_HTTP_CODE);
curl_close($ch1);
break;
echo "<pre>".print_r($result1, true)."</pre>";
?>
That is correct how you said, right?
The issues with your current code are:
1) You are supplying the memberid on the URL - this is not what you want for a POST to create a new user. So do
$url1 = 'https://' . $dataCenter1 . '.api.mailchimp.com/3.0/lists/' . $listID1 . '/members/';
instead.
2) Some of your cURL setup is wrong. For your POST fields you want
curl_setopt($ch1, CURLOPT_USERPWD, 'api_v3:' . $apiKey1);
curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, true);
get rid of
curl_setopt($ch1, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, false);

Curl and Sagepay

I'm having a lot of trouble integrating Sagepay InFrame Server with PHP, as there are no integration kits available for the new protocol (v3). I have the old kits for v2.23 but much of the code therein is deprecated.
At the moment the only way i have been successful in retrieving an OK status from the Sagepay Server servers is to have a form with the collection of hidden values required by Sagepay, including the cryptography field, and using the server URL as the form action. This gives me a status of 'OK' and the SecurityKey etc in the browser tab, but its not much use in the browser tab as i need that POST response back on my server, not on theirs.
For this i opted for curl. I hold the return values for curl_exec in a variable called $rawresponse, and dump the response after each attempt, and as it stands $rawresponse is returning as a false boolean:
$curlSession = curl_init();
curl_setopt ($curlSession, CURLOPT_URL, $url);
curl_setopt ($curlSession, CURLOPT_HEADER, 0);
curl_setopt ($curlSession, CURLOPT_POST, 1);
$data['Crypt'] = new CurlFile('filename.png', 'image/png', 'filename.png');
curl_setopt ($curlSession, CURLOPT_POSTFIELDS, $data);
curl_setopt($curlSession, CURLOPT_RETURNTRANSFER,1);
curl_setopt($curlSession, CURLOPT_TIMEOUT,30);
curl_setopt($curlSession, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curlSession, CURLOPT_SSL_VERIFYHOST, 0);
$rawresponse = curl_exec($curlSession);
Now as you can see here I am having to force the Crypt value to be of type CurlFile, which is what i think is breaking the request, however if i dont do that i get the following error:
"The usage of the #filename API for file uploading is deprecated. Please use the CURLFile class instead"
I can only ascertain from this that the cryptography is being mistaken for a file (possibly because the string starts with #), and to counter this im trying to force it to be an image.
So my question is this - is there a particular way to use CurlFile so cryptography strings can be understood? Is there a better way of integrating this functionality with Sagepay that anyone knows about? It really is a very confusing system, and the good documentation is let down by a complete lack of example.
Apologies for this, I was building the string the wrong way. Just in case anyone has a similar problem in the future i'll paste the code that works for me:
public function registerTransaction()
{
$VPSProtocol = urlencode($_POST['VPSProtocol']);
$TxType = urlencode($_POST['TxType']);
$Vendor = urlencode($_POST['Vendor']);
$VendorTxCode = urlencode($_POST['VendorTxCode']);
$Currency = urlencode($_POST['Currency']);
$Amount = urlencode($_POST['Amount']);
$NotificationURL = urlencode($_POST['NotificationURL']);
$Description = urlencode($_POST['Description']);
$BillingSurname = urlencode($_POST['BillingSurname']);
$BillingFirstnames = urlencode($_POST['BillingFirstnames']);
$BillingAddress1 = urlencode($_POST['BillingAddress1']);
$BillingCity = urlencode($_POST['BillingCity']);
$BillingPostCode = urlencode($_POST['BillingPostCode']);
$BillingCountry = urlencode($_POST['BillingCountry']);
$DeliverySurname = urlencode($_POST['DeliverySurname']);
$DeliveryFirstnames = urlencode($_POST['DeliveryFirstnames']);
$DeliveryAddress1 = urlencode($_POST['DeliveryAddress1']);
$DeliveryCity = urlencode($_POST['DeliveryCity']);
$DeliveryPostCode = urlencode($_POST['DeliveryPostCode']);
$DeliveryCountry = urlencode($_POST['DeliveryCountry']);
$url = "?VPSProtocol=" . $VPSProtocol;
$url .= "&TxType=" . $TxType;
$url .= "&Vendor=" . $Vendor;
$url .= "&VendorTxCode=" . $VendorTxCode;
$url .= "&Currency=" . $Currency;
$url .= "&Amount=" . $Amount;
$url .= "&NotificationURL=" . $NotificationURL;
$url .= "&Description=" . $Description;
$url .= "&BillingSurname=" . $BillingSurname;
$url .= "&BillingFirstnames=" . $BillingFirstnames;
$url .= "&BillingAddress1=" . $BillingAddress1;
$url .= "&BillingCity=" . $BillingCity;
$url .= "&BillingPostCode=" . $BillingPostCode;
$url .= "&BillingCountry=" . $BillingCountry;
$url .= "&DeliverySurname=" . $DeliverySurname;
$url .= "&DeliveryFirstnames=" . $DeliveryFirstnames;
$url .= "&DeliveryAddress1=" . $DeliveryAddress1;
$url .= "&DeliveryCity=" . $DeliveryCity;
$url .= "&DeliveryPostCode=" . $DeliveryPostCode;
$url .= "&DeliveryCountry=" . $DeliveryCountry;
$strPurchaseURL = "https://test.sagepay.com/gateway/service/vspserver-register.vsp";
$arrResponse = $this->requestPost($strPurchaseURL, $url);
dd($arrResponse);
}
public function requestPost($url, $data){
// Set a one-minute timeout for this script
set_time_limit(60);
// Initialise output variable
$output = array();
// Open the cURL session
$curlSession = curl_init();
curl_setopt ($curlSession, CURLOPT_URL, $url);
curl_setopt ($curlSession, CURLOPT_HEADER, 0);
curl_setopt ($curlSession, CURLOPT_POST, 1);
curl_setopt ($curlSession, CURLOPT_POSTFIELDS, $data);
curl_setopt($curlSession, CURLOPT_RETURNTRANSFER,1);
curl_setopt($curlSession, CURLOPT_TIMEOUT,30);
curl_setopt($curlSession, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curlSession, CURLOPT_SSL_VERIFYHOST, 2);
$rawresponse = curl_exec($curlSession);
dd($rawresponse);
//Store the raw response for later as it's useful to see for integration and understanding
$_SESSION["rawresponse"]=$rawresponse;
//Split response into name=value pairs
$response = preg_split(chr(10), $rawresponse);
// Check that a connection was made
if (curl_error($curlSession)){
// If it wasn't...
$output['Status'] = "FAIL";
$output['StatusDetail'] = curl_error($curlSession);
}
// Close the cURL session
curl_close ($curlSession);
// Tokenise the response
for ($i=0; $i<count($response); $i++){
// Find position of first "=" character
$splitAt = strpos($response[$i], "=");
// Create an associative (hash) array with key/value pairs ('trim' strips excess whitespace)
$output[trim(substr($response[$i], 0, $splitAt))] = trim(substr($response[$i], ($splitAt+1)));
} // END for ($i=0; $i<count($response); $i++)
// Return the output
return $output;
} // END function requestPost()

curl stays empty even if the url works

I'm just stuck with the curl thing...
It doesn't give me any problem before in my code but here, it appears when I do a var_dump, that the $EAACCOUNT is always empty... Nevertheless, I'm pretty sure that the url request is right because it works in other parts of my coding...
Do you guys have any idea how I could solve this?
$account= "http://www.ea.com/p/fut/a/" . $machine . "/l/". $ulocal ."/s/p/ut/game/fifa13/user/accountinfo?timestamp=". $time;
$auth = "http://www.ea.com/p/fut/a/" . $machine . "/l/". $ulocal ."/s/p/ut/auth";
$quest = "http://www.ea.com/p/fut/a/" . $machine . "/l/". $ulocal ."/s/p/ut/game/fifa13/phishing/validate";
//Cookie Data includes the two keys from above
$cookie_string = $EASW_KEY."; ".$EASF_SESS;
//Setup cURL HTTP request
$ch = curl_init($account);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_COOKIE, $cookie_string);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded')
);
$EAACCOUNT = curl_exec($ch);
curl_close($ch);
//Get personaID and Platform
$d = json_decode($EAACCOUNT, true);
$personaID = $d->userAccountInfo->personas[0]->personaId;
$platform = $d->userAccountInfo->personas[0]->userClubList[0]->platform;

Categories