Apple Pay for the web Startsession Handshake Error - php

I am currently trying to implement apple pay for the web which is quite the troublesome topic it seems. When I try to start a session according to the docs (https://developer.apple.com/documentation/apple_pay_on_the_web/apple_pay_js_api/requesting_an_apple_pay_payment_session) using Curl in PHP I receive a handshake error.
I don't know how to solve that. There is a very limited set of parameters available (link above) and nothing I tried so far worked.
My domain has TLS 1.3 and an overall ranking of A when I check via ssllabs.com
My call is currently looking like this
$url = 'https://apple-pay-gateway.apple.com/paymentservices/startSession';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(['merchantIdentifier' => '##my-merchant-id##', 'displayName' => 'something', 'initiative' => 'web', 'initiativeContext' => '##my-domain-name##']));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);

Related

PHP cURL returns FALSE on HTTPS

I'm trying to make a bot for: https://coinroll.it/api
From the site:
The Coinroll API is a stateless interface which works over HTTPS. Requests are made using POST variables (application/x-www-form-urlencoded) while responses are encoded in JSON (application/json). A HTTPS connection is required for accessing the API.
I have the following code:
$ch = curl_init();
$data = array('user' => 'xxx', 'password' => 'yyy');
curl_setopt($ch, CURLOPT_URL, 'https://coinroll.it');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
echo $result;
When I run this code, it returns a blank page, what am I doing wrong?
EDIT
I don't actually need to use cURl, if there is a better solution, please tell me.
You can prevent cURL from trying to verify the SSL certificate by using CURLOPT_VERIFYPEER.
Also set the action in the URL:
$ch = curl_init();
$data = array('user' => 'xxx', 'password' => 'yyy');
curl_setopt($ch, CURLOPT_URL, 'https://coinroll.it/getbalance');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
echo $result;
You can use the following cURL option in order to see what happens with the HTTP connection:
curl_setopt($ch, CURLOPT_VERBOSE, true);
When TRUE it outputs verbose information.
Today I had the case where "It had been working fine until now.", but it stopped working when the FQDN changed, and I had to self-sign another certificate, with a different DN.
After a few experiments, it turned out to be that the Subject Alternate Name (aka SAN) was not matching the certificate name, and the curl call had not been set with CURLOPT_SSL_VERIFYHOST, 2.
Conclusion: by default, CURLOPT_SSL_VERIFYHOST is set to 2, but, if your cert SAN is wrong, it will fail, unless you deactivate CURLOPT_SSL_VERIFYHOST, and, with it, CURLOPT_SSL_VERIFYPEER.
It is obviously the best practice to set both, and have a SAN that matches the subject.
Reminder: this is how to quickly check the SAN using OpenSSH on command line:
openssl x509 -in /etc/ssl/certs/recette.pharmags.fr.crt -noout -text | grep -A1 "Subject Alternative Name"

Differences in using PHP Curl vs command line curl

I am integrating the Badgeville REST API with my PHP 5.3, curl 7.22 application.
The API documentation for BV all uses command line curl calls for their examples. When I run these examples they work fine.
When I attempt to do the same thing with the PHP Curl class I always get a 500 error from the BV server.
I have tried to do the synonomous functionality with the Advanced Rest Client extension in Chrome.
PHP Curl Example:
$ch = curl_init('http://sandbox.v2.badgeville.com/api/berlin/[private_api_key]/users.json');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
if($this->getRequestType() == 'POST')
{
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS,
array(
'user[name]' => 'Generic+Username',
'user[email]' => 'johndoe%40domainname.com'
);
);
}
$response = curl_exec($ch);
Rest Client Example:
URL:
http://sandbox.v2.badgeville.com/api/berlin/[private_api_key]/users.json
POST
No Headers Payload:
user[name]=Generic+Username&user[email]=johndoe%40domainname.com
I have manually created the command line curl call and ran that with shell_exec(), but I would REALLY prefer not having to do that.
In my research I found a Drupal module and all the API calls are done through fsockopen() calls.
Is there some way to do successfully make Badgeville calls using the PHP Curl class?
As it turns out Badgeville has a 500 error when a curl request comes in that has headers set.
Error returning code:
$ch = curl_init('http://sandbox.v2.badgeville.com/api/berlin/[private_api_key]/users.json');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
if($this->getRequestType() == 'POST')
{
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS,
array(
'user[name]' => 'Generic+Username',
'user[email]' => 'johndoe%40domainname.com'
);
);
}
$response = curl_exec($ch);
Properly functioning code:
$ch = curl_init('http://sandbox.v2.badgeville.com/api/berlin/[private_api_key]/users.json');
//curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
if($this->getRequestType() == 'POST')
{
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS,
array(
'user[name]' => 'Generic+Username',
'user[email]' => 'johndoe%40domainname.com'
);
);
}
$response = curl_exec($ch);
SMH

REST API Implementation Sample Code

I know nothing about implementing an API. I do know PHP a bit. I have a situation where I need to call a REST API method to purge cache on a CDN server. Can somebody help me with some sample code?
The following is the sample request:
PUT <<url>>
Authorization: TOK:12345-12345
Accept: application/json
Content-Type: application/json
Host: api.edgecast.com
Content-Length: 87
{
"MediaPath":"<<urlhere>>"
"MediaType":"3"
}
Can somebody help me with code to implement this rest api request?
Thanks in advance.
I had to find the hard way too. This has been tested (with slight modifications from my original code)
//## GoGrid PHP REST API Call
define('TOKEN','XXXXX-XXXXX-XXXXX-XXXXXX'); // found on the cdn admin My Settings
define('ACCOUNT_NUMBER','XXXX'); // found on the cdn admin Top Right corner
function purgeCacheFileFromCDN($urlToPurge) {
//## Build the request
$request_params = (object) array('MediaPath' => $urlToPurge, 'MediaType' => 8); // MediaType 8=small 3=large
$data = json_encode($request_params);
//## setup the connection and call.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.edgecast.com/v2/mcc/customers/'.ACCOUNT_NUMBER.'/edge/purge');
curl_setopt($ch, CURLOPT_PORT , 443);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1); // For debugging
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1); // no caching
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1); // no caching
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: tok:'.TOKEN, 'Content-Type: application/json','Accept: application/json', 'Content-length: '.strlen($data)));
$head = curl_exec($ch);
$httpCode = curl_getinfo($ch);
curl_close($ch);
//## check if error
if ($httpCode['http_code'] != 200) {
echo 'Error reported: '.print_r(array($head,$httpCode),1); // output it to stdout this will be emailed to me via cron capture.
}
}
Was too lazy to write from the scratch so copied from amazingly pink site that Google advises in the first page of results.
$data = array("a" => $a);
$ch = curl_init($this->_serviceUrl . $id);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($data));
$response = curl_exec($ch);
if(!$response) {
return false;
}
PS: The source search request: http://www.google.ru/search?q=php+sample+put+request+curl
Here is my source gist for my fully implemented Grunt task for anyone else thinking about working with the EdgeCast API. You'll find in my example that I use a node module to execute the curl command which purges the CDN.
This was that I ended up with after spending hours trying to get an HTTP request to work within Node. I was able to get one working in Ruby and Python, but did not meet the requirements of this project.

getting results from a site using curl

I have been trying to post some variables to a site using POST method, using curl to get some results. I am posting to this link.
http://www.rasta.pk/Lhr/Lhr_Traffic.aspx
At this page you will see a drop down menu .. onchange some values are returned in "Yellow" colored table.
I have monitored this site and trying to get those results by making a post request to that link. But, I am getting "Bad Header" error. I have tried changing things but ubable to find a solution.
Here is my code:
"Canal Bank Rd",
"ScriptManager1 " => "UpdatePanelDDLRoads|DropDownRoads",
"__EVENTARGUMENT" => "",
"__EVENTTARGET" => "DropDownRoads"
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headerz);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_REFERER, "http://www.rasta.pk/Lhr/Lhr_Traffic.aspx");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
echo $output;
?>
There's too little details presented for us to know for sure.
A guess is that you're doing the wrong kind of post, since when you pass in a hash array to CURLOPT_POSTFIELDS it will do a multipart formpost which might not be what the server expects. Pass in a string instead to make a "normal" POST.
If that is not enough, use LiveHTTPHeaders or similar in a browser to figure out exactly what is sent in a "manual" session and then you make sure that your curl program mimics that operation as closely as possible.

Using CURL with Google

I want to CURL to Google to see how many results it returns for a certain search.
I've tried this:
$url = "http://www.google.com/search?q=".$strSearch."&hl=en&start=0&sa=N";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
$response = curl_exec($ch);
curl_close($ch);
But it just returns a 405 Method Allowed google error.
Any ideas?
Thanks
Use a GET request instead of a POST request. That is, get rid of
curl_setopt($ch, CURLOPT_POST, true);
Or even better, use their well defined search API instead of screen-scraping.
Scrapping Google is a very easy thing to do. However, if you don't require more than the first 30 results, then the search API is preferable (as others have suggested). Otherwise, here's some sample code. I've ripped this out of a couple of classes that I'm using so it might not be totally functional as is, but you should get the idea.
function queryToUrl($query, $start=null, $perPage=100, $country="US") {
return "http://www.google.com/search?" . $this->_helpers->url->buildQuery(array(
// Query
"q" => urlencode($query),
// Country (geolocation presumably)
"gl" => $country,
// Start offset
"start" => $start,
// Number of result to a page
"num" => $perPage
), true);
}
// Find first 100 result for "pizza" in Canada
$ch = curl_init(queryToUrl("pizza", 0, 100, "CA"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $this->getUserAgent(/*$proxyIp*/));
curl_setopt($ch, CURLOPT_MAXREDIRS, 4);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
Note: $this->_helpers->url->buildQuery() is identical to http_build_query except that it will drop empty parameters.
Use the Google Ajax API.
http://code.google.com/apis/ajaxsearch/
See this thread for how to get the number of results. While it refers to c# libraries, it might give you some pointers.
Before scrapping data please read https://support.google.com/websearch/answer/86640?rd=1
Against google terms
Automated traffic includes:
Sending searches from a robot, computer program, automated service, or search scraper
Using software that sends searches to Google to see how a website or webpage ranks on Google
CURLOPT_CUSTOMREQUEST => ($post)? "POST" : "GET"

Categories