From ff9fa205f88a974bc8f9a36d7b750e8c3f019e74 Mon Sep 17 00:00:00 2001 From: guzzilar Date: Tue, 22 Sep 2015 01:54:35 +0700 Subject: [PATCH 1/7] Add Omise charge post type for keep an WC order_id and an Omise charge_id into database --- omise-gateway.php | 1 + omise-wc-gateway.php | 52 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/omise-gateway.php b/omise-gateway.php index 831be791..b4ce1aa6 100644 --- a/omise-gateway.php +++ b/omise-gateway.php @@ -22,6 +22,7 @@ require_once 'omise-wc-myaccount.php'; require_once 'omise-wp-admin.php'; +add_action ( 'init', 'register_omise_wc_gateway_post_type' ); add_action ( 'plugins_loaded', 'register_omise_wc_gateway_plugin', 0 ); add_action ( 'plugins_loaded', 'prepare_omise_myaccount_panel', 0 ); add_action ( 'plugins_loaded', array ( Omise_Admin::get_instance(), 'register_admin_page_and_actions' ) ); diff --git a/omise-wc-gateway.php b/omise-wc-gateway.php index a38a5a80..c663ccbe 100644 --- a/omise-wc-gateway.php +++ b/omise-wc-gateway.php @@ -23,6 +23,7 @@ public function __construct() { $this->title = $this->settings ['title']; $this->description = $this->settings ['description']; $this->sandbox = isset($this->settings ['sandbox']) && $this->settings ['sandbox'] == 'yes'; + $this->omise_3ds = isset($this->settings ['omise_3ds']) && $this->settings ['omise_3ds'] == 'yes'; $this->test_private_key = $this->settings ['test_private_key']; $this->test_public_key = $this->settings ['test_public_key']; $this->live_private_key = $this->settings ['live_private_key']; @@ -59,6 +60,12 @@ function init_form_fields() { 'label' => __ ( 'Sandbox mode means everything is in TEST mode', $this->gateway_name ), 'default' => 'yes' ), + 'omise_3ds' => array ( + 'title' => __ ( '3DS Support', $this->gateway_name ), + 'type' => 'checkbox', + 'label' => __ ( 'Enable the 3DS support', $this->gateway_name ), + 'default' => 'no' + ), 'title' => array ( 'title' => __ ( 'Title:', $this->gateway_name ), 'type' => 'text', @@ -120,7 +127,7 @@ function payment_fields() { $viewData ["existingCards"] = $cards; } } - + Omise_Util::render_view ( 'includes/templates/omise-payment-form.php', $viewData ); } @@ -137,7 +144,7 @@ public function process_payment($order_id) { if (empty ( $token ) && empty ( $card_id )) { throw new Exception ( "Please select a card or enter new payment information." ); } - + $user = $order->get_user (); $omise_customer_id = $this->sandbox ? $user->test_omise_customer_id : $user->live_omise_customer_id; @@ -187,7 +194,8 @@ public function process_payment($order_id) { $data = array ( "amount" => $order->get_total () * 100, "currency" => $order->get_order_currency (), - "description" => "WooCommerce Order id " . $order_id + "description" => "WooCommerce Order id " . $order_id, + "return_uri" => $this->get_return_url($order) ); if (! empty ( $card_id ) && ! empty ( $omise_customer_id )) { @@ -199,10 +207,31 @@ public function process_payment($order_id) { } else { throw new Exception ( "Please select a card or enter new payment information." ); } - - $result = Omise::create_charge ( $this->private_key, $data ); - $success = $this->is_charge_success($result); + + $result = Omise::create_charge($this->private_key, $data); + if ($result->object === "error") { + throw new Exception ($result->message); + } else { + $post_id = wp_insert_post(array( + 'post_title' => 'Omise Charge Id '.$result->id, + 'post_type' => 'omise_charge_items', + 'post_status' => 'publish' + )); + + add_post_meta($post_id, '_omise_charge_id', $result->id); + add_post_meta($post_id, '_wc_order_id', $order_id); + } + $success = false; + if ($this->omise_3ds) { + return array ( + 'result' => 'success', + 'redirect' => $result->authorize_uri + ); + } else { + $success = $this->is_charge_success($result); + } + if ($success) { $order->payment_complete (); $order->add_order_note ( 'Payment with Omise successful' ); @@ -292,4 +321,15 @@ function add_omise_gateway($methods) { add_filter ( 'woocommerce_payment_gateways', 'add_omise_gateway' ); } +function register_omise_wc_gateway_post_type() { + register_post_type('omise_charge_items', array( + 'label' => 'Omise Charge Items', + 'labels' => array( + 'name' => 'Omise Charge Items', + 'singular_name' => 'Omise Charge Item' + ), + 'public' => true, + 'supports' => array('title','custom-fields') + )); +} ?> From 9d2190a8df47076a16e8f9a522a6c04a5fc90203 Mon Sep 17 00:00:00 2001 From: guzzilar Date: Tue, 22 Sep 2015 16:31:15 +0700 Subject: [PATCH 2/7] Fix 3DS handler method inside WC_Gateway_Omise class --- omise-api-wrapper.php | 11 ++++++++++ omise-wc-gateway.php | 50 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/omise-api-wrapper.php b/omise-api-wrapper.php index 3170248a..d7381946 100644 --- a/omise-api-wrapper.php +++ b/omise-api-wrapper.php @@ -16,6 +16,17 @@ public static function create_charge($apiKey, $chargeInfo){ $result = self::call_api($apiKey, "POST", "/charges", $chargeInfo); return json_decode($result); } + + /** + * Retrieve a charge + * @param string $apiKey + * @param Array $chargeInfo + * @return mixed + */ + public static function get_charges($apiKey, $charge_id=""){ + $result = self::call_api($apiKey, "GET", "/charges/{$charge_id}"); + return json_decode($result); + } /** * Creates a customer diff --git a/omise-wc-gateway.php b/omise-wc-gateway.php index c663ccbe..69ced619 100644 --- a/omise-wc-gateway.php +++ b/omise-wc-gateway.php @@ -31,6 +31,8 @@ public function __construct() { $this->public_key = $this->sandbox ? $this->test_public_key : $this->live_public_key; $this->private_key = $this->sandbox ? $this->test_private_key : $this->live_private_key; + add_action( 'woocommerce_api_wc_gateway_omise', array( $this, 'omise_3ds_handler' ) ); + add_action ( 'woocommerce_update_options_payment_gateways_' . $this->id, array ( &$this, 'process_admin_options' @@ -40,6 +42,7 @@ public function __construct() { $this, 'omise_scripts' )); + } /** @@ -195,7 +198,7 @@ public function process_payment($order_id) { "amount" => $order->get_total () * 100, "currency" => $order->get_order_currency (), "description" => "WooCommerce Order id " . $order_id, - "return_uri" => $this->get_return_url($order) + "return_uri" => add_query_arg( 'order_id', $order_id, site_url()."?wc-api=wc_gateway_omise" ) ); if (! empty ( $card_id ) && ! empty ( $omise_customer_id )) { @@ -220,6 +223,7 @@ public function process_payment($order_id) { add_post_meta($post_id, '_omise_charge_id', $result->id); add_post_meta($post_id, '_wc_order_id', $order_id); + add_post_meta($post_id, '_wc_confirmed_url', $this->get_return_url($order)); } $success = false; @@ -310,6 +314,50 @@ public function omise_scripts() { 'vault_url' => OMISE_VAULT_HOST ) ); } + + public function omise_3ds_handler() + { + if (!$_GET['order_id']) + die("order_id"); + + $order_id = $_GET['order_id']; + + $posts = get_posts(array( + 'post_type' => 'omise_charge_items', + 'meta_query' => array(array( + 'key' => '_wc_order_id', + 'value' => $order_id, + 'compare' => 'LIKE' + )) + )); + + if (empty($posts)) + die("charge was not found"); + + $order = wc_get_order($order_id); + if (!$order) + die("order was not found"); + + $confirmed_url = get_post_custom_values('_wc_confirmed_url', $posts[0]->ID); + $confirmed_url = $confirmed_url[0]; + + $charge_id = get_post_custom_values('_omise_charge_id', $posts[0]->ID); + $charge_id = $charge_id[0]; + + $result = Omise::get_charges($this->private_key, $charge_id); + + if ($this->is_charge_success($result)) { + $order->payment_complete(); + $order->add_order_note('Payment with Omise successful'); + + // Remove cart + WC()->cart->empty_cart(); + + header("Location: ".$confirmed_url); + } + + die(); + } } } From 45b822b2b88943d266525d3211c32471c210f6fc Mon Sep 17 00:00:00 2001 From: guzzilar Date: Wed, 23 Sep 2015 18:07:27 +0700 Subject: [PATCH 3/7] Fix process_payment method, add more condition for handle when a charge was failed --- omise-wc-gateway.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/omise-wc-gateway.php b/omise-wc-gateway.php index 69ced619..0db22466 100644 --- a/omise-wc-gateway.php +++ b/omise-wc-gateway.php @@ -31,7 +31,7 @@ public function __construct() { $this->public_key = $this->sandbox ? $this->test_public_key : $this->live_public_key; $this->private_key = $this->sandbox ? $this->test_private_key : $this->live_private_key; - add_action( 'woocommerce_api_wc_gateway_omise', array( $this, 'omise_3ds_handler' ) ); + add_action( 'woocommerce_api_wc_gateway_' . $this->id, array( $this, 'omise_3ds_handler' ) ); add_action ( 'woocommerce_update_options_payment_gateways_' . $this->id, array ( &$this, @@ -214,6 +214,8 @@ public function process_payment($order_id) { $result = Omise::create_charge($this->private_key, $data); if ($result->object === "error") { throw new Exception ($result->message); + } if ($result->failure_code) { + throw new Exception ($result->failure_message); } else { $post_id = wp_insert_post(array( 'post_title' => 'Omise Charge Id '.$result->id, From 49edfb6f85d50e0775848dac31569791547e4516 Mon Sep 17 00:00:00 2001 From: guzzilar Date: Thu, 24 Sep 2015 01:16:18 +0700 Subject: [PATCH 4/7] Use wp_die() function for handle error message after callback is fired. --- omise-wc-gateway.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/omise-wc-gateway.php b/omise-wc-gateway.php index 0db22466..cdf7db86 100644 --- a/omise-wc-gateway.php +++ b/omise-wc-gateway.php @@ -320,7 +320,7 @@ public function omise_scripts() { public function omise_3ds_handler() { if (!$_GET['order_id']) - die("order_id"); + wp_die( "Order was not found", "Omise Payment Gateway: Checkout", array( 'response' => 500 ) ); $order_id = $_GET['order_id']; @@ -329,16 +329,16 @@ public function omise_3ds_handler() 'meta_query' => array(array( 'key' => '_wc_order_id', 'value' => $order_id, - 'compare' => 'LIKE' + 'compare' => '=' )) )); if (empty($posts)) - die("charge was not found"); + wp_die( "Charge was not found", "Omise Payment Gateway: Checkout", array( 'response' => 500 ) ); $order = wc_get_order($order_id); if (!$order) - die("order was not found"); + wp_die( "Order was not found", "Omise Payment Gateway: Checkout", array( 'response' => 500 ) ); $confirmed_url = get_post_custom_values('_wc_confirmed_url', $posts[0]->ID); $confirmed_url = $confirmed_url[0]; @@ -358,6 +358,7 @@ public function omise_3ds_handler() header("Location: ".$confirmed_url); } + wp_die( "Access denied", "Access Denied", array( 'response' => 401 ) ); die(); } } From e86ea262848051a77ee0ed64e1142b2340f33159 Mon Sep 17 00:00:00 2001 From: guzzilar Date: Thu, 24 Sep 2015 13:59:59 +0700 Subject: [PATCH 5/7] Change the 3DS title to 3DSecure --- omise-wc-gateway.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/omise-wc-gateway.php b/omise-wc-gateway.php index cdf7db86..2afb8c71 100644 --- a/omise-wc-gateway.php +++ b/omise-wc-gateway.php @@ -64,9 +64,9 @@ function init_form_fields() { 'default' => 'yes' ), 'omise_3ds' => array ( - 'title' => __ ( '3DS Support', $this->gateway_name ), + 'title' => __ ( '3DSecure Support', $this->gateway_name ), 'type' => 'checkbox', - 'label' => __ ( 'Enable the 3DS support', $this->gateway_name ), + 'label' => __ ( 'Enables 3DSecure on this account', $this->gateway_name ), 'default' => 'no' ), 'title' => array ( From ea237107dc4902ec6e71dc0d5683861b3dfbb291 Mon Sep 17 00:00:00 2001 From: guzzilar Date: Thu, 24 Sep 2015 16:13:10 +0700 Subject: [PATCH 6/7] Change some method name, remove space indent, remove omise_charge post type from admin menu --- omise-api-wrapper.php | 4 ++-- omise-wc-gateway.php | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/omise-api-wrapper.php b/omise-api-wrapper.php index d7381946..83a13aeb 100644 --- a/omise-api-wrapper.php +++ b/omise-api-wrapper.php @@ -20,10 +20,10 @@ public static function create_charge($apiKey, $chargeInfo){ /** * Retrieve a charge * @param string $apiKey - * @param Array $chargeInfo + * @param Array $charge_id * @return mixed */ - public static function get_charges($apiKey, $charge_id=""){ + public static function get_charge($apiKey, $charge_id){ $result = self::call_api($apiKey, "GET", "/charges/{$charge_id}"); return json_decode($result); } diff --git a/omise-wc-gateway.php b/omise-wc-gateway.php index 2afb8c71..494a7496 100644 --- a/omise-wc-gateway.php +++ b/omise-wc-gateway.php @@ -218,7 +218,7 @@ public function process_payment($order_id) { throw new Exception ($result->failure_message); } else { $post_id = wp_insert_post(array( - 'post_title' => 'Omise Charge Id '.$result->id, + 'post_title' => 'Omise Charge Id '.$result->id, 'post_type' => 'omise_charge_items', 'post_status' => 'publish' )); @@ -346,7 +346,7 @@ public function omise_3ds_handler() $charge_id = get_post_custom_values('_omise_charge_id', $posts[0]->ID); $charge_id = $charge_id[0]; - $result = Omise::get_charges($this->private_key, $charge_id); + $result = Omise::get_charge($this->private_key, $charge_id); if ($this->is_charge_success($result)) { $order->payment_complete(); @@ -379,7 +379,6 @@ function register_omise_wc_gateway_post_type() { 'name' => 'Omise Charge Items', 'singular_name' => 'Omise Charge Item' ), - 'public' => true, 'supports' => array('title','custom-fields') )); } From e6c08cc19d0e0c9222119e6da704412dbd768d16 Mon Sep 17 00:00:00 2001 From: guzzilar Date: Thu, 24 Sep 2015 17:12:18 +0700 Subject: [PATCH 7/7] Fix the process to re-check charge is completed in callback method of WooCommerce --- omise-wc-gateway.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/omise-wc-gateway.php b/omise-wc-gateway.php index 494a7496..516a1b63 100644 --- a/omise-wc-gateway.php +++ b/omise-wc-gateway.php @@ -356,6 +356,14 @@ public function omise_3ds_handler() WC()->cart->empty_cart(); header("Location: ".$confirmed_url); + die(); + } else { + if ($result->failure_code && $result->failure_message) { + $order->add_order_note('Charge was not completed, '.$result->failure_message); + wp_die($result->failure_message, "Charge was not completed", array( 'response' => 500 )); + } else { + wp_die("Charge still in progress", "Charge still in progress", array( 'response' => 500 )); + } } wp_die( "Access denied", "Access Denied", array( 'response' => 401 ) );