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;

$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']}' ";

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:

$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}')";
//code above is for debugging - but not triggered however payment is received
if ($scrtt== my_super_secret_code) {
if ($_GET['confirmations'] >= 2) {

$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})";

//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?



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.

  • 1
    I 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? Mar 9, 2017 at 18:21
  • $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
    Mar 9, 2017 at 18:48

1 Answer 1



It started to work, after removing .htaccess file from /public_html on my webpage.. so simple solution..

i think it can be done with some reconfiguration too, but i am not using .htaccess, so it was the simpliest solution for me :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.