Advertisement
Guest User

Untitled

a guest
Jan 13th, 2016
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.32 KB | None | 0 0
  1. <?php
  2. public function callback()
  3.     {
  4.         Log::info('=== CALLBACK. ' . 'User id: '.Input::get('userid').', tx hash: '.Input::get('txid'));
  5.  
  6.         /* the url structure is different, so different segments of URI */
  7.         if ( Input::get( 'cryptotype' ) ) {
  8.             $this->crypto_type_id = Input::get( 'cryptotype' );
  9.         }
  10.  
  11.         $server_callback_secret = Config::get( 'bitcoin.callback_secret' );
  12.  
  13.         if ( $server_callback_secret != Input::get( 'secret' )) {
  14.             Log::error( '#callback: ' . SECRET_MISMATCH . ', full URL:  ' . Request::fullUrl() );
  15.             return Response::json( ['#callback: ' . SECRET_MISMATCH] );
  16.         }
  17.         /*--------------------------------------------*/
  18.  
  19.         /*sends callback on receive notification
  20.         gets a transaction hash id
  21.         calls bitcoind via RPC to get transaction info
  22.         calls a web url specified in the user account
  23.         called from /home/api/walletnotify.sh
  24.         sudo curl http://127.0.0.1/api/callback/?txid=a6eb6a8c2a66dbdfeb87faf820492222a80c2db3422706bdc1eb3bff0dbe8ab1&local=n00nez&loginname=ammm&password=PsQWsO4sDLwqTxxx&debug=1*/
  25.  
  26.         $tx_id = Input::get( 'txid' ); // check if not null
  27.         if ( ! $tx_id ) {
  28.             Log::error( "#callback, no tx id: " . NO_TX_ID );
  29.             return Response::json( ['error' => NO_TX_ID] );
  30.         }
  31.  
  32.         $user_id = Input::get('userid');
  33.         if ( ! $user_id ) {
  34.             // TODO daaaaamn
  35.             // return here with error
  36.         }
  37.         $this->user = User::find($user_id);
  38.  
  39.         // TODO if user is not set here. decide how to set user
  40.         $this->bitcoin_core->setRpcConnection($this->user->rpc_connection);
  41.  
  42.         try {
  43.             $tx_info = $this->bitcoin_core->gettransaction( $tx_id );
  44.         } catch ( Exception $e ) {
  45.             Log::error( '#callback: get transaction exception: ' . $e->getMessage() );
  46.             return Response::json( ['error' => '#callback: get transaction exception: ' . $e->getMessage()] );
  47.         }
  48.  
  49.         $confirms      = $tx_info['confirmations'];
  50.         $block_hash    = isset( $tx_info['blockhash'] ) ? $tx_info['blockhash'] : null;
  51.         $block_index   = isset( $tx_info['blockindex'] ) ? $tx_info['blockindex'] : null;
  52.         $block_time    = isset( $tx_info['blocktime'] ) ? $tx_info['blocktime'] : null;
  53.         $time          = $tx_info['time'];
  54.         $time_received = $tx_info['timereceived'];
  55.         $fee           = isset($tx_info['fee']) ? abs( bcmul($tx_info['fee'], SATOSHIS_FRACTION)) : null;
  56.  
  57.         $transaction_details = $tx_info["details"];
  58.  
  59.         /* Get input addresses */
  60.         $addresses = array();
  61.         $raw_tx = $this->bitcoin_core->getrawtransaction( $tx_id, 1 );
  62.  
  63.         foreach($raw_tx['vin'] as $i) {
  64.             $i_raw_tx = $this->bitcoin_core->getrawtransaction( $i['txid'], 1 );
  65.             $addresses[] = $i_raw_tx['vout'][$i['vout']]['scriptPubKey']['addresses'][0];
  66.         }
  67.  
  68.         foreach ($transaction_details as $tx)
  69.         {
  70.             $to_address    = $tx['address']; // address where transaction was sent to. from address may be multiple inputs which means many addresses
  71.             $account_name  = $tx['account'];
  72.             $address_from  = $addresses[0];
  73.             $category      = $tx['category'];
  74.             $btc_amount    = $tx["amount"];
  75.  
  76.             if ( ( Input::get( 'debug' ) or API_DEBUG == true ) ) {
  77.                 $this->print_debug( $tx_id, $tx_info, $block_hash, $block_index, $block_time, $account_name, $to_address, $category, $btc_amount );
  78.             }
  79.  
  80.             /******************* START of checking if its outgoing transaction *******************/
  81.             if ( $btc_amount < 0 )
  82.             {
  83.                 $this->processOutgoingTransaction( $user_id, $btc_amount, $to_address, $tx_id, $confirms );
  84.                 continue; // loop more in case there is something
  85.             }
  86.             /******************* END of checking if its outgoing transaction *******************/
  87.  
  88.             Log::info( "Address $to_address, amount (BTC): $btc_amount, confirms: $confirms received transaction id $tx_id" );
  89.  
  90.             /* whether new transaction or notify was fired on 1st confirmation */
  91.             $transaction_model = Transaction::getTransactionByTxIdAndAddress( $tx_id, $to_address );
  92.             $satoshi_amount    = bcmul( $btc_amount, SATOSHIS_FRACTION );
  93.             $is_own_address = false; // if not own address, then unknown address received transaction
  94.  
  95.             /* create common data for transaction */
  96.             $common_data = [
  97.                 'tx_id'             => $tx_id,
  98.                 'user_id'           => $this->user->id,
  99.                 'crypto_amount'     => $satoshi_amount,
  100.                 'network_fee'       => $fee,
  101.                 'crypto_type_id'    => $this->crypto_type_id,
  102.                 'address_to'        => $to_address,
  103.                 'address_from'      => $address_from,
  104.                 'confirmations'     => $confirms,
  105.                 'block_hash'        => $block_hash,
  106.                 'block_index'       => $block_index,
  107.                 'block_time'        => $block_time,
  108.                 'tx_time'           => $time,
  109.                 'tx_timereceived'   => $time_received,
  110.                 'tx_category'       => $category,
  111.                 'address_account'   => $account_name,
  112.             ];
  113.  
  114.             /******************* START processing the invoicing callback **************/
  115.             $invoice_address_model = InvoiceAddress::getAddress( $to_address );
  116.             if ( $invoice_address_model ) {
  117.                 $is_own_address = true;
  118.                 $this->processInvoiceAddress($transaction_model, $invoice_address_model, $common_data, $satoshi_amount);
  119.                 continue; // continue into the next loop
  120.             }
  121.             /*************** END processing the invoicing callback **************/
  122.  
  123.             /*************************************************************************************/
  124.             /* at this point its not the invoicing address, lookup address in address table
  125.             /*************************************************************************************/
  126.  
  127.             /************* It is incoming transaction, because it is sent to some of the inner addresses *************/
  128.             $address_model = Address::getAddress( $to_address );
  129.             if ( $address_model )
  130.             {
  131.                 $is_own_address = true;
  132.                 $this->processUserAddress($transaction_model, $address_model, $common_data, $satoshi_amount);
  133.                 continue;
  134.             }
  135.  
  136.             /* The receiving address wasn't in the database, so its not tied to any API user, but generated outside API directly in bitcoin core*/
  137.             if ( !$is_own_address )
  138.             {
  139.                 /* This can be enabled when needed to save payment for unknown address received
  140.                  * but because we have change addresses that are used in 'sendmany', we don't want to bloat transactions table */
  141.                 //$this->processUnknownAddress( $confirms, $transaction_model, $common_data, $btc_amount, $to_address, $satoshi_amount );
  142.                 continue;
  143.             }
  144.         }
  145.  
  146.         return '*ok*'; // just dummy return, since it's not being processed on other end. the return is processed in fetchUrl()
  147.  
  148.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement