diff --git a/craftgate-payment-gateway.php b/craftgate-payment-gateway.php
index c4383b0..bc2b593 100644
--- a/craftgate-payment-gateway.php
+++ b/craftgate-payment-gateway.php
@@ -5,7 +5,7 @@
* Description: Accept debit/credit card payments easily and directly on your WordPress site using Craftgate.
* Author: Craftgate
* Author URI: https://craftgate.io/
- * Version: 1.0.4
+ * Version: 1.0.5
* Requires at least: 4.4
* Tested up to: 5.8.3
* WC requires at least: 3.0.0
@@ -137,6 +137,7 @@ private function define_woocommerce_actions()
add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
add_action('woocommerce_receipt_craftgate_gateway', array($this, 'init_craftgate_checkout_form'));
add_action('woocommerce_api_craftgate_gateway_callback', array($this, 'handle_craftgate_checkout_form_result'));
+ add_action('woocommerce_api_craftgate_gateway_webhook', array($this, 'handle_craftgate_webhook_result'));
}
/**
@@ -175,39 +176,121 @@ public function init_craftgate_checkout_form($order_id = null)
}
}
+ /**
+ * Check payment is processed before
+ */
+ private function is_payment_processed_before($checkout_token)
+ {
+ $orders = wc_get_orders(array(
+ 'limit' => -1,
+ 'meta_key' => 'craftgate_checkout_token',
+ 'meta_value' => $checkout_token,
+ 'meta_compare' => '=',
+ 'return' => 'objects'
+ ));
+
+ foreach ($orders as $order) {
+ if (!in_array($order->get_status(), ['failed', 'pending'])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Decide whether process webhook request and return checkout token
+ */
+ private function should_process_webhook_request($webhook_data)
+ {
+ if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
+ return false;
+ }
+
+ $event_type = wc_clean($webhook_data['eventType']);
+ $status = wc_clean($webhook_data['status']);
+ $checkout_token = wc_clean($webhook_data['payloadId']);
+
+ if ($event_type !== 'CHECKOUTFORM_AUTH' || $status !== "SUCCESS" || !isset($checkout_token) || $this->is_payment_processed_before($checkout_token)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Handles Craftgate webhook result.
+ */
+ public function handle_craftgate_webhook_result()
+ {
+ $webhook_data = json_decode(file_get_contents('php://input'), true);
+ if (!isset($webhook_data) || !$this->should_process_webhook_request($webhook_data)) {
+ exit();
+ }
+
+ $checkout_token = wc_clean($webhook_data['payloadId']);;
+ $checkout_form_result = $this->retrieve_checkout_form_result($checkout_token);
+ if ($checkout_form_result->paymentStatus !== 'SUCCESS') {
+ exit();
+ }
+
+ $conversationId = $checkout_form_result->conversationId;
+ if (!isset($conversationId)) {
+ exit();
+ }
+ $order = $this->retrieve_order($conversationId);
+ $this->update_order_checkout_form_result_metadata($order, $checkout_form_result, $checkout_token);
+ $this->complete_order_for_success_payment($checkout_form_result, $order);
+ exit();
+ }
+
+ /**
+ * Completes order for success payment.
+ */
+ private function complete_order_for_success_payment($checkout_form_result, $order)
+ {
+ global $woocommerce;
+ if ($order->get_status() !== 'pending' && $order->get_status() !== 'failed') {
+ return;
+ }
+
+ if ($checkout_form_result->installment > 1) {
+ $this->update_order_for_installment($order, $checkout_form_result);
+ }
+
+ $customer_id = $order->get_user()->ID;
+ if (isset($checkout_form_result->cardUserKey) && $this->retrieve_card_user_key($customer_id, $this->api_key) != $checkout_form_result->cardUserKey) {
+ $this->save_card_user_key($customer_id, $checkout_form_result->cardUserKey, $this->api_key);
+ }
+
+ $order->payment_complete();
+ $orderMessage = 'Payment ID: ' . $checkout_form_result->id;
+ $order->add_order_note($orderMessage, 0, true);
+ WC()->cart->empty_cart();
+ $woocommerce->cart->empty_cart();
+ wc_empty_cart();
+ }
+
/**
* Handles Craftgate checkout result.
*/
public function handle_craftgate_checkout_form_result()
{
try {
- global $woocommerce;
$this->validate_handle_checkout_form_result_params();
$order_id = wc_clean($_GET["order_id"]);
$order = $this->retrieve_order($order_id);
- $GLOBALS["cg-lang-header"] = $this->get_option("language");
- $checkout_form_result = $this->craftgate_api->retrieve_checkout_form_result(wc_clean($_POST["token"]));
+ if ($order->get_status() == 'processing') {
+ echo "";
+ exit;
+ }
+ $checkout_token = wc_clean($_POST["token"]);
+ $checkout_form_result = $this->retrieve_checkout_form_result($checkout_token);
$this->validate_order_id_equals_conversation_id($checkout_form_result, $order_id);
- $this->update_order_checkout_form_result_metadata($order, $checkout_form_result);
+ $this->update_order_checkout_form_result_metadata($order, $checkout_form_result, $checkout_token);
// Checks payment error.
if (!isset($checkout_form_result->paymentError) && $checkout_form_result->paymentStatus === 'SUCCESS') {
- if ($checkout_form_result->installment > 1) {
- $this->update_order_for_installment($order, $checkout_form_result);
- }
-
- $customer_id = $order->get_user()->ID;
- if (isset($checkout_form_result->cardUserKey) && $this->retrieve_card_user_key($customer_id, $this->api_key) != $checkout_form_result->cardUserKey) {
- $this->save_card_user_key($customer_id, $checkout_form_result->cardUserKey, $this->api_key);
- }
-
- $order->payment_complete();
- $orderMessage = 'Payment ID: ' . $checkout_form_result->id;
- $order->add_order_note($orderMessage, 0, true);
- WC()->cart->empty_cart();
- $woocommerce->cart->empty_cart();
- wc_empty_cart();
+ $this->complete_order_for_success_payment($checkout_form_result, $order);
echo "";
} else {
$error = $checkout_form_result->paymentError->errorCode . ' - ' . $checkout_form_result->paymentError->errorDescription . ' - ' . $checkout_form_result->paymentError->errorGroup;
@@ -215,20 +298,24 @@ public function handle_craftgate_checkout_form_result()
$order->update_status('failed', $error);
$order->save();
wc_add_notice(__($checkout_form_result->paymentError->errorDescription, $this->text_domain), 'error');
- $redirectUrl = wc_get_checkout_url();
- echo "";
+ echo "";
}
exit;
} catch (Exception $e) {
error_log($e->getMessage());
wc_add_notice(__($e->getMessage(), $this->text_domain), 'error');
- $redirectUrl = wc_get_checkout_url();
- echo "";
+ echo "";
$this->render_error_message(__('An error occurred. Error Code: ', $this->text_domain) . '-2');
}
}
+ private function retrieve_checkout_form_result($checkout_token)
+ {
+ $GLOBALS["cg-lang-header"] = $this->get_option("language");
+ return $this->craftgate_api->retrieve_checkout_form_result($checkout_token);
+ }
+
/**
* Checks if API request is valid.
*
@@ -446,11 +533,12 @@ private function validate_order_id_equals_conversation_id($checkout_form_result,
* @param $order object WooCommerce order
* @param $checkout_form_result object Checkout Form result
*/
- private function update_order_checkout_form_result_metadata($order, $checkout_form_result)
+ private function update_order_checkout_form_result_metadata($order, $checkout_form_result, $checkout_token)
{
if (isset($checkout_form_result->id)) {
$order->update_meta_data('environment', $this->is_sandbox_active ? 'sandbox' : 'live');
$order->update_meta_data('craftgate_payment_id', $checkout_form_result->id);
+ $order->update_meta_data('craftgate_checkout_token', $checkout_token);
}
$order->save();
}
@@ -561,6 +649,13 @@ public function init_admin_settings_form_fields()
'description' => __('Example: hideFooter=true&animatedCard=true', $this->text_domain),
'default' => '',
),
+ 'webhook_url' => array(
+ 'title' => __('Webhook URL', $this->text_domain),
+ 'type' => 'text',
+ 'disabled' => true,
+ 'description' => __('The URL that payment results will be sent to on the server-side. You should enter this webhook address to Craftgate Merchant Panel to get webhook request. You can see details here.', $this->text_domain),
+ 'default' => rtrim(get_bloginfo('url'), '/') . '/' . "?wc-api=craftgate_gateway_webhook",
+ ),
);
}
diff --git a/languages/craftgate-payment-gateway-tr_TR.mo b/languages/craftgate-payment-gateway-tr_TR.mo
index c077c58..e936c3f 100644
Binary files a/languages/craftgate-payment-gateway-tr_TR.mo and b/languages/craftgate-payment-gateway-tr_TR.mo differ
diff --git a/languages/craftgate-payment-gateway-tr_TR.po b/languages/craftgate-payment-gateway-tr_TR.po
index a835b5e..0491661 100644
--- a/languages/craftgate-payment-gateway-tr_TR.po
+++ b/languages/craftgate-payment-gateway-tr_TR.po
@@ -1,8 +1,8 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
-"POT-Creation-Date: 2022-02-07 16:20+0300\n"
-"PO-Revision-Date: 2022-02-07 16:20+0300\n"
+"POT-Creation-Date: 2022-04-12 17:03+0300\n"
+"PO-Revision-Date: 2022-04-12 18:09+0300\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: tr\n"
@@ -24,28 +24,28 @@ msgstr ""
"Craftgate ile WordPress siteniz üzerinden kolay ve doğrudan banka/kredi "
"kartı ile ödeme alın."
-#: craftgate-payment-gateway.php:96 craftgate-payment-gateway.php:487
+#: craftgate-payment-gateway.php:96 craftgate-payment-gateway.php:603
msgid "Pay with Debit/Credit Card"
msgstr "Banka/Kredi Kartı ile Öde"
-#: craftgate-payment-gateway.php:160 craftgate-payment-gateway.php:164
-#: craftgate-payment-gateway.php:217
+#: craftgate-payment-gateway.php:171 craftgate-payment-gateway.php:175
+#: craftgate-payment-gateway.php:315
msgid "An error occurred. Error Code: "
msgstr "Bir hata meydana geldi. Hata Kodu: "
-#: craftgate-payment-gateway.php:257
+#: craftgate-payment-gateway.php:361
msgid "Installment Fee"
msgstr "Taksit Komisyonu"
-#: craftgate-payment-gateway.php:346
+#: craftgate-payment-gateway.php:450
msgid "Shipping Total"
msgstr "Gönderim Ücreti"
-#: craftgate-payment-gateway.php:404 craftgate-payment-gateway.php:417
+#: craftgate-payment-gateway.php:519 craftgate-payment-gateway.php:532
msgid "Your payment could not be processed."
msgstr "Ödemeniz alınamadı."
-#: craftgate-payment-gateway.php:459
+#: craftgate-payment-gateway.php:575
#, fuzzy
#| msgid ""
#| "You can create your Craftgate Payment Gateway account buradan oluşturabilirsiniz."
-#: craftgate-payment-gateway.php:463
+#: craftgate-payment-gateway.php:579
msgid "Craftgate Payment Gateway is not available to use"
msgstr "Craftgate Payment Gateway kullanılamaz"
-#: craftgate-payment-gateway.php:463
+#: craftgate-payment-gateway.php:579
msgid "The only supported currency is TRY."
msgstr "Sadece Türk lirası desteklenmektedir."
-#: craftgate-payment-gateway.php:476
+#: craftgate-payment-gateway.php:592
msgid "Enable/Disable"
msgstr "Aktif/Pasif"
-#: craftgate-payment-gateway.php:478
+#: craftgate-payment-gateway.php:594
msgid "Enable Craftgate"
msgstr "Craftgate’i Aktif Et"
-#: craftgate-payment-gateway.php:479
+#: craftgate-payment-gateway.php:595
msgid "Enable or disable the gateway."
msgstr "Craftgate’i aktif veya pasif yapabilirsiniz."
-#: craftgate-payment-gateway.php:483
+#: craftgate-payment-gateway.php:599
msgid "Title"
msgstr "Başlık"
-#: craftgate-payment-gateway.php:485
+#: craftgate-payment-gateway.php:601
msgid "This controls the title which the user sees during checkout."
msgstr "Kullanıcının ödeme esnasında göreceği başlık."
-#: craftgate-payment-gateway.php:490
+#: craftgate-payment-gateway.php:606
msgid "Description"
msgstr "Açıklama"
-#: craftgate-payment-gateway.php:492
+#: craftgate-payment-gateway.php:608
msgid "This controls the description which the user sees during checkout."
msgstr "Kullanıcının ödeme esnasında göreceği açıklama."
-#: craftgate-payment-gateway.php:493
+#: craftgate-payment-gateway.php:609
msgid "You can pay with Debit and Credit Card"
msgstr "Banka veya Kredi Kartı ile ödeyebilirsiniz"
-#: craftgate-payment-gateway.php:496
+#: craftgate-payment-gateway.php:612
msgid "Live API Key"
msgstr "Canlı API Key"
-#: craftgate-payment-gateway.php:498
+#: craftgate-payment-gateway.php:614
msgid "Enter your Live API Key."
msgstr "Canlı API Key’inizi giriniz."
-#: craftgate-payment-gateway.php:502
+#: craftgate-payment-gateway.php:618
msgid "Live Secret Key"
msgstr "Canlı Secret Key"
-#: craftgate-payment-gateway.php:504
+#: craftgate-payment-gateway.php:620
msgid "Enter your Live Secret Key."
msgstr "Canlı Secret Key’inizi giriniz."
-#: craftgate-payment-gateway.php:508
+#: craftgate-payment-gateway.php:624
msgid "Sandbox API Key"
msgstr "Sandbox API Key"
-#: craftgate-payment-gateway.php:510
+#: craftgate-payment-gateway.php:626
msgid "Enter your Sandbox API Key."
msgstr "Sandbox API Key’inizi giriniz."
-#: craftgate-payment-gateway.php:514
+#: craftgate-payment-gateway.php:630
msgid "Sandbox Secret Key"
msgstr "Sandbox Secret Key"
-#: craftgate-payment-gateway.php:516
+#: craftgate-payment-gateway.php:632
msgid "Enter your Sandbox Secret Key."
msgstr "Sandbox Secret Key’inizi giriniz."
-#: craftgate-payment-gateway.php:520
+#: craftgate-payment-gateway.php:636
msgid "Sandbox Mode"
msgstr "Sandbox Modu"
-#: craftgate-payment-gateway.php:522
+#: craftgate-payment-gateway.php:638
msgid "Enable Sandbox Mode"
msgstr "Sandbox Modu Aktif"
-#: craftgate-payment-gateway.php:524
+#: craftgate-payment-gateway.php:640
msgid "Enable test mode using sandbox API keys."
msgstr "Sandbox API bilgilerinizi kullanarak test modunu aktif edebilirsiniz."
-#: craftgate-payment-gateway.php:527
+#: craftgate-payment-gateway.php:643
msgid "Language"
msgstr "Dil"
-#: craftgate-payment-gateway.php:533
+#: craftgate-payment-gateway.php:649
msgid "Change the language of payment form."
msgstr ""
"Kullanıcının ödeme esnasında yer alan metinlerin gösterileceği dil seçeneği."
-#: craftgate-payment-gateway.php:537
+#: craftgate-payment-gateway.php:653
msgid "Iframe Options"
-msgstr ""
+msgstr "Iframe Ayarları"
-#: craftgate-payment-gateway.php:539
+#: craftgate-payment-gateway.php:655
msgid "Example: hideFooter=true&animatedCard=true"
+msgstr "Örnek: Example: hideFooter=true&animatedCard=true"
+
+#: craftgate-payment-gateway.php:659
+msgid "Webhook URL"
+msgstr "Webhook URL"
+
+#: craftgate-payment-gateway.php:662
+msgid ""
+"The URL that payment results will be sent to on the server-side. You should "
+"enter this webhook address to Craftgate Merchant Panel to get webhook "
+"request. You can see details at here."
msgstr ""
+"Ödeme sonucunun iletileceği URL. Webhook isteklerini alabilmek için "
+"Craftgate Merchant Panel üzerinden bu adresi girmelisiniz. Detaylara buradan ulaşabilirsiniz."
-#: craftgate-payment-gateway.php:610
+#: craftgate-payment-gateway.php:733
msgid "Craftgate Payment URL"
msgstr "Craftgate Ödeme URL"
-#: craftgate-payment-gateway.php:643
+#: craftgate-payment-gateway.php:766
msgid "Settings"
msgstr "Ayarlar"
diff --git a/readme.txt b/readme.txt
index dec5a19..d17ca35 100644
--- a/readme.txt
+++ b/readme.txt
@@ -4,7 +4,7 @@ Tags: craftgate, payment gateway, kredi kartı, banka kartı, ödeme, sanal pos,
Requires at least: 4.4
Tested up to: 5.8.3
Requires PHP: 5.6
-Stable tag: 1.0.4
+Stable tag: 1.0.5
License: GPLv3
License URI: https://www.gnu.org/licenses/gpl-3.0.html
@@ -50,6 +50,9 @@ Craftgate kullanarak ödeme geçirebilmek için üyeliğinizin olması gerekmekt
6. Sipariş Yönetim Sayfası
== Changelog ==
+= 1.0.5 - 2022-04-20 =
+* adds webhook feature to determine unhandled payments on client side
+
= 1.0.4 - 2022-02-28 =
* adds card storage functionality
* adds shipping total to payment items
@@ -72,6 +75,9 @@ Craftgate kullanarak ödeme geçirebilmek için üyeliğinizin olması gerekmekt
* First Release
== Upgrade Notice ==
+= 1.0.5 - 2022-04-20 =
+* adds webhook feature to determine unhandled payments on client side
+
= 1.0.4 - 2022-02-28 =
* adds card storage functionality
* adds shipping total to payment items