From 87d757d56d029be9ef19c0d67a85e4c779604e4b Mon Sep 17 00:00:00 2001 From: Grant Date: Fri, 1 Mar 2024 12:29:15 +0900 Subject: [PATCH 1/8] initial work --- Dockerfile | 2 +- docker-compose.yml | 2 +- includes/class-wc-gateway-komoju-block.php | 72 ++++++++++++++++++++++ index.php | 46 +++++++++++++- 4 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 includes/class-wc-gateway-komoju-block.php diff --git a/Dockerfile b/Dockerfile index 88bf1cc..395c4ba 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM wordpress:6.1.1 +FROM wordpress:6.4.2 ARG woocommerce_version diff --git a/docker-compose.yml b/docker-compose.yml index d4f8080..2790464 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,7 +21,7 @@ services: context: . dockerfile: Dockerfile args: - woocommerce_version: 6.3.1 + woocommerce_version: 8.5.1 ports: - "8000:80" restart: always diff --git a/includes/class-wc-gateway-komoju-block.php b/includes/class-wc-gateway-komoju-block.php new file mode 100644 index 0000000..e9c220e --- /dev/null +++ b/includes/class-wc-gateway-komoju-block.php @@ -0,0 +1,72 @@ +settings = get_option('woocommerce_wc_gateway_komoju_settings', []); + // $this->settings = get_option('woocommerce_komoju_settings', []); + // require_once '../class-wc-gateway-komoju.php'; + require_once dirname(__DIR__) . '/class-wc-gateway-komoju.php'; + $this->gateway = new WC_Gateway_Komoju(); + $this->settings = $this->gateway->settings; + // $this->settings = get_option('woocommerce_komoju_settings', []); + error_log('WC_Gateway_Komoju_Blocks gateway: ' . print_r($this->gateway, true)); + error_log('WC_Gateway_Komoju_Blocks settings: ' . print_r($this->settings, true)); + error_log('WC_Gateway_Komoju_Blocks title: ' . print_r($this->gateway->title, true)); + } + + public function is_active() { + error_log('WC_Gateway_Komoju_Blocks is_available 2: ' . print_r($this->gateway->is_available(), true)); + // return $this->gateway->is_available(); + return true; + } + + // public function get_payment_method_script_handles() { + // error_log('in get_payment_method_script_handles'); + + // // if (!is_checkout()) { + // // return []; + // // } + + // $komoju_fields_js = get_option('komoju_woocommerce_fields_url'); + // if (!$komoju_fields_js) { + // $komoju_fields_js = 'https://multipay.komoju.com/fields.js'; + // } + + // // wp_enqueue_script('komoju-fields', $komoju_fields_js); + + // wp_register_script( + // 'WC_Gateway_Komoju-blocks-integration', + // $komoju_fields_js, + // [ + // 'wc-blocks-registry', + // 'wc-settings', + // 'wp-element', + // 'wp-html-entities', + // 'wp-i18n', + // ], + // null, + // true + // ); + // // if( function_exists( 'wp_set_script_translations' ) ) { + // // wp_set_script_translations( 'wc_gateway_komoju-blocks-integration'); + + // // } + // return [ 'WC_Gateway_Komoju-blocks-integration' ]; + // } + + public function get_payment_method_data() { + error_log('in get_payment_method_data'); + return [ + 'title' => $this->gateway->title, + //'description' => $this->gateway->description, + ]; + } + +} +?> \ No newline at end of file diff --git a/index.php b/index.php index 7fcf6c3..ecb1561 100755 --- a/index.php +++ b/index.php @@ -6,6 +6,7 @@ Version: 3.0.8 Author: KOMOJU Author URI: https://komoju.com +WC tested up to: 8.5 */ add_action('plugins_loaded', 'woocommerce_komoju_init', 0); @@ -92,10 +93,53 @@ function woocommerce_komoju_handle_http_request() } } + /** + * Custom function to declare compatibility with cart_checkout_blocks feature + */ + function woocommerce_komoju_declare_checkout_blocks_compatibility() { + error_log('in woocommerce_komoju_declare_checkout_blocks_compatibility 2'); + // Check if the required class exists + if (class_exists('\Automattic\WooCommerce\Utilities\FeaturesUtil')) { + // Declare compatibility for 'cart_checkout_blocks' + \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('cart_checkout_blocks', __FILE__, true); + } + } + + /** + * Custom function to register a payment method type + + */ + function woocommerce_komoju_register_order_approval_payment_method_type() { + error_log('in woocommerce_komoju_register_order_approval_payment_method_type 2'); + + // Check if the required class exists + if (!class_exists('Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType')) { + return; + } + + // Include the custom Blocks Checkout class + require_once 'includes/class-wc-gateway-komoju-block.php'; + + // Hook the registration function to the 'woocommerce_blocks_payment_method_type_registration' action + add_action( + 'woocommerce_blocks_payment_method_type_registration', + function(Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry) { + // Register an instance of My_Custom_Gateway_Blocks + $payment_method_registry->register(new WC_Gateway_Komoju_Blocks); + } + ); + } + + add_filter('woocommerce_payment_gateways', 'woocommerce_add_komoju_gateway'); + + // Block setup actions + add_action('before_woocommerce_init', 'woocommerce_komoju_declare_checkout_blocks_compatibility'); + add_action('woocommerce_blocks_loaded', 'woocommerce_komoju_register_order_approval_payment_method_type'); + add_filter('woocommerce_get_settings_pages', 'woocommerce_add_komoju_settings_page'); add_action('woocommerce_api_wc_gateway_komoju', 'woocommerce_komoju_handle_http_request'); add_action('wp_enqueue_scripts', 'woocommerce_komoju_load_scripts'); add_filter('script_loader_tag', 'woocommerce_komoju_load_script_as_module', 10, 3); -} +} \ No newline at end of file From 43a83c3274bff6ecbe17eef277b71536c1c14828 Mon Sep 17 00:00:00 2001 From: Grant Date: Tue, 12 Mar 2024 17:12:57 +0900 Subject: [PATCH 2/8] some work trying to get blocks to work --- class-wc-gateway-komoju.php | 10 ++- includes/class-wc-gateway-komoju-block.php | 71 +++++++++---------- .../class-wc-gateway-komoju-single-slug.php | 10 +++ index.php | 8 +-- 4 files changed, 53 insertions(+), 46 deletions(-) diff --git a/class-wc-gateway-komoju.php b/class-wc-gateway-komoju.php index 8241ff2..7855c19 100755 --- a/class-wc-gateway-komoju.php +++ b/class-wc-gateway-komoju.php @@ -11,7 +11,7 @@ * @class WC_Gateway_Komoju * @extends WC_Payment_Gateway * - * @version 3.0.8 + * @version 3.1.0 * * @author Komoju */ @@ -28,6 +28,14 @@ class WC_Gateway_Komoju extends WC_Payment_Gateway /** @var WC_Logger Logger instance */ public static $log; + protected $debug; + protected $invoice_prefix; + protected $secretKey; + protected $webhookSecretToken; + protected $komoju_api; + protected $instructions; + protected $useOnHold; + /** * Constructor for the gateway. */ diff --git a/includes/class-wc-gateway-komoju-block.php b/includes/class-wc-gateway-komoju-block.php index e9c220e..e1497d0 100644 --- a/includes/class-wc-gateway-komoju-block.php +++ b/includes/class-wc-gateway-komoju-block.php @@ -5,60 +5,54 @@ class WC_Gateway_Komoju_Blocks extends AbstractPaymentMethodType { private $gateway; - protected $name = 'WC_Gateway_Komoju'; + protected $name = 'komoju'; // I think this is the id of WC_Gateway_Komoju public function initialize() { - // $this->settings = get_option('woocommerce_wc_gateway_komoju_settings', []); - // $this->settings = get_option('woocommerce_komoju_settings', []); - // require_once '../class-wc-gateway-komoju.php'; require_once dirname(__DIR__) . '/class-wc-gateway-komoju.php'; $this->gateway = new WC_Gateway_Komoju(); $this->settings = $this->gateway->settings; // $this->settings = get_option('woocommerce_komoju_settings', []); - error_log('WC_Gateway_Komoju_Blocks gateway: ' . print_r($this->gateway, true)); - error_log('WC_Gateway_Komoju_Blocks settings: ' . print_r($this->settings, true)); - error_log('WC_Gateway_Komoju_Blocks title: ' . print_r($this->gateway->title, true)); } public function is_active() { - error_log('WC_Gateway_Komoju_Blocks is_available 2: ' . print_r($this->gateway->is_available(), true)); - // return $this->gateway->is_available(); + error_log('WC_Gateway_Komoju_Blocks is_available: ' . print_r($this->gateway->is_available(), true)); + // return $this->gateway->is_available(); // Maybe we can get this from the gateway settings? return true; } - // public function get_payment_method_script_handles() { - // error_log('in get_payment_method_script_handles'); - - // // if (!is_checkout()) { - // // return []; - // // } + // Not sure what to do about this. We don't have js files to load directly... + public function get_payment_method_script_handles() { + if (!is_checkout()) { + return []; + } - // $komoju_fields_js = get_option('komoju_woocommerce_fields_url'); - // if (!$komoju_fields_js) { - // $komoju_fields_js = 'https://multipay.komoju.com/fields.js'; - // } + $komoju_fields_js = get_option('komoju_woocommerce_fields_url'); + // Is this where we store our checkout js? + if (!$komoju_fields_js) { + $komoju_fields_js = 'https://multipay.komoju.com/fields.js'; + } - // // wp_enqueue_script('komoju-fields', $komoju_fields_js); + // wp_enqueue_script('komoju-fields', $komoju_fields_js); - // wp_register_script( - // 'WC_Gateway_Komoju-blocks-integration', - // $komoju_fields_js, - // [ - // 'wc-blocks-registry', - // 'wc-settings', - // 'wp-element', - // 'wp-html-entities', - // 'wp-i18n', - // ], - // null, - // true - // ); - // // if( function_exists( 'wp_set_script_translations' ) ) { - // // wp_set_script_translations( 'wc_gateway_komoju-blocks-integration'); + wp_register_script( + 'WC_Gateway_Komoju-blocks-integration', + $komoju_fields_js, + [ + 'wc-blocks-registry', + 'wc-settings', + 'wp-element', + 'wp-html-entities', + 'wp-i18n', + ], + null, + true + ); + // if( function_exists( 'wp_set_script_translations' ) ) { + // wp_set_script_translations( 'wc_gateway_komoju-blocks-integration'); - // // } - // return [ 'WC_Gateway_Komoju-blocks-integration' ]; - // } + // } + return [ 'WC_Gateway_Komoju-blocks-integration' ]; + } public function get_payment_method_data() { error_log('in get_payment_method_data'); @@ -67,6 +61,5 @@ public function get_payment_method_data() { //'description' => $this->gateway->description, ]; } - } ?> \ No newline at end of file diff --git a/includes/class-wc-gateway-komoju-single-slug.php b/includes/class-wc-gateway-komoju-single-slug.php index 7988bf7..ff719aa 100644 --- a/includes/class-wc-gateway-komoju-single-slug.php +++ b/includes/class-wc-gateway-komoju-single-slug.php @@ -12,6 +12,16 @@ */ class WC_Gateway_Komoju_Single_Slug extends WC_Gateway_Komoju { + protected $publishableKey; + protected $payment_method; + protected $debug; + protected $invoice_prefix; + protected $secretKey; + protected $webhookSecretToken; + protected $komoju_api; + protected $instructions; + protected $useOnHold; + public function __construct($payment_method) { $slug = $payment_method['type_slug']; diff --git a/index.php b/index.php index ecb1561..3630b87 100755 --- a/index.php +++ b/index.php @@ -3,7 +3,7 @@ Plugin Name: KOMOJU Payments Plugin URI: https://github.com/komoju/komoju-woocommerce Description: Extends WooCommerce with KOMOJU gateway. -Version: 3.0.8 +Version: 3.1.0 Author: KOMOJU Author URI: https://komoju.com WC tested up to: 8.5 @@ -97,7 +97,6 @@ function woocommerce_komoju_handle_http_request() * Custom function to declare compatibility with cart_checkout_blocks feature */ function woocommerce_komoju_declare_checkout_blocks_compatibility() { - error_log('in woocommerce_komoju_declare_checkout_blocks_compatibility 2'); // Check if the required class exists if (class_exists('\Automattic\WooCommerce\Utilities\FeaturesUtil')) { // Declare compatibility for 'cart_checkout_blocks' @@ -110,8 +109,6 @@ function woocommerce_komoju_declare_checkout_blocks_compatibility() { */ function woocommerce_komoju_register_order_approval_payment_method_type() { - error_log('in woocommerce_komoju_register_order_approval_payment_method_type 2'); - // Check if the required class exists if (!class_exists('Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType')) { return; @@ -124,13 +121,12 @@ function woocommerce_komoju_register_order_approval_payment_method_type() { add_action( 'woocommerce_blocks_payment_method_type_registration', function(Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry) { - // Register an instance of My_Custom_Gateway_Blocks + // Register an instance of WC_Gateway_Komoju_Blocks $payment_method_registry->register(new WC_Gateway_Komoju_Blocks); } ); } - add_filter('woocommerce_payment_gateways', 'woocommerce_add_komoju_gateway'); // Block setup actions From 99f8c62a64b617f2a8267483443f265e4ca763d0 Mon Sep 17 00:00:00 2001 From: Grant Date: Tue, 12 Mar 2024 20:26:40 +0900 Subject: [PATCH 3/8] more work --- includes/class-wc-gateway-komoju-block.php | 83 ++++++++++--------- index.php | 23 +++-- .../komoju-php/lib/komoju/KomojuApi.php | 4 + 3 files changed, 66 insertions(+), 44 deletions(-) diff --git a/includes/class-wc-gateway-komoju-block.php b/includes/class-wc-gateway-komoju-block.php index e1497d0..57bced2 100644 --- a/includes/class-wc-gateway-komoju-block.php +++ b/includes/class-wc-gateway-komoju-block.php @@ -3,62 +3,67 @@ use Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType; class WC_Gateway_Komoju_Blocks extends AbstractPaymentMethodType { - - private $gateway; - protected $name = 'komoju'; // I think this is the id of WC_Gateway_Komoju - + protected $payment_method; + protected $name; + + public function __construct($payment_method) { + $this->payment_method = $payment_method; + $this->name = $payment_method->id; + } + public function initialize() { - require_once dirname(__DIR__) . '/class-wc-gateway-komoju.php'; - $this->gateway = new WC_Gateway_Komoju(); - $this->settings = $this->gateway->settings; + $this->settings = $this->payment_method->settings; + // $this->settings = $this->gateway->settings; // $this->settings = get_option('woocommerce_komoju_settings', []); + + // error_log('WC_Gateway_Komoju_Blocks initialize gateway: ' . print_r($this->gateway, true)); } public function is_active() { - error_log('WC_Gateway_Komoju_Blocks is_available: ' . print_r($this->gateway->is_available(), true)); - // return $this->gateway->is_available(); // Maybe we can get this from the gateway settings? - return true; + // error_log('WC_Gateway_Komoju_Blocks is_available: ' . print_r($this->gateway->is_available(), true)); + return $this->settings['enabled']; } // Not sure what to do about this. We don't have js files to load directly... public function get_payment_method_script_handles() { - if (!is_checkout()) { - return []; - } + return []; + // if (!is_checkout()) { + // return []; + // } - $komoju_fields_js = get_option('komoju_woocommerce_fields_url'); - // Is this where we store our checkout js? - if (!$komoju_fields_js) { - $komoju_fields_js = 'https://multipay.komoju.com/fields.js'; - } + // $komoju_fields_js = get_option('komoju_woocommerce_fields_url'); + // // Is this where we store our checkout js? + // if (!$komoju_fields_js) { + // $komoju_fields_js = 'https://multipay.komoju.com/fields.js'; + // } - // wp_enqueue_script('komoju-fields', $komoju_fields_js); + // // wp_enqueue_script('komoju-fields', $komoju_fields_js); - wp_register_script( - 'WC_Gateway_Komoju-blocks-integration', - $komoju_fields_js, - [ - 'wc-blocks-registry', - 'wc-settings', - 'wp-element', - 'wp-html-entities', - 'wp-i18n', - ], - null, - true - ); - // if( function_exists( 'wp_set_script_translations' ) ) { - // wp_set_script_translations( 'wc_gateway_komoju-blocks-integration'); + // wp_register_script( + // 'WC_Gateway_Komoju-blocks-integration', + // $komoju_fields_js, + // [ + // 'wc-blocks-registry', + // 'wc-settings', + // 'wp-element', + // 'wp-html-entities', + // 'wp-i18n', + // ], + // null, + // true + // ); + // // if( function_exists( 'wp_set_script_translations' ) ) { + // // wp_set_script_translations( 'wc_gateway_komoju-blocks-integration'); - // } - return [ 'WC_Gateway_Komoju-blocks-integration' ]; + // // } + // return [ 'WC_Gateway_Komoju-blocks-integration' ]; } public function get_payment_method_data() { - error_log('in get_payment_method_data'); + // error_log('WC_Gateway_Komoju_Blocks get_payment_method_data payment_method->method_description: ' . print_r($this->payment_method->method_description, true)); return [ - 'title' => $this->gateway->title, - //'description' => $this->gateway->description, + 'title' => $this->name, + 'description' => $this->payment_method->method_description ]; } } diff --git a/index.php b/index.php index 3630b87..809a5a8 100755 --- a/index.php +++ b/index.php @@ -97,9 +97,7 @@ function woocommerce_komoju_handle_http_request() * Custom function to declare compatibility with cart_checkout_blocks feature */ function woocommerce_komoju_declare_checkout_blocks_compatibility() { - // Check if the required class exists if (class_exists('\Automattic\WooCommerce\Utilities\FeaturesUtil')) { - // Declare compatibility for 'cart_checkout_blocks' \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('cart_checkout_blocks', __FILE__, true); } } @@ -109,7 +107,6 @@ function woocommerce_komoju_declare_checkout_blocks_compatibility() { */ function woocommerce_komoju_register_order_approval_payment_method_type() { - // Check if the required class exists if (!class_exists('Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType')) { return; } @@ -121,8 +118,24 @@ function woocommerce_komoju_register_order_approval_payment_method_type() { add_action( 'woocommerce_blocks_payment_method_type_registration', function(Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry) { - // Register an instance of WC_Gateway_Komoju_Blocks - $payment_method_registry->register(new WC_Gateway_Komoju_Blocks); + // This is how we register WC_Gateway_Komoju, but I think we need to register each payment method + // instead. See the uncommented code below. + // // Register an instance of WC_Gateway_Komoju_Blocks + // $payment_method_registry->register(new WC_Gateway_Komoju_Blocks); + + // Register each payment method separately. + require_once 'class-wc-gateway-komoju.php'; + require_once 'includes/class-wc-gateway-komoju-single-slug.php'; + $komoju_payment_methods = get_option('komoju_woocommerce_payment_methods'); + if (gettype($komoju_payment_methods) == 'array') { + foreach ($komoju_payment_methods as $payment_method) { + $method = new WC_Gateway_Komoju_Single_Slug($payment_method); + $payment_method_registry->register(new WC_Gateway_Komoju_Blocks($method)); + } + } else { + $payment_method = new WC_Gateway_Komoju(); + $payment_method_registry->register(new WC_Gateway_Komoju_Blocks($payment_method)); + } } ); } diff --git a/komoju-php/komoju-php/lib/komoju/KomojuApi.php b/komoju-php/komoju-php/lib/komoju/KomojuApi.php index b76f9ee..74315a4 100644 --- a/komoju-php/komoju-php/lib/komoju/KomojuApi.php +++ b/komoju-php/komoju-php/lib/komoju/KomojuApi.php @@ -2,6 +2,10 @@ class KomojuApi { + // protected $endpoint; + // protected $via; + // protected $secretKey; + public static function defaultEndpoint() { return 'https://komoju.com'; From f292a74b8d44b4cba5c18b6435e8165d22c26553 Mon Sep 17 00:00:00 2001 From: Richard Ramsden Date: Wed, 13 Mar 2024 13:46:05 +0900 Subject: [PATCH 4/8] Fix deprecation warnings --- class-wc-settings-page-komoju.php | 4 ++-- komoju-php/komoju-php/lib/komoju/KomojuApi.php | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/class-wc-settings-page-komoju.php b/class-wc-settings-page-komoju.php index db9489e..403eff4 100644 --- a/class-wc-settings-page-komoju.php +++ b/class-wc-settings-page-komoju.php @@ -357,8 +357,8 @@ private function fetch_all_payment_methods() { $api = new KomojuApi($this->secret_key()); - if (!$api->secretKey || strlen($api->secretKey) === 0) { - return null; + if (!$api->getSecretKey() || strlen($api->getSecretKey()) === 0) { + return null; } try { diff --git a/komoju-php/komoju-php/lib/komoju/KomojuApi.php b/komoju-php/komoju-php/lib/komoju/KomojuApi.php index 74315a4..1c2cba5 100644 --- a/komoju-php/komoju-php/lib/komoju/KomojuApi.php +++ b/komoju-php/komoju-php/lib/komoju/KomojuApi.php @@ -2,9 +2,9 @@ class KomojuApi { - // protected $endpoint; - // protected $via; - // protected $secretKey; + protected $endpoint; + protected $via; + protected $secretKey; public static function defaultEndpoint() { @@ -21,6 +21,11 @@ public static function endpoint() return $endpoint; } + public function getSecretKey() + { + return $this->secretKey; + } + public function __construct($secretKey) { $this->endpoint = self::endpoint(); From dbeb8aa93ef2a79989ac1ea4af19824300305c2b Mon Sep 17 00:00:00 2001 From: Richard Ramsden Date: Wed, 13 Mar 2024 14:31:14 +0900 Subject: [PATCH 5/8] Use singleton to make sure we don't double instantiate --- class-wc-gateway-komoju.php | 15 +++++++++++++++ index.php | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/class-wc-gateway-komoju.php b/class-wc-gateway-komoju.php index 7855c19..adb3943 100755 --- a/class-wc-gateway-komoju.php +++ b/class-wc-gateway-komoju.php @@ -19,6 +19,10 @@ class WC_Gateway_Komoju extends WC_Payment_Gateway { + + /** Singleton instance */ + private static $instance = null; + /** @var array Array of locales */ public $locale; @@ -36,6 +40,17 @@ class WC_Gateway_Komoju extends WC_Payment_Gateway protected $instructions; protected $useOnHold; + /** + * Constructor for the gateway. + */ + public static function getInstance() { + if (self::$instance == null) { + self::$instance = new WC_Gateway_Komoju(); + } + + return self::$instance; + } + /** * Constructor for the gateway. */ diff --git a/index.php b/index.php index 809a5a8..0d6e6f4 100755 --- a/index.php +++ b/index.php @@ -25,7 +25,7 @@ function woocommerce_add_komoju_gateway($methods) { require_once 'class-wc-gateway-komoju.php'; require_once 'includes/class-wc-gateway-komoju-single-slug.php'; - $methods[] = new WC_Gateway_Komoju(); + $methods[] = WC_Gateway_Komoju::getInstance(); $komoju_payment_methods = get_option('komoju_woocommerce_payment_methods'); if (gettype($komoju_payment_methods) == 'array') { @@ -133,7 +133,7 @@ function(Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_m $payment_method_registry->register(new WC_Gateway_Komoju_Blocks($method)); } } else { - $payment_method = new WC_Gateway_Komoju(); + $payment_method = WC_Gateway_Komoju::getInstance(); $payment_method_registry->register(new WC_Gateway_Komoju_Blocks($payment_method)); } } From 138ce5d100eac3b328e93e71fdd385d9c597da15 Mon Sep 17 00:00:00 2001 From: Grant Date: Wed, 13 Mar 2024 19:43:07 +0900 Subject: [PATCH 6/8] add instances to WC_Gateway_Komoju_Single_Slug and refactor --- class-wc-gateway-komoju.php | 8 ++ includes/class-wc-gateway-komoju-block.php | 87 +++++++++++-------- .../class-wc-gateway-komoju-single-slug.php | 1 + index.php | 73 +++++++++++----- 4 files changed, 108 insertions(+), 61 deletions(-) diff --git a/class-wc-gateway-komoju.php b/class-wc-gateway-komoju.php index adb3943..964e279 100755 --- a/class-wc-gateway-komoju.php +++ b/class-wc-gateway-komoju.php @@ -75,10 +75,12 @@ public function __construct() $this->description = $this->get_option('description'); $this->instructions = $this->get_option('instructions', $this->description); $this->useOnHold = $this->get_option('useOnHold'); + $this->supports[] = 'blocks'; // Filters // Actions add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']); + add_action('init', [$this, 'woocommerce_komoju_declare_checkout_blocks_compatibility']); if ($this->id === 'komoju') { include_once 'includes/class-wc-gateway-komoju-ipn-handler.php'; @@ -93,6 +95,12 @@ public function __construct() } } + function woocommerce_komoju_declare_checkout_blocks_compatibility() { + if (class_exists('\Automattic\WooCommerce\Utilities\FeaturesUtil')) { + \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('cart_checkout_blocks', __FILE__, true); + } + } + /* * This shows a link to komoju on order pages that were paid with this gateway. */ diff --git a/includes/class-wc-gateway-komoju-block.php b/includes/class-wc-gateway-komoju-block.php index 57bced2..1783126 100644 --- a/includes/class-wc-gateway-komoju-block.php +++ b/includes/class-wc-gateway-komoju-block.php @@ -13,57 +13,70 @@ public function __construct($payment_method) { public function initialize() { $this->settings = $this->payment_method->settings; - // $this->settings = $this->gateway->settings; - // $this->settings = get_option('woocommerce_komoju_settings', []); - - // error_log('WC_Gateway_Komoju_Blocks initialize gateway: ' . print_r($this->gateway, true)); } public function is_active() { - // error_log('WC_Gateway_Komoju_Blocks is_available: ' . print_r($this->gateway->is_available(), true)); return $this->settings['enabled']; } - // Not sure what to do about this. We don't have js files to load directly... + // We enqueue the komoju-fields js in woocommerce_komoju_load_scripts in index.php. Register + // the script here. public function get_payment_method_script_handles() { - return []; - // if (!is_checkout()) { - // return []; - // } + $komoju_fields_js = get_option('komoju_woocommerce_fields_url'); + if (!$komoju_fields_js) { + $komoju_fields_js = 'https://multipay.komoju.com/fields.js'; + } + + wp_register_script('komoju-fields', $komoju_fields_js, [], null, true); + + return ['komoju-fields']; + } - // $komoju_fields_js = get_option('komoju_woocommerce_fields_url'); - // // Is this where we store our checkout js? - // if (!$komoju_fields_js) { - // $komoju_fields_js = 'https://multipay.komoju.com/fields.js'; - // } + // // Not sure what to do about this. We don't have js files to load directly... + // public function get_payment_method_script_handles() { + // if (!is_checkout()) { + // return []; + // } - // // wp_enqueue_script('komoju-fields', $komoju_fields_js); + // return ['komoju-fields']; - // wp_register_script( - // 'WC_Gateway_Komoju-blocks-integration', - // $komoju_fields_js, - // [ - // 'wc-blocks-registry', - // 'wc-settings', - // 'wp-element', - // 'wp-html-entities', - // 'wp-i18n', - // ], - // null, - // true - // ); - // // if( function_exists( 'wp_set_script_translations' ) ) { - // // wp_set_script_translations( 'wc_gateway_komoju-blocks-integration'); + // // $komoju_fields_js = get_option('komoju_woocommerce_fields_url'); + // // // Is this where we store our checkout js? + // // if (!$komoju_fields_js) { + // // $komoju_fields_js = 'https://multipay.komoju.com/fields.js'; + // // } + + // // // wp_enqueue_script('komoju-fields', $komoju_fields_js); + + // // wp_register_script( + // // 'WC_Gateway_Komoju-blocks-integration', + // // $komoju_fields_js, + // // [ + // // 'wc-blocks-registry', + // // 'wc-settings', + // // 'wp-element', + // // 'wp-html-entities', + // // 'wp-i18n', + // // ], + // // null, + // // true + // // ); + // // // if( function_exists( 'wp_set_script_translations' ) ) { + // // // wp_set_script_translations( 'wc_gateway_komoju-blocks-integration'); - // // } - // return [ 'WC_Gateway_Komoju-blocks-integration' ]; - } + // // // } + // // return [ 'WC_Gateway_Komoju-blocks-integration' ]; + // } - public function get_payment_method_data() { - // error_log('WC_Gateway_Komoju_Blocks get_payment_method_data payment_method->method_description: ' . print_r($this->payment_method->method_description, true)); + public function get_payment_method_data() { return [ 'title' => $this->name, - 'description' => $this->payment_method->method_description + 'description' => $this->payment_method->method_description, + 'supports' => array_filter($this->payment_method->supports, array($this->payment_method, 'supports')), + 'blocks' => [ + 'editor' => 'woocommerce/checkout', + 'frontend' => 'woocommerce/checkout', + ], ]; } } diff --git a/includes/class-wc-gateway-komoju-single-slug.php b/includes/class-wc-gateway-komoju-single-slug.php index ff719aa..3ce4126 100644 --- a/includes/class-wc-gateway-komoju-single-slug.php +++ b/includes/class-wc-gateway-komoju-single-slug.php @@ -12,6 +12,7 @@ */ class WC_Gateway_Komoju_Single_Slug extends WC_Gateway_Komoju { + public static $instances = []; protected $publishableKey; protected $payment_method; protected $debug; diff --git a/index.php b/index.php index 0d6e6f4..8cb7c8d 100755 --- a/index.php +++ b/index.php @@ -21,22 +21,35 @@ function woocommerce_komoju_init() /** * Add the Gateway to WooCommerce **/ - function woocommerce_add_komoju_gateway($methods) - { + function get_komoju_payment_methods() { require_once 'class-wc-gateway-komoju.php'; require_once 'includes/class-wc-gateway-komoju-single-slug.php'; + $methods[] = WC_Gateway_Komoju::getInstance(); - $komoju_payment_methods = get_option('komoju_woocommerce_payment_methods'); - if (gettype($komoju_payment_methods) == 'array') { - foreach ($komoju_payment_methods as $payment_method) { - $methods[] = new WC_Gateway_Komoju_Single_Slug($payment_method); + // If single slug instances don't exist, instantiate them + if (empty(WC_Gateway_Komoju_Single_Slug::$instances)) { + $komoju_payment_methods = get_option('komoju_woocommerce_payment_methods'); + + if (gettype($komoju_payment_methods) == 'array') { + foreach ($komoju_payment_methods as $payment_method) { + $method = new WC_Gateway_Komoju_Single_Slug($payment_method); + WC_Gateway_Komoju_Single_Slug::$instances[] = $method; + } } } + if (!empty(WC_Gateway_Komoju_Single_Slug::$instances)) { + $methods = array_merge($methods, WC_Gateway_Komoju_Single_Slug::$instances); + } + return $methods; } + function woocommerce_add_komoju_gateway($methods) { + return get_komoju_payment_methods(); + } + /** * Add the KOMOJU settings page to WooCommerce **/ @@ -65,6 +78,7 @@ function woocommerce_komoju_load_scripts() wp_enqueue_script('komoju-fields', $komoju_fields_js); } + function woocommerce_komoju_load_script_as_module($tag, $handle, $src) { if ($handle !== 'komoju-fields') { @@ -114,30 +128,41 @@ function woocommerce_komoju_register_order_approval_payment_method_type() { // Include the custom Blocks Checkout class require_once 'includes/class-wc-gateway-komoju-block.php'; - // Hook the registration function to the 'woocommerce_blocks_payment_method_type_registration' action + // // Hook the registration function to the 'woocommerce_blocks_payment_method_type_registration' action + // add_action( + // 'woocommerce_blocks_payment_method_type_registration', + // function(Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry) { + // // This is how we register WC_Gateway_Komoju, but I think we need to register each payment method + // // instead. See the uncommented code below. + // // // Register an instance of WC_Gateway_Komoju_Blocks + // // $payment_method_registry->register(new WC_Gateway_Komoju_Blocks); + + // // Register each payment method separately. + // require_once 'class-wc-gateway-komoju.php'; + // require_once 'includes/class-wc-gateway-komoju-single-slug.php'; + // $komoju_payment_methods = get_option('komoju_woocommerce_payment_methods'); + // if (gettype($komoju_payment_methods) == 'array') { + // foreach ($komoju_payment_methods as $payment_method) { + // $method = new WC_Gateway_Komoju_Single_Slug($payment_method); + // $payment_method_registry->register(new WC_Gateway_Komoju_Blocks($method)); + // } + // } else { + // $payment_method = WC_Gateway_Komoju::getInstance(); + // $payment_method_registry->register(new WC_Gateway_Komoju_Blocks($payment_method)); + // } + // } + // ); + add_action( 'woocommerce_blocks_payment_method_type_registration', function(Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry) { - // This is how we register WC_Gateway_Komoju, but I think we need to register each payment method - // instead. See the uncommented code below. - // // Register an instance of WC_Gateway_Komoju_Blocks - // $payment_method_registry->register(new WC_Gateway_Komoju_Blocks); - - // Register each payment method separately. - require_once 'class-wc-gateway-komoju.php'; - require_once 'includes/class-wc-gateway-komoju-single-slug.php'; - $komoju_payment_methods = get_option('komoju_woocommerce_payment_methods'); - if (gettype($komoju_payment_methods) == 'array') { - foreach ($komoju_payment_methods as $payment_method) { - $method = new WC_Gateway_Komoju_Single_Slug($payment_method); - $payment_method_registry->register(new WC_Gateway_Komoju_Blocks($method)); - } - } else { - $payment_method = WC_Gateway_Komoju::getInstance(); + $komoju_payment_methods = get_komoju_payment_methods(); + + foreach ($komoju_payment_methods as $payment_method) { $payment_method_registry->register(new WC_Gateway_Komoju_Blocks($payment_method)); } } - ); + ); } add_filter('woocommerce_payment_gateways', 'woocommerce_add_komoju_gateway'); From e3127d0085e7924e199841c364056d19c6555918 Mon Sep 17 00:00:00 2001 From: Grant Date: Mon, 18 Mar 2024 17:40:56 +0900 Subject: [PATCH 7/8] refactor and start working on frontend implementation --- includes/class-wc-gateway-komoju-block.php | 63 +- includes/js/fields.js | 694 +++++++++++++++++++++ includes/js/komoju-fields-blocks.js | 34 + index.php | 28 +- 4 files changed, 744 insertions(+), 75 deletions(-) create mode 100644 includes/js/fields.js create mode 100644 includes/js/komoju-fields-blocks.js diff --git a/includes/class-wc-gateway-komoju-block.php b/includes/class-wc-gateway-komoju-block.php index 1783126..3bca46c 100644 --- a/includes/class-wc-gateway-komoju-block.php +++ b/includes/class-wc-gateway-komoju-block.php @@ -22,61 +22,28 @@ public function is_active() { // We enqueue the komoju-fields js in woocommerce_komoju_load_scripts in index.php. Register // the script here. public function get_payment_method_script_handles() { - $komoju_fields_js = get_option('komoju_woocommerce_fields_url'); - if (!$komoju_fields_js) { - $komoju_fields_js = 'https://multipay.komoju.com/fields.js'; - } + $komoju_fields_js = plugins_url('js/komoju-fields-blocks.js', __FILE__); + wp_register_script('komoju-fields-blocks', $komoju_fields_js, [], null, true); - wp_register_script('komoju-fields', $komoju_fields_js, [], null, true); - - return ['komoju-fields']; + return ['komoju-fields-blocks']; } - // // Not sure what to do about this. We don't have js files to load directly... - // public function get_payment_method_script_handles() { - // if (!is_checkout()) { - // return []; - // } - - // return ['komoju-fields']; - - // // $komoju_fields_js = get_option('komoju_woocommerce_fields_url'); - // // // Is this where we store our checkout js? - // // if (!$komoju_fields_js) { - // // $komoju_fields_js = 'https://multipay.komoju.com/fields.js'; - // // } - - // // // wp_enqueue_script('komoju-fields', $komoju_fields_js); - - // // wp_register_script( - // // 'WC_Gateway_Komoju-blocks-integration', - // // $komoju_fields_js, - // // [ - // // 'wc-blocks-registry', - // // 'wc-settings', - // // 'wp-element', - // // 'wp-html-entities', - // // 'wp-i18n', - // // ], - // // null, - // // true - // // ); - // // // if( function_exists( 'wp_set_script_translations' ) ) { - // // // wp_set_script_translations( 'wc_gateway_komoju-blocks-integration'); - - // // // } - // // return [ 'WC_Gateway_Komoju-blocks-integration' ]; - // } - - public function get_payment_method_data() { + public function get_payment_method_data() { + // Trying to pass the html from WC_Gateway_Komoju_Single_Slug::payment_fields to the + // frontend, without success. + ob_start(); + $this->payment_method->payment_fields(); + $paymentFields = ob_get_clean(); + return [ 'title' => $this->name, 'description' => $this->payment_method->method_description, 'supports' => array_filter($this->payment_method->supports, array($this->payment_method, 'supports')), - 'blocks' => [ - 'editor' => 'woocommerce/checkout', - 'frontend' => 'woocommerce/checkout', - ], + 'paymentFields' => $paymentFields, + // 'blocks' => [ + // 'editor' => 'woocommerce/checkout', + // 'frontend' => 'woocommerce/checkout', + // ], ]; } } diff --git a/includes/js/fields.js b/includes/js/fields.js new file mode 100644 index 0000000..e87afc2 --- /dev/null +++ b/includes/js/fields.js @@ -0,0 +1,694 @@ +var x = Object.defineProperty; +var K = (i,s)=>{ + for (var e in s) + x(i, e, { + get: s[e], + enumerable: !0 + }) +} +; +var c = { + CDN: "https://multipay.komoju.com", + ENV: "production", + HONEYBADGER_API_KEY: "hbp_aKD3g1hCztStGSvVXmhzrbEtOrtyKm3CqBxX", + GIT_REV: "af25e949e91d20f2e2276824995c8f8fd5c433ed" +}; +function y(i) { + window.komojuTranslations || (window.komojuTranslations = { + en: {}, + ja: {} + }); + for (let s of Object.keys(window.komojuTranslations)) + window.komojuTranslations[s] = { + ...window.komojuTranslations[s], + ...i[s] + } +} +var E = {}; +K(E, { + en: ()=>C, + ja: ()=>P +}); +var C = { + "customer-fee-will-be-charged": "A fee of %{fee} will be included.", + "dynamic-currency-notice": "Payment will be made in %{currency}: %{original} \u2192 %{converted}.", + "dynamic-currency-notice-with-fee": "Payment will be made in %{currency}: %{original} \u2192 %{converted}. (total: %{total})", + "payment-method-unavailable": "This payment method is currently unavailable.", + "verification-failed": "Verification failed.", + close: "Close" +} + , P = { + "customer-fee-will-be-charged": "%{fee}\u306E\u624B\u6570\u6599\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002", + "dynamic-currency-notice": "\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002", + "dynamic-currency-notice-with-fee": "\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002(\u5408\u8A08%{total})", + "payment-method-unavailable": "\u3053\u306E\u652F\u6255\u3044\u65B9\u6CD5\u306F\u73FE\u5728\u3054\u5229\u7528\u3044\u305F\u3060\u3051\u307E\u305B\u3093\u3002", + "verification-failed": "\u8A8D\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002", + close: "\u9589\u3058\u308B" +}; +var w = class { + constructor(s) { + this._sendWindow = new Promise(e=>this._setSendWindow = e), + this._receiveWindow = new Promise(e=>this._setReceiveWindow = e), + this.messageHandler = e=>{ + this.origin !== "*" && e.origin !== this.origin || this.handleMessage(e) + } + , + this.id = s ?? crypto.randomUUID(), + this.origin = "*", + this.promises = new Map, + this.listeners = new Map + } + setup(s) { + this._setSendWindow ? (this._setSendWindow(s.send), + this._setSendWindow = void 0) : this._sendWindow = Promise.resolve(s.send), + this._setReceiveWindow ? (this._setReceiveWindow(s.receive), + this._setReceiveWindow = void 0) : this._receiveWindow = Promise.resolve(s.receive), + s.receive.addEventListener("message", this.messageHandler) + } + send(s) { + let e = { + ...s, + brokerId: this.id, + id: crypto.randomUUID() + } + , t = null + , o = new Promise((n,r)=>{ + t = n + } + ); + if (!t) + throw new Error("Broker is busted"); + return this.promises.set(e.id, { + promise: o, + resolve: t + }), + this._sendWindow.then(n=>n.postMessage(e, this.origin)).then(()=>o) + } + receive(s, e) { + this.listeners.set(s, e) + } + async handleMessage(s) { + let e = s.data; + if (e.brokerId === this.id) + if (e.type === "ack") { + let t = e + , o = this.promises.get(t.id); + if (!o) + return; + o.resolve(t.response), + this.promises.delete(t.id) + } else { + let t = this.listeners.get(e.type) + , o = { + type: "ack", + brokerId: this.id, + id: e.id + }; + t && (o.response = await t(e) ?? void 0), + await this._sendWindow.then(n=>n.postMessage(o, this.origin)) + } + } + destroy() { + return this._receiveWindow.then(s=>s.removeEventListener("message", this.messageHandler)) + } +} +; +function k(i, s, e, t) { + if (!i.komojuApi) + throw new Error("KOMOJU API URL is null"); + if (!i.publishableKey) + throw new Error("KOMOJU publishable-key not set"); + return fetch(`${i.komojuApi}${e}`, { + method: s, + headers: { + accept: "application/json", + "content-type": "application/json", + authorization: `Basic ${btoa(`${i.publishableKey}:`)}`, + "komoju-via": "fields" + }, + body: t ? JSON.stringify(t) : void 0 + }) +} +y(E); +var m = class extends HTMLElement { + constructor() { + super(); + this._submitting = !1; + this.session = null; + this.broker = new w, + this.dialog = document.createElement("dialog"), + this.listenToMessagesFromIframe(this.broker), + this.dialog.style.width = "80%", + this.dialog.style.height = "80%", + this.dialog.style.padding = "0" + } + static get observedAttributes() { + return ["komoju-api", "session", "session-id", "publishable-key", "payment-type", "locale", "theme", "token", "name"] + } + get theme() { + return this.getAttribute("theme") + } + set theme(e) { + this.setAttribute("theme", e ?? "") + } + get komojuApi() { + return this.getAttribute("komoju-api") ?? "https://komoju.com" + } + set komojuApi(e) { + this.setAttribute("komoju-api", e) + } + connectedCallback() { + let e = new URLSearchParams; + e.append("broker", this.broker.id), + this.hasAttribute("komoju-api") && e.append("api", this.getAttribute("komoju-api")); + let t = document.createElement("iframe"); + t.setAttribute("sandbox", "allow-scripts allow-same-origin"), + t.setAttribute("allow", "payment *"), + t.title = "KOMOJU secure payment fields", + t.src = `${c.CDN}/fields-iframe.html#${e.toString()}`, + t.style.border = "none", + t.style.width = "100%", + t.style.overflow = "hidden", + t.height = "50", + t.addEventListener("load", ()=>{ + if (!t.contentWindow) + throw new Error("KOMOJU Fields: iframe had no contentWindow"); + this.broker.setup({ + send: t.contentWindow, + receive: window + }) + } + ), + this.replaceChildren(t, this.dialog); + let o = this.parentElement; + for (; o && o.tagName !== "FORM"; ) + o = o.parentElement; + if (!o) + return; + let n = o + , r = n.parentElement; + if (!r) + return; + let a = l=>{ + this._submitting || this.offsetParent !== null && l.target === n && (l.preventDefault(), + l.stopImmediatePropagation(), + this.submit(l)) + } + ; + r.addEventListener("submit", a, !0), + this.formSubmitHandler = { + form: n, + target: r, + handler: a + } + } + disconnectedCallback() { + this.formSubmitHandler && (this.formSubmitHandler.target.removeEventListener("submit", this.formSubmitHandler.handler, !0), + this.formSubmitHandler = void 0), + this.broker.destroy() + } + listenToMessagesFromIframe(e) { + e.receive("dispatch-event", t=>{ + let o = new CustomEvent(t.name,{ + detail: t.detail, + bubbles: !0, + composed: !0, + cancelable: !0 + }); + return t.name === "komoju-session-change" && (this.session = t.detail.session), + { + type: "dispatch-result", + cancel: !this.dispatchEvent(o) + } + } + ), + e.receive("resize", t=>{ + let o = this.querySelector("iframe"); + o.height = t.height + } + ), + e.receive("dialog-start", async t=>({ + type: "dialog-result", + result: await this.show3DSDialog(t.url) + })) + } + async attributeChangedCallback(e, t, o) { + this.broker.send({ + type: "attr", + attr: e, + value: o + }) + } + async submit(e) { + if (this.token) + return this.token; + let t = await this.broker.send({ + type: "submit" + }); + if (t?.type !== "submit-result") + throw new Error(`Unexpected submit response from komoju-fields iframe ${JSON.stringify(t)}`); + let o = t; + if (o.errors) { + this.dispatchEvent(new CustomEvent("komoju-invalid",{ + detail: { + errors: o.errors + }, + bubbles: !0, + composed: !0 + })); + return + } + if (o.pay) { + o.pay.error || await this.handlePayResult(o.pay); + return + } + if (o.token && e && this.formSubmitHandler) { + let n = this.formSubmitHandler.form + , r = this.getAttribute("name") ?? "komoju_token" + , a = document.querySelector(`input[name="${r}"]`); + a || (a = document.createElement("input"), + a.type = "hidden", + a.name = r, + n.append(a)), + a.value = o.token.id, + this.submitParentForm(); + return + } + if (o.token) + return this.token = o.token, + o.token; + throw new Error("KOMOJU Fields bug: submit result was not handled") + } + async handlePayResult(e) { + let t = this.session; + if (!t) + throw new Error("handlePayResult called without a session"); + let o = e.payment?.payment_details?.instructions_url; + if (o) { + let n = new URL(t.return_url ?? t.session_url); + n.searchParams.append("session_id", t.id), + this.showInstructionsDialog(o, n.toString()) + } else if (e.redirect_url) + window.location.href = e.redirect_url; + else + throw new Error(`payResult should have a redirect_url but doesnt ${JSON.stringify(e)}`) + } + async submitParentForm() { + if (!this.formSubmitHandler) + throw new Error("KOMOJU Fields: tried to submit nonexistent parent form"); + let e = this.formSubmitHandler.form; + try { + this._submitting = !0; + let t = new Event("submit",{ + bubbles: !0, + cancelable: !0 + }); + e.dispatchEvent(t) ? e.submit() : this.broker.send({ + type: "end-fade" + }) + } finally { + this._submitting = !1 + } + } + showInstructionsDialog(e, t) { + let o = this.dialog + , n = j(e); + n.style.height = "90%"; + let r = document.createElement("a") + , a = document.createElement("komoju-i18n"); + a.key = "close", + r.append(a), + r.classList.add("komoju-fields-close-dialog"), + r.href = t, + r.style.display = "block", + r.style.padding = "10px", + o.replaceChildren(r, n), + o.showModal() + } + show3DSDialog(e) { + return new Promise((t,o)=>{ + let n = this.dialog + , r = c.CDN + , a = j(e); + window.addEventListener("message", async l=>{ + if (l.origin === r) + try { + if (!l.data?._komojuFields) + return; + let {secureTokenId: d} = l.data; + if (!d) + throw new Error("No secureTokenId in message"); + let b = { + komojuApi: this.komojuApi, + publishableKey: this.getAttribute("publishable-key") ?? "" + } + , u = await k(b, "GET", `/api/v1/secure_tokens/${d}`); + if (u.status >= 400) { + let _ = await u.json(); + t({ + error: _ + }); + return + } + let L = await u.json(); + n.close(), + t({ + secureToken: L + }) + } catch (d) { + o(d) + } + } + ), + n.replaceChildren(a), + n.showModal() + } + ) + } +} +; +for (let i of m.observedAttributes) + i === "session" || i === "theme" || i === "komoju-api" || Object.defineProperty(m.prototype, H(i), { + get() { + return this.getAttribute(i) + }, + set(s) { + s === null ? this.removeAttribute(i) : this.setAttribute(i, s) + } + }); +function H(i) { + return i.split("-").reduce((s,e)=>s + e.charAt(0).toUpperCase() + e.slice(1)) +} +function j(i) { + let s = document.createElement("iframe"); + return s.setAttribute("sandbox", "allow-scripts allow-forms allow-same-origin"), + s.src = i, + s.style.border = "none", + s.style.width = "100%", + s.style.height = "100%", + s +} +var v = ` + +
+
+ + +`; +function M(i, s) { + if (!i.parentElement) + throw new Error("KOMOJU Fields bug: radio input has no parent"); + if (!i.parentElement.classList.contains("radio")) + throw new Error("KOMOJU Fields bug: radio input parent has no .radio class"); + i.checked && i.parentElement.classList.add("checked"), + i.addEventListener("change", ()=>{ + s.querySelectorAll(".radio.checked").forEach(e=>e.classList.remove("checked")), + i.parentElement.classList.add("checked") + } + ) +} +var h = new Set; +h.add("bank_transfer"); +h.add("credit_card"); +h.add("konbini"); +h.add("offsite"); +var T = h; +var A = "en"; +function S(i, s) { + i.querySelectorAll("komoju-i18n").forEach(e=>{ + e.render(s) + } + ) +} +var p = class extends HTMLElement { + static get observedAttributes() { + return ["key"] + } + get key() { + return this.getAttribute("key") + } + set key(s) { + this.setAttribute("key", s ?? "") + } + connectedCallback() { + this.render() + } + attributeChangedCallback(s, e, t) { + s === "key" && this.render() + } + findLocale() { + let s = this.parentElement; + for (; s && !s.getAttribute("locale"); ) + s = s.parentElement; + return s?.getAttribute("locale") ?? A + } + render(s) { + if (!this.key) + return; + s || (s = this.findLocale()), + Object.keys(window.komojuTranslations).includes(s) || (s = A); + let e = s.substring(0, 2) + , t = window.komojuTranslations[e][this.key]; + if (!t) { + console.error(`KOMOJU bug: missing translation for key: ${this.key}`); + return + } + let o = t.match(/%\{[\w-]+\}/g); + if (o) { + let n = t; + o.forEach(r=>{ + let a = r.replace(/%{|}/g, "") + , l = this.dataset[a]; + l && (n = n.replace(r, l)) + } + ), + this.textContent = n; + return + } + this.textContent = t + } +} +; +var f = class extends HTMLElement { + get theme() { + return this.getAttribute("theme") + } + set theme(s) { + this.setAttribute("theme", s ?? "") + } + applyTheme() { + let s = this.shadowRoot ?? document; + this.theme === null ? s.querySelectorAll("#theme,#inline-theme").forEach(e=>e.remove()) : this.theme.startsWith("http") || this.theme.startsWith("/") || this.theme.startsWith("data:") ? this.applyExternalTheme(s, this.theme) : this.applyInlineTheme(s, this.theme) + } + applyInlineTheme(s, e) { + s.querySelectorAll("#theme,#inline-theme").forEach(o=>o.remove()); + let t = document.createElement("style"); + t.id = "inline-theme", + t.textContent = e, + this.appendStyleTag(t) + } + applyExternalTheme(s, e) { + s.querySelectorAll("#inline-theme").forEach(o=>o.remove()); + let t = s.querySelector("#theme"); + t ? t.href !== this.theme && (t.href = e) : (t = document.createElement("link"), + t.id = "theme", + t.rel = "stylesheet", + t.href = e, + this.appendStyleTag(t)) + } + appendStyleTag(s) { + this.shadowRoot ? this.shadowRoot.append(s) : document.head.append(s) + } +} +; +var g = class extends f { + constructor() { + super(); + this.sessionChangedHandler = null; + let e = this.attachShadow({ + mode: "open" + }); + e.innerHTML = v; + let t = document.createElement("link"); + t.rel = "stylesheet", + t.href = `${c.CDN}/static/shared.css`, + e.append(t) + } + static get observedAttributes() { + return ["locale", "theme"] + } + get fields() { + return this.getAttribute("fields") + } + set fields(e) { + this.setAttribute("fields", e ?? "") + } + get locale() { + return this.getAttribute("locale") + } + set locale(e) { + this.setAttribute("locale", e ?? "") + } + async connectedCallback() { + let e = this.komojuFieldsElement() + , t = { + element: e, + handler: o=>{ + this.render(e) + } + }; + await this.setupPaymentTypesI18n(), + this.render(e), + e.addEventListener("komoju-session-change", t.handler), + this.sessionChangedHandler = t + } + disconnectedCallback() { + this.sessionChangedHandler && this.sessionChangedHandler.element.removeEventListener("komoju-session-change", this.sessionChangedHandler.handler) + } + async attributeChangedCallback(e, t, o) { + !this.shadowRoot || (e === "locale" && o && t !== o ? (S(this.shadowRoot, o), + this.updatePickerLocale(o)) : e === "theme" && this.applyTheme()) + } + komojuFieldsElement() { + return this.fields ? document.querySelector(`#${this.fields}`) : document.querySelector("komoju-fields") + } + render(e) { + if (!e.session || !this.shadowRoot) + return; + let t = this.shadowRoot.getElementById("picker") + , o = this.shadowRoot.getElementById("radio-template"); + if (!t) + throw new Error("KOMOJU Fields bug: wrong shadow DOM (no picker)"); + if (!o) + throw new Error("KOMOJU Fields bug: wrong shadow DOM (no template)"); + this.locale || (this.locale = e.session.default_locale.substring(0, 2)), + this.updatePickerLocale(this.locale), + t.replaceChildren(); + let n = 0; + for (let r of e.session.payment_methods) { + let a = r.offsite ? "offsite" : r.type; + if (e.hasAttribute("token") && !T.has(a)) + continue; + let l = o.content.cloneNode(!0) + , d = l.querySelector("input") + , b = l.querySelector("img") + , u = l.querySelector("komoju-i18n"); + (n === 0 || e.paymentType === r.type) && (d.checked = !0), + d.addEventListener("change", ()=>{ + e.paymentType = r.type + } + ), + M(d, this.shadowRoot), + b.src = `${e.komojuApi}/payment_methods/${r.type}.svg`, + u.key = r.type, + t.append(l), + n += 1 + } + !this.theme && e.theme && (this.theme = e.theme, + this.applyTheme()) + } + async setupPaymentTypesI18n() { + let e = this.komojuFieldsElement() + , t = await k(e, "GET", "/api/v1/payment_methods"); + this.komojuPaymentMethods = await t.json(); + for (let o of this.komojuPaymentMethods) { + let n = { + en: { + [o.type_slug]: o.name_en + }, + ja: { + [o.type_slug]: o.name_ja + }, + ko: { + [o.type_slug]: o.name_ko + } + }; + y(n) + } + } + updatePickerLocale(e) { + if (!this.shadowRoot) + return; + let t = this.shadowRoot.getElementById("picker"); + t && t.setAttribute("locale", e) + } +} +; +window.customElements.define("komoju-fields", m); +window.customElements.define("komoju-picker", g); +window.customElements.define("komoju-i18n", p); +window.komojuReportError = (i,s)=>{ + console.error(i, s) +} +; +if (window.komojuErrorReporting !== !1) { + (async()=>{ + let e = await import("/extras/error-reporting/module.js"); + window.komojuReportError = e.reportError + } + )(); + let i = s=>{ + let e = [/\/fields\.js:\d+:\d+\n/, /\/fields\/[\w-]+\/module\.js\n:\d+:\d+/, /\/extras\/[\w-]+\/module\.js\n:\d+:\d+/] + , t = s instanceof ErrorEvent ? s.error : s.reason; + t instanceof Error && (!t.stack || !e.find(o=>o.test(t.stack)) || window.komojuReportError(t)) + } + ; + window.addEventListener("error", i), + window.addEventListener("unhandledrejection", i) +} + +// function registerPaymentMethod(paymentMethod) { +// const settings = window.wc.wcSettings.getSetting(`${paymentMethod.title}_data`, {}); +// const label = window.wp.htmlEntities.decodeEntities(settings.title) || window.wp.i18n.__(paymentMethod.title, paymentMethod.title); +// const Content = () => { +// return window.wp.htmlEntities.decodeEntities(settings.description || ''); +// }; +// const Block_Gateway = { +// name: paymentMethod.title, +// label: label, +// content: Object(window.wp.element.createElement)(Content, null), +// edit: Object(window.wp.element.createElement)(Content, null), +// canMakePayment: () => true, +// ariaLabel: label, +// supports: { +// features: settings.supports, +// }, +// }; +// window.wc.wcBlocksRegistry.registerPaymentMethod(Block_Gateway); +// } + +// window.addEventListener('load', () => { +// paymentMethodData = window.wc.wcSettings.getSetting('paymentMethodData', {}); +// Object.values(paymentMethodData).forEach((value) => { +// registerPaymentMethod(value); +// }); +// }); diff --git a/includes/js/komoju-fields-blocks.js b/includes/js/komoju-fields-blocks.js new file mode 100644 index 0000000..dc331da --- /dev/null +++ b/includes/js/komoju-fields-blocks.js @@ -0,0 +1,34 @@ +function registerPaymentMethod(paymentMethod) { + const settings = window.wc.wcSettings.getSetting(`${paymentMethod.title}_data`, {}); + const label = window.wp.htmlEntities.decodeEntities(settings.title) || window.wp.i18n.__(paymentMethod.title, paymentMethod.title); + + // Need to rework WC_Gateway_Komoju_Single_Slug::payment_fields to get the komoju-fields element to show up + const createContent = () => { + return ''; + }; + + // Need to rework WC_Gateway_Komoju_Single_Slug::payment_fields to get the komoju-fields element to show up + const createEdit = () => { + return ''; + }; + + const Block_Gateway = { + name: paymentMethod.title, + label: label, + content: createContent(), + edit: createEdit(), + canMakePayment: () => true, + ariaLabel: label, + supports: { + features: settings.supports, + }, + }; + window.wc.wcBlocksRegistry.registerPaymentMethod(Block_Gateway); +} + +window.addEventListener('load', () => { + paymentMethodData = window.wc.wcSettings.getSetting('paymentMethodData', {}); + Object.values(paymentMethodData).forEach((value) => { + registerPaymentMethod(value); + }); +}); \ No newline at end of file diff --git a/index.php b/index.php index 8cb7c8d..1e107bc 100755 --- a/index.php +++ b/index.php @@ -118,7 +118,6 @@ function woocommerce_komoju_declare_checkout_blocks_compatibility() { /** * Custom function to register a payment method type - */ function woocommerce_komoju_register_order_approval_payment_method_type() { if (!class_exists('Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType')) { @@ -128,31 +127,6 @@ function woocommerce_komoju_register_order_approval_payment_method_type() { // Include the custom Blocks Checkout class require_once 'includes/class-wc-gateway-komoju-block.php'; - // // Hook the registration function to the 'woocommerce_blocks_payment_method_type_registration' action - // add_action( - // 'woocommerce_blocks_payment_method_type_registration', - // function(Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry) { - // // This is how we register WC_Gateway_Komoju, but I think we need to register each payment method - // // instead. See the uncommented code below. - // // // Register an instance of WC_Gateway_Komoju_Blocks - // // $payment_method_registry->register(new WC_Gateway_Komoju_Blocks); - - // // Register each payment method separately. - // require_once 'class-wc-gateway-komoju.php'; - // require_once 'includes/class-wc-gateway-komoju-single-slug.php'; - // $komoju_payment_methods = get_option('komoju_woocommerce_payment_methods'); - // if (gettype($komoju_payment_methods) == 'array') { - // foreach ($komoju_payment_methods as $payment_method) { - // $method = new WC_Gateway_Komoju_Single_Slug($payment_method); - // $payment_method_registry->register(new WC_Gateway_Komoju_Blocks($method)); - // } - // } else { - // $payment_method = WC_Gateway_Komoju::getInstance(); - // $payment_method_registry->register(new WC_Gateway_Komoju_Blocks($payment_method)); - // } - // } - // ); - add_action( 'woocommerce_blocks_payment_method_type_registration', function(Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry) { @@ -162,7 +136,7 @@ function(Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_m $payment_method_registry->register(new WC_Gateway_Komoju_Blocks($payment_method)); } } - ); + ); } add_filter('woocommerce_payment_gateways', 'woocommerce_add_komoju_gateway'); From 8514bb4ad8cbb919d198f2ad794c3c5bd7aa17fc Mon Sep 17 00:00:00 2001 From: Grant Date: Mon, 18 Mar 2024 17:42:29 +0900 Subject: [PATCH 8/8] remove fields.js --- includes/js/fields.js | 694 ------------------------------------------ 1 file changed, 694 deletions(-) delete mode 100644 includes/js/fields.js diff --git a/includes/js/fields.js b/includes/js/fields.js deleted file mode 100644 index e87afc2..0000000 --- a/includes/js/fields.js +++ /dev/null @@ -1,694 +0,0 @@ -var x = Object.defineProperty; -var K = (i,s)=>{ - for (var e in s) - x(i, e, { - get: s[e], - enumerable: !0 - }) -} -; -var c = { - CDN: "https://multipay.komoju.com", - ENV: "production", - HONEYBADGER_API_KEY: "hbp_aKD3g1hCztStGSvVXmhzrbEtOrtyKm3CqBxX", - GIT_REV: "af25e949e91d20f2e2276824995c8f8fd5c433ed" -}; -function y(i) { - window.komojuTranslations || (window.komojuTranslations = { - en: {}, - ja: {} - }); - for (let s of Object.keys(window.komojuTranslations)) - window.komojuTranslations[s] = { - ...window.komojuTranslations[s], - ...i[s] - } -} -var E = {}; -K(E, { - en: ()=>C, - ja: ()=>P -}); -var C = { - "customer-fee-will-be-charged": "A fee of %{fee} will be included.", - "dynamic-currency-notice": "Payment will be made in %{currency}: %{original} \u2192 %{converted}.", - "dynamic-currency-notice-with-fee": "Payment will be made in %{currency}: %{original} \u2192 %{converted}. (total: %{total})", - "payment-method-unavailable": "This payment method is currently unavailable.", - "verification-failed": "Verification failed.", - close: "Close" -} - , P = { - "customer-fee-will-be-charged": "%{fee}\u306E\u624B\u6570\u6599\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002", - "dynamic-currency-notice": "\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002", - "dynamic-currency-notice-with-fee": "\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002(\u5408\u8A08%{total})", - "payment-method-unavailable": "\u3053\u306E\u652F\u6255\u3044\u65B9\u6CD5\u306F\u73FE\u5728\u3054\u5229\u7528\u3044\u305F\u3060\u3051\u307E\u305B\u3093\u3002", - "verification-failed": "\u8A8D\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002", - close: "\u9589\u3058\u308B" -}; -var w = class { - constructor(s) { - this._sendWindow = new Promise(e=>this._setSendWindow = e), - this._receiveWindow = new Promise(e=>this._setReceiveWindow = e), - this.messageHandler = e=>{ - this.origin !== "*" && e.origin !== this.origin || this.handleMessage(e) - } - , - this.id = s ?? crypto.randomUUID(), - this.origin = "*", - this.promises = new Map, - this.listeners = new Map - } - setup(s) { - this._setSendWindow ? (this._setSendWindow(s.send), - this._setSendWindow = void 0) : this._sendWindow = Promise.resolve(s.send), - this._setReceiveWindow ? (this._setReceiveWindow(s.receive), - this._setReceiveWindow = void 0) : this._receiveWindow = Promise.resolve(s.receive), - s.receive.addEventListener("message", this.messageHandler) - } - send(s) { - let e = { - ...s, - brokerId: this.id, - id: crypto.randomUUID() - } - , t = null - , o = new Promise((n,r)=>{ - t = n - } - ); - if (!t) - throw new Error("Broker is busted"); - return this.promises.set(e.id, { - promise: o, - resolve: t - }), - this._sendWindow.then(n=>n.postMessage(e, this.origin)).then(()=>o) - } - receive(s, e) { - this.listeners.set(s, e) - } - async handleMessage(s) { - let e = s.data; - if (e.brokerId === this.id) - if (e.type === "ack") { - let t = e - , o = this.promises.get(t.id); - if (!o) - return; - o.resolve(t.response), - this.promises.delete(t.id) - } else { - let t = this.listeners.get(e.type) - , o = { - type: "ack", - brokerId: this.id, - id: e.id - }; - t && (o.response = await t(e) ?? void 0), - await this._sendWindow.then(n=>n.postMessage(o, this.origin)) - } - } - destroy() { - return this._receiveWindow.then(s=>s.removeEventListener("message", this.messageHandler)) - } -} -; -function k(i, s, e, t) { - if (!i.komojuApi) - throw new Error("KOMOJU API URL is null"); - if (!i.publishableKey) - throw new Error("KOMOJU publishable-key not set"); - return fetch(`${i.komojuApi}${e}`, { - method: s, - headers: { - accept: "application/json", - "content-type": "application/json", - authorization: `Basic ${btoa(`${i.publishableKey}:`)}`, - "komoju-via": "fields" - }, - body: t ? JSON.stringify(t) : void 0 - }) -} -y(E); -var m = class extends HTMLElement { - constructor() { - super(); - this._submitting = !1; - this.session = null; - this.broker = new w, - this.dialog = document.createElement("dialog"), - this.listenToMessagesFromIframe(this.broker), - this.dialog.style.width = "80%", - this.dialog.style.height = "80%", - this.dialog.style.padding = "0" - } - static get observedAttributes() { - return ["komoju-api", "session", "session-id", "publishable-key", "payment-type", "locale", "theme", "token", "name"] - } - get theme() { - return this.getAttribute("theme") - } - set theme(e) { - this.setAttribute("theme", e ?? "") - } - get komojuApi() { - return this.getAttribute("komoju-api") ?? "https://komoju.com" - } - set komojuApi(e) { - this.setAttribute("komoju-api", e) - } - connectedCallback() { - let e = new URLSearchParams; - e.append("broker", this.broker.id), - this.hasAttribute("komoju-api") && e.append("api", this.getAttribute("komoju-api")); - let t = document.createElement("iframe"); - t.setAttribute("sandbox", "allow-scripts allow-same-origin"), - t.setAttribute("allow", "payment *"), - t.title = "KOMOJU secure payment fields", - t.src = `${c.CDN}/fields-iframe.html#${e.toString()}`, - t.style.border = "none", - t.style.width = "100%", - t.style.overflow = "hidden", - t.height = "50", - t.addEventListener("load", ()=>{ - if (!t.contentWindow) - throw new Error("KOMOJU Fields: iframe had no contentWindow"); - this.broker.setup({ - send: t.contentWindow, - receive: window - }) - } - ), - this.replaceChildren(t, this.dialog); - let o = this.parentElement; - for (; o && o.tagName !== "FORM"; ) - o = o.parentElement; - if (!o) - return; - let n = o - , r = n.parentElement; - if (!r) - return; - let a = l=>{ - this._submitting || this.offsetParent !== null && l.target === n && (l.preventDefault(), - l.stopImmediatePropagation(), - this.submit(l)) - } - ; - r.addEventListener("submit", a, !0), - this.formSubmitHandler = { - form: n, - target: r, - handler: a - } - } - disconnectedCallback() { - this.formSubmitHandler && (this.formSubmitHandler.target.removeEventListener("submit", this.formSubmitHandler.handler, !0), - this.formSubmitHandler = void 0), - this.broker.destroy() - } - listenToMessagesFromIframe(e) { - e.receive("dispatch-event", t=>{ - let o = new CustomEvent(t.name,{ - detail: t.detail, - bubbles: !0, - composed: !0, - cancelable: !0 - }); - return t.name === "komoju-session-change" && (this.session = t.detail.session), - { - type: "dispatch-result", - cancel: !this.dispatchEvent(o) - } - } - ), - e.receive("resize", t=>{ - let o = this.querySelector("iframe"); - o.height = t.height - } - ), - e.receive("dialog-start", async t=>({ - type: "dialog-result", - result: await this.show3DSDialog(t.url) - })) - } - async attributeChangedCallback(e, t, o) { - this.broker.send({ - type: "attr", - attr: e, - value: o - }) - } - async submit(e) { - if (this.token) - return this.token; - let t = await this.broker.send({ - type: "submit" - }); - if (t?.type !== "submit-result") - throw new Error(`Unexpected submit response from komoju-fields iframe ${JSON.stringify(t)}`); - let o = t; - if (o.errors) { - this.dispatchEvent(new CustomEvent("komoju-invalid",{ - detail: { - errors: o.errors - }, - bubbles: !0, - composed: !0 - })); - return - } - if (o.pay) { - o.pay.error || await this.handlePayResult(o.pay); - return - } - if (o.token && e && this.formSubmitHandler) { - let n = this.formSubmitHandler.form - , r = this.getAttribute("name") ?? "komoju_token" - , a = document.querySelector(`input[name="${r}"]`); - a || (a = document.createElement("input"), - a.type = "hidden", - a.name = r, - n.append(a)), - a.value = o.token.id, - this.submitParentForm(); - return - } - if (o.token) - return this.token = o.token, - o.token; - throw new Error("KOMOJU Fields bug: submit result was not handled") - } - async handlePayResult(e) { - let t = this.session; - if (!t) - throw new Error("handlePayResult called without a session"); - let o = e.payment?.payment_details?.instructions_url; - if (o) { - let n = new URL(t.return_url ?? t.session_url); - n.searchParams.append("session_id", t.id), - this.showInstructionsDialog(o, n.toString()) - } else if (e.redirect_url) - window.location.href = e.redirect_url; - else - throw new Error(`payResult should have a redirect_url but doesnt ${JSON.stringify(e)}`) - } - async submitParentForm() { - if (!this.formSubmitHandler) - throw new Error("KOMOJU Fields: tried to submit nonexistent parent form"); - let e = this.formSubmitHandler.form; - try { - this._submitting = !0; - let t = new Event("submit",{ - bubbles: !0, - cancelable: !0 - }); - e.dispatchEvent(t) ? e.submit() : this.broker.send({ - type: "end-fade" - }) - } finally { - this._submitting = !1 - } - } - showInstructionsDialog(e, t) { - let o = this.dialog - , n = j(e); - n.style.height = "90%"; - let r = document.createElement("a") - , a = document.createElement("komoju-i18n"); - a.key = "close", - r.append(a), - r.classList.add("komoju-fields-close-dialog"), - r.href = t, - r.style.display = "block", - r.style.padding = "10px", - o.replaceChildren(r, n), - o.showModal() - } - show3DSDialog(e) { - return new Promise((t,o)=>{ - let n = this.dialog - , r = c.CDN - , a = j(e); - window.addEventListener("message", async l=>{ - if (l.origin === r) - try { - if (!l.data?._komojuFields) - return; - let {secureTokenId: d} = l.data; - if (!d) - throw new Error("No secureTokenId in message"); - let b = { - komojuApi: this.komojuApi, - publishableKey: this.getAttribute("publishable-key") ?? "" - } - , u = await k(b, "GET", `/api/v1/secure_tokens/${d}`); - if (u.status >= 400) { - let _ = await u.json(); - t({ - error: _ - }); - return - } - let L = await u.json(); - n.close(), - t({ - secureToken: L - }) - } catch (d) { - o(d) - } - } - ), - n.replaceChildren(a), - n.showModal() - } - ) - } -} -; -for (let i of m.observedAttributes) - i === "session" || i === "theme" || i === "komoju-api" || Object.defineProperty(m.prototype, H(i), { - get() { - return this.getAttribute(i) - }, - set(s) { - s === null ? this.removeAttribute(i) : this.setAttribute(i, s) - } - }); -function H(i) { - return i.split("-").reduce((s,e)=>s + e.charAt(0).toUpperCase() + e.slice(1)) -} -function j(i) { - let s = document.createElement("iframe"); - return s.setAttribute("sandbox", "allow-scripts allow-forms allow-same-origin"), - s.src = i, - s.style.border = "none", - s.style.width = "100%", - s.style.height = "100%", - s -} -var v = ` - -
-
- - -`; -function M(i, s) { - if (!i.parentElement) - throw new Error("KOMOJU Fields bug: radio input has no parent"); - if (!i.parentElement.classList.contains("radio")) - throw new Error("KOMOJU Fields bug: radio input parent has no .radio class"); - i.checked && i.parentElement.classList.add("checked"), - i.addEventListener("change", ()=>{ - s.querySelectorAll(".radio.checked").forEach(e=>e.classList.remove("checked")), - i.parentElement.classList.add("checked") - } - ) -} -var h = new Set; -h.add("bank_transfer"); -h.add("credit_card"); -h.add("konbini"); -h.add("offsite"); -var T = h; -var A = "en"; -function S(i, s) { - i.querySelectorAll("komoju-i18n").forEach(e=>{ - e.render(s) - } - ) -} -var p = class extends HTMLElement { - static get observedAttributes() { - return ["key"] - } - get key() { - return this.getAttribute("key") - } - set key(s) { - this.setAttribute("key", s ?? "") - } - connectedCallback() { - this.render() - } - attributeChangedCallback(s, e, t) { - s === "key" && this.render() - } - findLocale() { - let s = this.parentElement; - for (; s && !s.getAttribute("locale"); ) - s = s.parentElement; - return s?.getAttribute("locale") ?? A - } - render(s) { - if (!this.key) - return; - s || (s = this.findLocale()), - Object.keys(window.komojuTranslations).includes(s) || (s = A); - let e = s.substring(0, 2) - , t = window.komojuTranslations[e][this.key]; - if (!t) { - console.error(`KOMOJU bug: missing translation for key: ${this.key}`); - return - } - let o = t.match(/%\{[\w-]+\}/g); - if (o) { - let n = t; - o.forEach(r=>{ - let a = r.replace(/%{|}/g, "") - , l = this.dataset[a]; - l && (n = n.replace(r, l)) - } - ), - this.textContent = n; - return - } - this.textContent = t - } -} -; -var f = class extends HTMLElement { - get theme() { - return this.getAttribute("theme") - } - set theme(s) { - this.setAttribute("theme", s ?? "") - } - applyTheme() { - let s = this.shadowRoot ?? document; - this.theme === null ? s.querySelectorAll("#theme,#inline-theme").forEach(e=>e.remove()) : this.theme.startsWith("http") || this.theme.startsWith("/") || this.theme.startsWith("data:") ? this.applyExternalTheme(s, this.theme) : this.applyInlineTheme(s, this.theme) - } - applyInlineTheme(s, e) { - s.querySelectorAll("#theme,#inline-theme").forEach(o=>o.remove()); - let t = document.createElement("style"); - t.id = "inline-theme", - t.textContent = e, - this.appendStyleTag(t) - } - applyExternalTheme(s, e) { - s.querySelectorAll("#inline-theme").forEach(o=>o.remove()); - let t = s.querySelector("#theme"); - t ? t.href !== this.theme && (t.href = e) : (t = document.createElement("link"), - t.id = "theme", - t.rel = "stylesheet", - t.href = e, - this.appendStyleTag(t)) - } - appendStyleTag(s) { - this.shadowRoot ? this.shadowRoot.append(s) : document.head.append(s) - } -} -; -var g = class extends f { - constructor() { - super(); - this.sessionChangedHandler = null; - let e = this.attachShadow({ - mode: "open" - }); - e.innerHTML = v; - let t = document.createElement("link"); - t.rel = "stylesheet", - t.href = `${c.CDN}/static/shared.css`, - e.append(t) - } - static get observedAttributes() { - return ["locale", "theme"] - } - get fields() { - return this.getAttribute("fields") - } - set fields(e) { - this.setAttribute("fields", e ?? "") - } - get locale() { - return this.getAttribute("locale") - } - set locale(e) { - this.setAttribute("locale", e ?? "") - } - async connectedCallback() { - let e = this.komojuFieldsElement() - , t = { - element: e, - handler: o=>{ - this.render(e) - } - }; - await this.setupPaymentTypesI18n(), - this.render(e), - e.addEventListener("komoju-session-change", t.handler), - this.sessionChangedHandler = t - } - disconnectedCallback() { - this.sessionChangedHandler && this.sessionChangedHandler.element.removeEventListener("komoju-session-change", this.sessionChangedHandler.handler) - } - async attributeChangedCallback(e, t, o) { - !this.shadowRoot || (e === "locale" && o && t !== o ? (S(this.shadowRoot, o), - this.updatePickerLocale(o)) : e === "theme" && this.applyTheme()) - } - komojuFieldsElement() { - return this.fields ? document.querySelector(`#${this.fields}`) : document.querySelector("komoju-fields") - } - render(e) { - if (!e.session || !this.shadowRoot) - return; - let t = this.shadowRoot.getElementById("picker") - , o = this.shadowRoot.getElementById("radio-template"); - if (!t) - throw new Error("KOMOJU Fields bug: wrong shadow DOM (no picker)"); - if (!o) - throw new Error("KOMOJU Fields bug: wrong shadow DOM (no template)"); - this.locale || (this.locale = e.session.default_locale.substring(0, 2)), - this.updatePickerLocale(this.locale), - t.replaceChildren(); - let n = 0; - for (let r of e.session.payment_methods) { - let a = r.offsite ? "offsite" : r.type; - if (e.hasAttribute("token") && !T.has(a)) - continue; - let l = o.content.cloneNode(!0) - , d = l.querySelector("input") - , b = l.querySelector("img") - , u = l.querySelector("komoju-i18n"); - (n === 0 || e.paymentType === r.type) && (d.checked = !0), - d.addEventListener("change", ()=>{ - e.paymentType = r.type - } - ), - M(d, this.shadowRoot), - b.src = `${e.komojuApi}/payment_methods/${r.type}.svg`, - u.key = r.type, - t.append(l), - n += 1 - } - !this.theme && e.theme && (this.theme = e.theme, - this.applyTheme()) - } - async setupPaymentTypesI18n() { - let e = this.komojuFieldsElement() - , t = await k(e, "GET", "/api/v1/payment_methods"); - this.komojuPaymentMethods = await t.json(); - for (let o of this.komojuPaymentMethods) { - let n = { - en: { - [o.type_slug]: o.name_en - }, - ja: { - [o.type_slug]: o.name_ja - }, - ko: { - [o.type_slug]: o.name_ko - } - }; - y(n) - } - } - updatePickerLocale(e) { - if (!this.shadowRoot) - return; - let t = this.shadowRoot.getElementById("picker"); - t && t.setAttribute("locale", e) - } -} -; -window.customElements.define("komoju-fields", m); -window.customElements.define("komoju-picker", g); -window.customElements.define("komoju-i18n", p); -window.komojuReportError = (i,s)=>{ - console.error(i, s) -} -; -if (window.komojuErrorReporting !== !1) { - (async()=>{ - let e = await import("/extras/error-reporting/module.js"); - window.komojuReportError = e.reportError - } - )(); - let i = s=>{ - let e = [/\/fields\.js:\d+:\d+\n/, /\/fields\/[\w-]+\/module\.js\n:\d+:\d+/, /\/extras\/[\w-]+\/module\.js\n:\d+:\d+/] - , t = s instanceof ErrorEvent ? s.error : s.reason; - t instanceof Error && (!t.stack || !e.find(o=>o.test(t.stack)) || window.komojuReportError(t)) - } - ; - window.addEventListener("error", i), - window.addEventListener("unhandledrejection", i) -} - -// function registerPaymentMethod(paymentMethod) { -// const settings = window.wc.wcSettings.getSetting(`${paymentMethod.title}_data`, {}); -// const label = window.wp.htmlEntities.decodeEntities(settings.title) || window.wp.i18n.__(paymentMethod.title, paymentMethod.title); -// const Content = () => { -// return window.wp.htmlEntities.decodeEntities(settings.description || ''); -// }; -// const Block_Gateway = { -// name: paymentMethod.title, -// label: label, -// content: Object(window.wp.element.createElement)(Content, null), -// edit: Object(window.wp.element.createElement)(Content, null), -// canMakePayment: () => true, -// ariaLabel: label, -// supports: { -// features: settings.supports, -// }, -// }; -// window.wc.wcBlocksRegistry.registerPaymentMethod(Block_Gateway); -// } - -// window.addEventListener('load', () => { -// paymentMethodData = window.wc.wcSettings.getSetting('paymentMethodData', {}); -// Object.values(paymentMethodData).forEach((value) => { -// registerPaymentMethod(value); -// }); -// });