问题
I'm trying to post data to a payment gateway API. It required post data in xml format. I have the following code:
<?php
$requestUrl = 'https://api.given.bypg'; //$block->getPaymentUrl();
$amount = 100; // $block->totalOrderAmount()*100;
$approveUrl = $block->approveUrl();
$cancelUrl = $block->cancelUrl();
$declineUrl = $block->declineUrl();
$merchant = 'mydomain.com';
//$amount = '100'; // in cents. 1$ = 100cents.
$currency = '840'; // for dollar
$description = 'Happy customers is what we make.';
$merchantId = 'Nobel106513';
?>
<?php
echo $requestUrl;
$xml_data = '<TKKPG>
<Request>
<Operation>CreateOrder</Operation>
<Language>EN</Language>
<Order>
<OrderType>Purchase</OrderType>
<Merchant>'.$merchantId.'</Merchant>
<Amount>'.$amount.'</Amount>
<Currency>'.$currency.'</Currency>
<Description>'.$description.'</Description>
<ApproveURL>'.$approveUrl.'</ApproveURL>
<CancelURL>'.$cancelUrl.'</CancelURL>
<DeclineURL>'.$declineUrl.'</DeclineURL>
</Order>
</Request>
</TKKPG>';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $requestUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 60000);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);//My post data
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAPATH, "/etc/apache2/ssl/m4/mydomain.com.crt");
curl_setopt($ch, CURLOPT_CAINFO, "/etc/apache2/ssl/m4/mydomain.com.crt");
curl_setopt($ch, CURLOPT_CERTINFO, 1);
$headers = [];
array_push($headers, 'Content-Type: text/xml;charset=UTF-8');
//array_push($headers, 'SoapAction: *');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$content = trim(curl_exec($ch));
var_dump($content);
var_dump(curl_getinfo($ch));
var_dump(curl_errno($ch));
var_dump(curl_error($ch));
curl_close($ch);
- Output of
var_dump($content);
is empty''
. Output of
var_dump(curl_getinfo($ch));
.array (size=26)
'url' => string 'https://api.given.bypg'
'content_type' => null
'http_code' => int 0
'header_size' => int 0
'request_size' => int 0
'filetime' => int -1
'ssl_verify_result' => int 1
'redirect_count' => int 0
'total_time' => float 0.488533
'namelookup_time' => float 0.028558
'connect_time' => float 0.256858
'pretransfer_time' => float 0
'size_upload' => float 0
'size_download' => float 0
'speed_download' => float 0
'speed_upload' => float 0
'download_content_length' => float -1
'upload_content_length' => float -1
'starttransfer_time' => float 0
'redirect_time' => float 0
'redirect_url' => string '' (length=0)
'primary_ip' => string '91.227.244.57' (length=13)
'certinfo' =>
array (size=0)
empty
'primary_port' => int 8444
'local_ip' => string '192.168.100.64' (length=14)
'local_port' => int 53456Ouput of
var_dump(curl_errno($ch));
:int 60
Output of
var_dump(curl_error($ch));
:string 'SSL certificate problem: unable to get local issuer certificate' (length=63) It seems like the API is returning no data as seen on curl_getinfo(). Please help me, I have seen almost every solution suggested in communities.
I have edited my php.ini
file to give the path to the certificate downloaded from curl website. But this did not work as well.
回答1:
When you connect to the server to establish secure connection you as a client get server's certificate in the beginning of the conversation with it. This certificate and its private key are used to establish the secure connection. You client wants to ensure that the server's certificate is trusted and is not created by some man-in-the middle attacker. So your client need to have the CA certificate that signed the server certificate. The error above means that the client tried to find server's certificate issuer (or one of the issuers in the chain) and didn't find. The place it tries to find it is in the specified /etc/apache2/ssl/m4/mydomain.com.crt
file. You have two options: either add CA certificate to the file or to disable server certificate verification (not secure) by setting CURLOPT_SSL_VERIFYPEER
to false.
回答2:
I got support from my API providers who pointed something missing in my approach. For their gateway I needed to load the private key, public key and password that protects these keys in curl request. The solution is as follows:
/*ssl crts*/
$twpg_cert_file = "/etc/apache2/ssl/m4/mydomain.com.crt";
$twpg_key_file = "/etc/apache2/ssl/m4/mydomain.com.key";
$twpg_key_password = '';
/*ssl crts*/
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $requestUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 60000);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);//My post data
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSLCERT, $twpg_cert_file);
curl_setopt($ch, CURLOPT_SSLKEY, $twpg_key_file);
curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $twpg_key_password);
curl_setopt($ch, CURLOPT_CERTINFO, 1);
$headers = [];
array_push($headers, 'Content-Type: text/xml;charset=UTF-8');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$content = trim(curl_exec($ch));
curl_close($ch);
Now every thing works as expected.
来源:https://stackoverflow.com/questions/48202627/ssl-certificate-issue-unable-to-get-local-issuer-certificate