I'm trying to validate the callback send to my website in php.
Please I'm trying to use this api documentation https://support.cryptapi.io/article/how-to-verify-the-callback-signature to validate the callback send to my website but my code keep showing error to the api
I don't know whether it from my code
<?php
$pubkey =
"-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3FT0Ym8b3myVxhQW7ESuuu6lo\ndGAsUJs4fq+Ey//jm27jQ7HHHDmP1YJO7XE7Jf/0DTEJgcw4EZhJFVwsk6d3+4fy\nBsn0tKeyGMiaE6cVkX0cy6Y85o8zgc/CwZKc0uw6d5siAo++xl2zl+RGMXCELQVE\nox7pp208zTvown577wIDAQAB\n-----END PUBLIC KEY-----";
$signature = base64_decode($_SERVER['HTTP_X_CA_SIGNATURE']);
$algo = OPENSSL_ALGO_SHA256;
// if request is GET
$data = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
// if request is POST
$data = file_get_contents('php://input');
if (openssl_verify($data, $signature, $pubkey, $algo) == 1) {
require "cryptapi.php";
$url = $_GET['userdata'];
$postdata = CryptAPI\CryptAPI::process_callback($_GET);
$amount = $postdata['value_coin'];
$txid_in = $postdata['txid_in'];
$data = array(
'amount' => $amount,
'txid_in' => $txid_in
);
$payload = json_encode($data);
// Prepare new cURL resource
$ch = curl_init(urldecode($url));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
// Set HTTP Header for POST request
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($payload))
);
// Submit the POST request
$result = curl_exec($ch);
// Close cURL session handle
curl_close($ch);
echo "*ok*";
} else {
echo "error";
// signature NOT valid
}
?>
Ignore openssl_verify function first and use php curl function https://docs.cryptapi.io/#operation/logs That's what I did to achieve my expectation
CryptAPI\CryptAPI::process_callback($_GET) did not work for me, I used php curl provided at https://docs.cryptapi.io/#operation/logs
Firstly, ensure your callback URL can successfully execute action after payment if run manually eg https://example.com/verifypayment.php?order_id=908978675650&username=somebody&prod_id=200&amount=500&email=somebody@gmail.com&logticker=trc20_usdt Add any getter ($_GET) or setter ($_POST) you may need as paramaters but make sure there is a unique parameter which distinguishes the orders. In the above URL my unique parameter is order_id My codes go like this in the verifypayment.php
if(isset($_GET['order_id']) && isset($_GET['email']) && isset($_GET['amount']) && isset($_GET['logticker'])){
$id = intVal($_GET['order_id']);
$email = $_GET['email'];
$logticker = $_GET['logticker'];//ENSURE YOU USE THE APPROPRIATE TICKER https://cryptapi.io/cryptocurrencies/. SETTING TICKER AS PART OF YOUR PARAMETERS MAKES THE USAGE OF DIFFERENT COIN TICKERS DYNAMIC AND FLEXIBLE
$data = str_replace("@","%40",$data);//PLS ADD THIS LINE OF CODE IF EMAIL IS INCLUDED IN YOUR PARAMETERS TOO LIKE MINE CUZ CRYPTAPI SAVES @ IN ITS URLENCODE (%40)
$query = array(
"callback" => trim($data)
);
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cryptapi.io/" . $logticker . "/logs/?" .
http_build_query($query),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$error = curl_error($curl);
curl_close($curl);
if ($error) {
//echo "cURL Error #:" . $error; OR
error_log("cURL Error #:" . $error,0);
} else {
//echo $response;
$j = json_decode($response);
if(strcmp($j->status,"success")==0){//COMMAND EXECUTED SUCCESSFULLY IF APPROPRIATE URL IS CALLED
$callbacks = $j->callbacks;//ARRAY OF DEPOSITS MADE INTO THE ADDRESS_IN
if(is_array($callbacks)){
$trans = count($callbacks);//NUMBER OF DEPOSITS MADE INTO THE ADDRESS_IN
if($trans > 0){//IF ANY DEPOSIT IS MADE
$totalCoinDeposited = 0; $last_update = ''; $last_uuid = ''; $forwarded_amount = 0;
for($i = 0;$i < $trans;$i++){
$pending = intVal($callbacks[$i]->pending);
if($pending == 0){//IF DEPOSIT HAS BEEN CONFIRMED, IT S NO MORE PENDING
$value_coin = doubleVal($callbacks[$i]->value_coin);
$totalCoinDeposited += $value_coin;//GET THE SUM OF COIN SENT TO THE ADDRESS_IN
$last_update = $callbacks[$i]->last_update;
$last_uuid = $callbacks[$i]->uuid;
echo "TRANSACTION$i CONFIMRED<BR />";
}
if(strcmp($callbacks[$i]->result,"sent")==0){//IF DEPOSIT MADE HAS BEEN REMITTED INTO ADDRESS_OUT (YOUR OWN ADDRESS)
$forwarded_amount += doubleVal($callbacks[$i]->value_forwarded_coin);
}
}
if($totalCoinDeposited >= doubleVal($_GET['amount'])){//IF TOTAL COIN SENT TO THE ADDRESS_IN IS UP TO THE AMOUNT EXPECTED
//YOUR CODES HERE WHEN THE TRANSACTION IS CONFIRMED SUCCESSFUL
}
}
else{
//echo "No deposit yet";
//error_log("No deposit yet",0);
}
}
}
else{
//echo "Callback URL not found";
error_log("Callback URL not found",0);
}
}
}
I forgot to add. In my own case my server MOD_SECURITY did not allow their webhook to run the callback url from their end so I use CRON to auto run it. Ensure the callback url per order is stored in order table as well. There must be a column named order_confirmed or any name you can give it. Let your CRON loop the unconfirmed callback_urls via SQL query Eg "SELECT callback_url FROM order_table WHERE order_confirmed = 0"
//Before your SQL while loop
$urls = array();
//In your query while loop
while(...){
$urls[] = $callback_url; // WHERE $callback_url IS THE CALLBACK URL (VALUE) THAT COMES FROM THE COLUMN THAT STORES THE CALLBACK URL FOR AN ORDER
}
//After your query while loop
$curlMultiReq = curl_multi_init();
$ch = [];
foreach($urls as $key => $url){
$ch[$key] = curl_init($url);
curl_setopt($ch[$key], CURLOPT_HEADER, true); // we want headers
curl_setopt($ch[$key], CURLOPT_NOBODY, true); // we don't need body
curl_setopt($ch[$key], CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch[$key], CURLOPT_TIMEOUT,10);
curl_multi_add_handle($curlMultiReq, $ch[$key]);
}
$running = '';
do {
curl_multi_exec($curlMultiReq, $running);//THIS EXECUTES OR RUNS EACH CALLBACK URL AT THE BACKGROUND
curl_multi_select($curlMultiReq);
} while ($running > 0);
foreach(array_keys($ch) as $key){
//echo curl_getinfo($ch[$key], CURLINFO_HTTP_CODE);
//echo "\n";
curl_multi_remove_handle($curlMultiReq, $ch[$key]);
}
curl_multi_close($curlMultiReq);
ENSURE YOUR CALLBACK_URL UPDATE order_confirmed TO 1 IF THE TRANSACTION IS SUCCESSFUL SO THAT SUCCESSFUL TRANSACTIONS WONT BE LOOPED AGAIN
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.