startSession(); // Load order $order = new WC_Order ($order_id); $txnid = $order->get_transaction_id(); if (! $txnid) { return; } $api = $this->api_login(); if ($api instanceof WP_Error) { $_SESSION['valitor_login_error'] = $api->get_error_message(); echo '

' . __('Could not connect to Valitor!', 'valitor') . '

'; return; } $payment = $api->getPayment($txnid); if (! $payment) { return; } $payments = $payment->getPayments(); $pay = $payments[0]; if ($pay->getCapturedAmount() == 0) { // Order wasn't captured and must be captured now $amount = $pay->getReservedAmount(); // Amount to capture $salesTax = $order->get_total_tax(); //TODO: add orderLines, if is set to parse them $orderLines = array(array()); $capture_result = $api->captureReservation($txnid, $amount, $orderLines, $salesTax); if(! $capture_result->wasSuccessful()) { $order->add_order_note (__('Capture failed: ' . $capture_result->getMerchantErrorMessage(), 'Valitor')); // log to history $this->save_capture_failed_message ('Capture failed for order ' . $order_id . ': ' . $capture_result->getMerchantErrorMessage()); return; } else { update_post_meta ($order_id, '_captured', true); $order->add_order_note (__('Order captured: amount: ' . $amount, 'Valitor')); } } else { $this->save_capture_warning ('This order was already fully or partially captured: ' . $order_id); } } function save_capture_warning ($newMessage) { if (isset($_SESSION ['valitor_capture_warning'])) { $message = $_SESSION ['valitor_capture_warning'] . "
"; } else { $message = ""; } $_SESSION ['valitor_capture_warning'] = $message . $newMessage; } function save_capture_failed_message ($newMessage) { if (isset($_SESSION ['valitor_capture_failed'])) { $message = $_SESSION ['valitor_capture_failed'] . "
"; } else { $message = ""; } $_SESSION ['valitor_capture_failed'] = $message . $newMessage; } function show_user_message ($field, $type, $message = '') { $this->startSession(); if (! isset($_SESSION [$field])) { return; } echo "

$message $_SESSION[$field]

"; unset($_SESSION [$field]); } function login_error () { $this->show_user_message('valitor_login_error', 'error', 'Could not login to the Merchant API: '); } function capture_failed () { $this->show_user_message('valitor_capture_failed', 'error'); } function capture_warning () { $this->show_user_message('valitor_capture_warning', 'update-nag'); } function startSession () { if (session_id() === '') { session_start(); } } public function add_action_links ( $links ) { $newlink = array( 'Settings', ); return array_merge( $links, $newlink ); } public function valitor_localization_init() { load_plugin_textdomain('valitor', false, dirname(plugin_basename(__FILE__)) . '/languages/'); } public function valitor_settings_menu() { add_submenu_page( 'woocommerce', 'Valitor Settings', 'Valitor Settings', 'manage_options', $this->plugin_options_key, array( $this, 'valitor_settings' ) ); } public function valitor_register_settings() { register_setting( 'valitor-settings-group', 'valitor_gateway_url' ); register_setting( 'valitor-settings-group', 'valitor_username' ); register_setting( 'valitor-settings-group', 'valitor_password' ); register_setting( 'valitor-settings-group', 'valitor_payment_page' ); register_setting( 'valitor-settings-group', 'valitor_terminals_enabled', 'json_encode' ); } public function valitor_settings() { $terminals = false; $disabledTerminals = array(); $gateway_url = esc_attr( get_option('valitor_gateway_url') ); $username = get_option('valitor_username'); $password = get_option('valitor_password'); $payment_page = esc_attr( get_option('valitor_payment_page') ); if(!empty(get_option('valitor_terminals'))) { $terminals = json_decode(get_option('valitor_terminals')); } $enabledTerminals = json_decode( get_option('valitor_terminals_enabled') ); $terminal_info = json_decode( get_option('valitor_terminals') ); foreach ($terminal_info as $term) { //The key is the terminal name if (!in_array($term->key, $enabledTerminals)) { array_push($disabledTerminals, $term->key); } } $pluginDir = plugin_dir_path( __FILE__ ); //Directory for the terminals $terminalDir = $pluginDir.'terminals/'; //Temp dir in case the one from above is not writable $tmpDir = sys_get_temp_dir(); foreach ($disabledTerminals as $disabledTerm) { $disabledTerminalFileName = $disabledTerm.'.class.php'; $path = $terminalDir.$disabledTerminalFileName; $tmpPath = $tmpDir.'/'.$disabledTerminalFileName; //Check if there is a terminal created so it can be removed if (file_exists($path)) { unlink($path); } elseif (file_exists($tmpPath)) { unlink($tmpPath); } } if (!$enabledTerminals || $enabledTerminals == 'null') { $enabledTerminals = array(); } if(array_key_exists('settings-updated', $_REQUEST) && $_REQUEST['settings-updated'] == true) { $this->refreshTerminals(); } ?>

ID == $payment_page) { $exists = true; $page_title = $page->post_title; $page_id = $page->ID; } } if ($exists) { ?> :

name; ?> key, $enabledTerminals)) { ?>checked="checked" />
valitor_refresh_connection_form(); } } ?>

refreshTerminals(); } } function refreshTerminals(){ $api = $this->api_login(); if ($api instanceof WP_Error) { $_SESSION['valitor_login_error'] = $api->get_error_message(); echo '

' . __('Could not connect to Valitor!', 'valitor') . '

'; //Delete terminals and enabled terminals from database update_option('valitor_terminals', array()); update_option('valitor_terminals_enabled', array()); ?> ' . __('Connection OK !', 'valitor') . '

'; // Get list of terminals information $terminal_info = $api->getTerminals(); $terminals = array(); $terms = $terminal_info->getTerminals(); foreach ($terms as $terminal) { $terminals[] = array( 'key' => str_replace(' ','_', $terminal->getTitle()), 'name' => $terminal->getTitle(), ); } update_option('valitor_terminals', json_encode($terminals)); ?> form_fields = array( 'enabled' => array( 'title' => __( 'Enable/Disable', 'woocommerce' ), 'type' => 'checkbox', 'label' => __( 'Enable Valitor', 'valitor' ), 'default' => 'yes' ), 'title' => array( 'title' => __( 'Title', 'woocommerce' ), 'type' => 'text', 'description' => __( 'Title to show during checkout.', 'valitor' ), 'default' => __( 'Valitor', 'woocommerce' ), 'desc_tip' => true, ), 'description' => array( 'title' => __( 'Message', 'woocommerce' ), 'description' => __( 'Message to show during checkout.', 'valitor' ), 'type' => 'textarea', 'default' => '', ), 'payment_action' => array( 'title' => __( 'Payment action', 'woocommerce' ), 'description' => __( 'Make payment authorized or authorized and captured', 'valitor' ), 'type' => 'select', 'options' => array( 'authorize' => __('Authorize Only', 'valitor'), 'authorize_capture' => __('Authorize and Capture', 'valitor'), ), 'default' => '', ), 'currency' => array( 'title' => __( 'Currency', 'valitor' ), 'type' => 'select', 'description' => __( 'Select the currency does this terminal work with' ), 'options' => get_woocommerce_currencies(), 'default' => $this->default_currency, ), ); } public function process_payment( $order_id ) { global $woocommerce; $order = new WC_Order( $order_id ); // Return goto payment url return array( 'result' => 'success', 'redirect' => $order->get_checkout_payment_url( true ), ); } public function api_login() { if ($this->api === false) { $this->api = new ValitorMerchantAPI(esc_attr(get_option('valitor_gateway_url')), esc_attr(get_option('valitor_username')), esc_attr(get_option('valitor_password')), null); try { $this->api->login(); } catch(Exception $e) { return new WP_Error('error', "Could not login to the Merchant API: " . $e->getMessage()); } } return $this->api; } public function is_available() { // Check if payment method is enabled if ( 'yes' !== $this->enabled ) { return false; } //Check on payment currency $active_currency = get_woocommerce_currency(); if ($active_currency != $this->currency) { return false; } return true; } public function scheduled_subscription_payment( $amount, $renewal_order ) { try { if( $amount == 0 ) { $renewal_order->payment_complete(); return; } $transaction_id = ''; if ( wcs_order_contains_renewal( $renewal_order->id ) ) { //$parent_order = wcs_get_subscriptions_for_renewal_order( $renewal_order->id ); $parent_order_id = WC_Subscriptions_Renewal_Order::get_parent_order_id( $renewal_order->id ); } $orderinfo = new WC_Order($parent_order_id); $transaction_id = $orderinfo->get_transaction_id(); if( !$transaction_id ) { // Set subscription payment as failure $renewal_order->update_status( 'failed', __( 'Valitor could not locate transaction ID', 'valitor' ) ); return false; } $api = $this->api_login(); if ($api instanceof WP_Error) { $_SESSION['valitor_login_error'] = $api->get_error_message(); echo '

' . __('Could not connect to Valitor!', 'valitor') . '

'; return; } $result = $api->chargeSubscription( $transaction_id, $amount ); if ($result->wasSuccessful()) { $renewal_order->payment_complete(); } else { $renewal_order->update_status( 'failed', sprintf( __( 'Valitor payment declined: %s', 'valitor' ), $result->getErrorMessage() ) ); } } catch (Exception $e) { $renewal_order->update_status( 'failed', sprintf( __( 'Valitor payment declined: %s', 'valitor' ), $e->getMessage() ) ); } } public function valitor_get_currency_code( $number ) { $codes = array( '004' => 'AFA','012' => 'DZD','020' => 'ADP','031' => 'AZM','032' => 'ARS','036' => 'AUD','044' => 'BSD','048' => 'BHD', '050' => 'BDT','051' => 'AMD','052' => 'BBD','060' => 'BMD','064' => 'BTN','068' => 'BOB','072' => 'BWP','084' => 'BZD', '096' => 'BND','100' => 'BGL','108' => 'BIF','124' => 'CAD','132' => 'CVE','152' => 'CLP','156' => 'CNY','170' => 'COP', '188' => 'CRC','191' => 'HRK','192' => 'CUP','196' => 'CYP','203' => 'CZK','208' => 'DKK','214' => 'DOP','218' => 'ECS', '230' => 'ETB','232' => 'ERN','233' => 'EEK','238' => 'FKP','242' => 'FJD','262' => 'DJF','270' => 'GMD','288' => 'GHC', '292' => 'GIP','320' => 'GTQ','324' => 'GNF','328' => 'GYD','340' => 'HNL','344' => 'HKD','532' => 'ANG','533' => 'AWG', '578' => 'NOK','624' => 'GWP','752' => 'SEK','756' => 'CHF','784' => 'AED','818' => 'EGP','826' => 'GBP','840' => 'USD', '973' => 'AOA','974' => 'BYR','975' => 'BGN','976' => 'CDF','977' => 'BAM','978' => 'EUR','981' => 'GEL','983' => 'ECV', '984' => 'BOV','986' => 'BRL','990' => 'CLF' ); return $codes[$number]; } } // Init valitor settings and gateway function init_valitor_settings() { // Make sure WooCommerce and WooCommerce gateway is enabled and loaded if (!class_exists( 'WC_Payment_Gateway' )) { return; } $settings = new Valitor_settings(); // Add Gateway to WooCommerce if enabled if ( json_decode( get_option('valitor_terminals_enabled') ) ) { add_filter( 'woocommerce_payment_gateways', 'valitor_add_gateway' ); } // Add gateways to WooCommerce. function valitor_add_gateway($methods) { $pluginDir = plugin_dir_path( __FILE__ ); //Directory for the terminals $terminalDir = $pluginDir.'terminals/'; //Temp dir in case the one from above is not writable $tmpDir = sys_get_temp_dir(); // Get enabled terminals $terminals = json_decode( get_option('valitor_terminals_enabled') ); if ($terminals) { foreach ($terminals as $terminal) { // Load Terminal information $terminal_info = json_decode( get_option('valitor_terminals') ); $terminal_name = $terminal; foreach ($terminal_info as $term) { if ($term->key == $terminal) { $terminal_name = $term->name; } } // Check if file exists $path = $terminalDir.$terminal.'.class.php'; $tmpPath = $tmpDir.'/'.$terminal.'.class.php'; if (file_exists($path)) { require_once ($path); $methods[$terminal] = 'WC_Gateway_'.$terminal; } elseif (file_exists($tmpPath)) { require_once ($tmpPath); $methods[$terminal] = 'WC_Gateway_'.$terminal; } else { // Create file $template = file_get_contents($pluginDir.'templates/payment_class.tpl'); $filename = $terminalDir.$terminal.'.class.php'; // Check if terminals folder is writable or use tmp as fallback if (!is_writable($terminalDir)) { $filename = $tmpDir.'/'.$terminal.'.class.php'; } // Replace patterns $content = str_replace(array('{key}','{name}'),array($terminal,$terminal_name), $template); file_put_contents($filename, $content); } } } return $methods; } /// Make sure payment page form loads payment template add_filter( 'template_include', 'valitor_page_template', 99 ); function valitor_page_template( $template ) { // Get payment form page id $payment_form_page_id = esc_attr( get_option('valitor_payment_page') ); if ( is_page( $payment_form_page_id ) && $payment_form_page_id !='') { // Make sure the template is only loaded from Valitor //if ($_SERVER['REMOTE_ADDR'] == '77.66.40.133') { // Load template override $template = locate_template( 'valitor-payment-form.php' ); // If no template override load template from plugin if ( !$template ) { $template = dirname(__FILE__) . '/templates/valitor-payment-form.php'; } //} } return $template; } // Capture function add_action( 'add_meta_boxes', 'valitor_add_meta_boxes' ); add_action( 'wp_ajax_valitor_capture', 'valitor_capture_callback' ); add_action( 'wp_ajax_valitor_refund', 'valitor_refund_callback' ); add_action( 'admin_footer', 'valitor_action_javascript' ); // Create payment page function add_action( 'valitor_checkout_order_review', 'woocommerce_order_review'); add_action( 'wp_ajax_create_valitor_payment_page', 'create_valitor_payment_page_callback' ); function valitor_add_meta_boxes() { global $post, $woocommerce; if ($post->post_type != 'shop_order') { return true; } // Load order $order = new WC_Order($post->ID); $payment_method = $order->get_payment_method(); // Only show on valitor orders if (strpos($payment_method,'valitor') !== false) { add_meta_box( 'valitor-actions', __( 'Valitor actions', 'valitor' ), 'valitor_meta_box', 'shop_order', 'normal' ); } return true; } function valitor_meta_box( $post ) { // Load order $order = new WC_Order($post->ID); $orderItems = $order->get_items(); $txnid = $order->get_transaction_id(); if ($txnid) { $settings = new Valitor_settings(); $api = $settings->api_login(); if ($api instanceof WP_Error) { $_SESSION['valitor_login_error'] = $api->get_error_message(); echo '

' . __('Could not connect to Valitor!', 'valitor') . '

'; return; } $payment = $api->getPayment($txnid); if ($payment) { $payments = $payment->getPayments(); foreach ($payments as $pay) { $reserved = $pay->getReservedAmount(); $captured = $pay->getCapturedAmount(); $refunded = $pay->getRefundedAmount(); $status = $pay->getCurrentStatus(); if ($status == 'released') { echo '
'.__('Payment released', 'valitor').''; } else { $charge = $reserved - $captured - $refunded; if ($charge <= 0) $charge = 0.00; ?>
Payment reserved: get_currency()?>
Payment captured: get_currency()?>
Payment refunded: get_currency()?>
Payment chargeable: get_currency()?>


get_quantity(); $priceExcTaxPerUnit = (float)number_format($itemData->get_total() / $qty, 2, '.', ''); $totalTaxPerUnit = (float)number_format($itemData->get_total_tax() / $qty, 2, '.', ''); $incTax = wc_price($priceExcTaxPerUnit + $totalTaxPerUnit); $excTax = wc_price($priceExcTaxPerUnit); $sku = $product->get_sku(); $totalIncTax = wc_price($itemData->get_total()+$itemData->get_total_tax()); echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; } // Shipping method if ($order->get_shipping_total() <> 0 || $order->get_shipping_tax() <> 0) { $order_shipping_methods = $order->get_shipping_methods(); foreach ($order_shipping_methods as $ordershipping_key => $ordershippingmethods) { $shipping_id = $ordershippingmethods['method_id']; } $totalIncTax = wc_price((float)number_format($order->get_shipping_total() + $order->get_shipping_tax(), 2, '.', '')); $excTax = wc_price($order->get_shipping_total()); echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; } ?>
Product name Price with tax Price without tax Ordered Quantity Total amount
' . $itemData->get_product()->get_name() . '' . $incTax . '' . $excTax . '' . $qty . '' . $totalIncTax . '
' . $order->get_shipping_method(). '' . $totalIncTax . '' . $excTax . '' . 1 . '' . $totalIncTax . '

'; echo ''; echo 'Capture'; echo 'Refund'; echo '
'; } } } } else { echo __('Order got no transaction', 'valitor'); } } function valitor_action_javascript() { global $post; if(isset($post->ID)) { // Check if woocommerce order if ($post->post_type == 'shop_order') { ?> 'page', 'post_content' => '', 'post_parent' => 0, 'post_author' => $user_ID, 'post_status' => 'publish', 'post_title' => 'Valitor payment form', ); // Create page $page_id = wp_insert_post($page); if ($page_id == 0) { echo json_encode( array('status' => 'error', 'message' => __('Error creating page, try again','valitor')) ); } else { echo json_encode( array('status' => 'ok', 'message' => __('Payment page created','valitor'), 'page_id' => $page_id) ); } wp_die(); } function valitor_capture_callback() { global $wpdb; $order_id = sanitize_text_field($_POST['order_id']); $amount = (float)$_POST['amount']; if (!$order_id || !$amount) { echo json_encode(array('status' => 'error', 'message' => 'error')); wp_die(); } // Load order $order = new WC_Order($order_id); $txnid = $order->get_transaction_id(); if ($txnid) { $api = new ValitorMerchantAPI(esc_attr( get_option('valitor_gateway_url') ), esc_attr( get_option('valitor_username') ), esc_attr( get_option('valitor_password') ), null); try { $api->login(); } catch (Exception $e) { $_SESSION['valitor_login_error'] = $e->getMessage(); return new WP_Error( 'error', "Could not login to the Merchant API: ".$e->getMessage()); } $postOrderLines = $_POST['orderLines']; if(!empty($postOrderLines)) { $selectedProducts = array( 'skuList'=>array(), 'skuQty'=>array() ); foreach ($postOrderLines as $productData){ if ($productData[1]['value'] > 0) { $selectedProducts['skuList'][] = $productData[0]['value']; $selectedProducts['skuQty'][$productData[0]['value']] = $productData[1]['value']; } } $orderLines = createOrderLines($order, $selectedProducts); $salesTax = 0; foreach ($orderLines as $orderLine) { $salesTax += $orderLine['taxAmount']; } } else { $orderLines = array(array()); $salesTax = $order->get_total_tax(); } // Capture amount $capture_result = $api->captureReservation($txnid, $amount, $orderLines, $salesTax); if(!$capture_result->wasSuccessful()) { // log to history $order->add_order_note( __('Capture failed: ' . $capture_result->getMerchantErrorMessage(), 'Valitor') ); echo json_encode( array('status' => 'error', 'message' => $capture_result->getMerchantErrorMessage()) ); } else { // Get payment data $payment = $api->getPayment($txnid); if ($payment) { $payments = $payment->getPayments(); foreach ($payments as $pay) { $reserved = $pay->getReservedAmount(); $captured = $pay->getCapturedAmount(); $refunded = $pay->getRefundedAmount(); $charge = $reserved - $captured - $refunded; if ($charge <= 0) $charge = 0.00; } } update_post_meta( $order_id, '_captured', true ); $order_note = __('Order captured: amount: '.$amount, 'Valitor'); $order->add_order_note( $order_note ); $note_html = '
  • '.$order_note.'

    '.sprintf( __( 'added on %1$s at %2$s', 'woocommerce' ), date_i18n( wc_date_format(), time() ), date_i18n( wc_time_format(), time() ) ).'

  • '; echo json_encode( array('status' => 'ok', 'captured' => number_format($captured,2), 'reserved' => number_format($reserved,2), 'refunded' => number_format($refunded,2), 'chargeable' => number_format($charge,2), 'message' => $capture_result, 'note' => $note_html) ); } } wp_die(); } function valitor_refund_callback() { $orderLines = array(array()); $wcRefundOrderLines = array(array()); $order_id = sanitize_text_field($_POST['order_id']); $amount = (float)$_POST['amount']; if (!$order_id || !$amount) { echo json_encode(array('status' => 'error', 'message' => 'error')); wp_die(); } // Load order $order = new WC_Order($order_id); $txnid = $order->get_transaction_id(); if ($txnid) { $api = new ValitorMerchantAPI(esc_attr( get_option('valitor_gateway_url') ), esc_attr( get_option('valitor_username') ), esc_attr( get_option('valitor_password') ), null); try { $api->login(); } catch (Exception $e) { $_SESSION['valitor_login_error'] = $e->getMessage(); return new WP_Error( 'error', "Could not login to the Merchant API: ".$e->getMessage()); } $postOrderLines = $_POST['orderLines']; if(!empty($postOrderLines)) { $selectedProducts = array( 'skuList'=>array(), 'skuQty'=>array() ); foreach ($postOrderLines as $productData){ if ($productData[1]['value'] > 0) { $selectedProducts['skuList'][] = $productData[0]['value']; $selectedProducts['skuQty'][$productData[0]['value']] = $productData[1]['value']; } } $orderLines = createOrderLines($order, $selectedProducts); $wcRefundOrderLines = createOrderLines($order, $selectedProducts, true); } function wcRefund($order, $wcRefundOrderLines, $amount, $orderId) { // Restock the items $refundOperation = wc_create_refund( array( 'amount' => $amount, 'reason' => null, 'order_id' => $orderId, 'line_items'=> $wcRefundOrderLines, 'refund_payment'=> false, 'restock_items'=> true )); if ($refundOperation instanceof WP_Error) { $order->add_order_note( __($refundOperation->get_error_message(), 'valitor') ); } else { $order->add_order_note( __('Refunded products have been re-added to the inventory', 'valitor') ); } } // Refund the amount OR release if a refund is not possible $releaseFlag = false; if (get_post_meta($order_id, '_captured', true) || get_post_meta($order_id, '_refunded', true)) { $refund_result = $api->refundCapturedReservation($txnid, $amount, $orderLines); if($refund_result->wasSuccessful()) { wcRefund($order, $wcRefundOrderLines, $amount, $order_id); update_post_meta( $order_id, '_refunded', true ); } } else { if ($order->get_remaining_refund_amount() == 0) { $refund_result = $api->releaseReservation($txnid); if($refund_result->wasSuccessful()) { $releaseFlag = true; update_post_meta( $order_id, '_released', true ); } } else { $refund_result = $api->refundCapturedReservation($txnid, $amount, $orderLines); if($refund_result->wasSuccessful()) { wcRefund($order, $wcRefundOrderLines, $amount, $order_id); update_post_meta( $order_id, '_refunded', true ); } } } if(!$refund_result->wasSuccessful()) { $order->add_order_note(__('Refund failed: ' . $refund_result->getMerchantErrorMessage(), 'valitor')); echo json_encode(array('status' => 'error', 'message' => $refund_result->getMerchantErrorMessage())); } else { // Get payment data $payment = $api->getPayment($txnid); if ($payment) { $payments = $payment->getPayments(); foreach ($payments as $pay) { $reserved = $pay->getReservedAmount(); $captured = $pay->getCapturedAmount(); $refunded = $pay->getRefundedAmount(); $charge = $reserved - $captured - $refunded; if ($charge <= 0) $charge = 0.00; } } if ($releaseFlag) { $order->add_order_note( __('Order released', 'valitor') ); $orderNote = "The order has been released"; }else { $order->add_order_note( __('Order refunded: amount '.$amount, 'valitor') ); $orderNote = 'Order refunded: amount '.$amount; } $note_html = '
  • '.$orderNote.'

    '.sprintf( __( 'added on %1$s at %2$s', 'woocommerce' ), date_i18n( wc_date_format(), time() ), date_i18n( wc_time_format(), time() ) ).'

  • '; echo json_encode( array('status' => 'ok', 'captured' => number_format($captured,2), 'reserved' => number_format($reserved,2), 'refunded' => number_format($refunded,2), 'chargeable' => number_format($charge,2), 'message' => $refund_result, 'note' => $note_html) ); } } wp_die(); } } // Make sure plugins are loaded before running gateway add_action( 'plugins_loaded', 'init_valitor_settings', 0 );