';
printf( __( 'Payment of %s BTC will be due.', 'abf' ), $response_btc );
echo '
';
} catch ( \Exception $e ) {
echo '
';
echo '
';
echo '
';
_e(
'Unable to provide an order value in BTC at this time.',
'abf'
);
echo '
';
echo '
';
echo '
';
}
}
/**
* Initialise Gateway Settings Form Fields
*/
function abf_init_form_fields()
{
$this->form_fields = array(
'enabled' => array(
'title' => __('On/off', 'woocommerce'),
'type' => 'checkbox',
'label' => __('On', 'woocommerce'),
'default' => 'no'
),
'address' => array(
'title' => __('Destination Bitcoin address', 'woocommerce'),
'type' => 'text',
'description' => __('Your Destination Bitcoin address', 'woocommerce'),
'default' => ''
),
'debug' => array(
'title' => __('Debug Mode', 'woocommerce'),
'type' => 'checkbox',
'label' => __('On', 'woocommerce'),
'description' => __('All callback responses, debugging messages, errors logs store in "wp-content/wc-logs" but as a best practice do not enable this unless you are having issues with the plugin.', 'woocommerce'),
'default' => 'no'
),
'order_states' => array(
'type' => 'order_states'
),
'count_confirmations' => array(
'title' => __('Minimum confirmations count', 'woocommerce'),
'type' => 'text',
'description' => __('Minimum confirmations count for accepting payment. Must be an integer.', 'woocommerce'),
'default' => '1'
),
'merchant' => array(
'title' => __('Merchant name', 'woocommerce'),
'type' => 'text',
'description' => __('Shows Merchant name in the payment order. If this field is blank then Site Title from General settings will be shown.', 'woocommerce'),
'default' => ''
),
);
}
/**
* Generate the dibs button link
*/
public function abf_convert_to_btc($currency, $value)
{
if ($currency == 'BTC') {
return $value;
} else { if ( $currency == 'BTC' || $currency == 'USD' || $currency == 'EUR' || $currency == 'GBP') {
$response_btc = wp_remote_get('https://apirone.com/api/v1/tobtc?currency=' . $currency . '&value=' . $value);
return round($response_btc['body'], 8);
} else {
$args = array(
'headers' => array(
'User-Agent' => 'Apirone Bitcoin Gateway',
'CB-VERSION' => '2017-08-07'
)
);
$response_coinbase = wp_remote_request('https://api.coinbase.com/v2/prices/BTC-'. $currency .'/buy', $args);
$response_coinbase = json_decode($response_coinbase['body'], true);
$response_coinbase = $response_coinbase['data']['amount'];
if (is_numeric($response_coinbase)) {
return round($value / $response_coinbase, 8);
} else {
return 0;
};
}
}
}
public function abf_getKey($order_id){
global $wpdb;
global $woocommerce;
$order = new WC_Order($order_id);
$query =
"SELECT *
FROM {$wpdb->prefix}woocommerce_apirone_secret";
$key = $wpdb->get_results($query);
return md5($key->mdkey . $order->order_key);
}
//checks that order has sale
public function abf_getSales($order_id, $address = NULL) {
global $wpdb;
if (is_null($address)) {
$query = $wpdb->prepare(
"SELECT *
FROM {$wpdb->prefix}woocommerce_apirone_sale
WHERE order_id = %d",
$order_id
);
} else {
$query = $wpdb->prepare(
"SELECT *
FROM {$wpdb->prefix}woocommerce_apirone_sale
WHERE order_id = %d AND address = %s",
$order_id,
$address
);
}
$sales = $wpdb->get_results($query);
return $sales;
}
public function abf_getTransactions($order_id){
global $wpdb;
$query = $wpdb->prepare(
"SELECT *
FROM {$wpdb->prefix}woocommerce_apirone_transactions
WHERE order_id = %d",
$order_id
);
$transactions = $wpdb->get_results($query);
return $transactions;
}
public function abf_addTransaction($order_id, $thash, $input_thash, $paid, $confirmations) {
global $wpdb;
$transactions_table = $wpdb->prefix . 'woocommerce_apirone_transactions';
$wpdb->delete($transactions_table, array(
'input_thash' => $input_thash
));
return $wpdb->insert($transactions_table, array(
'time' => current_time('mysql'),
'confirmations' => $confirmations,
'paid' => $paid,
'order_id' => $order_id,
'thash' => $thash,
'input_thash' => $input_thash
));
}
public function abf_addSale($order_id, $address) {
global $wpdb;
$sale_table = $wpdb->prefix . 'woocommerce_apirone_sale';
return $wpdb->insert($sale_table, array(
'time' => current_time('mysql'),
'order_id' => $order_id,
'address' => $address
));
}
public function abf_updateTransaction($where_input_thash, $where_paid, $confirmations, $thash = NULL, $where_order_id = NULL, $where_thash = 'empty') {
global $wpdb;
if (!is_null($thash)) {
$thash = esc_sql($thash);
}
if (!is_null($where_order_id)) {
$where_order_id = esc_sql($where_order_id);
}
$transactions_table = $wpdb->prefix . 'woocommerce_apirone_transactions';
$where_paid = esc_sql($where_paid);
$confirmations = esc_sql($confirmations);
$where_thash = esc_sql($where_thash);
$where_input_thash = esc_sql($where_input_thash);
if (is_null($thash) || is_null($where_order_id)) {
$update_query = array(
'time' => current_time('mysql'),
'confirmations' => $confirmations,
);
$where = array(
'paid' => $where_paid,
'thash' => $where_thash,
'input_thash' => $where_input_thash
);
} else{
$update_query = array(
'time' => current_time('mysql'),
'confirmations' => $confirmations
);
$where = array(
'input_thash' => $where_input_thash,
'thash' => $thash
);
}
return $wpdb->update($transactions_table, $update_query, $where);
}
public function abf_sale_exists($order_id, $input_address)
{
$sales = $this->abf_getSales($order_id, $input_address);
if ($sales[0]->address == $input_address) {return true;} else {return false;};
}
// function that checks what user complete full payment for order
public function abf_check_remains($order_id)
{
global $woocommerce;
$order = new WC_Order($order_id);
$total = $this->abf_convert_to_btc(get_option('woocommerce_currency'), $order->order_total);
$transactions = $this->abf_getTransactions($order_id);
$remains = 0;
$total_paid = 0;
$total_empty = 0;
foreach ($transactions as $transaction) {
if ($transaction->thash == "empty") $total_empty+=$transaction->paid;
$total_paid+=$transaction->paid;
}
$total_paid/=1E8;
$total_empty/=1E8;
$remains = $total - $total_paid;
$remains_wo_empty = $remains + $total_empty;
if ($remains_wo_empty > 0) {
return false;
} else {
return true;
};
}
public function abf_remains_to_pay($order_id)
{
global $woocommerce;
$order = new WC_Order($order_id);
$transactions = $this->abf_getTransactions($order_id);
$total_paid = 0;
foreach ($transactions as $transaction) {
$total_paid+=$transaction->paid;
}
$response_btc = $this->abf_convert_to_btc(get_option('woocommerce_currency'), $order->order_total);
$remains = $response_btc - $total_paid/1E8;
if($remains < 0) $remains = 0;
return $remains;
}
public function abf_check_data($apirone_order){
$abf_check_code = 100; //No value
if (!empty($apirone_order['value'])) {
$abf_check_code = 101; //No input address
if (!empty($apirone_order['input_address'])) {
$abf_check_code = 102; //No order_id
if (!empty($apirone_order['orderId'])) {
$abf_check_code = 103; //No secret
if (!empty($apirone_order['secret'])) {
$abf_check_code = 104; //No confirmations
if ($apirone_order['confirmations']>=0) {
$abf_check_code = 105; //No key
if (!empty($apirone_order['key'])) {
$abf_check_code = 106; //No input transaction hash
if (!empty($apirone_order['input_transaction_hash'])) {
$abf_check_code = 200; //No transaction hash
if (!empty($apirone_order['transaction_hash'])){
$abf_check_code = 201; //All data is ready
}
}
}
}
}
}
}
}
return $abf_check_code;
}
public function abf_transaction_exists($thash, $order_id){
$transactions = $this->abf_getTransactions($order_id);
$flag = false;
foreach ($transactions as $transaction) {
if($thash == $transaction->thash){
$flag = true; // same transaction was in DB
break;
}
}
return $flag;
}
public function abf_input_transaction_exists($input_thash, $order_id){
$transactions = $this->abf_getTransactions($order_id);
$flag = false;
foreach ($transactions as $transaction) {
if($input_thash == $transaction->input_thash){
$flag = true; // same transaction was in DB
break;
}
}
return $flag;
}
public function secret_is_valid($secret, $order_id){
$flag = false;
if($secret == $this->abf_getKey($order_id)){
$flag = true;
}
return $flag;
}
public function key_is_valid($key, $order_id){
global $woocommerce;
$order = new WC_Order($order_id);
$flag = false;
if($key == $order->order_key){
$flag = true;
}
return $flag;
}
public function confirmations_is_ok($confirmations){
$flag = false;
if($confirmations >= ABF_COUNT_CONFIRMATIONS) {
$flag = true;
}
return $flag;
}
public function abf_validate_data($apirone_order){
$abf_check_code = 300; //No sale exists
if ($this->abf_sale_exists($apirone_order['orderId'], $apirone_order['input_address'])) {
$abf_check_code = 301; //key is invalid
if ($this->key_is_valid($apirone_order['key'], $apirone_order['orderId'])) {
$abf_check_code = 302; //Secret is invalid
if ($this->secret_is_valid($apirone_order['secret'], $apirone_order['orderId'])) {
$abf_check_code = 400; //validate complete
}
}
}
return $abf_check_code;
}
public function abf_empty_transaction_hash($apirone_order){
if ($this->abf_input_transaction_exists($apirone_order['input_transaction_hash'],$apirone_order['orderId'])) {
$this->abf_updateTransaction(
$apirone_order['input_transaction_hash'],
$apirone_order['value'],
$apirone_order['confirmations']
);
$abf_check_code = 500; //update existing transaction
} else {
$this->abf_addTransaction(
$apirone_order['orderId'],
'empty',
$apirone_order['input_transaction_hash'],
$apirone_order['value'],
$apirone_order['confirmations']
);
$abf_check_code = 501; //insert new transaction in DB without transaction hash
}
return $abf_check_code;
}
public function abf_calculate_payamount($apirone_order){
$transactions = $this->abf_getTransactions($apirone_order['orderId']);
$payamount = 0;
foreach ($transactions as $transaction) {
if($transaction->thash != 'empty')
$payamount += $transaction->paid;
}
return $payamount;
}
public function abf_skip_transaction($apirone_order){
$abf_check_code = NULL;
if(($apirone_order['confirmations'] >= ABF_MAX_CONFIRMATIONS) && (ABF_MAX_CONFIRMATIONS != 0)) {// if callback's confirmations count more than ABF_MAX_CONFIRMATIONS we answer *ok*
$abf_check_code="*ok*";
$this->abf_logger('[Info] Skipped transaction: ' . $apirone_order['transaction_hash'] . ' with confirmations: ' . $apirone_order['confirmations']);
};
return $abf_check_code;
}
public function abf_take_notes($apirone_order){
global $woocommerce;
$order = new WC_Order($apirone_order['orderId']);
$response_btc = $this->abf_convert_to_btc(get_option('woocommerce_currency'), $order->order_total);
$payamount = $this->abf_calculate_payamount($apirone_order);
$notes = 'Input Address: ' . $apirone_order['input_address'] . '; Transaction Hash: ' . $apirone_order['transaction_hash'] . '; Payment: ' . number_format($apirone_order['value']/1E8, 8, '.', '') . ' BTC; ';
$notes .= 'Total paid: '.number_format(($payamount)/1E8, 8, '.', '').' BTC; ';
if (($payamount)/1E8 < $response_btc)
$notes .= 'User trasfrer not enough money in your shop currency. Waiting for next payment; ';
if (($payamount)/1E8 > $response_btc)
$notes .= 'User trasfrer more money than You need in your shop currency; ';
$notes .= 'Order total: '.$response_btc . ' BTC; ';
if ($this->abf_check_remains($apirone_order['orderId'])){ //checking that payment is complete, if not enough money on payment it's not completed
$notes .= 'Successfully paid.';
}
return $notes;
}
public function abf_filled_transaction_hash($apirone_order){
global $woocommerce;
$order = new WC_Order($apirone_order['orderId']);
$order_states = get_option('woocommerce_apirone_settings');
$order_states = $order_states['order_states'];
if($this->abf_transaction_exists($apirone_order['transaction_hash'],$apirone_order['orderId'])){
$abf_check_code = 600;//update transaction
$this->abf_updateTransaction(
$apirone_order['input_transaction_hash'],
$apirone_order['value'],
$apirone_order['confirmations'],
$apirone_order['transaction_hash'],
$apirone_order['orderId']
);
} else {
$abf_check_code = 601; //small confirmations count for update tx
if ($this->confirmations_is_ok($apirone_order['confirmations'])) {
$this->abf_addTransaction(
$apirone_order['orderId'],
$apirone_order['transaction_hash'],
$apirone_order['input_transaction_hash'],
$apirone_order['value'],
$apirone_order['confirmations']
);
$notes = $this->abf_take_notes($apirone_order);
$order->add_order_note($notes);
$abf_check_code = '*ok*';//insert new TX with transaction_hash
if ($this->abf_check_remains($apirone_order['orderId'])){ //checking that payment is complete, if not enough money on payment is not completed
$complete_order_status = $order_states['complete'];
$order->update_status($complete_order_status, __('Payment complete', 'woocommerce'));
WC()->cart->empty_cart();
$order->payment_complete();
} else{
$partiallypaid_order_status = $order_states['partiallypaid'];
$order->update_status($partiallypaid_order_status, __('Partially paid', 'woocommerce'));
}
}
}
return $abf_check_code;
}
public function abf_generate_form($order_id)
{
global $woocommerce;
$order = new WC_Order($order_id);
if ($this->testmode == 'yes') {
$apirone_adr = $this->testurl;
} else {
$apirone_adr = $this->liveurl;
}
$_SESSION['testmode'] = $this->testmode;
if($this->get_option('merchant')){
$merchant = sanitize_text_field($this->get_option('merchant'));
} else {
$merchant = get_bloginfo('name');
}
$response_btc = $this->abf_convert_to_btc(get_option('woocommerce_currency'), $order->order_total);
if($this->enabled === 'no'){
return "Payment method disabled";
}
if ($this->abf_is_valid_for_use() && $response_btc > 0) {
/**
* Args for Forward query
*/
$sales = $this->abf_getSales($order_id);
if ($sales == null) {
$secret = $this->abf_getKey($order_id);
$order_states = get_option('woocommerce_apirone_settings');
$order_states = $order_states['order_states'];
$new_order_status = $order_states['new'];
$order->update_status($new_order_status, __('New order generated', 'woocommerce'));
$args = array(
'address' => $this->address,
'callback' => urlencode(ABF_SHOP_URL . '?wc-api=callback_apirone&key=' . $order->order_key . '&secret=' . $secret . '&order_id=' . $order_id)
);
$apirone_create = $apirone_adr . '?method=create&address=' . $args['address'] . '&callback=' . $args['callback'];
$response_create = wp_remote_get( $apirone_adr . '?method=create&address=' . $args['address'] . '&callback=' . $args['callback'] );
if(!is_null($response_create['body'])){
$response_create = json_decode($response_create['body'], true);
} else{
echo "No Input Address from Apirone :(";
}
if ($response_create['input_address'] != null){
$this->abf_addSale($order_id, $response_create['input_address']);
} else {
echo "No Input Address from Apirone :(";
}
} else {
$response_create['input_address'] = $sales[0]->address;
}
if ($response_create['input_address'] != null){
echo '
Please send ' . $response_btc . ' BTC
to address:
'. $response_create['input_address'] . '
Merchant:
' . $merchant . '
Amount to pay:
' . $response_btc . ' BTC
Arrived amount:
0.00000000 BTC
Remains to pay:
' . $response_btc . ' BTC
Date:
'.date('Y-m-d').'
Transaction(s):
No TX yet
Status:
Loading data
If you are unable to complete your payment, you can try again later to place a new order with saved cart. You can pay partially, but please do not close this window before next payment to prevent loss of bitcoin address and invoice number.