3
I am trying to create automated receive Bitcoin payments via Blockchain API. I have my API key, xpub, everything. I'm using PHP.
Here is the part of my code for generating wallet address:
$scrt = my_super_secret_code_60_chars_long;
$my_callback_url = "http://mysite.com/lib/payment.php?secret={$scrt}";
$my_xpub = "my_xpub_key";
$my_api_key = "my_secret_api_key";
$root_url = "https://api.blockchain.info/v2/receive";
$parameters = "xpub=" .$my_xpub. "&callback=" .urlencode($my_callback_url). "&key=" .$my_api_key;
$qry= "SELECT ID,RECEIVE_ADDR FROM MY_TABLE WHERE WALLET = '{$_GET['wallet']}' ";
$result = mysqli_query($conn,$qry);
$row = mysqli_fetch_row($result);
$reci = $row[1];
$uid = $row[0];
if ($reci=='none') {
//if the user does not have generated receive address, triggering this
$response = file_get_contents($root_url . '?' . $parameters);
$object = json_decode($response);
echo 'Send Payment To : ' . $object->address;
$qry= "UPDATE MY_TABLE SET RECEIVE_ADDR='". $object->address ."' WHERE WALLET = '{$_GET['wallet']}' ";
mysqli_query($conn,$qry);
}
This code works, but I have a problem with the callback to payment.php.
It's not triggering when the payment is received, however manually, I can simulate the received payment by calling PHP with correct parameters.
Here is the relevant part of payment.php:
<?php
$scrtt = $_GET['secret']; //password is passed back to the callback URL
$transaction_hash = $_GET['transaction_hash'];
$value_in_satoshi = $_GET['value'];
$value_in_btc = $value_in_satoshi / 100000000;
$gt='CALLBACK CALLED - TXID:'.$transaction_hash.' VALUE '.$value_in_satoshi.' SCRT:'.$scrtt.' CONFIRMS:'.$_GET['confirmations'];
$qry= "INSERT INTO DEBUG (TE) VALUES ('{$gt}')";
mysqli_query($conn,$qry);
//code above is for debugging - but not triggered however payment is received
if ($scrtt== my_super_secret_code) {
if ($_GET['confirmations'] >= 2) {
$confirms=$_GET['confirmations'];
$qry= "SELECT ID FROM MY_TABLE WHERE RECEIVE_ADDR = '{$_GET['address']}'";
$result = mysqli_query($conn,$qry);
$row = mysqli_fetch_row($result);
$uid = $row[0];
$qry= "SELECT TXHASH FROM PAYMENTS WHERE TXHASH = '{$_GET['transaction_hash']}' ";
$result = mysqli_query($conn,$qry);
$row = mysqli_fetch_row($result);
$tx = $row[0];
if ($tx <> $transaction_hash) {
$qry="INSERT INTO PAYMENTS (TXHASH,USER_ID,SATS,CONFIRMS) VALUES ('{$transaction_hash}',{$uid},{$value_in_satoshi},{$confirms})";
mysqli_query($conn,$qry);
//new tx - insert
}
//Insert into confirmed payments
}
}
echo '*ok*';
?>
My problem is, the callback is never called— can anyone check my code and tell me where I the problem is?
thanks
UPDATE:
I investigated a little and here is my result (however it's still not working)
I found the url to check a callback log directly on the blockchain: https://api.blockchain.info/v2/receive/callback_log?callback=http-urlencoded_my_website/callback.php?parameters&key=my-api-key
The log shows me something like that:
callback":"http://mysite.com/callback.php?param=myparam","called_at":"2017-03-10T13:05:39Z","response_code":403,"raw_response":"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>403 Forbidden</title>\n</head><body>\n<h1>Forbidden</h1>\n<p>You don't have permission to access /callback.php\non this server.<br />\n</p>\n<p>Additionally, a 403 Forbidden\nerror was encountered while trying to use an ErrorDocument to handle the request.</p>\n</body></html>\n"}]
Can someone help me with that? I am an owner of this domain and I can access this page with all of my browsers.
1I would just like to point out that your code is vulnerable to SQL injection. Are you definitely sure that the code inside
if ($reci=='none') {actually gets executed? – Adam Lindsay – 2017-03-09T18:21:59.740$reci is a variable that is assigned from user's actual receive address from mysql database.. and the default value for that field is 'none' .. I tested it many times and yes, it works.. this if clause is avoiding double generate BTC address for single user – Fero – 2017-03-09T18:48:38.530