From 1bb4c6aad2845f39536d07238152d75bdbee5fc9 Mon Sep 17 00:00:00 2001 From: Makoto Mizukami Date: Tue, 30 Jul 2024 13:27:29 +0900 Subject: [PATCH 1/2] Set transaction ID on process_payment to make the order cancellable --- includes/class-wc-gateway-komoju-single-slug.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/includes/class-wc-gateway-komoju-single-slug.php b/includes/class-wc-gateway-komoju-single-slug.php index c5c45ae..6b83f16 100644 --- a/includes/class-wc-gateway-komoju-single-slug.php +++ b/includes/class-wc-gateway-komoju-single-slug.php @@ -215,6 +215,9 @@ public function process_payment($order_id, $payment_type = null) 'payment_details' => $token, ]); + $order->set_transaction_id($session->payment_data->external_order_num); + $order->save(); + if ($result->redirect_url) { return [ 'result' => 'success', From 057be1b483ec050e8b473f103d38cbbd4ad74309 Mon Sep 17 00:00:00 2001 From: Makoto Mizukami Date: Wed, 31 Jul 2024 11:07:43 +0900 Subject: [PATCH 2/2] Attempt cancellation of duplicated payments --- includes/class-wc-gateway-komoju-ipn-handler.php | 3 +-- includes/class-wc-gateway-komoju-single-slug.php | 11 +++++++++++ komoju-php/komoju-php/lib/komoju/KomojuApi.php | 5 +++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/includes/class-wc-gateway-komoju-ipn-handler.php b/includes/class-wc-gateway-komoju-ipn-handler.php index 1fa256f..c9a2b5a 100644 --- a/includes/class-wc-gateway-komoju-ipn-handler.php +++ b/includes/class-wc-gateway-komoju-ipn-handler.php @@ -121,6 +121,7 @@ public function valid_response($webhookEvent) $order = $this->get_komoju_order($webhookEvent, $this->invoice_prefix); if ($order) { + $this->save_komoju_meta_data($order, $webhookEvent); switch ($webhookEvent->status()) { case 'captured': $this->payment_status_captured($order, $webhookEvent); @@ -214,8 +215,6 @@ protected function payment_status_captured($order, $webhookEvent) $this->validate_amount($order, $webhookEvent->grand_total() - $webhookEvent->payment_method_fee()); } - $this->save_komoju_meta_data($order, $webhookEvent); - if ('captured' === $webhookEvent->status()) { $this->payment_complete($order, !empty($webhookEvent->uuid()) ? wc_clean($webhookEvent->uuid()) : '', __('IPN payment captured', 'komoju-woocommerce')); diff --git a/includes/class-wc-gateway-komoju-single-slug.php b/includes/class-wc-gateway-komoju-single-slug.php index 6b83f16..0950919 100644 --- a/includes/class-wc-gateway-komoju-single-slug.php +++ b/includes/class-wc-gateway-komoju-single-slug.php @@ -205,6 +205,17 @@ public function process_payment($order_id, $payment_type = null) // Otherwise we will redirect to the KOMOJU hosted page. $token = sanitize_text_field($_POST['komoju_payment_token']); + // Gimmick: If there is a KOMOJU payment UUID already set for the order, try to cancel the preceding payment. + // Some considerations: + // - It will be helpful to prevent duplicated Konbini payments, which can be caused through the "order-pay" page. + // - If the metadata is set, the payment already exists, and it is safe to cancel the payment. + // - It is also worth to note that the paths to this code guarantee that this order is payable, i.e., no payment is captured or has expired yet, and therefore it is cancellable. + // - If the metadata is not set, there is nothing we can do anyway. + $komoju_payment_id = $order->get_meta('komoju_payment_id'); + if (!empty($komoju_payment_id)) { + $this->komoju_api->cancel($komoju_payment_id, []); + } + if (!$token || $token === '') { return parent::process_payment($order_id, $this->payment_method['type_slug']); } diff --git a/komoju-php/komoju-php/lib/komoju/KomojuApi.php b/komoju-php/komoju-php/lib/komoju/KomojuApi.php index 46bea67..a31ea42 100644 --- a/komoju-php/komoju-php/lib/komoju/KomojuApi.php +++ b/komoju-php/komoju-php/lib/komoju/KomojuApi.php @@ -59,6 +59,11 @@ public function refund($paymentUuid, $payload) return $this->post('/api/v1/payments/' . $paymentUuid . '/refund', $payload); } + public function cancel($paymentUuid, $payload) + { + return $this->post('/api/v1/payments/' . $paymentUuid . '/cancel', $payload); + } + private function get($uri, $asArray = false) { $ch = curl_init($this->endpoint . $uri);