this is my Vesta.php i made this to send the API requests and use it internally
<?php
require 'includes/Config.php';
class VestaAPI {
private $_instance = null;
public static function getInstance() {
if ($_instance == null) {
$_instance = new VestaAPI();
}
return $_instance;
}
public static function runCMD($cmd,$arg1 = "",$arg2 = "",$arg3 = "",$arg4 = "",$arg5 = "",$arg6 = "",$arg7 = "",$arg8 = "",$arg9 = "",$arg10 = ""){
ini_set('max_execution_time', 30);
set_time_limit(30);
// Server credentials
$settings = Config::getInstance()->getSettings();
$vst_hostname = $settings["vestaLogin"]["Host"];
$vst_username = $settings["vestaLogin"]["Username"];
$vst_password = $settings["vestaLogin"]["Password"];
$vst_command = $cmd;
// Prepare POST query
$postvars = array(
'user' => $vst_username,
'password' => $vst_password,
'cmd' => $vst_command,
'arg1' => $arg1,
'arg2' => $arg2
);
$postdata = http_build_query($postvars);
// Send POST query via cURL
$postdata = http_build_query($postvars);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://' . $vst_hostname . ':81/api/');
curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_LOW_SPEED_LIMIT, 1); // cancel if below 1 byte/second
curl_setopt($ch, CURLOPT_LOW_SPEED_TIME, 30); // for a period of 30 seconds
curl_setopt($post, CURLOPT_AUTOREFERER, true);
curl_setopt($post, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($post, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($post, CURLOPT_TIMEOUT, 30 );
curl_setopt(CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
return curl_exec($curl);
}
public static function arrayToXml($array, &$xml){
foreach ($array as $key => $value) {
if(is_array($value)){
if(is_int($key)){
$key = "e";
}
$label = $xml->addChild($key);
arrayToXml($value, $label);
}
else {
$xml->addChild($key, $value);
}
}
}
}
// to get your instance use
?>
but when i try to run this code here (to suspend a website or to unsuspend) i get error 500
<?php
require 'includes/Vesta.php';
if(isset($_POST["username"])){}else{die("ERROR 403");}
$output = VestaAPI::runCMD("v-suspend-user",$_POST["username"]);
if(strstr($output, "Error:")) {die($output);}else{
die("Done!");
}
?>
but if i am getting the data of the account it works i think it must be a time out issue but here is the php error log
2016/02/15 00:53:55 [error] 14102#0: *6 upstream prematurely closed
connection while reading response header from upstream, client:
86.6.39.173, server: testing.DOMAIN.co.uk, request: "POST /suspendUser.php HTTP/1.1", upstream:
"http://45.58.48.103:8080/suspendUser.php", host:
"testing.DOMAIN.co.uk", referrer: "http://testing.DOMAIN.co.uk/"
i have replaced my domain with DOMAIN
Perhaps you run the API request from the same server as the vestacp installation.
This is happening because after suspend/unsuspend user, the vestacp web service is restarted.
You must set $arg2='no', to prevent web service restart, and restart it at a later time.
Related
I want to get an Authentication Token for the Microsoft Translator API. This is my code:
<?php
//1. initialize cURL
$ch = curl_init();
//2. set options
//Set to POST request
curl_setopt($ch, CURLOPT_POST,1);
// URL to send the request to
curl_setopt($ch, CURLOPT_URL, 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken');
//return instead of outputting directly
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//whether to include header in the output. here set to false
curl_setopt($ch, CURLOPT_HEADER, 0);
//pass my subscription key
curl_setopt($ch, CURLOPT_POSTFIELDS,array(Subscription-Key => '<my-key>'));
//CURLOPT_SSL_VERIFYPEER- Set to false to stop verifying certificate
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//3. Execute the request and fetch the response. check for errors
$output = curl_exec($ch);
if ($output === FALSE) {
echo "cURL Error" . curl_error($ch);
}
//4. close and free up the curl handle
curl_close($ch);
//5. display raw output
print_r($output);
?>
it gives me the following error:
{ "statusCode": 401, "message": "Access denied due to missing subscription key. Make sure to include subscription key when making requests to an API." }
which could mean that the key is invalid according to the website below, but I ensured the key is valid on the same website.
http://docs.microsofttranslator.com/oauth-token.html
I did find some examples online on how to get the Authenticationtoken, but they are outdated.
How can I get the AuthenticationToken/achieve that microsoft recognises my key?
You're passing the subscription-key wrong -
The subscription key should passed in the header (Ocp-Apim-Subscription-Key) or as a querystring parameter in the URL ?Subscription-Key=
And you should use Key1 or Key2 generated by the Azure cognitive service dashboard.
FYI - M$ has made a token generator available for testing purposes, this should give you a clue which keys are used for which purpose:
http://docs.microsofttranslator.com/oauth-token.html
Here's a working PHP script which translates a string from EN to FR (it's based on an outdated WP plugin called Wp-Slug-Translate by BoLiQuan which I've modified for this purpose):
<?php
define("CLIENTID",'<client-name>'); // client name/id
define("CLIENTSECRET",'<client-key>'); // Put key1 or key 2 here
define("SOURCE","en");
define("TARGET","fr");
class WstHttpRequest
{
function curlRequest($url, $header = array(), $postData = ''){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
if(!empty($header)){
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
if(!empty($postData)){
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($postData) ? http_build_query($postData) : $postData);
}
$curlResponse = curl_exec($ch);
curl_close($ch);
return $curlResponse;
}
}
class WstMicrosoftTranslator extends WstHttpRequest
{
private $_clientID = CLIENTID;
private $_clientSecret = CLIENTSECRET;
private $_fromLanguage = SOURCE;
private $_toLanguage = TARGET;
private $_grantType = "client_credentials";
private $_scopeUrl = "http://api.microsofttranslator.com";
private $_authUrl = "https://api.cognitive.microsoft.com/sts/v1.0/issueToken";
// added subscription-key
private function _getTokens(){
try{
$header = array('Ocp-Apim-Subscription-Key: '.$this->_clientSecret);
$postData = array(
'grant_type' => $this->_grantType,
'scope' => $this->_scopeUrl,
'client_id' => $this->_clientID,
'client_secret' => $this->_clientSecret
);
$response = $this->curlRequest($this->_authUrl, $header, $postData);
if (!empty($response))
return $response;
}
catch(Exception $e){
echo "Exception-" . $e->getMessage();
}
}
function translate($inputStr){
$params = "text=" . rawurlencode($inputStr) . "&from=" . $this->_fromLanguage . "&to=" . $this->_toLanguage;
$translateUrl = "http://api.microsofttranslator.com/v2/Http.svc/Translate?$params";
$accessToken = $this->_getTokens();
$authHeader = "Authorization: Bearer " . $accessToken;
$header = array($authHeader, "Content-Type: text/xml");
$curlResponse = $this->curlRequest($translateUrl, $header);
$xmlObj = simplexml_load_string($curlResponse);
$translatedStr = '';
foreach((array)$xmlObj[0] as $val){
$translatedStr = $val;
}
return $translatedStr;
}
}
function bing_translator($string) {
$wst_microsoft= new WstMicrosoftTranslator();
return $wst_microsoft->translate($string);
}
echo bing_translator("How about translating this?");
?>
Add your key also in the URL.
curl_setopt($ch, CURLOPT_URL, 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken?Subscription-Key={your key}');
But leave it also in the CURLOPT_POSTFIELDS.
There is something going wrong with the google api php client. Even though I followed the installation on github precisely it still wont work. Im not using the Composer way but i downloaded the release. I have tried to use different paths in the response-callback.php require_once like
'google-api-php-client/src/google/autoload.php'
'google-api-php-client/vendor_autoload.php'
But nothing worked...
Error:
Fatal error: require_once(): Failed opening required 'google-api-php-client/vendor/autoload.php' (include_path='.:/Users/mike/Documents/test:/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/php/sdk') in /Users/mike/Documents/test/response-callback.php on line 3
Warning: require_once(google-api-php-client/vendor/autoload.php): failed to open stream: No such file or directory in /Users/mike/Documents/test/response-callback.php on line 3
app.yaml:
application: csimporttest
version: 1
runtime: php55
api_version: 1
handlers:
- url: /.*
script: main.php
main.php
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h2>Hi! Stackoverflow!</h2>
<?php include'response-callback.php';
echo "response-callback file: ", $test;
?>
Import google contacts
</body>
</html>
response-callback.php
<?php
require_once 'google-api-php-client/vendor/autoload.php';
$test = 'WORKS!';
$google_client_id = 'SECRET';
$google_client_secret = 'SECRET';
$google_redirect_uri = 'https://csimporttest.appspot.com';
//setup new google client
$client = new Google_Client();
$client -> setApplicationName('csimporttest');
$client -> setClientid($google_client_id);
$client -> setClientSecret($google_client_secret);
$client -> setRedirectUri($google_redirect_uri);
$client -> setAccessType('online');
$client -> setScopes('https://www.googleapis.com/auth/contacts.readonly');
$googleImportUrl = $client -> createAuthUrl();
function curl($url, $post = "") {
$curl = curl_init();
$userAgent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';
curl_setopt($curl, CURLOPT_URL, $url);
//The URL to fetch. This can also be set when initializing a session with curl_init().
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
//TRUE to return the transfer as a string of the return value of curl_exec() instead of outputting it out directly.
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
//The number of seconds to wait while trying to connect.
if ($post != "") {
curl_setopt($curl, CURLOPT_POST, 5);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
}
curl_setopt($curl, CURLOPT_USERAGENT, $userAgent);
//The contents of the "User-Agent: " header to be used in a HTTP request.
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
//To follow any "Location: " header that the server sends as part of the HTTP header.
curl_setopt($curl, CURLOPT_AUTOREFERER, TRUE);
//To automatically set the Referer: field in requests where it follows a Location: redirect.
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
//The maximum number of seconds to allow cURL functions to execute.
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
//To stop cURL from verifying the peer's certificate.
$contents = curl_exec($curl);
curl_close($curl);
return $contents;
}
if(isset($_SESSION['google_code'])) {
$auth_code = $_SESSION['google_code'];
$max_results = 200;
$fields=array(
'code'=> urlencode($auth_code),
'client_id'=> urlencode($google_client_id),
'client_secret'=> urlencode($google_client_secret),
'redirect_uri'=> urlencode($google_redirect_uri),
'grant_type'=> urlencode('authorization_code')
);
$post = '';
foreach($fields as $key=>$value)
{
$post .= $key.'='.$value.'&';
}
$post = rtrim($post,'&');
$result = curl('https://www.googleapis.com/oauth2/v4/token',$post);
$response = json_decode($result);
$accesstoken = $response->access_token;
$url = 'https://www.google.com/m8/feeds/contacts/default/full?max-results='.$max_results.'&alt=json&v=3.0&oauth_token='.$accesstoken;
$xmlresponse = curl($url);
$contacts = json_decode($xmlresponse,true);
$return = array();
if (!empty($contacts['feed']['entry'])) {
foreach($contacts['feed']['entry'] as $contact) {
//retrieve Name and email address
$return[] = array (
'name'=> $contact['title']['$t'],
'email' => $contact['gd$email'][0]['address'],
);
}
}
$google_contacts = $return;
unset($_SESSION['google_code']);
}
?>
Just put the whole Google php client library in your project folder, then change
require_once 'google-api-php-client/vendor/autoload.php';
to:
require_once 'google-api-php-client-1-master/src/Google/autoload.php';
When I click on the <a> which stands in main.php to import the contacts and I click through the accepts of google so I allow them to see my contacts. And then when I return to own page... it doesn't show any contacts at all. I think it's because I don't return any contacts, but I don't know how.
app.yaml:
application: csimporttest
version: 1
runtime: php55
api_version: 1
handlers:
- url: /.*
script: main.php
main.php:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h2>Hi!</h2>
<?php include('response-callback.php');?>
Import
</body>
</html>
response-callback.php;
<?php
session_start();
require_once 'google-api-php-client-master/src/Google/autoload.php';
$google_client_id = 'SECRET';
$google_client_secret = 'SECRET';
$google_redirect_uri = 'https://csimporttest.appspot.com/response-callback.php';
//setup new google client
$client = new Google_Client();
$client -> setApplicationName('csimporttest');
$client -> setClientid($google_client_id);
$client -> setClientSecret($google_client_secret);
$client -> setRedirectUri($google_redirect_uri);
$client -> setAccessType('online');
$client -> setScopes('https://www.googleapis.com/auth/contacts.readonly');
$googleImportUrl = $client -> createAuthUrl();
function curl($url, $post = "") {
$curl = curl_init();
$userAgent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';
curl_setopt($curl, CURLOPT_URL, $url);
//The URL to fetch. This can also be set when initializing a session with curl_init().
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
//TRUE to return the transfer as a string of the return value of curl_exec() instead of outputting it out directly.
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
//The number of seconds to wait while trying to connect.
if ($post != "") {
curl_setopt($curl, CURLOPT_POST, 5);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
}
curl_setopt($curl, CURLOPT_USERAGENT, $userAgent);
//The contents of the "User-Agent: " header to be used in a HTTP request.
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
//To follow any "Location: " header that the server sends as part of the HTTP header.
curl_setopt($curl, CURLOPT_AUTOREFERER, TRUE);
//To automatically set the Referer: field in requests where it follows a Location: redirect.
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
//The maximum number of seconds to allow cURL functions to execute.
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
//To stop cURL from verifying the peer's certificate.
$contents = curl_exec($curl);
curl_close($curl);
return $contents;
}
//google response with contact. We set a session and redirect back
if (isset($_GET['code'])) {
$auth_code = $_GET["code"];
$_SESSION['google_code'] = $auth_code;
header('Location: ' . $google_redirect_uri);
}
if(isset($_SESSION['google_code'])) {
$auth_code = $_SESSION['google_code'];
$max_results = 200;
$fields=array(
'code'=> urlencode($auth_code),
'client_id'=> urlencode($google_client_id),
'client_secret'=> urlencode($google_client_secret),
'redirect_uri'=> urlencode($google_redirect_uri),
'grant_type'=> urlencode('authorization_code')
);
$post = '';
foreach($fields as $key=>$value)
{
$post .= $key.'='.$value.'&';
}
$post = rtrim($post,'&');
$result = curl('https://www.googleapis.com/oauth2/v4/token',$post);
$response = json_decode($result);
$accesstoken = $response->access_token;
$url = 'https://www.google.com/m8/feeds/contacts/default/full?max-results='.$max_results.'&alt=json&v=3.0&oauth_token='.$accesstoken;
$xmlresponse = curl($url);
$contacts = json_decode($xmlresponse,true);
$return = array();
if (!empty($contacts['feed']['entry'])) {
foreach($contacts['feed']['entry'] as $contact) {
//retrieve Name and email address
$return[] = array (
'name'=> $contact['title']['$t'],
'email' => $contact['gd$email'][0]['address'],
);
}
}
$google_contacts = $return;
unset($_SESSION['google_code']);
}
if (!empty($contacts['feed']['entry'])) {
foreach($contacts['feed']['entry'] as $contact) {
//retrieve Name and email address
$return[] = array (
'name'=> $contact['title']['$t'],
'email' => $contact['gd$email'][0]['address'],
);
//retrieve user photo
if (isset($contact['link'][0]['href'])) {
$url = $contact['link'][0]['href'];
$url = $url . '&access_token=' . urlencode($accesstoken);
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 15);
curl_setopt($curl, CURLOPT_VERBOSE, true);
$image = curl_exec($curl);
curl_close($curl);
}
$return['image'] = $image;
echo '';
}
}
?>
The last thing the code does is set '$google_contacts = $return', so it's up to your app to do something useful with the $google_contacts array, such as display it. The blog where this code originated doesn't mention that the code sample displays anything, only that it is an example of how to retrieve contacts.
You can use an var_dump() to see if the array google_contacts is actually filled. Put this in the main.php:
<?php
var_dump($google_contacts);
?>
If you get an output in the var_dump you can use an html table and an easy foreach, look below:
<table border='1' class="table table-striped table-condensed">
<thead>
<tr>
<th>Naam </th>
<th>Email </th>
</tr>
</thead>
<tbody>
<?php
foreach ($google_contacts as $contacts){
echo'<tr>';
echo'<td>'. $contacts['name']."</td>";
echo'<td>'. $contacts['email'].'</td>';
echo'</tr>';
}
?>
</tbody>
</table>
I have been researching and trying for 2 days to make a test call with PayPal Adaptive API
I hand wrote a fairly simple test code using php cURL...
protected function makePayment($a=''){
if($a==''){return 'OOPs';}
$amount = "1.00";
$receiver = "RECEIVER TEST EMAIL";
$url = 'https://api-3t.sandbox.paypal.com/nvp/Pay';
$paypalHeaders = array(
'X-PAYPAL-SECURITY-USERID : XXXXXXXX',
'X-PAYPAL-SECURITY-PASSWORD : XXXXXXX',
'X-PAYPAL-SECURITY-SIGNATURE : XXXXXXX',
'X-PAYPAL-SECURITY-VERSION: 1.8.6',
'X-PAYPAL-DEVICE-IPADDRESS: <MY SITE IP>',
'X-PAYPAL-REQUEST-DATA-FORMAT : NV',
'X-PAYPAL-RESPONSE-DATA-FORMAT : NV',
'X-PAYPAL-APPLICATION-ID : APP-80W284485P519543T',
'X-PAYPAL-SANDBOX-EMAIL-ADDRESS: MY-SANDBOX-APP-OWNER#email.com'
);
// Format the call payload.
$payload = array(
"actionType"=>"PAY",
"currencyCode"=>"USD",
"receiverList"=>array(
"receiver"=>array(
array("amount"=>$amount,"email"=>$receiver)
)
),
"returnUrl"=>"https://biddingblock.com/api/payment.php",
"cancelUrl"=>"https://biddingblock.com/index.htm",
"requestEnvelope"=>array(
"errorLanguage"=>"en_US",
"detailLevel"=>"ReturnAll"
)
);
// Make the call
$curl = curl_init();
curl_setopt($curl, CURLOPT_VERBOSE, 1);
curl_setopt($curl, CURLOPT_HEADER, TRUE);
curl_setopt($curl, CURLOPT_HTTPHEADER, $paypalHeaders);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $Request);
$Response = curl_exec($curl);
curl_close($curl);
return $Response;
* Every modification I have tried on this code still doesn't get past first base and I receive the following error back *
HTTP/1.1 400 Bad Request
Server: AkamaiGHost
Mime-Version: 1.0
Content-Type: text/html
Content-Length: 176
Expires: Mon, 31 Mar 2014 12:31:45 GMT
Date: Mon, 31 Mar 2014 12:31:45 GMT
Connection: close
An error occurred while processing your request.
Reference #166.d80300cc.1396269105.de2dda4
I am NOT using the Adaptive API PHP SDK and this is more or less the complete code minus the real keys and receiver email
What am I doing wrong?
Can someone please help?
PS: I have also tried this using DATA-FORMAT JSON and JSON encoding the payload array.
This is working for me:
$nvp = "&PAYMENTREQUEST_0_PAYMENTACTION=SALE";
$nvp.= "&PAYMENTREQUEST_0_AMT=19.95";
$nvp.= "&PAYMENTREQUEST_0_CURRENCYCODE=USD";
$nvp.= "&RETURNURL=http://www.dropial.com/success.html";
$nvp.= "&CANCELURL=http://www.dropial.com/cancel.html";
$response = wpp_hash('SetExpressCheckout', $nvp);
if ($response['ACK'] == 'Success') {
$this->Session->setFlash('Payment Successful');
} else {
$this->Session->setFlash('Payment Failed');
}
The function wpp_hash is defined as:
public function wpp_hash($method = null, $nvp = null) {
$curl_handler = curl_init();
curl_setopt($curl_handler, CURLOPT_URL, 'https://api-3t.sandbox.paypal.com/nvp';
curl_setopt($curl_handler, CURLOPT_VERBOSE, 1);
curl_setopt($curl_handler, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl_handler, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl_handler, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handler, CURLOPT_POST, 1);
$required_nvp = 'METHOD='.$method;
$required_nvp .= '&VERSION='.urlencode(Configure::read('Paypal.version'));
$required_nvp .= '&USER='.urlencode(Configure::read('Paypal.username'));
$required_nvp .= '&PWD='.urlencode(Configure::read('Paypal.password'));
$required_nvp .= '&SIGNATURE='.urlencode(Configure::read('Paypal.signature'));
curl_setopt($curl_handler, CURLOPT_POSTFIELDS, $required_nvp.$nvp);
$http_responder = curl_exec($curl_handler);
curl_close($curl_handler);
pr($http_responder);
if (!$http_responder) {
throw new BadRequestException($method.'failed: '.curl_error($curl_handler).' ('.curl_errno($curl_handler).')');
}
$responder = explode('&', $http_responder);
$parsed_response = array();
foreach($responder as $response) {
$response_array = explode('=', $response);
if (count($response_array) >= 1){
$parsed_response[$response_array[0]] = urldecode($response_array[1]);
}
}
if ((count($parsed_response) < 1) || !array_key_exists('ACK', $parsed_response)){
throw new BadRequestException('Invalid HTTP Response for POST request ('.$required_nvp.$nvp.') to '.Configure::read('Paypal.endpoint'));
}
return $parsed_response;
}
You can change the method to use another PayPal transaction. In my case I'm using express checkout.
I have moved beyond this and used a work around by running this with the following method.
Thanks
Here is the solution I have adopted...
$payload = array(
"actionType"=>"PAY",
"currencyCode"=>"USD",
"receiverList"=>array(
"receiver"=>array(
array("amount"=>$amount,"email"=>$receiver)
)
),
"feesPayer"=>"PRIMARYRECEIVER",
"returnUrl"=>"MyRETURN_URL",
"cancelUrl"=>"MyCANCEL_URL",
"requestEnvelope"=>array(
"errorLanguage"=>"en_US",
"detailLevel"=>"ReturnAll"
)
);
$request = 'curl -s --insecure'.$TEST_url.' -d "'.addslashes(json_encode($payload)).'"';
$response = json_decode(exec($request));
I am trying to build a script that posts information into the RoyalMail tracking system and extracts the output.
What I currently have is getting an error from their server - see the link, somehow it is detecting that I am not using their website as per normal and throwing me an error.
Things I think I have taken into account:
Using an exact copy of their form by parsing it beforehand (the post parameters)
Saving the cookies between each request
Accepting redirect headers
Providing a refer header that is actually valid (the previously visited page)
Does anyone know anything else I need to check or can figure out what I am doing wrong?
A full copy of the source is at EDIT: please see my answer below
Websites usually use 2 ways to detect if you are a human or a bot: HTTP REFERER and USER AGENT. I suggest you use Curl it specified user agent and referer (replace 'http://something/' with real URL of a page you would normally visit before navigating to the url you want to download with PHP):
<?php
$url = 'http://track2.royalmail.com/portal/rm/track';
$html = file_get_contents2($url, '');
$post['_dyncharset'] = 'ISO-8859-1';
$post['trackConsigniaPage'] = 'track';
$post['/rmg/track/RMTrackFormHandler.value.searchCompleteUrl'] = '/portal/rm/trackresults?catId=22700601&pageId=trt_rmresultspage';
$post['_D:/rmg/track/RMTrackFormHandler.value.searchCompleteUrl'] = '';
$post['/rmg/track/RMTrackFormHandler.value.invalidInputUrl'] = '/portal/rm/trackresults?catId=22700601&pageId=trt_rmresultspage&keyname=track_blank';
$post['_D:/rmg/track/RMTrackFormHandler.value.invalidInputUrl'] = '';
$post['/rmg/track/RMTrackFormHandler.value.searchBusyUrl'] = '/portal/rm/trackresults?catId=22700601&pageId=trt_busypage&keyname=3E_track';
$post['_D:/rmg/track/RMTrackFormHandler.value.searchBusyUrl'] = '';
$post['/rmg/track/RMTrackFormHandler.value.searchWaitUrl'] = '/portal/rm/trackresults?catId=22700601&timeout=true&pageId=trt_timeoutpage&keyname=3E_track';
$post['_D:/rmg/track/RMTrackFormHandler.value.searchWaitUrl'] = '';
$post['/rmg/track/RMTrackFormHandler.value.keyname'] = '3E_track';
$post['_D:/rmg/track/RMTrackFormHandler.value.keyname'] = '';
$post['/rmg/track/RMTrackFormHandler.value.previousTrackingNumber'] = '';
$post['_D:/rmg/track/RMTrackFormHandler.value.previousTrackingNumber'] = '';
$post['/rmg/track/RMTrackFormHandler.value.trackingNumber'] = 'ZW791944749GB';
$post['_D:/rmg/track/RMTrackFormHandler.value.trackingNumber'] = '';
$post['/rmg/track/RMTrackFormHandler.track.x'] = '50';
$post['/rmg/track/RMTrackFormHandler.track.y'] = '14';
$post['_D:/rmg/track/RMTrackFormHandler.track'] = '';
$post['/rmg/track/RMTrackFormHandler.value.day'] = '19';
$post['_D:/rmg/track/RMTrackFormHandler.value.day'] = '';
$post['/rmg/track/RMTrackFormHandler.value.month'] = '5';
$post['_D:/rmg/track/RMTrackFormHandler.value.month'] = '';
$post['/rmg/track/RMTrackFormHandler.value.year'] = '2012';
$post['_D:/rmg/track/RMTrackFormHandler.value.year'] = '';
$post['_DARGS'] = '/portal/rmgroup/apps/templates/html/rm/rmTrackResultPage.jsp';
$url2 = 'http://track2.royalmail.com/portal/rm?_DARGS=/portal/rmgroup/apps/templates/html/rm/rmTrackAndTraceForm.jsp';
$html2 = file_get_contents2($url2, $url, $post);
echo $html2;
function file_get_contents2($address, $referer, $post = false)
{
$useragent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1";
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $address);
curl_setopt($c, CURLOPT_USERAGENT, $useragent);
curl_setopt($c, CURLOPT_HEADER, 0);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
if ($post)
{
$postF = http_build_query($post);
curl_setopt($c, CURLOPT_POST, true);
curl_setopt($c, CURLOPT_POSTFIELDS, $postF);
}
curl_setopt($c, CURLOPT_COOKIEJAR, 'cookie.txt');
//curl_setopt($c, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($c, CURLOPT_REFERER, $referer);
curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
if (!$data = curl_exec($c))
{
return false;
}
return $data;
}
The above updated code returned me:
Item ZW791944749GB was posted at 1 High Street RG17 9TJ on 19/05/12 and is being progressed through our network for delivery.
So it seems it works.
I have now fixed it, the problem was with PHP curl and following redirects, it seems that it doesn't always post the request data and sends a GET request when following.
To deal with this I disabled curl follow location with curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); and then built a follow location system myself that works recursively. Essentially it extracts the location header from the response, checks for a 301 or a 302 and then runs the method again as required.
This means the information will definitely be POSTED again.
I also improved the user agent string, simply copying my current one on the basis it won't be blocked for a long while as in 2012 it is in active use!
Here is a final copy of the curl class (in case the link dies - been down voted for that in the past) which is working:
/**
* Make a curl request respecting redirects
* Also supports posts
*/
class pegCurlRequest {
private $url, $postFields = array(), $referer = NULL, $timeout = 3;
private $debug = false, $postString = "";
private $curlInfo = array();
private $content = "";
private $response_meta_info = array();
static $cookie;
function __construct($url, $postFields = array(), $referer = NULL, $timeout = 3) {
$this->setUrl($url);
$this->setPost($postFields);
$this->setReferer($referer);
$this->setTimeout($timeout);
if(empty(self::$cookie)) self::$cookie = tempnam("/tmp", "pegCurlRequest"); //one time cookie
}
function setUrl($url) {
$this->url = $url;
}
function setTimeout($timeout) {
$this->timeout = $timeout;
}
function setPost($postFields) {
if(is_array($postFields)) {
$this->postFields = $postFields;
}
$this->updatePostString();
}
function updatePostString() {
//Cope with posting
$this->postString = "";
if(!empty($this->postFields)) {
foreach($this->postFields as $key=>$value) { $this->postString .= $key.'='.$value.'&'; }
$this->postString= rtrim($this->postString,'&'); //Trim off the waste
}
}
function setReferer($referer) {
//Set a referee either specified or based on the url
$this->referer = $referer;
}
function debugInfo() {
//Debug
if($this->debug) {
echo "<table><tr><td colspan='2'><b><u>Pre Curl Request</b><u></td></tr>";
echo "<tr><td><b>URL: </b></td><td>{$this->url}</td></tr>";
if(!empty(self::$cookie)) echo "<tr><td><b>Cookie String: </b></td><td>".self::$cookie."</td></tr>";
if(!empty($this->referer)) echo "<tr><td><b>Referer: </b></td><td>".$this->referer."</td></tr>";
if(!empty($this->postString)) echo "<tr><td><b>Post String: </b></td><td>".$this->postString."</td></tr>";
if(!empty($this->postFields)) {
echo "<tr><td><b>Post Values:</b></td><td><table>";
foreach($this->postFields as $key=>$value)
echo "<tr><td>$key</td><td>$value</td></tr>";
echo "</table>";
}
echo "</td></tr></table><br />\n";
}
}
function debugFurtherInfo() {
//Debug
if($this->debug) {
echo "<table><tr><td colspan='2'><b><u>Post Curl Request</b><u></td></tr>";
echo "<tr><td><b>URL: </b></td><td>{$this->url}</td></tr>";
if(!empty($this->referer)) echo "<tr><td><b>Referer: </b></td><td>".$this->referer."</td></tr>";
if(!empty($this->curlInfo)) {
echo "<tr><td><b>Curl Info:</b></td><td><table>";
foreach($this->curlInfo as $key=>$value)
echo "<tr><td>$key</td><td>$value</td></tr>";
echo "</table>";
}
echo "</td></tr></table><br />\n";
}
}
/**
* Make the actual request
*/
function makeRequest($url=NULL) {
//Shorthand request
if(!is_null($url))
$this->setUrl($url);
//Output debug info
$this->debugInfo();
//Using a shared cookie
$cookie = self::$cookie;
//Setting up the starting information
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 Safari/536.11" );
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_ENCODING, "gzip");
//register a callback function which will process the headers
//this assumes your code is into a class method, and uses $this->readHeader as the callback //function
curl_setopt($ch, CURLOPT_HEADERFUNCTION, array(&$this,'readHeader'));
//Some servers (like Lighttpd) will not process the curl request without this header and will return error code 417 instead.
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Expect:"));
//Referer
if(empty($this->referer)) {
curl_setopt($ch, CURLOPT_REFERER, dirname($this->url));
} else {
curl_setopt($ch, CURLOPT_REFERER, $this->referer);
}
//Posts
if(!empty($this->postFields)) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->postString);
}
//Redirects, transfers and timeouts
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, false);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout);
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
//Debug
if($this->debug) {
curl_setopt($ch, CURLOPT_VERBOSE, true); // logging stuffs
curl_setopt($ch, CURLINFO_HEADER_OUT, true); // enable tracking
}
//Get the content and the header info
$content = curl_exec($ch);
$response = curl_getinfo($ch);
//get the default response headers
$headers = curl_getinfo($ch);
//add the headers from the custom headers callback function
$this->response_meta_info = array_merge($headers, $this->response_meta_info);
curl_close($ch); //be nice
//Curl info
$this->curlInfo = $response;
//Output debug info
$this->debugFurtherInfo();
//Are we being redirected?
if ($response['http_code'] == 301 || $response['http_code'] == 302) {
$location = $this->getHeaderLocation();
if(!empty($location)) { //the location exists
$this->setReferer($this->getTrueUrl()); //update referer
return $this->makeRequest($location); //recurse to location
}
}
//Is there a javascript redirect on the page?
elseif (preg_match("/window\.location\.replace\('(.*)'\)/i", $content, $value) ||
preg_match("/window\.location\=\"(.*)\"/i", $content, $value)) {
$this->setReferer($this->getTrueUrl()); //update referer
return $this->makeRequest($value[1]); //recursion
} else {
$this->content = $content; //set the content - final page
}
}
/**
* Get the url after any redirection
*/
function getTrueUrl() {
return $this->curlInfo['url'];
}
function __toString() {
return $this->content;
}
/**
* CURL callback function for reading and processing headers
* Override this for your needs
*
* #param object $ch
* #param string $header
* #return integer
*/
private function readHeader($ch, $header) {
//This is run for every header, use ifs to grab and add
$location = $this->extractCustomHeader('Location: ', '\n', $header);
if ($location) {
$this->response_meta_info['location'] = trim($location);
}
return strlen($header);
}
private function extractCustomHeader($start,$end,$header) {
$pattern = '/'. $start .'(.*?)'. $end .'/';
if (preg_match($pattern, $header, $result)) {
return $result[1];
} else {
return false;
}
}
function getHeaders() {
return $this->response_meta_info;
}
function getHeaderLocation() {
return $this->response_meta_info['location'];
}
}
Well first of all, you are talking about the Royal Mail. So I'm not sure if this simple little trick would trip them up...
But what you could try is spoofing your user agent with a quick ini_set() -
ini_set('user_agent', 'Mozilla/5.0 (X11; CrOS i686 1660.57.0) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.46 Safari/535.19'
That's an Ubuntu chrome user agent string.
The cURL user agent string would look quite different. For example:
curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
It's a long shot - but they might be rejecting requests that are not originating from recognized browsers.