PluginProbe
DOKU Payment / trunk
DOKU Payment vtrunk
1.3.30 trunk 1.3.17 1.3.18 1.3.19 1.3.20 1.3.21 1.3.22 1.3.23 1.3.24 1.3.25 1.3.26 1.3.27 1.3.28 1.3.29
doku-payment / Module / JokulCheckoutModule.php

JokulCheckoutModule.php in DOKU Payment trunk, at Module/JokulCheckoutModule.php

706 lines 33.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) exit;
4
5 require_once(DOKU_PAYMENT_PLUGIN_PATH . '/Service/JokulCheckoutService.php');
6 require_once(DOKU_PAYMENT_PLUGIN_PATH . '/Service/JokulCheckStatusService.php');
7 require_once(DOKU_PAYMENT_PLUGIN_PATH . '/Common/JokulDb.php');
8 require_once(DOKU_PAYMENT_PLUGIN_PATH . '/Common/JokulUtils.php');
9
10 class DokuCheckoutModule extends WC_Payment_Gateway
11 {
12 public $method_name;
13 public $method_code;
14 public $checkout_msg;
15 public $environmentPaymentJokul;
16 public $sandboxClientId;
17 public $sandboxSharedKey;
18 public $prodClientId;
19 public $prodSharedKey;
20 public $expiredTime;
21 public $emailNotifications;
22 public $abandonedCart;
23 public $timeRangeAbandonedCart;
24 public $customExpireDate;
25 public $channelName;
26 public $payment_method;
27 public $auto_redirect_jokul;
28 public $sac_check;
29 public $sac_textbox;
30 public $paymentDescription;
31 public $dokuUtils;
32 public $dokuDB;
33 public $dokuCheckStatusService;
34 public $dokuCheckoutService;
35 public $orderId;
36
37 public function __construct()
38 {
39 $this->init_form_fields();
40 $this->id = 'doku_checkout';
41 $this->has_fields = true;
42 $this->method_name = 'DOKU Checkout';
43 $this->method_code = 'JOKUL_CHECKOUT';
44 $this->title = !empty($this->get_option('channel_name')) ? $this->get_option('channel_name') : $this->method_name;
45 $this->method_title = __('DOKU Payment', 'doku-payment');
46 $this->method_description = sprintf(__('Customize how DOKU payment methods appear to your customers at checkout, including payment labels and QRIS configuration.', 'doku-payment'));
47 $this->checkout_msg = 'This your payment on DOKU Checkout : ';
48
49 $this->init_settings();
50 $mainSettings = get_option('woocommerce_doku_gateway_settings');
51 $this->environmentPaymentJokul = $mainSettings['environment_payment_jokul'];
52 $this->sandboxClientId = $mainSettings['sandbox_client_id'];
53 $this->sandboxSharedKey = $mainSettings['sandbox_shared_key'];
54 $this->prodClientId = $mainSettings['prod_client_id'];
55 $this->prodSharedKey = $mainSettings['prod_shared_key'];
56 $this->expiredTime = $mainSettings['expired_time'];
57 $this->emailNotifications = $mainSettings['email_notifications'];
58 $this->abandonedCart = $mainSettings['abandoned_cart'];
59 $this->timeRangeAbandonedCart = $mainSettings['time_range_abandoned_cart'];
60 $this->customExpireDate = $mainSettings['custom_time_range_abandoned_cart'];
61
62 $this->enabled = $this->get_option('enabled');
63 $this->channelName = $this->get_option('channel_name');
64 $paymentDescription = $this->get_option('payment_description');
65
66 $this->payment_method = $this->get_option('payment_method');
67 $this->auto_redirect_jokul = $this->get_option('auto_redirect_jokul');
68
69 $this->sac_check = $mainSettings['sac_check' ];
70 $this->sac_textbox = $mainSettings['sac_textbox'];
71
72 if (empty($paymentDescription)) {
73 $this->paymentDescription = 'Bayar Pesanan Dengan DOKU Checkout';
74 } else {
75 $this->paymentDescription = $paymentDescription;
76 }
77
78 add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
79
80 $queryArray = explode("&", sanitize_text_field($_SERVER['QUERY_STRING']));
81 if (WC()->session != null) {
82 $chosen_payment_method = WC()->session->get('chosen_payment_method');
83 if ($this->id == 'doku_checkout') {
84 if (in_array("jokul=show", $queryArray)) {
85 add_filter('the_title', array($this, 'woo_title_order_pending'));
86 add_action('woocommerce_thankyou_' . $this->id, array($this, 'thank_you_page_pending'), 1, 10);
87 } else {
88 add_filter('the_title', array($this, 'woo_title_order_received'));
89 }
90 }
91 }
92 if ( is_admin() ) {
93 if ( ! has_action( 'woocommerce_admin_order_data_after_order_details', array( 'DokuCheckoutModule', 'doku_add_check_status_button' ) ) ) {
94 add_action( 'woocommerce_admin_order_data_after_order_details', array( 'DokuCheckoutModule', 'doku_add_check_status_button' ) );
95 }
96 if ( ! has_action( 'wp_ajax_doku_check_status', array( 'DokuCheckoutModule', 'doku_handle_ajax_check_status' ) ) ) {
97 add_action( 'wp_ajax_doku_check_status', array( 'DokuCheckoutModule', 'doku_handle_ajax_check_status' ) );
98 }
99 if ( ! has_action( 'woocommerce_admin_order_data_after_billing_address', array( 'DokuCheckoutModule', 'doku_display_payment_status_in_billing' ) ) ) {
100 add_action( 'woocommerce_admin_order_data_after_billing_address', array( 'DokuCheckoutModule', 'doku_display_payment_status_in_billing' ) );
101 }
102 }
103
104 }
105
106 function calculateMinutes($abandonedCart, $timeRangeAbandonedCart, $customExpireDate) {
107 $minutes = 0;
108
109 if ($abandonedCart === 'yes') {
110 if ($timeRangeAbandonedCart !== 'Custom') {
111 switch ($timeRangeAbandonedCart) {
112 case 'Tomorrow':
113 $minutes = 1440;
114 break;
115 case '7':
116 case '7 day':
117 $minutes = 10080;
118 break;
119 case '14':
120 case '14 day':
121 $minutes = 20160;
122 break;
123 case '30':
124 case '30 day':
125 $minutes = 43200;
126 break;
127 default:
128 $minutes = 0;
129 break;
130 }
131 } else {
132 $customDays = max(1, min(30, intval($customExpireDate)));
133 $minutes = $customDays * 1440;
134 }
135 }
136
137 return $minutes;
138 }
139
140 public function get_order_data($order)
141 {
142 $pattern = "/[^A-Za-z0-9? .,_-]/";
143 $order_id = $order->get_id();
144 $dp = wc_get_price_decimals();
145 $order_data = array();
146 // add line items
147 foreach ($order->get_items() as $item_id => $item) {
148 $product = $item->get_product();
149 $term_names = wp_get_post_terms( $item->get_product_id(), 'product_cat', array('fields' => 'names') );
150 $categories_string = implode(',', $term_names);
151 $product_id = null;
152 $product_sku = null;
153 $image_url = null;
154 $product_url = null;
155
156 // Check if the product exists.
157 if (is_object($product)) {
158 $product_id = $product->get_id();
159 $product_sku = $product->get_sku();
160 $image_id = $product->get_image_id();
161 $image_url = wp_get_attachment_image_url( $image_id, 'full' );
162 $product_url = $product->get_permalink();
163 }
164
165 $order_data[] = array(
166 'id' => $product_id,
167 'price' => wc_format_decimal($order->get_item_total($item, false, false), $dp),
168 'quantity' => wc_stock_amount($item['qty']),
169 'name' => preg_replace($pattern, "", $item['name']),
170 'sku' => !empty($product_sku) ? $product_sku : $product_id,
171 'type' => 'produk',
172 'category' => 'marketplace',
173 'image_url' => !empty($image_url) ? $image_url : '',
174 'url' => $product_url
175 );
176 }
177 // Add shipping.
178 foreach ($order->get_shipping_methods() as $shipping_item_id => $shipping_item) {
179 $product = isset($item) && is_object($item) ? $item->get_product() : null;
180 $image_url = null;
181 $product_url = null;
182
183 // Check if the product exists.
184 if (is_object($product)) {
185 $product_id = $product->get_id();
186 $product_sku = $product->get_sku();
187 $image_id = $product->get_image_id();
188 $image_url = wp_get_attachment_image_url( $image_id, 'full' );
189 $product_url = $product->get_permalink();
190 }
191 if (wc_format_decimal($shipping_item['cost'], $dp) > 0) {
192 $order_data[] = array(
193 'id' => 'shipping',
194 'name' => preg_replace($pattern, "", $shipping_item['name']),
195 'price' => wc_format_decimal($shipping_item['cost'], $dp),
196 'quantity' => 1,
197 'sku' => 'shipping',
198 'type' => 'produk',
199 'category' => 'fee',
200 'image_url' => !empty($image_url) ? $image_url : '',
201 'url' => $product_url
202 );
203 }
204 }
205 // Add taxes.
206 foreach ($order->get_tax_totals() as $tax_code => $tax) {
207 $product = isset($item) && is_object($item) ? $item->get_product() : null;
208 $image_url = null;
209 $product_url = null;
210
211 if (is_object($product)) {
212 $product_id = $product->get_id();
213 $image_id = $product->get_image_id();
214 $image_url = wp_get_attachment_image_url( $image_id, 'full' );
215 $product_url = $product->get_permalink();
216 }
217 if (wc_format_decimal($tax->amount, $dp) > 0) {
218 $order_data[] = array(
219 'id' => 'tax-' . $product_id . '-' . preg_replace($pattern, "", $tax->label),
220 'name' => preg_replace($pattern, "", $tax->label),
221 'price' => wc_format_decimal($tax->amount, $dp),
222 'quantity' => 1,
223 'type' => 'produk',
224 'sku' => 'tax-' . $product_id . '-' . preg_replace($pattern, "", $tax->label),
225 'category' => 'fee',
226 'image_url' => !empty($image_url) ? $image_url : '',
227 'url' => $product_url
228 );
229 }
230 }
231 // Add fees.
232 foreach ($order->get_fees() as $fee_item_id => $fee_item) {
233 $product = isset($item) && is_object($item) ? $item->get_product() : null;
234 $image_url = null;
235 $product_url = null;
236
237 if (is_object($product)) {
238 $product_id = $product->get_id();
239 $image_id = $product->get_image_id();
240 $image_url = wp_get_attachment_image_url( $image_id, 'full' );
241 $product_url = $product->get_permalink();
242 }
243 $fee_name = isset($fee_item['name']) ? $fee_item['name'] : '';
244 $order_data[] = array(
245 'id' => 'fee-' . $product_id . '-' . preg_replace($pattern, "", $fee_name),
246 'name' => preg_replace($pattern, "", $fee_name),
247 'price' => wc_format_decimal($order->get_line_total($fee_item), $dp),
248 'quantity' => 1,
249 'type' => 'produk',
250 'sku' => 'fee-' . $product_id . '-' . preg_replace($pattern, "", $fee_name),
251 'category' => 'fee',
252 'image_url' => !empty($image_url) ? $image_url : '',
253 'url' => $product_url
254 );
255 }
256 // woocommerce_cli_order_data is a WooCommerce core hook, used here to filter order data.
257 // This hook name is not created or defined by this plugin and cant be modified.
258 $order_data = apply_filters('woocommerce_cli_order_data', $order_data);
259 return $order_data;
260 }
261
262 public function process_payment($order_id)
263 {
264 global $woocommerce;
265 $pattern = "/[^A-Za-z0-9? .-\/+,=_:@]/";
266
267 $order = wc_get_order($order_id);
268 $amount = $order->get_total();
269 $order_data = $order->get_data();
270
271 $this->dokuUtils = new DokuUtils();
272 $formattedPhoneNumber = $this->dokuUtils->formatPhoneNumber($order->get_billing_phone());
273
274 $params = array(
275 'customerId' => 0 !== $order->get_customer_id() ? $order->get_customer_id() : null,
276 'customerEmail' => $order->get_billing_email(),
277 'first_name' => $order->get_billing_first_name(),
278 'last_name' => $order->get_billing_last_name(),
279 'customerName' => $order->get_billing_first_name() . " " . $order->get_billing_last_name(),
280 'amount' => $amount,
281 'invoiceNumber' => $order->get_order_number(),
282 'expiryTime' => $this->expiredTime,
283 'phone' => $formattedPhoneNumber,
284 'country' => $order->get_billing_country(),
285 'address' => preg_replace($pattern, "", $order->get_shipping_address_1()),
286 'itemQty' => $this->get_order_data($order),
287 'payment_method' => $this->payment_method,
288 'postcode' => $order_data['billing']['postcode'],
289 'state' => $order_data['billing']['state'],
290 'city' => $order_data['billing']['city'],
291 'info1' => '',
292 'info2' => '',
293 'info3' => '',
294 'woo_version' => $woocommerce->version,
295 'reusableStatus' => false,
296 'callback_url_result' => $this->get_return_url($order) . '&' . $order_id,
297 'sac_check' => $this->sac_check,
298 'auto_redirect' => $this->auto_redirect_jokul,
299 'sac_textbox' => $this->sac_textbox,
300 'first_name_shipping' => $order->get_shipping_first_name(),
301 'address_shipping' => preg_replace($pattern, "", $order->get_shipping_address_1()),
302 'city_shipping' => $order->get_shipping_city(),
303 'postal_code_shipping' => $order->get_shipping_postcode(),
304 'recoverAbandonedCart' => ($this->abandonedCart === 'yes'),
305 'expiredRecoveredCart' => $this->calculateMinutes($this->abandonedCart, $this->timeRangeAbandonedCart, $this->customExpireDate)
306 );
307
308 if ($this->environmentPaymentJokul == 'false') {
309 $clientId = $this->sandboxClientId;
310 $sharedKey = $this->sandboxSharedKey;
311 } else if ($this->environmentPaymentJokul == 'true') {
312 $clientId = $this->prodClientId;
313 $sharedKey = $this->prodSharedKey;
314 }
315
316 $config = array(
317 'client_id' => $clientId,
318 'shared_key' => $sharedKey,
319 'environment' => $this->environmentPaymentJokul
320 );
321
322 update_post_meta($order_id, 'checkoutParams', $params);
323 update_post_meta($order_id, 'checkoutConfig', $config);
324
325 $this->dokuCheckoutService = new DokuCheckoutService();
326 $response = $this->dokuCheckoutService->generated($config, $params);
327 if (!is_wp_error($response)) {
328 if (isset($response['message']) && is_array($response['message']) && isset($response['message'][0]) && $response['message'][0] == "SUCCESS" && isset($response['response']['payment']['url'])) {
329 update_post_meta($order_id, 'checkoutUrl', $response['response']['payment']['url']);
330 $resultDb = DokuCheckoutModule::addDb($response, $amount);
331 if($resultDb === false || $resultDb === 0){
332 http_response_code(500);
333 echo esc_html(http_response_code());
334 wc_add_notice('Cant be proceed into checkout page. Please try again.', 'error');
335 }
336 $this->orderId = $order_id;
337 return array(
338 'result' => 'success',
339 'redirect' => $response['response']['payment']['url']
340 );
341 } else {
342 $error_msg = 'Unknown error';
343 if (isset($response['error']['message']) && is_string($response['error']['message'])) {
344 $error_msg = $response['error']['message'];
345 } elseif (isset($response['message'])) {
346 if (is_array($response['message']) && !empty($response['message'][0])) {
347 $error_msg = is_string($response['message'][0]) ? $response['message'][0] : json_encode($response['message'][0]);
348 } elseif (is_string($response['message'])) {
349 $error_msg = $response['message'];
350 }
351 } elseif (isset($response['error']) && is_string($response['error'])) {
352 $error_msg = $response['error'];
353 }
354 wc_add_notice('There is something wrong. Please try again. ' . $error_msg, 'error');
355 return array(
356 'result' => 'failure',
357 'redirect' => ''
358 );
359 }
360 } else {
361 wc_add_notice('There is something wrong. Please try again.', 'error');
362 return array(
363 'result' => 'failure',
364 'redirect' => ''
365 );
366 }
367 }
368
369 public function init_form_fields()
370 {
371 $this->form_fields = require(DOKU_PAYMENT_PLUGIN_PATH . '/Form/JokulCheckoutSetting.php');
372 }
373
374 public function process_admin_options()
375 {
376 $this->init_settings();
377
378 $post_data = $this->get_post_data();
379
380 foreach ($this->get_form_fields() as $key => $field) {
381 if ('title' !== $this->get_field_type($field)) {
382 try {
383 $this->settings[$key] = $this->get_field_value($key, $field, $post_data);
384 } catch (Exception $e) {
385 $this->add_error($e->getMessage());
386 }
387 }
388 }
389
390 if (!isset($post_data['woocommerce_' . $this->id . '_enabled']) && $this->get_option_key() == 'woocommerce_' . $this->id . '_settings') {
391 $this->settings['enabled'] = $this->enabled;
392 }
393
394 if (isset($post_data['woocommerce_' . $this->id . '_secret_key']) || isset($post_data['woocommerce_' . $this->id . '_secret_key_dev'])) {
395 delete_transient('main_settings_jokul_pg');
396 }
397 // woocommerce_settings_api_sanitized_fields_ is a WooCommerce core hook, do not modify its name
398 // This hook name is not created or defined by this plugin and cant be modified.
399 return update_option($this->get_option_key(), apply_filters('woocommerce_settings_api_sanitized_fields_' . $this->id, $this->settings), 'yes');
400 }
401
402 public function admin_options()
403 {
404 wp_enqueue_script(
405 'admin-options-module',
406 plugin_dir_url(__FILE__) . '../Js/admin-options-module.js',
407 ['jquery'],
408 '1.0.0',
409 true
410 );
411
412 wp_localize_script('admin-options-module', 'woocommerceData', [
413 'id' => $this->id,
414 'title' => $this->title
415 ]);
416
417 ?>
418 <table class="form-table">
419 <?php $this->generate_settings_html(); ?>
420 </table>
421 <?php
422 }
423
424
425 public function payment_fields()
426 {
427 if ($this->paymentDescription) {
428 echo esc_html($this->paymentDescription);
429 }
430 }
431
432 public function addDb($response, $amount)
433 {
434 $this->dokuUtils = new DokuUtils();
435 $getIp = $this->dokuUtils->getIpaddress();
436 $trx = array();
437 $trx['invoice_number'] = $response['response']['order']['invoice_number'];
438 $trx['result_msg'] = $response['message'][0];
439 $trx['process_type'] = 'PAYMENT_PENDING';
440 $trx['raw_post_data'] = json_encode($response);
441 $trx['ip_address'] = $getIp;
442 $trx['amount'] = $amount;
443 $trx['payment_channel'] = $this->method_code;
444 $trx['payment_code'] = "";
445 $trx['doku_payment_datetime'] = gmdate("Y-m-d H:i:s");
446 $trx['process_datetime'] = gmdate("Y-m-d H:i:s");
447 $trx['message'] = "Payment Pending message come from Jokul. Success : completed";
448
449
450 $this->dokuDB = new DokuDB();
451 return $this->dokuDB->addData($trx);
452 }
453
454 public function thank_you_page_pending($order_id)
455 {
456 $jokulCheckoutURL = get_post_meta($order_id, 'checkoutUrl', true);
457 if (!$jokulCheckoutURL) {
458 return;
459 }
460
461 header('Location: ' . $jokulCheckoutURL);
462 die();
463 }
464
465 function woo_title_order_pending($title)
466 {
467 if ($title === 'Order received') {
468 return "Payment Pending";
469 } else {
470 return $title;
471 }
472 }
473
474 function woo_title_order_received($title)
475 {
476 global $woocommerce;
477
478 if (function_exists('is_order_received_page') && is_order_received_page() && $title === 'Order received') {
479 global $wp;
480 $order_id = absint($wp->query_vars['order-received']);
481 $order = wc_get_order($order_id);
482
483 if (!$order || $order->get_payment_method() !== 'doku_checkout') {
484 return $title;
485 }
486
487 $woocommerce->cart->empty_cart();
488 wc_reduce_stock_levels($order->get_id());
489
490 $paramsValue = get_post_meta($order->get_id(), 'checkoutParams', true);
491 $configValue = get_post_meta($order->get_id(), 'checkoutConfig', true);
492
493 if (is_array($paramsValue) && is_array($configValue)) {
494 $this->dokuCheckStatusService = new DokuCheckStatusService();
495 $response = $this->dokuCheckStatusService->generated($configValue, $paramsValue);
496
497 if (!is_wp_error($response) && is_array($response)) {
498 if (isset($response['acquirer']['id']) && strtolower($response['acquirer']['id']) == strtolower('OVO')) {
499 $dokuUtils = new DokuUtils();
500 $dokuDB = new DokuDB();
501 $dokuUtils->doku_log($dokuUtils, 'Jokul Acquirer : ' . $response['acquirer']['id'], $paramsValue['invoiceNumber']);
502 if (isset($response['transaction']['status']) && strtolower($response['transaction']['status']) == strtolower('SUCCESS')) {
503 $dokuDB->updateData($paramsValue['invoiceNumber'], $response['transaction']['status']);
504 $order = wc_get_order($paramsValue['invoiceNumber']);
505 $order->update_status('processing');
506 $order->payment_complete();
507 $dokuUtils->doku_log($dokuUtils, 'DOKU Check Status Update Status : ' . 'processing', $paramsValue['invoiceNumber']);
508 } else {
509 $dokuDB->updateData($paramsValue['invoiceNumber'], $response['transaction']['status'] ?? 'FAILED');
510 $order = wc_get_order($paramsValue['invoiceNumber']);
511 $order->update_status('failed');
512 $dokuUtils->doku_log($dokuUtils, 'DOKU Check Status Update Status : ' . 'failed', $paramsValue['invoiceNumber']);
513 }
514 }
515 }
516 }
517
518 return "Order Received";
519 } else {
520 return $title;
521 }
522 }
523
524 public static function doku_add_check_status_button( $order ) {
525 if ( $order->get_payment_method() === 'doku_checkout' && $order->has_status( array( 'pending', 'on-hold', 'cancelled' ) ) ) {
526 wp_enqueue_script(
527 'doku-admin-check-status',
528 plugin_dir_url(__FILE__) . '../Js/doku-admin-check-status.js',
529 array('jquery'),
530 '1.0.0',
531 true
532 );
533
534 wp_localize_script('doku-admin-check-status', 'dokuAdminCheckStatusData', array(
535 'ajaxurl' => admin_url('admin-ajax.php'),
536 'nonce' => wp_create_nonce( "doku_check_status_nonce" ),
537 'order_id' => $order->get_id()
538 ));
539 ?>
540 <div class="form-field form-field-wide" style="border-top: 1px solid #eee; padding-top: 15px; margin-top: 15px; clear: both;">
541 <div style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap;">
542 <button type="button" id="doku-check-status-btn" class="button button-primary button-large">
543 <?php _e( 'Check Payment Status', 'doku-payment' ); ?>
544 </button>
545 <span id="doku-status-spinner" class="spinner" style="float: none; margin: 0; vertical-align: middle;"></span>
546 </div>
547 <div style="margin-top: 10px; min-height: 20px;">
548 <div id="doku-status-feedback" style="font-weight: bold; font-size: 13px; display: inline-block;"></div>
549 </div>
550 </div>
551 <?php
552 }
553 }
554
555 public static function doku_handle_ajax_check_status() {
556 check_ajax_referer( 'doku_check_status_nonce', 'security' );
557
558 if ( ! current_user_can( 'manage_woocommerce' ) && ! current_user_can( 'edit_shop_orders' ) ) {
559 wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
560 }
561
562 $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0;
563 if ( ! $order_id ) {
564 wp_send_json_error( array( 'message' => 'Invalid Order ID.' ) );
565 }
566
567 $order = wc_get_order( $order_id );
568 if ( ! $order ) {
569 wp_send_json_error( array( 'message' => 'Order not found.' ) );
570 }
571
572 $paramsValue = get_post_meta( $order_id, 'checkoutParams', true );
573 $configValue = get_post_meta( $order_id, 'checkoutConfig', true );
574
575 if ( ! is_array( $paramsValue ) || ! is_array( $configValue ) ) {
576 wp_send_json_error( array( 'message' => 'DOKU parameters/config not found for this order.' ) );
577 }
578
579 require_once( DOKU_PAYMENT_PLUGIN_PATH . '/Service/JokulCheckStatusService.php' );
580 $checkStatusService = new DokuCheckStatusService();
581 $response = $checkStatusService->generated( $configValue, $paramsValue );
582
583 $dokuUtils = new DokuUtils();
584 $dokuDB = new DokuDB();
585
586 // Log to debug.log and doku_log (Dual Logging)
587 error_log('Manual Check Status Request for Invoice: ' . $paramsValue['invoiceNumber']);
588 $dokuUtils->doku_log('DokuCheckoutModule', '===== MANUAL CHECK STATUS START =====', $paramsValue['invoiceNumber']);
589 $dokuUtils->doku_log('DokuCheckoutModule', 'Manual Check Status Request config: ' . json_encode( $configValue ), $paramsValue['invoiceNumber']);
590
591 if ( is_wp_error( $response ) || ! is_array( $response ) ) {
592 error_log('Manual Check Status Error for Invoice: ' . $paramsValue['invoiceNumber'] . ' - Connection failed');
593 $dokuUtils->doku_log('DokuCheckoutModule', 'Manual Check Status Error: Connection failed or invalid response format', $paramsValue['invoiceNumber']);
594 $dokuUtils->doku_log('DokuCheckoutModule', '===== MANUAL CHECK STATUS END - HTTP 500 =====', $paramsValue['invoiceNumber']);
595 wp_send_json_error( array( 'message' => 'Failed to connect to DOKU API.' ) );
596 }
597
598 error_log('Manual Check Status Response for Invoice: ' . $paramsValue['invoiceNumber'] . ' - Status: ' . ($response['transaction']['status'] ?? 'UNKNOWN'));
599 $dokuUtils->doku_log('DokuCheckoutModule', 'Manual Check Status Response: ' . json_encode( $response, JSON_PRETTY_PRINT ), $paramsValue['invoiceNumber']);
600
601 if ( ! isset( $response['transaction'] ) ) {
602 $error_detail = 'Invalid API Response';
603 if ( isset( $response['error']['message'] ) ) {
604 $error_detail = $response['error']['message'];
605 } elseif ( isset( $response['message'] ) ) {
606 $error_detail = $response['message'];
607 }
608
609 $dokuUtils->doku_log('DokuCheckoutModule', 'Manual Check Status API/Credential Error. Status remains unchanged. Response: ' . json_encode( $response ), $paramsValue['invoiceNumber']);
610 $dokuUtils->doku_log('DokuCheckoutModule', '===== MANUAL CHECK STATUS END =====', $paramsValue['invoiceNumber']);
611
612 wp_send_json_error( array(
613 'message' => 'API Error: ' . $error_detail,
614 'should_reload' => false
615 ) );
616 }
617
618 if ( isset( $response['transaction']['status'] ) && strtolower( $response['transaction']['status'] ) == strtolower( 'SUCCESS' ) ) {
619 // Update database jokuldb
620 $dokuDB->updateData( $paramsValue['invoiceNumber'], 'PAYMENT_COMPLETED' );
621
622 // Complete order in WooCommerce
623 $order->update_status( 'processing' );
624 $order->payment_complete();
625 $order->add_order_note( __( 'DOKU: Manual Check Status succeeded. Payment marked as completed.', 'doku-payment' ) );
626
627 $dokuUtils->doku_log('DokuCheckoutModule', 'Manual Check Status SUCCESS. Order updated to processing.', $paramsValue['invoiceNumber']);
628 $dokuUtils->doku_log('DokuCheckoutModule', '===== MANUAL CHECK STATUS END - HTTP 200 =====', $paramsValue['invoiceNumber']);
629 wp_send_json_success( array( 'message' => 'Payment SUCCESS! Order status updated to Processing.' ) );
630 } else {
631 $status = isset( $response['transaction']['status'] ) ? $response['transaction']['status'] : 'UNKNOWN';
632
633 if ( strtolower( $status ) == 'failed' ) {
634 // Update database jokuldb to failed
635 $dokuDB->updateData( $paramsValue['invoiceNumber'], 'PAYMENT_FAILED' );
636
637 // Fail order in WooCommerce
638 $order->update_status( 'failed', __( 'DOKU: Manual Check Status detected failed payment. Status updated to Failed.', 'doku-payment' ) );
639
640 $dokuUtils->doku_log('DokuCheckoutModule', 'Manual Check Status FAILED. Order updated to failed. Response: ' . json_encode( $response ), $paramsValue['invoiceNumber']);
641 $dokuUtils->doku_log('DokuCheckoutModule', '===== MANUAL CHECK STATUS END - HTTP 200 =====', $paramsValue['invoiceNumber']);
642 wp_send_json_error( array(
643 'message' => 'Payment FAILED! Order status updated to Failed.',
644 'should_reload' => true
645 ) );
646 } elseif ( strtolower( $status ) == 'expired' ) {
647 // Update database jokuldb to expired
648 $dokuDB->updateData( $paramsValue['invoiceNumber'], 'PAYMENT_EXPIRED' );
649
650 // Cancel order in WooCommerce
651 if ( ! $order->has_status( 'cancelled' ) ) {
652 $order->update_status( 'cancelled', __( 'DOKU: Manual Check Status detected expired payment. Status updated to Cancelled.', 'doku-payment' ) );
653 }
654
655 $dokuUtils->doku_log('DokuCheckoutModule', 'Manual Check Status EXPIRED. Order updated to cancelled. Response: ' . json_encode( $response ), $paramsValue['invoiceNumber']);
656 $dokuUtils->doku_log('DokuCheckoutModule', '===== MANUAL CHECK STATUS END - HTTP 200 =====', $paramsValue['invoiceNumber']);
657 wp_send_json_error( array(
658 'message' => 'Payment EXPIRED! Order status updated to Cancelled.',
659 'should_reload' => true
660 ) );
661 } else {
662 $order->add_order_note( sprintf( __( 'DOKU: Manual Check Status returned status: %s.', 'doku-payment' ), $status ) );
663
664 $dokuUtils->doku_log('DokuCheckoutModule', 'Manual Check Status result: ' . $status . ' - Response: ' . json_encode( $response ), $paramsValue['invoiceNumber']);
665 $dokuUtils->doku_log('DokuCheckoutModule', '===== MANUAL CHECK STATUS END =====', $paramsValue['invoiceNumber']);
666 wp_send_json_error( array(
667 'message' => 'Payment status is currently: ' . $status,
668 'should_reload' => false
669 ) );
670 }
671 }
672 }
673
674 public static function doku_display_payment_status_in_billing( $order ) {
675 if ( $order->get_payment_method() === 'doku_checkout' ) {
676 global $wpdb;
677 $table = $wpdb->prefix . 'jokuldb';
678 $trx_status = $wpdb->get_var( $wpdb->prepare( "SELECT process_type FROM $table WHERE invoice_number = %s ORDER BY trx_id DESC LIMIT 1", $order->get_id() ) );
679
680 // Format status label and color
681 $status_label = 'PENDING';
682 $status_color = '#ecc715'; // Yellow/Orange for pending
683
684 if ( $trx_status ) {
685 if ( strpos( strtoupper( $trx_status ), 'COMPLETED' ) !== false || strtoupper( $trx_status ) === 'SUCCESS' ) {
686 $status_label = 'SUCCESS';
687 $status_color = '#46b450'; // Green for success
688 } elseif ( strpos( strtoupper( $trx_status ), 'FAILED' ) !== false ) {
689 $status_label = 'FAILED';
690 $status_color = '#dc3232'; // Red for failed
691 } elseif ( strpos( strtoupper( $trx_status ), 'EXPIRED' ) !== false ) {
692 $status_label = 'EXPIRED';
693 $status_color = '#767676'; // Dark Gray for expired
694 } else {
695 $status_label = strtoupper( $trx_status );
696 }
697 }
698
699 echo '<div style="margin-top: 15px; border-top: 1px dashed #ccc; padding-top: 10px;">';
700 echo '<p><strong>DOKU Payment Status:</strong><br />';
701 echo '<span style="display: inline-block; margin-top: 5px; font-weight: bold; color: #fff; background-color: ' . esc_attr( $status_color ) . '; padding: 4px 10px; border-radius: 4px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px;">' . esc_html( $status_label ) . '</span></p>';
702 echo '</div>';
703 }
704 }
705 }
706