Version Description
TUESDAY, 21ST DECEMBER 2021 = * New: Express Checkout
Download this release
Release Info
Developer | brainstormworg |
Plugin | Stripe Payments For WooCommerce by Checkout Plugins |
Version | 1.1.0 |
Comparing to | |
See all releases |
Code changes from version 1.0.0 to 1.1.0
- admin/admin-controller.php +375 -40
- admin/assets/css/admin.css +128 -128
- admin/assets/css/express-checkout.css +42 -0
- admin/assets/js/admin.js +2 -2
- admin/assets/js/express-checkout.js +180 -0
- assets/css/stripe-elements.css +101 -0
- assets/js/payment-request.js +566 -0
- autoloader.php +4 -2
- checkout-plugins-stripe-woo.php +2 -2
- compatibility/apple-developer-merchantid-domain-association +1 -0
- compatibility/apple-pay.php +283 -0
- gateway/stripe/card-payments.php +179 -52
- gateway/stripe/frontend-scripts.php +53 -3
- gateway/stripe/payment-request-api.php +869 -0
- gateway/stripe/stripe-api.php +26 -7
- inc/helper.php +96 -109
- inc/traits/subscriptions.php +12 -9
- readme.txt +16 -1
admin/admin-controller.php
CHANGED
@@ -10,13 +10,13 @@ namespace CPSW\Admin;
|
|
10 |
|
11 |
use CPSW\Gateway\Stripe\Stripe_Api;
|
12 |
use CPSW\Inc\Traits\Get_Instance;
|
|
|
13 |
use CPSW\Inc\Helper;
|
14 |
use CPSW\Gateway\Stripe\Webhook;
|
15 |
use Stripe\OAuth;
|
16 |
use WC_Admin_Settings;
|
17 |
use Exception;
|
18 |
|
19 |
-
|
20 |
/**
|
21 |
* Admin Controller - This class is used to update or delete stripe settings.
|
22 |
*
|
@@ -67,15 +67,16 @@ class Admin_Controller {
|
|
67 |
* @since 0.0.1
|
68 |
*/
|
69 |
public function __construct() {
|
70 |
-
|
71 |
$this->init();
|
|
|
72 |
foreach ( $this->settings_keys as $key ) {
|
73 |
$this->settings[ $key ] = get_option( $key );
|
74 |
}
|
75 |
|
76 |
$this->navigation = [
|
77 |
-
'cpsw_api_settings'
|
78 |
-
'cpsw_stripe'
|
|
|
79 |
];
|
80 |
|
81 |
}
|
@@ -86,7 +87,6 @@ class Admin_Controller {
|
|
86 |
* @since 0.0.1
|
87 |
*/
|
88 |
public function init() {
|
89 |
-
|
90 |
add_filter( 'woocommerce_settings_tabs_array', [ $this, 'add_settings_tab' ], 50 );
|
91 |
add_action( 'woocommerce_settings_tabs_cpsw_api_settings', [ $this, 'settings_tab' ] );
|
92 |
add_action( 'woocommerce_update_options_cpsw_api_settings', [ $this, 'update_settings' ] );
|
@@ -97,14 +97,18 @@ class Admin_Controller {
|
|
97 |
add_action( 'woocommerce_admin_field_cpsw_stripe_connect', [ $this, 'stripe_connect' ] );
|
98 |
add_action( 'woocommerce_admin_field_cpsw_account_id', [ $this, 'account_id' ] );
|
99 |
add_action( 'woocommerce_admin_field_cpsw_webhook_url', [ $this, 'webhook_url' ] );
|
|
|
|
|
100 |
|
101 |
-
add_action( '
|
102 |
-
add_action( '
|
103 |
|
104 |
add_action( 'wp_ajax_cpsw_test_stripe_connection', [ $this, 'connection_test' ] );
|
105 |
add_action( 'wp_ajax_cpsw_disconnect_account', [ $this, 'disconnect_account' ] );
|
|
|
106 |
|
107 |
add_action( 'woocommerce_settings_save_cpsw_api_settings', [ $this, 'check_connection_on_updates' ] );
|
|
|
108 |
add_filter( 'cpsw_settings', [ $this, 'filter_settings_fields' ], 1 );
|
109 |
add_action( 'update_option_cpsw_mode', [ $this, 'update_mode' ], 10, 3 );
|
110 |
|
@@ -114,6 +118,49 @@ class Admin_Controller {
|
|
114 |
|
115 |
add_filter( 'woocommerce_get_sections_checkout', [ $this, 'add_settings_links' ] );
|
116 |
add_filter( 'woocommerce_get_sections_cpsw_api_settings', [ $this, 'add_settings_links' ] );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
}
|
118 |
|
119 |
/**
|
@@ -122,14 +169,13 @@ class Admin_Controller {
|
|
122 |
* @since 0.0.1
|
123 |
*/
|
124 |
public function initialise_warnings() {
|
125 |
-
|
126 |
// If keys are not set bail.
|
127 |
if ( ! $this->are_keys_set() ) {
|
128 |
add_action( 'admin_notices', [ $this, 'are_keys_set_check' ] );
|
129 |
}
|
130 |
|
131 |
// If no SSL bail.
|
132 |
-
if ( 'live' ===
|
133 |
add_action( 'admin_notices', [ $this, 'ssl_not_connect' ] );
|
134 |
}
|
135 |
|
@@ -142,7 +188,6 @@ class Admin_Controller {
|
|
142 |
if ( isset( $_GET['cpsw_call'] ) && ! empty( $_GET['cpsw_call'] ) && 'failed' === $_GET['cpsw_call'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
143 |
add_action( 'admin_notices', [ $this, 'connect_failed_notice' ] );
|
144 |
}
|
145 |
-
|
146 |
}
|
147 |
|
148 |
/**
|
@@ -151,7 +196,6 @@ class Admin_Controller {
|
|
151 |
* @since 0.0.1
|
152 |
*/
|
153 |
public function enqueue_scripts() {
|
154 |
-
|
155 |
if ( isset( $_GET['page'] ) && 'wc-settings' === $_GET['page'] && isset( $_GET['tab'] ) && ( 'cpsw_api_settings' === $_GET['tab'] || isset( $_GET['section'] ) && 'cpsw_stripe' === $_GET['section'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
156 |
|
157 |
wp_register_style( 'cpsw-admin-style', plugins_url( 'assets/css/admin.css', __FILE__ ), [], CPSW_VERSION, 'all' );
|
@@ -166,7 +210,7 @@ class Admin_Controller {
|
|
166 |
[
|
167 |
'site_url' => get_site_url() . '/wp-admin/admin.php?page=wc-settings',
|
168 |
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
169 |
-
'cpsw_mode' =>
|
170 |
'admin_nonce' => wp_create_nonce( 'cpsw_admin_nonce' ),
|
171 |
'dashboard_url' => admin_url( 'admin.php?page=wc-settings&tab=cpsw_api_settings' ),
|
172 |
'generic_error' => __( 'Something went wrong! Please reload the page and try again.', 'checkout-plugins-stripe-woo' ),
|
@@ -178,6 +222,37 @@ class Admin_Controller {
|
|
178 |
'stripe_connect_other_acc' => __( 'You can connect other Stripe account now.', 'checkout-plugins-stripe-woo' ),
|
179 |
'is_connected' => $this->is_stripe_connected(),
|
180 |
'is_manually_connected' => isset( $_GET['connect'] ) ? sanitize_text_field( $_GET['connect'] ) : '', //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
]
|
182 |
);
|
183 |
}
|
@@ -270,7 +345,6 @@ class Admin_Controller {
|
|
270 |
* @param string $value Field name in string.
|
271 |
*/
|
272 |
public function stripe_connect( $value ) {
|
273 |
-
|
274 |
if ( true === $this->is_stripe_connected() ) {
|
275 |
return;
|
276 |
}
|
@@ -320,7 +394,7 @@ class Admin_Controller {
|
|
320 |
return;
|
321 |
}
|
322 |
|
323 |
-
$option_value =
|
324 |
?>
|
325 |
<tr valign="top">
|
326 |
<th scope="row">
|
@@ -383,7 +457,6 @@ class Admin_Controller {
|
|
383 |
<?php
|
384 |
}
|
385 |
|
386 |
-
|
387 |
/**
|
388 |
* This method is used to display block for Stripe webhook url.
|
389 |
*
|
@@ -418,13 +491,58 @@ class Admin_Controller {
|
|
418 |
<?php
|
419 |
}
|
420 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
421 |
/**
|
422 |
* This method is used to display Stripe Account key information on the settings page.
|
423 |
*
|
424 |
* @param string $value Name of the field.
|
425 |
*/
|
426 |
public function account_keys( $value ) {
|
427 |
-
|
428 |
if ( empty( Helper::get_setting( 'cpsw_pub_key' ) ) && empty( Helper::get_setting( 'cpsw_test_pub_key' ) ) ) {
|
429 |
return;
|
430 |
}
|
@@ -463,9 +581,7 @@ class Admin_Controller {
|
|
463 |
* @param string $value Name of the field.
|
464 |
*/
|
465 |
public function connect_button( $value ) {
|
466 |
-
|
467 |
-
$data = WC_Admin_Settings::get_field_description( $value );
|
468 |
-
|
469 |
$description = $data['description'];
|
470 |
$tooltip_html = $data['tooltip_html'];
|
471 |
$manual_link = false;
|
@@ -534,7 +650,6 @@ class Admin_Controller {
|
|
534 |
woocommerce_admin_fields( $this->get_settings() );
|
535 |
}
|
536 |
|
537 |
-
|
538 |
/**
|
539 |
* Uses the WooCommerce options API to save settings via the @see woocommerce_update_options() function.
|
540 |
*/
|
@@ -568,7 +683,6 @@ class Admin_Controller {
|
|
568 |
);
|
569 |
}
|
570 |
|
571 |
-
|
572 |
/**
|
573 |
* This method is used to initialize all stripe configuration fields.
|
574 |
*
|
@@ -685,14 +799,12 @@ class Admin_Controller {
|
|
685 |
return $settings;
|
686 |
}
|
687 |
|
688 |
-
|
689 |
/**
|
690 |
* Checks for response after stripe onboarding process
|
691 |
*
|
692 |
* @return void
|
693 |
*/
|
694 |
public function admin_options() {
|
695 |
-
|
696 |
if ( ! isset( $_GET['cpsw_connect_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( $_GET['cpsw_connect_nonce'] ), 'stripe-connect' ) ) {
|
697 |
return;
|
698 |
}
|
@@ -748,14 +860,12 @@ class Admin_Controller {
|
|
748 |
}
|
749 |
}
|
750 |
|
751 |
-
|
752 |
/**
|
753 |
* Perform a connection test
|
754 |
*
|
755 |
* @return $mixed
|
756 |
*/
|
757 |
public function connection_test() {
|
758 |
-
|
759 |
if ( ! isset( $_GET['_security'] ) || ! wp_verify_nonce( sanitize_text_field( $_GET['_security'] ), 'cpsw_admin_nonce' ) ) {
|
760 |
return wp_send_json_error( [ 'message' => __( 'Error: Sorry, the nonce security check didn’t pass. Please reload the page and try again.', 'checkout-plugins-stripe-woo' ) ] );
|
761 |
}
|
@@ -870,6 +980,25 @@ class Admin_Controller {
|
|
870 |
return wp_send_json_success( [ 'message' => __( 'Stripe keys are reset successfully.', 'checkout-plugins-stripe-woo' ) ] );
|
871 |
}
|
872 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
873 |
/**
|
874 |
* This method is used get account information from stripe.
|
875 |
*
|
@@ -881,13 +1010,13 @@ class Admin_Controller {
|
|
881 |
return false;
|
882 |
}
|
883 |
|
884 |
-
$stripe_api = Stripe_Api
|
885 |
$response = $stripe_api->accounts( 'retrieve', [ $account_id ] );
|
886 |
if ( $response['success'] ) {
|
887 |
$response = $response['data'];
|
888 |
return $response->settings->dashboard->display_name;
|
889 |
} else {
|
890 |
-
return
|
891 |
}
|
892 |
}
|
893 |
|
@@ -898,7 +1027,7 @@ class Admin_Controller {
|
|
898 |
* @return $array array It returns cpsw_settings array.
|
899 |
*/
|
900 |
public function filter_settings_fields( $array = [] ) {
|
901 |
-
if ( 'success' !==
|
902 |
unset( $array['test_mode'] );
|
903 |
unset( $array['webhook_url'] );
|
904 |
unset( $array['test_webhook_secret'] );
|
@@ -952,7 +1081,7 @@ class Admin_Controller {
|
|
952 |
* @return $mixed
|
953 |
*/
|
954 |
public function is_stripe_connected() {
|
955 |
-
if ( 'success' ===
|
956 |
return true;
|
957 |
}
|
958 |
return false;
|
@@ -964,7 +1093,6 @@ class Admin_Controller {
|
|
964 |
* @return $mixed
|
965 |
*/
|
966 |
public function check_connection_on_updates() {
|
967 |
-
|
968 |
if ( 'yes' === Helper::get_setting( 'cpsw_auto_connect' ) ) {
|
969 |
return;
|
970 |
}
|
@@ -1065,7 +1193,6 @@ class Admin_Controller {
|
|
1065 |
update_option( 'cpsw_con_status', 'success' );
|
1066 |
update_option( 'cpsw_mode', 'live' );
|
1067 |
}
|
1068 |
-
|
1069 |
}
|
1070 |
|
1071 |
/**
|
@@ -1073,17 +1200,17 @@ class Admin_Controller {
|
|
1073 |
*
|
1074 |
* @param string $old_value Old value of the option.
|
1075 |
* @param strign $value New value of the option.
|
|
|
1076 |
* @return void
|
1077 |
*/
|
1078 |
public function update_mode( $old_value, $value ) {
|
1079 |
-
|
1080 |
-
if ( 'yes' === get_option( 'cpsw_auto_connect' ) ) {
|
1081 |
return;
|
1082 |
}
|
1083 |
|
1084 |
-
if ( ! empty(
|
1085 |
update_option( 'cpsw_mode', 'live' );
|
1086 |
-
} elseif ( ! empty(
|
1087 |
update_option( 'cpsw_mode', 'test' );
|
1088 |
}
|
1089 |
}
|
@@ -1105,7 +1232,6 @@ class Admin_Controller {
|
|
1105 |
* @return void
|
1106 |
*/
|
1107 |
public function add_breadcrumb() {
|
1108 |
-
|
1109 |
if ( ! empty( $this->navigation ) ) {
|
1110 |
?>
|
1111 |
<ul class="subsubsub">
|
@@ -1134,13 +1260,16 @@ class Admin_Controller {
|
|
1134 |
* Adds settings link to the checkout section.
|
1135 |
*
|
1136 |
* @param array $settings_tab Settings tabs array.
|
|
|
1137 |
* @return array $settings_tab Settings tabs array returned.
|
1138 |
*/
|
1139 |
public function add_settings_links( $settings_tab ) {
|
1140 |
-
if ( isset( $_GET['section'] ) && 'cpsw_stripe' === $_GET['section'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
1141 |
-
$settings_tab['cpsw_api_settings']
|
1142 |
-
$settings_tab['cpsw_stripe']
|
|
|
1143 |
}
|
|
|
1144 |
return apply_filters( 'cpsw_setting_tabs', $settings_tab );
|
1145 |
}
|
1146 |
|
@@ -1148,10 +1277,10 @@ class Admin_Controller {
|
|
1148 |
* Adds manual api keys links.
|
1149 |
*
|
1150 |
* @param string $links default copyright link with text.
|
|
|
1151 |
* @return string $links Return customized copyright text with link.
|
1152 |
*/
|
1153 |
public function add_manual_connect_link( $links ) {
|
1154 |
-
|
1155 |
if ( ! isset( $_GET['page'] ) || ! isset( $_GET['tab'] ) || 'wc-settings' !== $_GET['page'] || 'cpsw_api_settings' !== $_GET['tab'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
1156 |
return $links;
|
1157 |
}
|
@@ -1181,4 +1310,210 @@ class Admin_Controller {
|
|
1181 |
}
|
1182 |
}
|
1183 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1184 |
}
|
10 |
|
11 |
use CPSW\Gateway\Stripe\Stripe_Api;
|
12 |
use CPSW\Inc\Traits\Get_Instance;
|
13 |
+
use CPSW\Inc\Logger;
|
14 |
use CPSW\Inc\Helper;
|
15 |
use CPSW\Gateway\Stripe\Webhook;
|
16 |
use Stripe\OAuth;
|
17 |
use WC_Admin_Settings;
|
18 |
use Exception;
|
19 |
|
|
|
20 |
/**
|
21 |
* Admin Controller - This class is used to update or delete stripe settings.
|
22 |
*
|
67 |
* @since 0.0.1
|
68 |
*/
|
69 |
public function __construct() {
|
|
|
70 |
$this->init();
|
71 |
+
|
72 |
foreach ( $this->settings_keys as $key ) {
|
73 |
$this->settings[ $key ] = get_option( $key );
|
74 |
}
|
75 |
|
76 |
$this->navigation = [
|
77 |
+
'cpsw_api_settings' => __( 'Stripe API Settings', 'checkout-plugins-stripe-woo' ),
|
78 |
+
'cpsw_stripe' => __( 'Credit Cards', 'checkout-plugins-stripe-woo' ),
|
79 |
+
'cpsw_express_checkout' => __( 'Express Checkout', 'checkout-plugins-stripe-woo' ),
|
80 |
];
|
81 |
|
82 |
}
|
87 |
* @since 0.0.1
|
88 |
*/
|
89 |
public function init() {
|
|
|
90 |
add_filter( 'woocommerce_settings_tabs_array', [ $this, 'add_settings_tab' ], 50 );
|
91 |
add_action( 'woocommerce_settings_tabs_cpsw_api_settings', [ $this, 'settings_tab' ] );
|
92 |
add_action( 'woocommerce_update_options_cpsw_api_settings', [ $this, 'update_settings' ] );
|
97 |
add_action( 'woocommerce_admin_field_cpsw_stripe_connect', [ $this, 'stripe_connect' ] );
|
98 |
add_action( 'woocommerce_admin_field_cpsw_account_id', [ $this, 'account_id' ] );
|
99 |
add_action( 'woocommerce_admin_field_cpsw_webhook_url', [ $this, 'webhook_url' ] );
|
100 |
+
add_action( 'woocommerce_admin_field_cpsw_express_checkout_preview', [ $this, 'express_checkout_preview' ] );
|
101 |
+
add_action( 'woocommerce_admin_field_express_checkout_notice', [ $this, 'express_checkout_notice' ] );
|
102 |
|
103 |
+
add_action( 'admin_init', [ $this, 'admin_options' ] );
|
104 |
+
add_action( 'admin_init', [ $this, 'initialise_warnings' ] );
|
105 |
|
106 |
add_action( 'wp_ajax_cpsw_test_stripe_connection', [ $this, 'connection_test' ] );
|
107 |
add_action( 'wp_ajax_cpsw_disconnect_account', [ $this, 'disconnect_account' ] );
|
108 |
+
add_action( 'wp_ajax_cpsw_js_errors', [ $this, 'js_errors' ] );
|
109 |
|
110 |
add_action( 'woocommerce_settings_save_cpsw_api_settings', [ $this, 'check_connection_on_updates' ] );
|
111 |
+
add_filter( 'woocommerce_save_settings_checkout_cpsw_express_checkout', [ $this, 'cpsw_express_checkout_option_updates' ] );
|
112 |
add_filter( 'cpsw_settings', [ $this, 'filter_settings_fields' ], 1 );
|
113 |
add_action( 'update_option_cpsw_mode', [ $this, 'update_mode' ], 10, 3 );
|
114 |
|
118 |
|
119 |
add_filter( 'woocommerce_get_sections_checkout', [ $this, 'add_settings_links' ] );
|
120 |
add_filter( 'woocommerce_get_sections_cpsw_api_settings', [ $this, 'add_settings_links' ] );
|
121 |
+
add_filter( 'woocommerce_get_settings_checkout', [ $this, 'checkout_settings' ], 10, 2 );
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Saves section cpsw_express_checkout_data to cpsw_stripe settings
|
126 |
+
*
|
127 |
+
* @return array
|
128 |
+
* @since 1.1.0
|
129 |
+
*/
|
130 |
+
public function cpsw_express_checkout_option_updates() {
|
131 |
+
if ( isset( $_POST['save'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
|
132 |
+
$express_checkout = [];
|
133 |
+
$radio_checkbox = [
|
134 |
+
'express_checkout_enabled' => 'no',
|
135 |
+
'express_checkout_product_sticky_footer' => 'no',
|
136 |
+
'express_checkout_product_checkout_page' => 'no',
|
137 |
+
];
|
138 |
+
foreach ( $_POST as $key => $value ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
|
139 |
+
if ( 0 === strpos( $key, 'cpsw_express_checkout' ) ) {
|
140 |
+
$k = sanitize_text_field( str_replace( 'cpsw_', '', $key ) );
|
141 |
+
if ( ! empty( $radio_checkbox ) && in_array( $k, array_keys( $radio_checkbox ), true ) ) {
|
142 |
+
$express_checkout[ $k ] = 'yes';
|
143 |
+
unset( $radio_checkbox[ $k ] );
|
144 |
+
} else {
|
145 |
+
if ( is_array( $value ) ) {
|
146 |
+
$express_checkout[ $k ] = array_map( 'sanitize_text_field', $value );
|
147 |
+
} else {
|
148 |
+
$express_checkout[ $k ] = sanitize_text_field( $value );
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
unset( $_POST[ $key ] ); //phpcs:ignore WordPress.Security.NonceVerification.Missing
|
153 |
+
}
|
154 |
+
}
|
155 |
+
|
156 |
+
if ( ! empty( $express_checkout ) ) {
|
157 |
+
$cpsw_stripe = get_option( 'woocommerce_cpsw_stripe_settings' );
|
158 |
+
$cpsw_stripe = array_merge( $cpsw_stripe, $radio_checkbox, $express_checkout );
|
159 |
+
update_option( 'woocommerce_cpsw_stripe_settings', $cpsw_stripe );
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
return false;
|
164 |
}
|
165 |
|
166 |
/**
|
169 |
* @since 0.0.1
|
170 |
*/
|
171 |
public function initialise_warnings() {
|
|
|
172 |
// If keys are not set bail.
|
173 |
if ( ! $this->are_keys_set() ) {
|
174 |
add_action( 'admin_notices', [ $this, 'are_keys_set_check' ] );
|
175 |
}
|
176 |
|
177 |
// If no SSL bail.
|
178 |
+
if ( 'live' === Helper::get_payment_mode() && ! is_ssl() ) {
|
179 |
add_action( 'admin_notices', [ $this, 'ssl_not_connect' ] );
|
180 |
}
|
181 |
|
188 |
if ( isset( $_GET['cpsw_call'] ) && ! empty( $_GET['cpsw_call'] ) && 'failed' === $_GET['cpsw_call'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
189 |
add_action( 'admin_notices', [ $this, 'connect_failed_notice' ] );
|
190 |
}
|
|
|
191 |
}
|
192 |
|
193 |
/**
|
196 |
* @since 0.0.1
|
197 |
*/
|
198 |
public function enqueue_scripts() {
|
|
|
199 |
if ( isset( $_GET['page'] ) && 'wc-settings' === $_GET['page'] && isset( $_GET['tab'] ) && ( 'cpsw_api_settings' === $_GET['tab'] || isset( $_GET['section'] ) && 'cpsw_stripe' === $_GET['section'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
200 |
|
201 |
wp_register_style( 'cpsw-admin-style', plugins_url( 'assets/css/admin.css', __FILE__ ), [], CPSW_VERSION, 'all' );
|
210 |
[
|
211 |
'site_url' => get_site_url() . '/wp-admin/admin.php?page=wc-settings',
|
212 |
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
213 |
+
'cpsw_mode' => Helper::get_payment_mode(),
|
214 |
'admin_nonce' => wp_create_nonce( 'cpsw_admin_nonce' ),
|
215 |
'dashboard_url' => admin_url( 'admin.php?page=wc-settings&tab=cpsw_api_settings' ),
|
216 |
'generic_error' => __( 'Something went wrong! Please reload the page and try again.', 'checkout-plugins-stripe-woo' ),
|
222 |
'stripe_connect_other_acc' => __( 'You can connect other Stripe account now.', 'checkout-plugins-stripe-woo' ),
|
223 |
'is_connected' => $this->is_stripe_connected(),
|
224 |
'is_manually_connected' => isset( $_GET['connect'] ) ? sanitize_text_field( $_GET['connect'] ) : '', //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
225 |
+
'cpsw_admin_settings_tab' => isset( $_GET['tab'] ) ? sanitize_text_field( $_GET['tab'] ) : '', //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
226 |
+
]
|
227 |
+
);
|
228 |
+
}
|
229 |
+
|
230 |
+
if ( isset( $_GET['page'] ) && 'wc-settings' === $_GET['page'] && isset( $_GET['tab'] ) && 'checkout' === $_GET['tab'] && isset( $_GET['section'] ) && 'cpsw_express_checkout' === $_GET['section'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
231 |
+
wp_register_style( 'cpsw-express-checkout-style', plugins_url( 'assets/css/express-checkout.css', __FILE__ ), [], CPSW_VERSION, 'all' );
|
232 |
+
wp_enqueue_style( 'cpsw-express-checkout-style' );
|
233 |
+
|
234 |
+
wp_register_script( 'cpsw-stripe-external', 'https://js.stripe.com/v3/', [], CPSW_VERSION, true );
|
235 |
+
wp_enqueue_script( 'cpsw-stripe-external' );
|
236 |
+
|
237 |
+
wp_register_script( 'cpsw-express-checkout-js', plugins_url( 'assets/js/express-checkout.js', __FILE__ ), [ 'jquery', 'cpsw-stripe-external' ], CPSW_VERSION, true );
|
238 |
+
wp_enqueue_script( 'cpsw-express-checkout-js' );
|
239 |
+
|
240 |
+
$public_key = ( 'live' === Helper::get_payment_mode() ) ? Helper::get_setting( 'cpsw_pub_key' ) : Helper::get_setting( 'cpsw_test_pub_key' );
|
241 |
+
|
242 |
+
wp_localize_script(
|
243 |
+
'cpsw-express-checkout-js',
|
244 |
+
'cpsw_express_checkout',
|
245 |
+
[
|
246 |
+
'public_key' => $public_key,
|
247 |
+
'style' => [
|
248 |
+
'type' => Helper::get_setting( 'express_checkout_button_type', 'cpsw_stripe' ),
|
249 |
+
'theme' => Helper::get_setting( 'express_checkout_button_theme', 'cpsw_stripe' ),
|
250 |
+
'height' => (int) Helper::get_setting( 'express_checkout_button_height', 'cpsw_stripe' ),
|
251 |
+
],
|
252 |
+
'messages' => [
|
253 |
+
/* translators: Html Markup*/
|
254 |
+
'no_method' => sprintf( __( 'No payment method detected. Either your browser is not supported or you do not have save cards. For more details read %1$1sdocument$2$2s.', 'checkout-plugins-stripe-woo' ), '<a href="https://stripe.com/docs/stripe-js/elements/payment-request-button#html-js-testing" target="_blank">', '</a>' ),
|
255 |
+
],
|
256 |
]
|
257 |
);
|
258 |
}
|
345 |
* @param string $value Field name in string.
|
346 |
*/
|
347 |
public function stripe_connect( $value ) {
|
|
|
348 |
if ( true === $this->is_stripe_connected() ) {
|
349 |
return;
|
350 |
}
|
394 |
return;
|
395 |
}
|
396 |
|
397 |
+
$option_value = Helper::get_setting( 'cpsw_account_id' );
|
398 |
?>
|
399 |
<tr valign="top">
|
400 |
<th scope="row">
|
457 |
<?php
|
458 |
}
|
459 |
|
|
|
460 |
/**
|
461 |
* This method is used to display block for Stripe webhook url.
|
462 |
*
|
491 |
<?php
|
492 |
}
|
493 |
|
494 |
+
/**
|
495 |
+
* Displays express checkout button preview
|
496 |
+
*
|
497 |
+
* @param array $value settings data.
|
498 |
+
*
|
499 |
+
* @return void
|
500 |
+
*/
|
501 |
+
public function express_checkout_preview( $value ) {
|
502 |
+
?>
|
503 |
+
<tr valign="top">
|
504 |
+
<th scope="row">
|
505 |
+
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?> </label>
|
506 |
+
</th>
|
507 |
+
<td class="form-wc form-wc-<?php echo esc_attr( $value['class'] ); ?>">
|
508 |
+
<fieldset>
|
509 |
+
<div class="cpsw_express_checkout_preview_wrapper">
|
510 |
+
<div class="cpsw_express_checkout_preview"></div>
|
511 |
+
</div>
|
512 |
+
</fieldset>
|
513 |
+
<?php if ( ! empty( $value['desc'] ) ) { ?>
|
514 |
+
<fieldset class="cpsw_express_checkout_preview_description">
|
515 |
+
<div class="notice inline notice-warning cpsw_inline_notice" style="margin: 5px 0 -10px;padding:10px 20px;">
|
516 |
+
<?php echo wp_kses_post( $value['desc'] ); ?>
|
517 |
+
</div>
|
518 |
+
</fieldset>
|
519 |
+
<?php } ?>
|
520 |
+
</td>
|
521 |
+
</tr>
|
522 |
+
<?php
|
523 |
+
}
|
524 |
+
|
525 |
+
/**
|
526 |
+
* Displays express checkout button preview
|
527 |
+
*
|
528 |
+
* @param array $value settings data.
|
529 |
+
*
|
530 |
+
* @return void
|
531 |
+
*/
|
532 |
+
public function express_checkout_notice( $value ) {
|
533 |
+
?>
|
534 |
+
<div class="notice inline notice-error cpsw_inline_notice" style="margin: 5px 0 -10px;padding:10px 20px;">
|
535 |
+
<?php echo wp_kses_post( $value['desc'] ); ?>
|
536 |
+
</div>
|
537 |
+
<?php
|
538 |
+
}
|
539 |
+
|
540 |
/**
|
541 |
* This method is used to display Stripe Account key information on the settings page.
|
542 |
*
|
543 |
* @param string $value Name of the field.
|
544 |
*/
|
545 |
public function account_keys( $value ) {
|
|
|
546 |
if ( empty( Helper::get_setting( 'cpsw_pub_key' ) ) && empty( Helper::get_setting( 'cpsw_test_pub_key' ) ) ) {
|
547 |
return;
|
548 |
}
|
581 |
* @param string $value Name of the field.
|
582 |
*/
|
583 |
public function connect_button( $value ) {
|
584 |
+
$data = WC_Admin_Settings::get_field_description( $value );
|
|
|
|
|
585 |
$description = $data['description'];
|
586 |
$tooltip_html = $data['tooltip_html'];
|
587 |
$manual_link = false;
|
650 |
woocommerce_admin_fields( $this->get_settings() );
|
651 |
}
|
652 |
|
|
|
653 |
/**
|
654 |
* Uses the WooCommerce options API to save settings via the @see woocommerce_update_options() function.
|
655 |
*/
|
683 |
);
|
684 |
}
|
685 |
|
|
|
686 |
/**
|
687 |
* This method is used to initialize all stripe configuration fields.
|
688 |
*
|
799 |
return $settings;
|
800 |
}
|
801 |
|
|
|
802 |
/**
|
803 |
* Checks for response after stripe onboarding process
|
804 |
*
|
805 |
* @return void
|
806 |
*/
|
807 |
public function admin_options() {
|
|
|
808 |
if ( ! isset( $_GET['cpsw_connect_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( $_GET['cpsw_connect_nonce'] ), 'stripe-connect' ) ) {
|
809 |
return;
|
810 |
}
|
860 |
}
|
861 |
}
|
862 |
|
|
|
863 |
/**
|
864 |
* Perform a connection test
|
865 |
*
|
866 |
* @return $mixed
|
867 |
*/
|
868 |
public function connection_test() {
|
|
|
869 |
if ( ! isset( $_GET['_security'] ) || ! wp_verify_nonce( sanitize_text_field( $_GET['_security'] ), 'cpsw_admin_nonce' ) ) {
|
870 |
return wp_send_json_error( [ 'message' => __( 'Error: Sorry, the nonce security check didn’t pass. Please reload the page and try again.', 'checkout-plugins-stripe-woo' ) ] );
|
871 |
}
|
980 |
return wp_send_json_success( [ 'message' => __( 'Stripe keys are reset successfully.', 'checkout-plugins-stripe-woo' ) ] );
|
981 |
}
|
982 |
|
983 |
+
/**
|
984 |
+
* Logs js errors
|
985 |
+
*
|
986 |
+
* @return json
|
987 |
+
*/
|
988 |
+
public function js_errors() {
|
989 |
+
if ( ! isset( $_POST['_security'] ) || ! wp_verify_nonce( sanitize_text_field( $_POST['_security'] ), 'cpsw_js_error_nonce' ) ) {
|
990 |
+
return wp_send_json_error( [ 'message' => __( 'Invalid Nonce', 'checkout-plugins-stripe-woo' ) ] );
|
991 |
+
}
|
992 |
+
|
993 |
+
if ( isset( $_POST['error'] ) ) {
|
994 |
+
$error = $_POST['error'];
|
995 |
+
$error_message = $error['message'] . ' (' . $error['type'] . ')';
|
996 |
+
Logger::error( $error_message, true );
|
997 |
+
return wp_send_json_success( [ 'message' => $error_message ] );
|
998 |
+
}
|
999 |
+
exit();
|
1000 |
+
}
|
1001 |
+
|
1002 |
/**
|
1003 |
* This method is used get account information from stripe.
|
1004 |
*
|
1010 |
return false;
|
1011 |
}
|
1012 |
|
1013 |
+
$stripe_api = new Stripe_Api();
|
1014 |
$response = $stripe_api->accounts( 'retrieve', [ $account_id ] );
|
1015 |
if ( $response['success'] ) {
|
1016 |
$response = $response['data'];
|
1017 |
return $response->settings->dashboard->display_name;
|
1018 |
} else {
|
1019 |
+
return '';
|
1020 |
}
|
1021 |
}
|
1022 |
|
1027 |
* @return $array array It returns cpsw_settings array.
|
1028 |
*/
|
1029 |
public function filter_settings_fields( $array = [] ) {
|
1030 |
+
if ( 'success' !== Helper::get_setting( 'cpsw_con_status' ) && 'success' !== Helper::get_setting( 'cpsw_test_con_status' ) ) {
|
1031 |
unset( $array['test_mode'] );
|
1032 |
unset( $array['webhook_url'] );
|
1033 |
unset( $array['test_webhook_secret'] );
|
1081 |
* @return $mixed
|
1082 |
*/
|
1083 |
public function is_stripe_connected() {
|
1084 |
+
if ( 'success' === Helper::get_setting( 'cpsw_con_status' ) || 'success' === Helper::get_setting( 'cpsw_test_con_status' ) ) {
|
1085 |
return true;
|
1086 |
}
|
1087 |
return false;
|
1093 |
* @return $mixed
|
1094 |
*/
|
1095 |
public function check_connection_on_updates() {
|
|
|
1096 |
if ( 'yes' === Helper::get_setting( 'cpsw_auto_connect' ) ) {
|
1097 |
return;
|
1098 |
}
|
1193 |
update_option( 'cpsw_con_status', 'success' );
|
1194 |
update_option( 'cpsw_mode', 'live' );
|
1195 |
}
|
|
|
1196 |
}
|
1197 |
|
1198 |
/**
|
1200 |
*
|
1201 |
* @param string $old_value Old value of the option.
|
1202 |
* @param strign $value New value of the option.
|
1203 |
+
*
|
1204 |
* @return void
|
1205 |
*/
|
1206 |
public function update_mode( $old_value, $value ) {
|
1207 |
+
if ( 'yes' === Helper::get_setting( 'cpsw_auto_connect' ) ) {
|
|
|
1208 |
return;
|
1209 |
}
|
1210 |
|
1211 |
+
if ( ! empty( Helper::get_setting( 'cpsw_secret_key' ) ) && empty( Helper::get_setting( 'cpsw_test_secret_key' ) ) ) {
|
1212 |
update_option( 'cpsw_mode', 'live' );
|
1213 |
+
} elseif ( ! empty( Helper::get_setting( 'cpsw_test_secret_key' ) ) && empty( Helper::get_setting( 'cpsw_secret_key' ) ) ) {
|
1214 |
update_option( 'cpsw_mode', 'test' );
|
1215 |
}
|
1216 |
}
|
1232 |
* @return void
|
1233 |
*/
|
1234 |
public function add_breadcrumb() {
|
|
|
1235 |
if ( ! empty( $this->navigation ) ) {
|
1236 |
?>
|
1237 |
<ul class="subsubsub">
|
1260 |
* Adds settings link to the checkout section.
|
1261 |
*
|
1262 |
* @param array $settings_tab Settings tabs array.
|
1263 |
+
*
|
1264 |
* @return array $settings_tab Settings tabs array returned.
|
1265 |
*/
|
1266 |
public function add_settings_links( $settings_tab ) {
|
1267 |
+
if ( isset( $_GET['section'] ) && ( 'cpsw_stripe' === $_GET['section'] || 'cpsw_express_checkout' === $_GET['section'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
1268 |
+
$settings_tab['cpsw_api_settings'] = __( 'Stripe API Settings', 'checkout-plugins-stripe-woo' );
|
1269 |
+
$settings_tab['cpsw_stripe'] = __( 'Credit Cards', 'checkout-plugins-stripe-woo' );
|
1270 |
+
$settings_tab['cpsw_express_checkout'] = __( 'Express Checkout', 'checkout-plugins-stripe-woo' );
|
1271 |
}
|
1272 |
+
array_shift( $settings_tab );
|
1273 |
return apply_filters( 'cpsw_setting_tabs', $settings_tab );
|
1274 |
}
|
1275 |
|
1277 |
* Adds manual api keys links.
|
1278 |
*
|
1279 |
* @param string $links default copyright link with text.
|
1280 |
+
*
|
1281 |
* @return string $links Return customized copyright text with link.
|
1282 |
*/
|
1283 |
public function add_manual_connect_link( $links ) {
|
|
|
1284 |
if ( ! isset( $_GET['page'] ) || ! isset( $_GET['tab'] ) || 'wc-settings' !== $_GET['page'] || 'cpsw_api_settings' !== $_GET['tab'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
1285 |
return $links;
|
1286 |
}
|
1310 |
}
|
1311 |
}
|
1312 |
|
1313 |
+
/**
|
1314 |
+
* Add settings for section checkout
|
1315 |
+
*
|
1316 |
+
* @param array $settings existing settings.
|
1317 |
+
* @param string $current_section section.
|
1318 |
+
* @return array
|
1319 |
+
*/
|
1320 |
+
public function checkout_settings( $settings, $current_section ) {
|
1321 |
+
if ( 'cpsw_api_settings' === $current_section ) {
|
1322 |
+
header( 'Location: ' . admin_url() . 'admin.php?page=wc-settings&tab=cpsw_api_settings' );
|
1323 |
+
exit();
|
1324 |
+
}
|
1325 |
+
if ( 'cpsw_express_checkout' === $current_section ) {
|
1326 |
+
$settings = [];
|
1327 |
+
$values = Helper::get_gateway_settings();
|
1328 |
+
|
1329 |
+
if ( 'no' === $values['enabled'] ) {
|
1330 |
+
$settings = [
|
1331 |
+
'notice' => [
|
1332 |
+
'title' => '',
|
1333 |
+
'type' => 'express_checkout_notice',
|
1334 |
+
'desc' => __( 'Express Checkout is a feature of Card Payments. Enable Card Payments to use Express Checkout', 'checkout-plugins-stripe-woo' ),
|
1335 |
+
],
|
1336 |
+
];
|
1337 |
+
} else {
|
1338 |
+
$settings = [
|
1339 |
+
'section_title' => [
|
1340 |
+
'name' => __( 'Express Checkout', 'checkout-plugins-stripe-woo' ),
|
1341 |
+
'type' => 'title',
|
1342 |
+
/* translators: HTML Markup*/
|
1343 |
+
'desc' => sprintf( __( 'Accept payment using Apple Pay, Google Pay, Browser Payment Method.%1$1sExpress checkout uses Payment Request API which is based on client\'s browser and saved cards.%1$1sPlease check %2$2sprerequisite%3$3s for Apple Pay, Google Pay and Browser Payment Method.', 'checkout-plugins-stripe-woo' ), '<br/>', '<a href="https://stripe.com/docs/stripe-js/elements/payment-request-button#html-js-testing" target="_blank">', '</a>' ),
|
1344 |
+
'id' => 'cpsw_express_checkout',
|
1345 |
+
],
|
1346 |
+
'enable' => [
|
1347 |
+
'name' => __( 'Enable Express Checkout', 'checkout-plugins-stripe-woo' ),
|
1348 |
+
'id' => 'cpsw_express_checkout_enabled',
|
1349 |
+
'type' => 'checkbox',
|
1350 |
+
'value' => $values['express_checkout_enabled'],
|
1351 |
+
],
|
1352 |
+
'button_location' => [
|
1353 |
+
'title' => __( 'Show button on', 'checkout-plugins-stripe-woo' ),
|
1354 |
+
'type' => 'multiselect',
|
1355 |
+
'class' => 'cpsw_express_checkout_location',
|
1356 |
+
'id' => 'cpsw_express_checkout_location',
|
1357 |
+
'desc_tip' => __( 'Choose page to display express checkout buttons. By default displayed in all pages.', 'checkout-plugins-stripe-woo' ),
|
1358 |
+
'options' => [
|
1359 |
+
'product' => __( 'Product', 'checkout-plugins-stripe-woo' ),
|
1360 |
+
'cart' => __( 'Cart', 'checkout-plugins-stripe-woo' ),
|
1361 |
+
'checkout' => __( 'Checkout', 'checkout-plugins-stripe-woo' ),
|
1362 |
+
],
|
1363 |
+
'value' => $values['express_checkout_location'],
|
1364 |
+
],
|
1365 |
+
'button_type' => [
|
1366 |
+
'title' => __( 'Button type', 'checkout-plugins-stripe-woo' ),
|
1367 |
+
'type' => 'select',
|
1368 |
+
'id' => 'cpsw_express_checkout_button_type',
|
1369 |
+
'desc' => __( 'Select label for express checkout button.', 'checkout-plugins-stripe-woo' ),
|
1370 |
+
'value' => $values['express_checkout_button_type'],
|
1371 |
+
'options' => [
|
1372 |
+
'default' => __( 'Default', 'checkout-plugins-stripe-woo' ),
|
1373 |
+
'book' => __( 'Book', 'checkout-plugins-stripe-woo' ),
|
1374 |
+
'buy' => __( 'Buy', 'checkout-plugins-stripe-woo' ),
|
1375 |
+
'donate' => __( 'Donate', 'checkout-plugins-stripe-woo' ),
|
1376 |
+
],
|
1377 |
+
'desc_tip' => true,
|
1378 |
+
],
|
1379 |
+
'button_theme' => [
|
1380 |
+
'title' => __( 'Button theme', 'checkout-plugins-stripe-woo' ),
|
1381 |
+
'type' => 'select',
|
1382 |
+
'id' => 'cpsw_express_checkout_button_theme',
|
1383 |
+
'desc' => __( 'Select theme for express checkout button.', 'checkout-plugins-stripe-woo' ),
|
1384 |
+
'value' => $values['express_checkout_button_theme'],
|
1385 |
+
'options' => [
|
1386 |
+
'dark' => __( 'Dark', 'checkout-plugins-stripe-woo' ),
|
1387 |
+
'light' => __( 'Light', 'checkout-plugins-stripe-woo' ),
|
1388 |
+
'light-outline' => __( 'Light Outline', 'checkout-plugins-stripe-woo' ),
|
1389 |
+
],
|
1390 |
+
'desc_tip' => true,
|
1391 |
+
],
|
1392 |
+
'button_height' => [
|
1393 |
+
'title' => __( 'Button height', 'checkout-plugins-stripe-woo' ),
|
1394 |
+
'type' => 'number',
|
1395 |
+
'id' => 'cpsw_express_checkout_button_height',
|
1396 |
+
'desc' => __( 'Select height for express checkout button (in px). Button height can be between 35px to 60px. Default height 40px.', 'checkout-plugins-stripe-woo' ),
|
1397 |
+
'value' => $values['express_checkout_button_height'],
|
1398 |
+
'desc_tip' => true,
|
1399 |
+
],
|
1400 |
+
'separator_text' => [
|
1401 |
+
'title' => __( 'Separator text', 'checkout-plugins-stripe-woo' ),
|
1402 |
+
'type' => 'text',
|
1403 |
+
'id' => 'cpsw_express_checkout_separator',
|
1404 |
+
'desc' => __( 'Add express checkout button separator text. This will separate express checkout button with other buttons.', 'checkout-plugins-stripe-woo' ),
|
1405 |
+
'value' => $values['express_checkout_separator'],
|
1406 |
+
'desc_tip' => true,
|
1407 |
+
],
|
1408 |
+
'preview' => [
|
1409 |
+
'title' => __( 'Button Preview', 'checkout-plugins-stripe-woo' ),
|
1410 |
+
'type' => 'cpsw_express_checkout_preview',
|
1411 |
+
'id' => 'cpsw_express_checkout_preview',
|
1412 |
+
],
|
1413 |
+
'section_end' => [
|
1414 |
+
'type' => 'sectionend',
|
1415 |
+
'id' => 'cpsw_express_checkout',
|
1416 |
+
],
|
1417 |
+
'product_page_section_title' => [
|
1418 |
+
'name' => __( 'Product page options', 'checkout-plugins-stripe-woo' ),
|
1419 |
+
'type' => 'title',
|
1420 |
+
'desc' => __( 'Advanced customization options for product page.', 'checkout-plugins-stripe-woo' ),
|
1421 |
+
'id' => 'cpsw_express_checkout_product_page',
|
1422 |
+
],
|
1423 |
+
'above_woocommerce_button' => [
|
1424 |
+
'title' => __( 'Button position', 'checkout-plugins-stripe-woo' ),
|
1425 |
+
'type' => 'select',
|
1426 |
+
'id' => 'cpsw_express_checkout_product_page_position',
|
1427 |
+
'desc' => __( 'Select the position of Express Checkout button. This option will work only for product page.', 'checkout-plugins-stripe-woo' ),
|
1428 |
+
'value' => $values['express_checkout_product_page_position'],
|
1429 |
+
'options' => [
|
1430 |
+
'above' => __( 'Above Add to Cart', 'checkout-plugins-stripe-woo' ),
|
1431 |
+
'below' => __( 'Below Add to Cart', 'checkout-plugins-stripe-woo' ),
|
1432 |
+
],
|
1433 |
+
'desc_tip' => true,
|
1434 |
+
],
|
1435 |
+
'sticky_footer' => [
|
1436 |
+
'name' => __( 'Responsive behaviour', 'checkout-plugins-stripe-woo' ),
|
1437 |
+
/* translators: HTML Markup*/
|
1438 |
+
'desc' => sprintf( __( 'If checked the express checkout button will stick%1$1sat bottom of screen on responsive devices.', 'checkout-plugins-stripe-woo' ), '<br/>' ),
|
1439 |
+
'type' => 'checkbox',
|
1440 |
+
'id' => 'cpsw_express_checkout_product_sticky_footer',
|
1441 |
+
'value' => $values['express_checkout_product_sticky_footer'],
|
1442 |
+
],
|
1443 |
+
'product_page_section_end' => [
|
1444 |
+
'type' => 'sectionend',
|
1445 |
+
'id' => 'cpsw_express_checkout',
|
1446 |
+
],
|
1447 |
+
'checkout_page_section_title' => [
|
1448 |
+
'name' => __( 'Checkout page options', 'checkout-plugins-stripe-woo' ),
|
1449 |
+
'type' => 'title',
|
1450 |
+
'desc' => __( 'Advanced customization options for checkout page.', 'checkout-plugins-stripe-woo' ),
|
1451 |
+
'id' => 'cpsw_express_checkout_product_page',
|
1452 |
+
],
|
1453 |
+
'checkout_page_options' => [
|
1454 |
+
'title' => __( 'Advanced options', 'checkout-plugins-stripe-woo' ),
|
1455 |
+
'type' => 'checkbox',
|
1456 |
+
'id' => 'cpsw_express_checkout_product_checkout_page',
|
1457 |
+
'value' => $values['express_checkout_product_checkout_page'],
|
1458 |
+
],
|
1459 |
+
'title' => [
|
1460 |
+
'title' => __( 'Title', 'checkout-plugins-stripe-woo' ),
|
1461 |
+
'type' => 'text',
|
1462 |
+
'class' => 'cpsw_checkout_options',
|
1463 |
+
'id' => 'cpsw_express_checkout_title',
|
1464 |
+
'desc' => __( 'Add a title above express checkout button on checkout page.', 'checkout-plugins-stripe-woo' ),
|
1465 |
+
'value' => $values['express_checkout_title'],
|
1466 |
+
'desc_tip' => true,
|
1467 |
+
],
|
1468 |
+
'tagline' => [
|
1469 |
+
'title' => __( 'Tagline', 'checkout-plugins-stripe-woo' ),
|
1470 |
+
'type' => 'text',
|
1471 |
+
'class' => 'cpsw_checkout_options',
|
1472 |
+
'id' => 'cpsw_express_checkout_tagline',
|
1473 |
+
'desc' => __( 'Add a tagline just above express checkout button on checkout page.', 'checkout-plugins-stripe-woo' ),
|
1474 |
+
'value' => $values['express_checkout_tagline'],
|
1475 |
+
'desc_tip' => true,
|
1476 |
+
],
|
1477 |
+
'checkout_button_width' => [
|
1478 |
+
'title' => __( 'Button width', 'checkout-plugins-stripe-woo' ),
|
1479 |
+
'type' => 'number',
|
1480 |
+
'class' => 'cpsw_checkout_options',
|
1481 |
+
'id' => 'cpsw_express_checkout_button_width',
|
1482 |
+
'desc' => __( 'Select width for button (in px). Minimum width should be 150px, Default width 100%', 'checkout-plugins-stripe-woo' ),
|
1483 |
+
'value' => $values['express_checkout_button_width'],
|
1484 |
+
'desc_tip' => true,
|
1485 |
+
],
|
1486 |
+
'checkout_button_alignment' => [
|
1487 |
+
'title' => __( 'Alignment', 'checkout-plugins-stripe-woo' ),
|
1488 |
+
'type' => 'select',
|
1489 |
+
'class' => 'cpsw_checkout_options',
|
1490 |
+
'id' => 'cpsw_express_checkout_button_alignment',
|
1491 |
+
'desc' => __( 'This setting will align title, tagline and button based on selection on checkout page.', 'checkout-plugins-stripe-woo' ),
|
1492 |
+
'value' => $values['express_checkout_button_alignment'],
|
1493 |
+
'options' => [
|
1494 |
+
'left' => __( 'Left', 'checkout-plugins-stripe-woo' ),
|
1495 |
+
'center' => __( 'Center', 'checkout-plugins-stripe-woo' ),
|
1496 |
+
'right' => __( 'Right', 'checkout-plugins-stripe-woo' ),
|
1497 |
+
],
|
1498 |
+
'desc_tip' => true,
|
1499 |
+
],
|
1500 |
+
'checkout_separator_text' => [
|
1501 |
+
'title' => __( 'Separator text', 'checkout-plugins-stripe-woo' ),
|
1502 |
+
'type' => 'text',
|
1503 |
+
'class' => 'cpsw_checkout_options',
|
1504 |
+
'id' => 'cpsw_express_checkout_separator_checkout',
|
1505 |
+
'desc' => __( 'Add separator text for checkout page. If empty will show default separator text.', 'checkout-plugins-stripe-woo' ),
|
1506 |
+
'value' => $values['express_checkout_separator_checkout'],
|
1507 |
+
'desc_tip' => true,
|
1508 |
+
],
|
1509 |
+
'checkout_page_section_end' => [
|
1510 |
+
'type' => 'sectionend',
|
1511 |
+
'id' => 'cpsw_express_checkout',
|
1512 |
+
],
|
1513 |
+
];
|
1514 |
+
}
|
1515 |
+
}
|
1516 |
+
|
1517 |
+
return $settings;
|
1518 |
+
}
|
1519 |
}
|
admin/assets/css/admin.css
CHANGED
@@ -1,128 +1,128 @@
|
|
1 |
-
/*
|
2 |
-
* Admin Style
|
3 |
-
*/
|
4 |
-
|
5 |
-
.form_overlay {
|
6 |
-
opacity: 0.5;
|
7 |
-
pointer-events: none;
|
8 |
-
}
|
9 |
-
|
10 |
-
.form-wc-wc_cpsw_connect_btn fieldset {
|
11 |
-
margin: 20px 0 20px 0;
|
12 |
-
}
|
13 |
-
|
14 |
-
.form-wc-wc_cpsw_connect_btn img {
|
15 |
-
margin: 5px 10px 0 10px;
|
16 |
-
width: 20px;
|
17 |
-
float: left;
|
18 |
-
}
|
19 |
-
|
20 |
-
.form-wc-wc_cpsw_connect_btn .cpsw_connect_btn,
|
21 |
-
.form-wc-account_id .cpsw_connect_btn {
|
22 |
-
background: #6772e5;
|
23 |
-
display: inline-block;
|
24 |
-
height: 38px;
|
25 |
-
text-decoration: none;
|
26 |
-
width: 240px;
|
27 |
-
|
28 |
-
border-radius: 4px;
|
29 |
-
-moz-border-radius: 4px;
|
30 |
-
-webkit-border-radius: 4px;
|
31 |
-
|
32 |
-
user-select: none;
|
33 |
-
-moz-user-select: none;
|
34 |
-
-webkit-user-select: none;
|
35 |
-
-ms-user-select: none;
|
36 |
-
|
37 |
-
-webkit-font-smoothing: antialiased;
|
38 |
-
}
|
39 |
-
|
40 |
-
.form-wc-account_id .cpsw_connect_btn {
|
41 |
-
margin: 10px;
|
42 |
-
}
|
43 |
-
|
44 |
-
.form-wc-wc_cpsw_connect_btn .cpsw_connect_btn:hover {
|
45 |
-
background: #3f4ddf;
|
46 |
-
}
|
47 |
-
|
48 |
-
.form-wc-wc_cpsw_connect_btn .cpsw_connect_btn span,
|
49 |
-
.form-wc-account_id .cpsw_connect_btn span {
|
50 |
-
color: #fff;
|
51 |
-
display: block;
|
52 |
-
font-family: sohne-var, "Helvetica Neue", Arial, sans-serif;
|
53 |
-
font-size: 15px;
|
54 |
-
font-weight: 400;
|
55 |
-
line-height: 14px;
|
56 |
-
padding: 11px 0 0 65px;
|
57 |
-
position: relative;
|
58 |
-
text-align: left;
|
59 |
-
}
|
60 |
-
|
61 |
-
.form-wc-wc_cpsw_connect_btn .cpsw_connect_btn span::before,
|
62 |
-
.form-wc-account_id .cpsw_connect_btn span::before {
|
63 |
-
background-repeat: no-repeat;
|
64 |
-
content: "";
|
65 |
-
height: 20px;
|
66 |
-
left: 16%;
|
67 |
-
position: absolute;
|
68 |
-
top: 30%;
|
69 |
-
width: 49.58px;
|
70 |
-
background-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3C!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 468 222.5' style='enable-background:new 0 0 468 222.5;' xml:space='preserve'%3E%3Cstyle type='text/css'%3E .st0%7Bfill-rule:evenodd;clip-rule:evenodd;fill:%23FFFFFF;%7D%0A%3C/style%3E%3Cg%3E%3Cpath class='st0' d='M6.796 7.639c0-1.03.845-1.427 2.245-1.427 2.008 0 4.544.608 6.552 1.691V1.695C13.4.823 11.234.479 9.041.479 3.678.48.111 3.28.111 7.956c0 7.292 10.04 6.13 10.04 9.273 0 1.215-1.057 1.611-2.536 1.611-2.193 0-4.993-.898-7.213-2.113v6.288a18.315 18.315 0 007.213 1.506c5.495 0 9.273-2.722 9.273-7.45-.027-7.873-10.092-6.473-10.092-9.432z'/%3E%3Cpath class='st0' d='M6.796 7.639c0-1.03.845-1.427 2.245-1.427 2.008 0 4.544.608 6.552 1.691V1.695C13.4.823 11.234.479 9.041.479 3.678.48.111 3.28.111 7.956c0 7.292 10.04 6.13 10.04 9.273 0 1.215-1.057 1.611-2.536 1.611-2.193 0-4.993-.898-7.213-2.113v6.288a18.315 18.315 0 007.213 1.506c5.495 0 9.273-2.722 9.273-7.45-.027-7.873-10.092-6.473-10.092-9.432z'/%3E%3C/g%3E%3C/svg%3E"); /* stylelint-disable-line function-url-quotes */
|
71 |
-
background-size: 380px;
|
72 |
-
}
|
73 |
-
|
74 |
-
.wc-connect-stripe-help {
|
75 |
-
margin-top: 10px;
|
76 |
-
}
|
77 |
-
|
78 |
-
.form-wc-wc_cpsw_connect_btn .st_connect_mn_dv {
|
79 |
-
margin-top: 14px;
|
80 |
-
}
|
81 |
-
|
82 |
-
.form-wc-wc_cpsw_test_button fieldset {
|
83 |
-
margin: 20px 0 20px 0;
|
84 |
-
}
|
85 |
-
|
86 |
-
.form-wc-wc_cpsw_test_button a {
|
87 |
-
border: 1px solid rgb(103, 114, 229);
|
88 |
-
}
|
89 |
-
|
90 |
-
.form-wc-wc_cpsw_test_button a,
|
91 |
-
.form-wc-wc_cpsw_test_button a > span {
|
92 |
-
padding: 5px;
|
93 |
-
color: rgb(103, 114, 229);
|
94 |
-
font-weight: 500;
|
95 |
-
background: #fff;
|
96 |
-
border-radius: 5px;
|
97 |
-
text-decoration: none;
|
98 |
-
}
|
99 |
-
|
100 |
-
.stipe-connect-active {
|
101 |
-
color: #008000;
|
102 |
-
font-weight: 500;
|
103 |
-
}
|
104 |
-
|
105 |
-
.form-wc-wc_stripe_acc_keys fieldset {
|
106 |
-
margin-top: 10px !important;
|
107 |
-
}
|
108 |
-
|
109 |
-
.cpsw_connect_mn_btn,
|
110 |
-
.cpsw_connect_hide_btn {
|
111 |
-
text-decoration: udnerline;
|
112 |
-
color: inherit;
|
113 |
-
font-size: 12px;
|
114 |
-
}
|
115 |
-
|
116 |
-
.account_status .cpsw_connect_mn_btn,
|
117 |
-
.account_status .cpsw_connect_hide_btn {
|
118 |
-
color: #2271b1;
|
119 |
-
font-size: 14px;
|
120 |
-
}
|
121 |
-
|
122 |
-
#wpfooter {
|
123 |
-
display: block !important;
|
124 |
-
}
|
125 |
-
|
126 |
-
.form-wc-account_id .cpsw_connect_hide_btn {
|
127 |
-
display: none;
|
128 |
-
}
|
1 |
+
/*
|
2 |
+
* Admin Style
|
3 |
+
*/
|
4 |
+
|
5 |
+
.form_overlay {
|
6 |
+
opacity: 0.5;
|
7 |
+
pointer-events: none;
|
8 |
+
}
|
9 |
+
|
10 |
+
.form-wc-wc_cpsw_connect_btn fieldset {
|
11 |
+
margin: 20px 0 20px 0;
|
12 |
+
}
|
13 |
+
|
14 |
+
.form-wc-wc_cpsw_connect_btn img {
|
15 |
+
margin: 5px 10px 0 10px;
|
16 |
+
width: 20px;
|
17 |
+
float: left;
|
18 |
+
}
|
19 |
+
|
20 |
+
.form-wc-wc_cpsw_connect_btn .cpsw_connect_btn,
|
21 |
+
.form-wc-account_id .cpsw_connect_btn {
|
22 |
+
background: #6772e5;
|
23 |
+
display: inline-block;
|
24 |
+
height: 38px;
|
25 |
+
text-decoration: none;
|
26 |
+
width: 240px;
|
27 |
+
|
28 |
+
border-radius: 4px;
|
29 |
+
-moz-border-radius: 4px;
|
30 |
+
-webkit-border-radius: 4px;
|
31 |
+
|
32 |
+
user-select: none;
|
33 |
+
-moz-user-select: none;
|
34 |
+
-webkit-user-select: none;
|
35 |
+
-ms-user-select: none;
|
36 |
+
|
37 |
+
-webkit-font-smoothing: antialiased;
|
38 |
+
}
|
39 |
+
|
40 |
+
.form-wc-account_id .cpsw_connect_btn {
|
41 |
+
margin: 10px;
|
42 |
+
}
|
43 |
+
|
44 |
+
.form-wc-wc_cpsw_connect_btn .cpsw_connect_btn:hover {
|
45 |
+
background: #3f4ddf;
|
46 |
+
}
|
47 |
+
|
48 |
+
.form-wc-wc_cpsw_connect_btn .cpsw_connect_btn span,
|
49 |
+
.form-wc-account_id .cpsw_connect_btn span {
|
50 |
+
color: #fff;
|
51 |
+
display: block;
|
52 |
+
font-family: sohne-var, "Helvetica Neue", Arial, sans-serif;
|
53 |
+
font-size: 15px;
|
54 |
+
font-weight: 400;
|
55 |
+
line-height: 14px;
|
56 |
+
padding: 11px 0 0 65px;
|
57 |
+
position: relative;
|
58 |
+
text-align: left;
|
59 |
+
}
|
60 |
+
|
61 |
+
.form-wc-wc_cpsw_connect_btn .cpsw_connect_btn span::before,
|
62 |
+
.form-wc-account_id .cpsw_connect_btn span::before {
|
63 |
+
background-repeat: no-repeat;
|
64 |
+
content: "";
|
65 |
+
height: 20px;
|
66 |
+
left: 16%;
|
67 |
+
position: absolute;
|
68 |
+
top: 30%;
|
69 |
+
width: 49.58px;
|
70 |
+
background-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3C!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 468 222.5' style='enable-background:new 0 0 468 222.5;' xml:space='preserve'%3E%3Cstyle type='text/css'%3E .st0%7Bfill-rule:evenodd;clip-rule:evenodd;fill:%23FFFFFF;%7D%0A%3C/style%3E%3Cg%3E%3Cpath class='st0' d='M6.796 7.639c0-1.03.845-1.427 2.245-1.427 2.008 0 4.544.608 6.552 1.691V1.695C13.4.823 11.234.479 9.041.479 3.678.48.111 3.28.111 7.956c0 7.292 10.04 6.13 10.04 9.273 0 1.215-1.057 1.611-2.536 1.611-2.193 0-4.993-.898-7.213-2.113v6.288a18.315 18.315 0 007.213 1.506c5.495 0 9.273-2.722 9.273-7.45-.027-7.873-10.092-6.473-10.092-9.432z'/%3E%3Cpath class='st0' d='M6.796 7.639c0-1.03.845-1.427 2.245-1.427 2.008 0 4.544.608 6.552 1.691V1.695C13.4.823 11.234.479 9.041.479 3.678.48.111 3.28.111 7.956c0 7.292 10.04 6.13 10.04 9.273 0 1.215-1.057 1.611-2.536 1.611-2.193 0-4.993-.898-7.213-2.113v6.288a18.315 18.315 0 007.213 1.506c5.495 0 9.273-2.722 9.273-7.45-.027-7.873-10.092-6.473-10.092-9.432z'/%3E%3C/g%3E%3C/svg%3E"); /* stylelint-disable-line function-url-quotes */
|
71 |
+
background-size: 380px;
|
72 |
+
}
|
73 |
+
|
74 |
+
.wc-connect-stripe-help {
|
75 |
+
margin-top: 10px;
|
76 |
+
}
|
77 |
+
|
78 |
+
.form-wc-wc_cpsw_connect_btn .st_connect_mn_dv {
|
79 |
+
margin-top: 14px;
|
80 |
+
}
|
81 |
+
|
82 |
+
.form-wc-wc_cpsw_test_button fieldset {
|
83 |
+
margin: 20px 0 20px 0;
|
84 |
+
}
|
85 |
+
|
86 |
+
.form-wc-wc_cpsw_test_button a {
|
87 |
+
border: 1px solid rgb(103, 114, 229);
|
88 |
+
}
|
89 |
+
|
90 |
+
.form-wc-wc_cpsw_test_button a,
|
91 |
+
.form-wc-wc_cpsw_test_button a > span {
|
92 |
+
padding: 5px;
|
93 |
+
color: rgb(103, 114, 229);
|
94 |
+
font-weight: 500;
|
95 |
+
background: #fff;
|
96 |
+
border-radius: 5px;
|
97 |
+
text-decoration: none;
|
98 |
+
}
|
99 |
+
|
100 |
+
.stipe-connect-active {
|
101 |
+
color: #008000;
|
102 |
+
font-weight: 500;
|
103 |
+
}
|
104 |
+
|
105 |
+
.form-wc-wc_stripe_acc_keys fieldset {
|
106 |
+
margin-top: 10px !important;
|
107 |
+
}
|
108 |
+
|
109 |
+
.cpsw_connect_mn_btn,
|
110 |
+
.cpsw_connect_hide_btn {
|
111 |
+
text-decoration: udnerline;
|
112 |
+
color: inherit;
|
113 |
+
font-size: 12px;
|
114 |
+
}
|
115 |
+
|
116 |
+
.account_status .cpsw_connect_mn_btn,
|
117 |
+
.account_status .cpsw_connect_hide_btn {
|
118 |
+
color: #2271b1;
|
119 |
+
font-size: 14px;
|
120 |
+
}
|
121 |
+
|
122 |
+
#wpfooter {
|
123 |
+
display: block !important;
|
124 |
+
}
|
125 |
+
|
126 |
+
.form-wc-account_id .cpsw_connect_hide_btn {
|
127 |
+
display: none;
|
128 |
+
}
|
admin/assets/css/express-checkout.css
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.cpsw_express_checkout_preview_wrapper {
|
2 |
+
max-width: 380px;
|
3 |
+
width: 100%;
|
4 |
+
}
|
5 |
+
|
6 |
+
.cpsw_floating_preview {
|
7 |
+
width: 400px;
|
8 |
+
position: fixed;
|
9 |
+
left: 900px;
|
10 |
+
top: 300px;
|
11 |
+
}
|
12 |
+
|
13 |
+
.cpsw_express_checkout_preview {
|
14 |
+
max-width: 100%;
|
15 |
+
}
|
16 |
+
|
17 |
+
.cpsw_preview_title {
|
18 |
+
font-weight: 600;
|
19 |
+
margin-bottom: 0.5em;
|
20 |
+
margin-top: 0;
|
21 |
+
}
|
22 |
+
|
23 |
+
.cpsw_preview_tagline {
|
24 |
+
font-style: italic;
|
25 |
+
margin-bottom: 1em;
|
26 |
+
}
|
27 |
+
|
28 |
+
.cpsw_preview_notice {
|
29 |
+
font-style: italic;
|
30 |
+
font-size: 12px;
|
31 |
+
clear: both;
|
32 |
+
margin-top: 1em;
|
33 |
+
display: none;
|
34 |
+
}
|
35 |
+
|
36 |
+
.cpsw_button_preview_label {
|
37 |
+
font-weight: 600;
|
38 |
+
margin-bottom: 1em;
|
39 |
+
font-size: 15px;
|
40 |
+
display: none;
|
41 |
+
}
|
42 |
+
|
admin/assets/js/admin.js
CHANGED
@@ -24,7 +24,7 @@
|
|
24 |
$( '#cpsw_live_webhook_secret' ).closest( 'tr' ).hide();
|
25 |
}
|
26 |
|
27 |
-
if ( cpsw_ajax_object.is_connected === '' ) {
|
28 |
$( '.woocommerce-save-button' ).hide();
|
29 |
}
|
30 |
|
@@ -191,6 +191,6 @@
|
|
191 |
} );
|
192 |
} );
|
193 |
$( document ).ready( function() {
|
194 |
-
$( '.
|
195 |
} );
|
196 |
}( jQuery ) );
|
24 |
$( '#cpsw_live_webhook_secret' ).closest( 'tr' ).hide();
|
25 |
}
|
26 |
|
27 |
+
if ( cpsw_ajax_object.is_connected === '' && 'cpsw_api_settings' === cpsw_ajax_object.cpsw_admin_settings_tab ) {
|
28 |
$( '.woocommerce-save-button' ).hide();
|
29 |
}
|
30 |
|
191 |
} );
|
192 |
} );
|
193 |
$( document ).ready( function() {
|
194 |
+
$( '.cpsw_select_woo' ).selectWoo();
|
195 |
} );
|
196 |
}( jQuery ) );
|
admin/assets/js/express-checkout.js
ADDED
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
( function( $ ) {
|
3 |
+
const pubKey = cpsw_express_checkout.public_key;
|
4 |
+
let style = cpsw_express_checkout.style;
|
5 |
+
|
6 |
+
const stripe = Stripe( pubKey );
|
7 |
+
|
8 |
+
function generateExpressCheckoutDemo() {
|
9 |
+
try {
|
10 |
+
const data = {
|
11 |
+
country: 'US',
|
12 |
+
currency: 'usd',
|
13 |
+
total: {
|
14 |
+
label: 'Demo total',
|
15 |
+
amount: 1099,
|
16 |
+
},
|
17 |
+
requestPayerName: true,
|
18 |
+
requestPayerEmail: true,
|
19 |
+
};
|
20 |
+
|
21 |
+
const paymentRequest = stripe.paymentRequest( data );
|
22 |
+
|
23 |
+
const elements = stripe.elements();
|
24 |
+
|
25 |
+
const prButton = elements.create( 'paymentRequestButton', {
|
26 |
+
paymentRequest,
|
27 |
+
style: {
|
28 |
+
paymentRequestButton: {
|
29 |
+
type: style.type,
|
30 |
+
theme: style.theme,
|
31 |
+
height: style.height + 'px',
|
32 |
+
},
|
33 |
+
},
|
34 |
+
} );
|
35 |
+
|
36 |
+
paymentRequest.canMakePayment().then( function( result ) {
|
37 |
+
if ( ! result ) {
|
38 |
+
return;
|
39 |
+
}
|
40 |
+
|
41 |
+
prButton.on( 'click', function( e ) {
|
42 |
+
e.preventDefault();
|
43 |
+
} );
|
44 |
+
|
45 |
+
if ( $( '.cpsw_express_checkout_preview_wrapper .cpsw_express_checkout_preview' ).length > 0 ) {
|
46 |
+
$( '.cpsw_button_preview_label' ).css( { display: 'block' } );
|
47 |
+
$( '.cpsw_express_checkout_preview_wrapper .cpsw_express_checkout_preview' ).fadeIn();
|
48 |
+
prButton.mount( '.cpsw_express_checkout_preview_wrapper .cpsw_express_checkout_preview' );
|
49 |
+
$( '.cpsw_preview_title' ).html( $( '#cpsw_express_checkout_title' ).val() );
|
50 |
+
$( '.cpsw_preview_tagline' ).html( $( '#cpsw_express_checkout_tagline' ).val() );
|
51 |
+
if ( $( '#cpsw_express_checkout_product_checkout_page' ).is( ':checked' ) ) {
|
52 |
+
const buttonWidth = $( '#cpsw_express_checkout_button_width' ).val() + 'px';
|
53 |
+
$( '.cpsw_express_checkout_preview' ).width( buttonWidth );
|
54 |
+
|
55 |
+
$( '.cpsw_express_checkout_preview_wrapper' ).css( { textAlign: $( '#cpsw_express_checkout_button_alignment' ).val() } );
|
56 |
+
if ( $( '#cpsw_express_checkout_button_alignment' ).val() === 'center' ) {
|
57 |
+
$( '.cpsw_express_checkout_preview' ).css( { margin: '0 auto', float: 'none' } );
|
58 |
+
} else {
|
59 |
+
$( '.cpsw_express_checkout_preview' ).css( { marginBottom: '1em', float: $( '#cpsw_express_checkout_button_alignment' ).val() } );
|
60 |
+
}
|
61 |
+
}
|
62 |
+
}
|
63 |
+
} );
|
64 |
+
} catch ( e ) {
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
function addCheckoutPreviewElement() {
|
69 |
+
removeCheckoutPreviewElement();
|
70 |
+
$( '.cpsw_express_checkout_preview_wrapper' ).prepend( '<h3 class="cpsw_preview_title"></h3><p class="cpsw_preview_tagline"></p>' );
|
71 |
+
$( '.cpsw_express_checkout_preview_wrapper' ).after( '<p class="cpsw_preview_notice">NOTE: Title and Tagline appears only on checkout page</p>' );
|
72 |
+
$( '.cpsw_preview_notice' ).css( { display: 'block' } );
|
73 |
+
|
74 |
+
const buttonWidth = $( '#cpsw_express_checkout_button_width' ).val() + 'px';
|
75 |
+
$( '.cpsw_express_checkout_preview' ).width( buttonWidth );
|
76 |
+
|
77 |
+
$( '.cpsw_express_checkout_preview_wrapper' ).css( { textAlign: $( '#cpsw_express_checkout_button_alignment' ).val() } );
|
78 |
+
if ( $( '#cpsw_express_checkout_button_alignment' ).val() === 'center' ) {
|
79 |
+
$( '.cpsw_express_checkout_preview' ).css( { margin: '0 auto', float: 'none' } );
|
80 |
+
} else {
|
81 |
+
$( '.cpsw_express_checkout_preview' ).css( { marginBottom: '1em', float: $( '#cpsw_express_checkout_button_alignment' ).val() } );
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
function removeCheckoutPreviewElement() {
|
86 |
+
$( '.cpsw_preview_title, .cpsw_preview_tagline, .cpsw_preview_notice' ).remove();
|
87 |
+
$( '.cpsw_express_checkout_preview' ).css( { margin: '0 auto', float: 'none', width: '100%' } );
|
88 |
+
}
|
89 |
+
|
90 |
+
function toggleCheckoutOptions() {
|
91 |
+
if ( ! $( '#cpsw_express_checkout_product_checkout_page' ).is( ':checked' ) ) {
|
92 |
+
$( '.cpsw_checkout_options' ).each( function() {
|
93 |
+
$( this ).parents( 'tr' ).hide();
|
94 |
+
removeCheckoutPreviewElement();
|
95 |
+
} );
|
96 |
+
} else {
|
97 |
+
$( '.cpsw_checkout_options' ).each( function() {
|
98 |
+
$( this ).parents( 'tr' ).show();
|
99 |
+
addCheckoutPreviewElement();
|
100 |
+
$( '#cpsw_express_checkout_title' ).trigger( 'keyup' );
|
101 |
+
$( '#cpsw_express_checkout_tagline' ).trigger( 'keyup' );
|
102 |
+
} );
|
103 |
+
}
|
104 |
+
}
|
105 |
+
|
106 |
+
$( document ).ready( function() {
|
107 |
+
$( '.cpsw_express_checkout_location' ).selectWoo();
|
108 |
+
generateExpressCheckoutDemo( style );
|
109 |
+
|
110 |
+
$( '#cpsw_express_checkout_button_type, #cpsw_express_checkout_button_theme' ).change( function() {
|
111 |
+
style = {
|
112 |
+
type: $( '#cpsw_express_checkout_button_type' ).val(),
|
113 |
+
theme: $( '#cpsw_express_checkout_button_theme' ).val(),
|
114 |
+
height: $( '#cpsw_express_checkout_button_height' ).val(),
|
115 |
+
|
116 |
+
};
|
117 |
+
$( '.cpsw_express_checkout_preview_wrapper .cpsw_express_checkout_preview' ).hide();
|
118 |
+
generateExpressCheckoutDemo( style );
|
119 |
+
} );
|
120 |
+
|
121 |
+
$( '#cpsw_express_checkout_button_height' ).change( function() {
|
122 |
+
if ( $( this ).val() > 60 ) {
|
123 |
+
$( this ).val( 60 );
|
124 |
+
}
|
125 |
+
|
126 |
+
if ( $( this ).val() < 35 ) {
|
127 |
+
$( this ).val( 35 );
|
128 |
+
}
|
129 |
+
|
130 |
+
style = {
|
131 |
+
type: $( '#cpsw_express_checkout_button_type' ).val(),
|
132 |
+
theme: $( '#cpsw_express_checkout_button_theme' ).val(),
|
133 |
+
height: $( '#cpsw_express_checkout_button_height' ).val(),
|
134 |
+
|
135 |
+
};
|
136 |
+
$( '.cpsw_express_checkout_preview_wrapper .cpsw_express_checkout_preview' ).hide();
|
137 |
+
generateExpressCheckoutDemo( style );
|
138 |
+
} );
|
139 |
+
|
140 |
+
toggleCheckoutOptions();
|
141 |
+
|
142 |
+
$( '#cpsw_express_checkout_product_checkout_page' ).change( function() {
|
143 |
+
toggleCheckoutOptions();
|
144 |
+
} );
|
145 |
+
|
146 |
+
if ( $( document ).width() > 1200 ) {
|
147 |
+
const buttonPreview = $( '.cpsw_express_checkout_preview_wrapper' ).parents( 'fieldset' );
|
148 |
+
buttonPreview.parents( 'tr' ).hide();
|
149 |
+
$( '.submit' ).after( '<div class="cpsw_floating_preview"><span class="cpsw_button_preview_label">Button preview</div>' );
|
150 |
+
$( '.cpsw_floating_preview' ).append( buttonPreview );
|
151 |
+
}
|
152 |
+
|
153 |
+
$( '#cpsw_express_checkout_title' ).keyup( function() {
|
154 |
+
$( '.cpsw_preview_title' ).html( $( this ).val() );
|
155 |
+
} );
|
156 |
+
|
157 |
+
$( '#cpsw_express_checkout_tagline' ).keyup( function() {
|
158 |
+
$( '.cpsw_preview_tagline' ).html( $( this ).val() );
|
159 |
+
} );
|
160 |
+
|
161 |
+
$( '#cpsw_express_checkout_button_width' ).change( function() {
|
162 |
+
let buttonWidth = $( '#cpsw_express_checkout_button_width' ).val();
|
163 |
+
if ( buttonWidth < 150 ) {
|
164 |
+
$( '#cpsw_express_checkout_button_width' ).val( 150 );
|
165 |
+
buttonWidth = 150;
|
166 |
+
alert( 'Express Checkout button width should not be less than 150px' );
|
167 |
+
}
|
168 |
+
$( '.cpsw_express_checkout_preview' ).width( buttonWidth );
|
169 |
+
} );
|
170 |
+
|
171 |
+
$( '#cpsw_express_checkout_button_alignment' ).change( function() {
|
172 |
+
$( '.cpsw_express_checkout_preview_wrapper' ).css( { textAlign: $( this ).val() } );
|
173 |
+
if ( $( this ).val() === 'center' ) {
|
174 |
+
$( '.cpsw_express_checkout_preview' ).css( { margin: '0 auto', float: 'none' } );
|
175 |
+
} else {
|
176 |
+
$( '.cpsw_express_checkout_preview' ).css( { marginBottom: '1em', float: $( this ).val() } );
|
177 |
+
}
|
178 |
+
} );
|
179 |
+
} );
|
180 |
+
}( jQuery ) );
|
assets/css/stripe-elements.css
CHANGED
@@ -28,3 +28,104 @@
|
|
28 |
.payment_method_cpsw_stripe .wc-saved-payment-methods {
|
29 |
display: none;
|
30 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
.payment_method_cpsw_stripe .wc-saved-payment-methods {
|
29 |
display: none;
|
30 |
}
|
31 |
+
|
32 |
+
.payment-method-disabled {
|
33 |
+
opacity: 0.2;
|
34 |
+
cursor: not-allowed;
|
35 |
+
}
|
36 |
+
|
37 |
+
#cpsw-payment-request-button {
|
38 |
+
max-width: 100%;
|
39 |
+
border-radius: 3px;
|
40 |
+
box-shadow: 0 1px 2px rgb(0 0 0 / 50%);
|
41 |
+
}
|
42 |
+
|
43 |
+
#cpsw-payment-request-wrapper {
|
44 |
+
clear: both;
|
45 |
+
display: none;
|
46 |
+
|
47 |
+
/* padding-top: 1em; */
|
48 |
+
}
|
49 |
+
|
50 |
+
#cpsw-payment-request-wrapper.checkout.center #cpsw-payment-request-title,
|
51 |
+
#cpsw-payment-request-wrapper.checkout.center #cpsw-payment-request-tagline,
|
52 |
+
#cpsw-payment-request-separator.checkout.center {
|
53 |
+
text-align: center;
|
54 |
+
}
|
55 |
+
|
56 |
+
#cpsw-payment-request-wrapper.checkout.center div {
|
57 |
+
margin: 0 auto;
|
58 |
+
}
|
59 |
+
|
60 |
+
#cpsw-payment-request-wrapper.checkout.right #cpsw-payment-request-title,
|
61 |
+
#cpsw-payment-request-wrapper.checkout.right #cpsw-payment-request-tagline,
|
62 |
+
#cpsw-payment-request-separator.checkout.right {
|
63 |
+
text-align: right;
|
64 |
+
}
|
65 |
+
|
66 |
+
#cpsw-payment-request-wrapper.checkout.right #cpsw-payment-request-button {
|
67 |
+
float: right;
|
68 |
+
}
|
69 |
+
|
70 |
+
#cpsw-payment-request-separator.checkout.left {
|
71 |
+
text-align: left;
|
72 |
+
}
|
73 |
+
|
74 |
+
#cpsw-payment-request-wrapper.below {
|
75 |
+
padding-top: 0;
|
76 |
+
}
|
77 |
+
|
78 |
+
#cpsw-payment-request-separator {
|
79 |
+
clear: both;
|
80 |
+
padding: 1em 0;
|
81 |
+
text-align: center;
|
82 |
+
display: none;
|
83 |
+
}
|
84 |
+
|
85 |
+
#cpsw-payment-request-wrapper.checkout #cpsw-payment-request-title {
|
86 |
+
font-weight: 600;
|
87 |
+
margin-bottom: 0.5em;
|
88 |
+
}
|
89 |
+
|
90 |
+
#cpsw-payment-request-wrapper.checkout #cpsw-payment-request-button {
|
91 |
+
margin-top: 5px;
|
92 |
+
}
|
93 |
+
|
94 |
+
#cpsw-payment-request-wrapper.checkout #cpsw-payment-request-tagline {
|
95 |
+
font-style: italic;
|
96 |
+
margin-bottom: 1em;
|
97 |
+
}
|
98 |
+
|
99 |
+
#cpsw-payment-request-wrapper.product #cpsw-payment-request-title,
|
100 |
+
#cpsw-payment-request-wrapper.cart #cpsw-payment-request-title {
|
101 |
+
display: none;
|
102 |
+
}
|
103 |
+
|
104 |
+
#cpsw-payment-request-wrapper.product #cpsw-payment-request-tagline,
|
105 |
+
#cpsw-payment-request-wrapper.cart #cpsw-payment-request-tagline {
|
106 |
+
display: none;
|
107 |
+
}
|
108 |
+
|
109 |
+
@media only screen and (max-width: 600px) {
|
110 |
+
|
111 |
+
#cpsw-payment-request-wrapper.product.sticky {
|
112 |
+
position: fixed;
|
113 |
+
bottom: 0;
|
114 |
+
left: 0;
|
115 |
+
z-index: 1000000;
|
116 |
+
clear: both;
|
117 |
+
padding: 5px 0.5em 0.5em 0.5em;
|
118 |
+
border: none;
|
119 |
+
width: 100%;
|
120 |
+
margin: 0;
|
121 |
+
background-color: #88888880;
|
122 |
+
}
|
123 |
+
|
124 |
+
#cpsw-payment-request-wrapper.product #cpsw-payment-request-title {
|
125 |
+
display: none;
|
126 |
+
}
|
127 |
+
|
128 |
+
#cpsw-payment-request-wrapper.product #cpsw-payment-request-tagline {
|
129 |
+
display: none;
|
130 |
+
}
|
131 |
+
}
|
assets/js/payment-request.js
ADDED
@@ -0,0 +1,566 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
( function( $ ) {
|
2 |
+
const pubKey = cpsw_payment_request.public_key;
|
3 |
+
const mode = cpsw_payment_request.mode;
|
4 |
+
const ajaxUrl = cpsw_payment_request.ajax_url;
|
5 |
+
const nonce = cpsw_payment_request.nonce;
|
6 |
+
const isProductPage = cpsw_payment_request.is_product_page;
|
7 |
+
const currencyCode = cpsw_payment_request.currency_code;
|
8 |
+
const countryCode = cpsw_payment_request.country_code;
|
9 |
+
const style = cpsw_payment_request.style;
|
10 |
+
const jsNonce = cpsw_payment_request.nonce.js_nonce;
|
11 |
+
const endpoint = cpsw_payment_request.ajax_endpoint;
|
12 |
+
let smallScreen = true;
|
13 |
+
|
14 |
+
let requestType = '';
|
15 |
+
|
16 |
+
if ( '' === pubKey || ( 'live' === mode ) ) {
|
17 |
+
return;
|
18 |
+
}
|
19 |
+
|
20 |
+
const stripe = Stripe( pubKey );
|
21 |
+
|
22 |
+
function getAjaxEndpoint( param ) {
|
23 |
+
return endpoint.toString().replace( '%%endpoint%%', param );
|
24 |
+
}
|
25 |
+
|
26 |
+
function initializePaymentButton() {
|
27 |
+
let data;
|
28 |
+
if ( isProductPage ) {
|
29 |
+
data = {
|
30 |
+
total: cpsw_payment_request.product.total,
|
31 |
+
currency: cpsw_payment_request.currency_code,
|
32 |
+
country: cpsw_payment_request.country_code,
|
33 |
+
requestPayerName: true,
|
34 |
+
requestPayerEmail: true,
|
35 |
+
requestPayerPhone: true,
|
36 |
+
requestShipping: cpsw_payment_request.product.requestShipping,
|
37 |
+
displayItems: cpsw_payment_request.product.displayItems,
|
38 |
+
};
|
39 |
+
generatePaymentButton( data );
|
40 |
+
} else {
|
41 |
+
const params = {
|
42 |
+
cart_nonce: nonce.payment,
|
43 |
+
};
|
44 |
+
|
45 |
+
$.ajax( {
|
46 |
+
type: 'POST',
|
47 |
+
data: params,
|
48 |
+
url: getAjaxEndpoint( 'cpsw_get_cart_details' ),
|
49 |
+
success( response ) {
|
50 |
+
data = {
|
51 |
+
total: response.order_data.total,
|
52 |
+
currency: currencyCode,
|
53 |
+
country: countryCode,
|
54 |
+
requestPayerName: true,
|
55 |
+
requestPayerEmail: true,
|
56 |
+
requestPayerPhone: true,
|
57 |
+
requestShipping: response.shipping_required,
|
58 |
+
displayItems: response.order_data.displayItems,
|
59 |
+
};
|
60 |
+
generatePaymentButton( data );
|
61 |
+
},
|
62 |
+
} );
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
function generatePaymentButton( data ) {
|
67 |
+
try {
|
68 |
+
const paymentRequest = stripe.paymentRequest( data );
|
69 |
+
|
70 |
+
const elements = stripe.elements();
|
71 |
+
|
72 |
+
let height = style.height;
|
73 |
+
|
74 |
+
if ( $( document ).width() < 660 ) {
|
75 |
+
height = 40;
|
76 |
+
smallScreen = true;
|
77 |
+
} else {
|
78 |
+
smallScreen = false;
|
79 |
+
}
|
80 |
+
|
81 |
+
const prButton = elements.create( 'paymentRequestButton', {
|
82 |
+
paymentRequest,
|
83 |
+
style: {
|
84 |
+
paymentRequestButton: {
|
85 |
+
type: style.type,
|
86 |
+
theme: style.theme,
|
87 |
+
height: height + 'px',
|
88 |
+
},
|
89 |
+
},
|
90 |
+
} );
|
91 |
+
|
92 |
+
paymentRequest.canMakePayment().then( function( result ) {
|
93 |
+
if ( ! result ) {
|
94 |
+
return;
|
95 |
+
}
|
96 |
+
|
97 |
+
if ( result.applePay ) {
|
98 |
+
requestType = 'apple_pay';
|
99 |
+
} else if ( result.googlePay ) {
|
100 |
+
requestType = 'google_pay';
|
101 |
+
} else {
|
102 |
+
requestType = 'payment_request_api';
|
103 |
+
}
|
104 |
+
|
105 |
+
attachPaymentRequestButtonEventListeners( prButton, paymentRequest );
|
106 |
+
|
107 |
+
$( '#cpsw-payment-request-wrapper' ).show();
|
108 |
+
if ( $( '#cpsw-payment-request-wrapper #cpsw-payment-request-button' ).length > 0 ) {
|
109 |
+
prButton.mount( '#cpsw-payment-request-wrapper #cpsw-payment-request-button' );
|
110 |
+
}
|
111 |
+
|
112 |
+
if ( $( '#cpsw-payment-request-separator' ).hasClass( 'cart' ) ) {
|
113 |
+
$( '#cpsw-payment-request-separator' ).show();
|
114 |
+
}
|
115 |
+
|
116 |
+
if ( $( '#cpsw-payment-request-separator' ).hasClass( 'checkout' ) ) {
|
117 |
+
$( '#cpsw-payment-request-separator' ).show();
|
118 |
+
}
|
119 |
+
|
120 |
+
if ( $( '#cpsw-payment-request-separator' ).hasClass( 'product' ) ) {
|
121 |
+
if ( smallScreen && $( '#cpsw-payment-request-wrapper' ).hasClass( 'sticky' ) ) {
|
122 |
+
$( '#cpsw-payment-request-separator' ).hide();
|
123 |
+
} else {
|
124 |
+
$( '#cpsw-payment-request-separator' ).show();
|
125 |
+
}
|
126 |
+
}
|
127 |
+
} );
|
128 |
+
|
129 |
+
paymentRequest.on( 'shippingaddresschange', function( e ) {
|
130 |
+
$.when( updateShippingAddress( e.shippingAddress ) ).then( function( response ) {
|
131 |
+
if ( 'success' === response.result ) {
|
132 |
+
e.updateWith( { status: response.result, shippingOptions: response.shipping_options, total: response.total, displayItems: response.displayItems } );
|
133 |
+
}
|
134 |
+
if ( 'fail' === response.result ) {
|
135 |
+
e.updateWith( { status: 'fail' } );
|
136 |
+
}
|
137 |
+
} );
|
138 |
+
} );
|
139 |
+
|
140 |
+
paymentRequest.on( 'shippingoptionchange', function( e ) {
|
141 |
+
$.when( updateShippingOption( e.shippingOption ) ).then( function( response ) {
|
142 |
+
if ( 'success' === response.result ) {
|
143 |
+
e.updateWith( { status: 'success', total: response.total, displayItems: response.displayItems } );
|
144 |
+
}
|
145 |
+
|
146 |
+
if ( 'fail' === response.result ) {
|
147 |
+
e.updateWith( { status: 'fail' } );
|
148 |
+
}
|
149 |
+
} );
|
150 |
+
} );
|
151 |
+
|
152 |
+
paymentRequest.on( 'paymentmethod', function( e ) {
|
153 |
+
$.when( createPaymentMethod( e, requestType ) ).then( function( response ) {
|
154 |
+
if ( 'success' === response.result ) {
|
155 |
+
confirmPaymentIntent( e, response.redirect );
|
156 |
+
} else {
|
157 |
+
abortPayment( e, response.messages );
|
158 |
+
}
|
159 |
+
} );
|
160 |
+
} );
|
161 |
+
} catch ( e ) {
|
162 |
+
logError( e );
|
163 |
+
}
|
164 |
+
}
|
165 |
+
|
166 |
+
function updateShippingAddress( address ) {
|
167 |
+
const data = {
|
168 |
+
shipping_address_nonce: nonce.shipping,
|
169 |
+
country: address.country,
|
170 |
+
state: address.region,
|
171 |
+
postcode: address.postalCode,
|
172 |
+
city: address.city,
|
173 |
+
address: typeof address.addressLine[ 0 ] === 'undefined' ? '' : address.addressLine[ 0 ],
|
174 |
+
address_2: typeof address.addressLine[ 1 ] === 'undefined' ? '' : address.addressLine[ 1 ],
|
175 |
+
payment_request_type: requestType,
|
176 |
+
is_product_page: isProductPage,
|
177 |
+
};
|
178 |
+
|
179 |
+
return $.ajax( {
|
180 |
+
type: 'POST',
|
181 |
+
data,
|
182 |
+
url: getAjaxEndpoint( 'cpsw_update_shipping_address' ),
|
183 |
+
} );
|
184 |
+
}
|
185 |
+
|
186 |
+
function updateShippingOption( shippingOption ) {
|
187 |
+
const data = {
|
188 |
+
shipping_option_nonce: nonce.shipping_option,
|
189 |
+
shipping_method: [ shippingOption.id ],
|
190 |
+
payment_request_type: requestType,
|
191 |
+
is_product_page: isProductPage,
|
192 |
+
};
|
193 |
+
|
194 |
+
return $.ajax( {
|
195 |
+
type: 'POST',
|
196 |
+
data,
|
197 |
+
url: getAjaxEndpoint( 'cpsw_update_shipping_option' ),
|
198 |
+
} );
|
199 |
+
}
|
200 |
+
|
201 |
+
function attachPaymentRequestButtonEventListeners( prButton, paymentRequest ) {
|
202 |
+
prButton.on( 'click', function() {
|
203 |
+
$( 'body' ).addClass( 'cpsw-prButton-clicked' );
|
204 |
+
} );
|
205 |
+
|
206 |
+
if ( isProductPage ) {
|
207 |
+
listenProductPageEvents( prButton, paymentRequest );
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
+
function addProductToCart() {
|
212 |
+
let productId = $( '.single_add_to_cart_button' ).val();
|
213 |
+
|
214 |
+
// Check if product is a variable product.
|
215 |
+
if ( $( '.single_variation_wrap' ).length ) {
|
216 |
+
productId = $( '.single_variation_wrap' ).find( 'input[name="product_id"]' ).val();
|
217 |
+
}
|
218 |
+
|
219 |
+
const data = {
|
220 |
+
add_to_cart_nonce: nonce.add_to_cart,
|
221 |
+
action: 'add_to_cart',
|
222 |
+
product_id: productId,
|
223 |
+
qty: $( '.quantity .qty' ).val(),
|
224 |
+
attributes: $( '.variations_form' ).length ? getAttributes().data : [],
|
225 |
+
};
|
226 |
+
|
227 |
+
// add addons data to the POST body
|
228 |
+
const formData = $( 'form.cart' ).serializeArray();
|
229 |
+
$.each( formData, function( i, field ) {
|
230 |
+
if ( /^addon-/.test( field.name ) ) {
|
231 |
+
if ( /\[\]$/.test( field.name ) ) {
|
232 |
+
const fieldName = field.name.substring( 0, field.name.length - 2 );
|
233 |
+
if ( data[ fieldName ] ) {
|
234 |
+
data[ fieldName ].push( field.value );
|
235 |
+
} else {
|
236 |
+
data[ fieldName ] = [ field.value ];
|
237 |
+
}
|
238 |
+
} else {
|
239 |
+
data[ field.name ] = field.value;
|
240 |
+
}
|
241 |
+
}
|
242 |
+
} );
|
243 |
+
|
244 |
+
return $.ajax( {
|
245 |
+
type: 'POST',
|
246 |
+
data,
|
247 |
+
url: getAjaxEndpoint( 'cpsw_add_to_cart' ),
|
248 |
+
} );
|
249 |
+
}
|
250 |
+
|
251 |
+
function listenProductPageEvents( prButton, paymentRequest ) {
|
252 |
+
const addToCart = $( '.single_add_to_cart_button' );
|
253 |
+
|
254 |
+
prButton.on( 'click', function( event ) {
|
255 |
+
// First check if product can be added to cart.
|
256 |
+
if ( addToCart.is( '.disabled' ) ) {
|
257 |
+
event.preventDefault();
|
258 |
+
addToCart.trigger( 'click' );
|
259 |
+
return;
|
260 |
+
}
|
261 |
+
|
262 |
+
addProductToCart();
|
263 |
+
} );
|
264 |
+
|
265 |
+
$( document.body ).on( 'woocommerce_variation_has_changed', function() {
|
266 |
+
if ( addToCart.is( '.disabled' ) ) {
|
267 |
+
$( '#cpsw-payment-request-button' ).addClass( 'payment-method-disabled' );
|
268 |
+
return;
|
269 |
+
}
|
270 |
+
$( '#cpsw-payment-request-button' ).removeClass( 'payment-method-disabled' );
|
271 |
+
blockPaymentRequestButton();
|
272 |
+
|
273 |
+
$.when( getSelectedProductData() ).then( function( response ) {
|
274 |
+
if ( response.error ) {
|
275 |
+
displayErrorMessage( response.error );
|
276 |
+
} else {
|
277 |
+
$.when(
|
278 |
+
paymentRequest.update( {
|
279 |
+
total: response.total,
|
280 |
+
displayItems: response.displayItems,
|
281 |
+
} ),
|
282 |
+
).then( function() {
|
283 |
+
unblockPaymentRequestButton();
|
284 |
+
} );
|
285 |
+
}
|
286 |
+
} );
|
287 |
+
} );
|
288 |
+
|
289 |
+
$( 'form.cart .quantity' ).on( 'input', '.qty', function() {
|
290 |
+
if ( addToCart.is( '.disabled' ) ) {
|
291 |
+
return;
|
292 |
+
}
|
293 |
+
blockPaymentRequestButton();
|
294 |
+
} );
|
295 |
+
|
296 |
+
$( 'form.cart .quantity' ).on( 'input', '.qty', debounce( 250, function() {
|
297 |
+
if ( addToCart.is( '.disabled' ) ) {
|
298 |
+
return;
|
299 |
+
}
|
300 |
+
blockPaymentRequestButton();
|
301 |
+
|
302 |
+
$.when( getSelectedProductData() ).then( function( response ) {
|
303 |
+
if ( response.error ) {
|
304 |
+
displayErrorMessage( response.error );
|
305 |
+
} else {
|
306 |
+
$.when(
|
307 |
+
paymentRequest.update( {
|
308 |
+
total: response.total,
|
309 |
+
displayItems: response.displayItems,
|
310 |
+
} ),
|
311 |
+
).then( function() {
|
312 |
+
unblockPaymentRequestButton();
|
313 |
+
} );
|
314 |
+
}
|
315 |
+
} );
|
316 |
+
} ) );
|
317 |
+
}
|
318 |
+
|
319 |
+
function debounce( wait, func, immediate ) {
|
320 |
+
let timeout;
|
321 |
+
|
322 |
+
return function() {
|
323 |
+
const context = this;
|
324 |
+
const args = arguments;
|
325 |
+
|
326 |
+
const later = function() {
|
327 |
+
timeout = null;
|
328 |
+
if ( ! immediate ) {
|
329 |
+
func.apply( context, args );
|
330 |
+
}
|
331 |
+
};
|
332 |
+
|
333 |
+
const callNow = immediate && ! timeout;
|
334 |
+
|
335 |
+
clearTimeout( timeout );
|
336 |
+
|
337 |
+
timeout = setTimeout( later, wait );
|
338 |
+
|
339 |
+
if ( callNow ) {
|
340 |
+
func.apply( context, args );
|
341 |
+
}
|
342 |
+
};
|
343 |
+
}
|
344 |
+
|
345 |
+
function getSelectedProductData() {
|
346 |
+
let productId = $( '.single_add_to_cart_button' ).val();
|
347 |
+
|
348 |
+
// Check if product is a variable product.
|
349 |
+
if ( $( '.single_variation_wrap' ).length ) {
|
350 |
+
productId = $( '.single_variation_wrap' ).find( 'input[name="product_id"]' ).val();
|
351 |
+
}
|
352 |
+
|
353 |
+
const addons = $( '#product-addons-total' ).data( 'price_data' ) || [];
|
354 |
+
const addonValue = addons.reduce( function( sum, addon ) {
|
355 |
+
return sum + addon.cost;
|
356 |
+
}, 0 );
|
357 |
+
|
358 |
+
const data = {
|
359 |
+
selected_product_nonce: nonce.selected_product_data,
|
360 |
+
product_id: productId,
|
361 |
+
qty: $( '.quantity .qty' ).val(),
|
362 |
+
attributes: $( '.variations_form' ).length ? getAttributes().data : [],
|
363 |
+
addon_value: addonValue,
|
364 |
+
};
|
365 |
+
|
366 |
+
return $.ajax( {
|
367 |
+
type: 'POST',
|
368 |
+
data,
|
369 |
+
url: getAjaxEndpoint( 'cpsw_selected_product_data' ),
|
370 |
+
} );
|
371 |
+
}
|
372 |
+
|
373 |
+
function blockPaymentRequestButton( ) {
|
374 |
+
if ( $( '#cpsw-payment-request-button' ).data( 'blockUI.isBlocked' ) ) {
|
375 |
+
return;
|
376 |
+
}
|
377 |
+
|
378 |
+
$( '#cpsw-payment-request-button' ).addClass( 'cpsw_request_button_blocked' ).block( { message: null } );
|
379 |
+
}
|
380 |
+
|
381 |
+
function unblockPaymentRequestButton() {
|
382 |
+
$( '#cpsw-payment-request-button' ).removeClass( 'cpsw_request_button_blocked' ).unblock();
|
383 |
+
}
|
384 |
+
|
385 |
+
function getAttributes() {
|
386 |
+
const select = $( '.variations_form' ).find( '.variations select' ),
|
387 |
+
data = {};
|
388 |
+
let count = 0,
|
389 |
+
chosen = 0;
|
390 |
+
|
391 |
+
select.each( function() {
|
392 |
+
const attributeName = $( this ).data( 'attribute_name' ) || $( this ).attr( 'name' );
|
393 |
+
const value = $( this ).val() || '';
|
394 |
+
|
395 |
+
if ( value.length > 0 ) {
|
396 |
+
chosen++;
|
397 |
+
}
|
398 |
+
|
399 |
+
count++;
|
400 |
+
data[ attributeName ] = value;
|
401 |
+
} );
|
402 |
+
|
403 |
+
return {
|
404 |
+
count,
|
405 |
+
chosenCount: chosen,
|
406 |
+
data,
|
407 |
+
};
|
408 |
+
}
|
409 |
+
|
410 |
+
function preparePaymentMethod( event ) {
|
411 |
+
const paymentMethod = event.paymentMethod;
|
412 |
+
const billingDetails = paymentMethod.billing_details;
|
413 |
+
const email = billingDetails.email;
|
414 |
+
const phone = billingDetails.phone;
|
415 |
+
const billing = billingDetails.address;
|
416 |
+
const name = billingDetails.name;
|
417 |
+
const shipping = event.shippingAddress;
|
418 |
+
const data = {
|
419 |
+
checkout_nonce: nonce.checkout,
|
420 |
+
billing_first_name: null !== name ? name.split( ' ' ).slice( 0, 1 ).join( ' ' ) : '',
|
421 |
+
billing_last_name: null !== name ? name.split( ' ' ).slice( 1 ).join( ' ' ) : '',
|
422 |
+
billing_company: '',
|
423 |
+
billing_email: null !== email ? email : event.payerEmail,
|
424 |
+
billing_phone: null !== phone ? phone : event.payerPhone && event.payerPhone.replace( '/[() -]/g', '' ),
|
425 |
+
billing_country: null !== billing ? billing.country : '',
|
426 |
+
billing_address_1: null !== billing ? billing.line1 : '',
|
427 |
+
billing_address_2: null !== billing ? billing.line2 : '',
|
428 |
+
billing_city: null !== billing ? billing.city : '',
|
429 |
+
billing_state: null !== billing ? billing.state : '',
|
430 |
+
billing_postcode: null !== billing ? billing.postal_code : '',
|
431 |
+
shipping_first_name: '',
|
432 |
+
shipping_last_name: '',
|
433 |
+
shipping_company: '',
|
434 |
+
shipping_country: '',
|
435 |
+
shipping_address_1: '',
|
436 |
+
shipping_address_2: '',
|
437 |
+
shipping_city: '',
|
438 |
+
shipping_state: '',
|
439 |
+
shipping_postcode: '',
|
440 |
+
shipping_method: [ null === event.shippingOption ? null : event.shippingOption.id ],
|
441 |
+
order_comments: '',
|
442 |
+
payment_method: 'cpsw_stripe',
|
443 |
+
ship_to_different_address: 1,
|
444 |
+
terms: 1,
|
445 |
+
payment_method_created: paymentMethod.id,
|
446 |
+
payment_request_type: requestType,
|
447 |
+
};
|
448 |
+
|
449 |
+
if ( shipping ) {
|
450 |
+
data.shipping_first_name = shipping.recipient.split( ' ' ).slice( 0, 1 ).join( ' ' );
|
451 |
+
data.shipping_last_name = shipping.recipient.split( ' ' ).slice( 1 ).join( ' ' );
|
452 |
+
data.shipping_company = shipping.organization;
|
453 |
+
data.shipping_country = shipping.country;
|
454 |
+
data.shipping_address_1 = typeof shipping.addressLine[ 0 ] === 'undefined' ? '' : shipping.addressLine[ 0 ];
|
455 |
+
data.shipping_address_2 = typeof shipping.addressLine[ 1 ] === 'undefined' ? '' : shipping.addressLine[ 1 ];
|
456 |
+
data.shipping_city = shipping.city;
|
457 |
+
data.shipping_state = shipping.region;
|
458 |
+
data.shipping_postcode = shipping.postalCode;
|
459 |
+
}
|
460 |
+
|
461 |
+
return data;
|
462 |
+
}
|
463 |
+
|
464 |
+
function createPaymentMethod( event ) {
|
465 |
+
const data = preparePaymentMethod( event );
|
466 |
+
return $.ajax( {
|
467 |
+
type: 'POST',
|
468 |
+
data,
|
469 |
+
dataType: 'json',
|
470 |
+
url: getAjaxEndpoint( 'cpsw_payment_request_checkout' ),
|
471 |
+
} );
|
472 |
+
}
|
473 |
+
|
474 |
+
function confirmPaymentIntent( event, hash ) {
|
475 |
+
const partials = hash.match(
|
476 |
+
/^#?confirm-(pi|si)-([^:]+):(.+)$/,
|
477 |
+
);
|
478 |
+
|
479 |
+
if ( ! partials || 4 > partials.length ) {
|
480 |
+
return;
|
481 |
+
}
|
482 |
+
|
483 |
+
const intentClientSecret = partials[ 2 ];
|
484 |
+
const redirectURL = decodeURIComponent( partials[ 3 ] );
|
485 |
+
|
486 |
+
confirmPayment( event, intentClientSecret, redirectURL );
|
487 |
+
}
|
488 |
+
|
489 |
+
function confirmPayment( event, clientSecret, redirectURL ) {
|
490 |
+
stripe.confirmCardPayment( clientSecret, {} ).then( function( result ) {
|
491 |
+
if ( result.error ) {
|
492 |
+
// Show error to your customer
|
493 |
+
$( '.woocommerce-error' ).remove();
|
494 |
+
$( 'form.woocommerce-checkout' ).unblock();
|
495 |
+
logError( result.error );
|
496 |
+
displayErrorMessage( result.error );
|
497 |
+
} else {
|
498 |
+
// The payment has been processed!
|
499 |
+
if ( result.paymentIntent.status === 'succeeded' || result.paymentIntent.status === 'requires_capture' ) {
|
500 |
+
$.blockUI( {
|
501 |
+
message: null,
|
502 |
+
overlayCSS: {
|
503 |
+
background: '#fff',
|
504 |
+
opacity: 0.6,
|
505 |
+
},
|
506 |
+
} );
|
507 |
+
event.complete( 'success' );
|
508 |
+
window.location = redirectURL;
|
509 |
+
}
|
510 |
+
}
|
511 |
+
} );
|
512 |
+
}
|
513 |
+
|
514 |
+
function logError( error ) {
|
515 |
+
$.ajax( {
|
516 |
+
type: 'POST',
|
517 |
+
dataType: 'json',
|
518 |
+
url: ajaxUrl,
|
519 |
+
data: { action: 'cpsw_js_errors', _security: jsNonce, error },
|
520 |
+
beforeSend: () => {
|
521 |
+
$( 'body' ).css( 'cursor', 'progress' );
|
522 |
+
},
|
523 |
+
success( response ) {
|
524 |
+
if ( response.success === true ) {
|
525 |
+
} else if ( response.success === false ) {
|
526 |
+
return response.message;
|
527 |
+
}
|
528 |
+
$( 'body' ).css( 'cursor', 'default' );
|
529 |
+
},
|
530 |
+
error() {
|
531 |
+
$( 'body' ).css( 'cursor', 'default' );
|
532 |
+
alert( 'Something went wrong!' );
|
533 |
+
},
|
534 |
+
} );
|
535 |
+
}
|
536 |
+
|
537 |
+
function displayErrorMessage( message ) {
|
538 |
+
$( '.woocommerce-error' ).remove();
|
539 |
+
|
540 |
+
if ( isProductPage ) {
|
541 |
+
const element = $( '.product' ).first();
|
542 |
+
element.before( message );
|
543 |
+
window.scrollTo( { top: 100, behavior: 'smooth' } );
|
544 |
+
} else {
|
545 |
+
const $form = $( '.shop_table.cart, #cpsw-payment-request-wrapper.checkout' ).closest( 'form' );
|
546 |
+
$form.before( message );
|
547 |
+
window.scrollTo( { top: 100, behavior: 'smooth' } );
|
548 |
+
}
|
549 |
+
}
|
550 |
+
|
551 |
+
function abortPayment( event, message ) {
|
552 |
+
event.complete( 'fail' );
|
553 |
+
displayErrorMessage( message );
|
554 |
+
}
|
555 |
+
|
556 |
+
initializePaymentButton();
|
557 |
+
|
558 |
+
$( document.body ).on( 'updated_cart_totals', function() {
|
559 |
+
initializePaymentButton();
|
560 |
+
} );
|
561 |
+
|
562 |
+
// We need to refresh payment request data when total is updated.
|
563 |
+
$( document.body ).on( 'updated_checkout', function() {
|
564 |
+
initializePaymentButton();
|
565 |
+
} );
|
566 |
+
}( jQuery ) );
|
autoloader.php
CHANGED
@@ -8,8 +8,9 @@
|
|
8 |
|
9 |
namespace CPSW;
|
10 |
|
11 |
-
use CPSW\Inc\Helper;
|
12 |
use CPSW\Gateway\Stripe\Card_Payments;
|
|
|
|
|
13 |
use CPSW\Admin\Admin_Controller;
|
14 |
use CPSW\Gateway\Stripe\Webhook;
|
15 |
|
@@ -89,9 +90,9 @@ class CPSW_Loader {
|
|
89 |
* @return void
|
90 |
*/
|
91 |
public function setup_classes() {
|
92 |
-
Helper::get_instance();
|
93 |
Admin_Controller::get_instance();
|
94 |
Webhook::get_instance();
|
|
|
95 |
}
|
96 |
|
97 |
/**
|
@@ -118,6 +119,7 @@ class CPSW_Loader {
|
|
118 |
|
119 |
if ( class_exists( 'woocommerce' ) ) {
|
120 |
Card_Payments::get_instance();
|
|
|
121 |
} else {
|
122 |
add_action( 'admin_notices', [ $this, 'wc_is_not_active' ] );
|
123 |
}
|
8 |
|
9 |
namespace CPSW;
|
10 |
|
|
|
11 |
use CPSW\Gateway\Stripe\Card_Payments;
|
12 |
+
use CPSW\Gateway\Stripe\Payment_Request_Api;
|
13 |
+
use CPSW\Compatibility\Apple_Pay;
|
14 |
use CPSW\Admin\Admin_Controller;
|
15 |
use CPSW\Gateway\Stripe\Webhook;
|
16 |
|
90 |
* @return void
|
91 |
*/
|
92 |
public function setup_classes() {
|
|
|
93 |
Admin_Controller::get_instance();
|
94 |
Webhook::get_instance();
|
95 |
+
Apple_Pay::get_instance();
|
96 |
}
|
97 |
|
98 |
/**
|
119 |
|
120 |
if ( class_exists( 'woocommerce' ) ) {
|
121 |
Card_Payments::get_instance();
|
122 |
+
Payment_Request_Api::get_instance();
|
123 |
} else {
|
124 |
add_action( 'admin_notices', [ $this, 'wc_is_not_active' ] );
|
125 |
}
|
checkout-plugins-stripe-woo.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Checkout Plugins - Stripe for WooCommerce
|
4 |
* Plugin URI: https://www.checkoutplugins.com/
|
5 |
* Description: Stripe for WooCommerce delivers a simple, secure way to accept credit card payments in your WooCommerce store. Reduce payment friction and boost conversions using this free plugin!
|
6 |
-
* Version: 1.
|
7 |
* Author: Brainstorm Force
|
8 |
* Author URI: https://brainstormforce.com/
|
9 |
* License: GPLv2 or later
|
@@ -20,6 +20,6 @@ define( 'CPSW_FILE', __FILE__ );
|
|
20 |
define( 'CPSW_BASE', plugin_basename( CPSW_FILE ) );
|
21 |
define( 'CPSW_DIR', plugin_dir_path( CPSW_FILE ) );
|
22 |
define( 'CPSW_URL', plugins_url( '/', CPSW_FILE ) );
|
23 |
-
define( 'CPSW_VERSION', '1.
|
24 |
|
25 |
require_once 'autoloader.php';
|
3 |
* Plugin Name: Checkout Plugins - Stripe for WooCommerce
|
4 |
* Plugin URI: https://www.checkoutplugins.com/
|
5 |
* Description: Stripe for WooCommerce delivers a simple, secure way to accept credit card payments in your WooCommerce store. Reduce payment friction and boost conversions using this free plugin!
|
6 |
+
* Version: 1.1.0
|
7 |
* Author: Brainstorm Force
|
8 |
* Author URI: https://brainstormforce.com/
|
9 |
* License: GPLv2 or later
|
20 |
define( 'CPSW_BASE', plugin_basename( CPSW_FILE ) );
|
21 |
define( 'CPSW_DIR', plugin_dir_path( CPSW_FILE ) );
|
22 |
define( 'CPSW_URL', plugins_url( '/', CPSW_FILE ) );
|
23 |
+
define( 'CPSW_VERSION', '1.1.0' );
|
24 |
|
25 |
require_once 'autoloader.php';
|
compatibility/apple-developer-merchantid-domain-association
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
7B227073704964223A2239373943394538343346343131343044463144313834343232393232313734313034353044314339464446394437384337313531303944334643463542433731222C2276657273696F6E223A312C22637265617465644F6E223A313536363233343735303036312C227369676E6174757265223A22333038303036303932613836343838366637306430313037303261303830333038303032303130313331306633303064303630393630383634383031363530333034303230313035303033303830303630393261383634383836663730643031303730313030303061303830333038323033653333303832303338386130303330323031303230323038346333303431343935313964353433363330306130363038326138363438636533643034303330323330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333031653137306433313339333033353331333833303331333333323335333735613137306433323334333033353331333633303331333333323335333735613330356633313235333032333036303335353034303330633163363536333633326437333664373032643632373236663662363537323264373336393637366535663535343333343264353035323466343433313134333031323036303335353034306230633062363934663533323035333739373337343635366437333331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333035393330313330363037326138363438636533643032303130363038326138363438636533643033303130373033343230303034633231353737656465626436633762323231386636386464373039306131323138646337623062643666326332383364383436303935643934616634613534313162383334323065643831316633343037653833333331663163353463336637656233323230643662616435643465666634393238393839336537633066313361333832303231313330383230323064333030633036303335353164313330313031666630343032333030303330316630363033353531643233303431383330313638303134323366323439633434663933653465663237653663346636323836633366613262626664326534623330343530363038326230363031303530353037303130313034333933303337333033353036303832623036303130353035303733303031383632393638373437343730336132663266366636333733373032653631373037303663363532653633366636643266366636333733373033303334326436313730373036633635363136393633363133333330333233303832303131643036303335353164323030343832303131343330383230313130333038323031306330363039326138363438383666373633363430353031333038316665333038316333303630383262303630313035303530373032303233303831623630633831623335323635366336393631366536333635323036663665323037343638363937333230363336353732373436393636363936333631373436353230363237393230363136653739323037303631373237343739323036313733373337353664363537333230363136333633363537303734363136653633363532303666363632303734363836353230373436383635366532303631373037303663363936333631363236633635323037333734363136653634363137323634323037343635373236643733323036313665363432303633366636653634363937343639366636653733323036663636323037353733363532633230363336353732373436393636363936333631373436353230373036663663363936333739323036313665363432303633363537323734363936363639363336313734363936663665323037303732363136333734363936333635323037333734363137343635366436353665373437333265333033363036303832623036303130353035303730323031313632613638373437343730336132663266373737373737326536313730373036633635326536333666366432663633363537323734363936363639363336313734363536313735373436383666373236393734373932663330333430363033353531643166303432643330326233303239613032376130323538363233363837343734373033613266326636333732366332653631373037303663363532653633366636643266363137303730366336353631363936333631333332653633373236633330316430363033353531643065303431363034313439343537646236666435373438313836383938393736326637653537383530376537396235383234333030653036303335353164306630313031666630343034303330323037383033303066303630393261383634383836663736333634303631643034303230353030333030613036303832613836343863653364303430333032303334393030333034363032323130306265303935373166653731653165373335623535653561666163623463373266656234343566333031383532323263373235313030326236316562643666353530323231303064313862333530613564643664643665623137343630333562313165623263653837636661336536616636636264383338303839306463383263646461613633333038323032656533303832303237356130303330323031303230323038343936643266626633613938646139373330306130363038326138363438636533643034303330323330363733313162333031393036303335353034303330633132343137303730366336353230353236663666373432303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330316531373064333133343330333533303336333233333334333633333330356131373064333233393330333533303336333233333334333633333330356133303761333132653330326330363033353530343033306332353431373037303663363532303431373037303663363936333631373436393666366532303439366537343635363737323631373436393666366532303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346630313731313834313964373634383564353161356532353831303737366538383061326566646537626165346465303864666334623933653133333536643536363562333561653232643039373736306432323465376262613038666437363137636538386362373662623636373062656338653832393834666635343435613338316637333038316634333034363036303832623036303130353035303730313031303433613330333833303336303630383262303630313035303530373330303138363261363837343734373033613266326636663633373337303265363137303730366336353265363336663664326636663633373337303330333432643631373037303663363537323666366637343633363136373333333031643036303335353164306530343136303431343233663234396334346639336534656632376536633466363238366333666132626266643265346233303066303630333535316431333031303166663034303533303033303130316666333031663036303335353164323330343138333031363830313462626230646561313538333338383961613438613939646562656264656261666461636232346162333033373036303335353164316630343330333032653330326361303261613032383836323636383734373437303361326632663633373236633265363137303730366336353265363336663664326636313730373036633635373236663666373436333631363733333265363337323663333030653036303335353164306630313031666630343034303330323031303633303130303630613261383634383836663736333634303630323065303430323035303033303061303630383261383634386365336430343033303230333637303033303634303233303361636637323833353131363939623138366662333563333536636136326266663431376564643930663735346461323865626566313963383135653432623738396638393866373962353939663938643534313064386639646539633266653032333033323264643534343231623061333035373736633564663333383362393036376664313737633263323136643936346663363732363938323132366635346638376137643162393963623962303938393231363130363939306630393932316430303030333138323031386233303832303138373032303130313330383138363330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533303230383463333034313439353139643534333633303064303630393630383634383031363530333034303230313035303061303831393533303138303630393261383634383836663730643031303930333331306230363039326138363438383666373064303130373031333031633036303932613836343838366637306430313039303533313066313730643331333933303338333133393331333733313332333333303561333032613036303932613836343838366637306430313039333433313164333031623330306430363039363038363438303136353033303430323031303530306131306130363038326138363438636533643034303330323330326630363039326138363438383666373064303130393034333132323034323062303731303365313430613462386231376262613230316130336163643036396234653431366232613263383066383661383338313435633239373566633131333030613036303832613836343863653364303430333032303434363330343430323230343639306264636637626461663833636466343934396534633035313039656463663334373665303564373261313264376335666538633033303033343464663032323032363764353863393365626233353031333836363062353730373938613064643731313734316262353864626436613138363633353038353431656565393035303030303030303030303030227D
|
compatibility/apple-pay.php
ADDED
@@ -0,0 +1,283 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Apple Pay domain association
|
4 |
+
*
|
5 |
+
* @package checkout-plugins-stripe-woo
|
6 |
+
* @since 1.1.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
namespace CPSW\Compatibility;
|
10 |
+
|
11 |
+
use CPSW\Inc\Traits\Get_Instance;
|
12 |
+
use CPSW\Gateway\Stripe\Stripe_Api;
|
13 |
+
use CPSW\Inc\Helper;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Apple Pay Domain Verification class
|
17 |
+
*/
|
18 |
+
class Apple_Pay {
|
19 |
+
|
20 |
+
use Get_Instance;
|
21 |
+
|
22 |
+
const APPLE_PAY_FILE = 'apple-developer-merchantid-domain-association';
|
23 |
+
const APPLE_PAY_DIR = '.well-known';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Domain verification flag
|
27 |
+
*
|
28 |
+
* @var bool
|
29 |
+
*/
|
30 |
+
public $domain_is_verfied;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Verified domain stored in database
|
34 |
+
*
|
35 |
+
* @var string
|
36 |
+
*/
|
37 |
+
public $verified_domain;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Current domain
|
41 |
+
*
|
42 |
+
* @var string
|
43 |
+
*/
|
44 |
+
public $domain;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Stores apple pay domain verification failure message.
|
48 |
+
*
|
49 |
+
* @var string
|
50 |
+
*/
|
51 |
+
private $failure_message;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Constructor
|
55 |
+
*/
|
56 |
+
public function __construct() {
|
57 |
+
add_action( 'init', [ $this, 'apple_pay_domain_association_rewrite_rule' ] );
|
58 |
+
add_action( 'admin_init', [ $this, 'is_domain_verified' ] );
|
59 |
+
add_filter( 'query_vars', [ $this, 'add_domain_association_query_var' ], 10, 1 );
|
60 |
+
add_action( 'parse_request', [ $this, 'parse_domain_association_request' ], 10, 1 );
|
61 |
+
|
62 |
+
$this->domain_is_verfied = get_option( 'cpsw_apple_pay_domain_is_verfied' );
|
63 |
+
$this->verified_domain = get_option( 'cpsw_apple_pay_verified_domain' );
|
64 |
+
$this->secret_key = Helper::get_setting( 'cpsw_secret_key' );
|
65 |
+
$this->failure_message = '';
|
66 |
+
$this->domain = isset( $_SERVER['HTTP_HOST'] ) ? $_SERVER['HTTP_HOST'] : str_replace( array( 'https://', 'http://' ), '', get_site_url() );
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Rewrite rules for apple pay domain association.
|
71 |
+
*
|
72 |
+
* @return void
|
73 |
+
*/
|
74 |
+
public function apple_pay_domain_association_rewrite_rule() {
|
75 |
+
$regex = '^\\' . self::APPLE_PAY_DIR . '\/' . self::APPLE_PAY_FILE . '$';
|
76 |
+
$redirect = 'index.php?' . self::APPLE_PAY_FILE . '=1';
|
77 |
+
|
78 |
+
add_rewrite_rule( $regex, $redirect, 'top' );
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Add domain association query var
|
83 |
+
*
|
84 |
+
* @param array $query_vars existing query vars.
|
85 |
+
* @return array
|
86 |
+
*/
|
87 |
+
public function add_domain_association_query_var( $query_vars ) {
|
88 |
+
$query_vars[] = self::APPLE_PAY_FILE;
|
89 |
+
return $query_vars;
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Parse current domain should serve apple pay domain association file or not.
|
94 |
+
*
|
95 |
+
* @param object $wp query parameters.
|
96 |
+
* @return void
|
97 |
+
*/
|
98 |
+
public function parse_domain_association_request( $wp ) {
|
99 |
+
if (
|
100 |
+
self::APPLE_PAY_DIR . '/' . self::APPLE_PAY_FILE !== $wp->request ||
|
101 |
+
self::APPLE_PAY_FILE !== $wp->query_vars['attachment']
|
102 |
+
) {
|
103 |
+
return;
|
104 |
+
}
|
105 |
+
|
106 |
+
$path = CPSW_DIR . 'compatibility/' . self::APPLE_PAY_FILE;
|
107 |
+
header( 'Content-Type: text/plain;charset=utf-8' );
|
108 |
+
echo esc_html( @file_get_contents( $path ) ); // @codingStandardsIgnoreLine
|
109 |
+
exit;
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Checks if current domain is verified or not else verifys current domain.
|
114 |
+
*
|
115 |
+
* @return boolean
|
116 |
+
*/
|
117 |
+
public function is_domain_verified() {
|
118 |
+
if ( ! empty( $this->verified_domain ) && $this->domain === $this->verified_domain && $this->domain_is_verfied ) {
|
119 |
+
return;
|
120 |
+
}
|
121 |
+
|
122 |
+
$settings = Helper::get_gateway_settings();
|
123 |
+
$this->express_checkout = $settings['express_checkout_enabled'];
|
124 |
+
if ( 'yes' !== $this->express_checkout || 'yes' !== $settings['enabled'] ) {
|
125 |
+
return;
|
126 |
+
}
|
127 |
+
|
128 |
+
if ( isset( $_GET['page'] ) && isset( $_GET['tab'] ) && isset( $_GET['section'] ) && 'wc-settings' === $_GET['page'] && 'checkout' === $_GET['tab'] && 'cpsw_express_checkout' === $_GET['section'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
129 |
+
if ( ! is_ssl() ) {
|
130 |
+
add_action( 'admin_notices', [ $this, 'no_ssl_notice' ] );
|
131 |
+
return;
|
132 |
+
}
|
133 |
+
|
134 |
+
flush_rewrite_rules();
|
135 |
+
|
136 |
+
$response = $this->move_file_to_apple_dir();
|
137 |
+
if ( ! $response['success'] ) {
|
138 |
+
$this->failure_message = $response['message'];
|
139 |
+
add_action( 'admin_notices', [ $this, 'apple_pay_verification_failed' ] );
|
140 |
+
return;
|
141 |
+
}
|
142 |
+
|
143 |
+
$this->verify_domain_for_apple_pay();
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Moves domain association file to required directory
|
149 |
+
*
|
150 |
+
* @return array
|
151 |
+
*/
|
152 |
+
public function move_file_to_apple_dir() {
|
153 |
+
if ( $this->check_hosted_file() ) {
|
154 |
+
return [
|
155 |
+
'success' => true,
|
156 |
+
];
|
157 |
+
}
|
158 |
+
|
159 |
+
$well_known_dir = untrailingslashit( ABSPATH ) . '/' . self::APPLE_PAY_DIR;
|
160 |
+
$fullpath = $well_known_dir . '/' . self::APPLE_PAY_FILE;
|
161 |
+
|
162 |
+
if ( ! file_exists( $well_known_dir ) ) {
|
163 |
+
if ( ! @mkdir( $well_known_dir, 0755 ) ) { // @codingStandardsIgnoreLine
|
164 |
+
return [
|
165 |
+
'success' => false,
|
166 |
+
/* translators: 1 - 4 html entities */
|
167 |
+
'message' => sprintf( __( 'Unable to create domain association folder to domain root due to file permissions. Please create %1$1s.well-known%2$2s directory under domain root and place %3$3sdomain verification file%4$4s under it and refresh.', 'checkout-plugins-stripe-woo' ), '<code>', '</code>', '<a href="https://stripe.com/files/apple-pay/apple-developer-merchantid-domain-association" target="_blank">', '</a>' ),
|
168 |
+
];
|
169 |
+
}
|
170 |
+
}
|
171 |
+
|
172 |
+
if ( ! @copy( CPSW_DIR . 'compatibility/' . self::APPLE_PAY_FILE, $fullpath ) ) { // @codingStandardsIgnoreLine
|
173 |
+
return [
|
174 |
+
'success' => false,
|
175 |
+
'message' => __( 'Unable to copy domain association file to domain root.', 'checkout-plugins-stripe-woo' ),
|
176 |
+
];
|
177 |
+
}
|
178 |
+
|
179 |
+
return [
|
180 |
+
'success' => true,
|
181 |
+
];
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Checks if hosted domain verification file is correct or not, updates if required.
|
186 |
+
*
|
187 |
+
* @return bool
|
188 |
+
*/
|
189 |
+
public function check_hosted_file() {
|
190 |
+
$new_contents = @file_get_contents( CPSW_DIR . 'compatibility/' . self::APPLE_PAY_FILE ); // @codingStandardsIgnoreLine
|
191 |
+
$fullpath = untrailingslashit( ABSPATH ) . '/' . self::APPLE_PAY_DIR . '/' . self::APPLE_PAY_FILE;
|
192 |
+
$local_contents = @file_get_contents( $fullpath ); // @codingStandardsIgnoreLine
|
193 |
+
$url = get_site_url() . '/' . self::APPLE_PAY_DIR . '/' . self::APPLE_PAY_FILE;
|
194 |
+
$response = @wp_remote_get( $url ); // @codingStandardsIgnoreLine
|
195 |
+
$remote_contents = @wp_remote_retrieve_body( $response ); // @codingStandardsIgnoreLine
|
196 |
+
|
197 |
+
return $local_contents === $new_contents || $remote_contents === $new_contents;
|
198 |
+
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Automatic verification for apple pay using stripe api
|
202 |
+
*
|
203 |
+
* @return void
|
204 |
+
*/
|
205 |
+
public function verify_domain_for_apple_pay() {
|
206 |
+
|
207 |
+
if ( empty( $this->secret_key ) ) {
|
208 |
+
add_action( 'admin_notices', [ $this, 'no_live_secret_key' ] );
|
209 |
+
return;
|
210 |
+
}
|
211 |
+
|
212 |
+
add_filter( 'cpsw_get_secret_key', [ $this, 'get_live_secret_key' ], 10, 1 );
|
213 |
+
$stripe = new Stripe_Api();
|
214 |
+
|
215 |
+
$response = $stripe->apple_pay_domains(
|
216 |
+
'create',
|
217 |
+
[
|
218 |
+
[
|
219 |
+
'domain_name' => $this->domain,
|
220 |
+
],
|
221 |
+
]
|
222 |
+
);
|
223 |
+
|
224 |
+
$verification_response = $response['success'] ? $response['data'] : false;
|
225 |
+
|
226 |
+
if ( $verification_response ) {
|
227 |
+
update_option( 'cpsw_apple_pay_verified_domain', $this->domain );
|
228 |
+
update_option( 'cpsw_apple_pay_domain_is_verfied', true );
|
229 |
+
add_action( 'admin_notices', [ $this, 'apple_pay_verification_success' ] );
|
230 |
+
} else {
|
231 |
+
$this->failure_message = $response['message'];
|
232 |
+
delete_option( 'cpsw_apple_pay_domain_is_verfied' );
|
233 |
+
add_action( 'admin_notices', [ $this, 'apple_pay_verification_failed' ] );
|
234 |
+
}
|
235 |
+
}
|
236 |
+
|
237 |
+
/**
|
238 |
+
* Generates admin notice if no live secret key is found
|
239 |
+
*
|
240 |
+
* @return void
|
241 |
+
*/
|
242 |
+
public function no_live_secret_key() {
|
243 |
+
echo wp_kses_post( '<div class="notice notice-error is-dismissible"><p>' . __( 'We cannot find live secret key in database, Live secret key is required for Apple Pay domain verification. ', 'checkout-plugins-stripe-woo' ) . '</p></div>' );
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Generates admin notice for apple pay success
|
248 |
+
*
|
249 |
+
* @return void
|
250 |
+
*/
|
251 |
+
public function apple_pay_verification_success() {
|
252 |
+
echo wp_kses_post( '<div class="notice notice-success is-dismissible"><p>' . __( 'Apple Pay domain verification successful.', 'checkout-plugins-stripe-woo' ) . '</p></div>' );
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Generates admin notice for SSL requirment for payment request Api
|
257 |
+
*
|
258 |
+
* @return void
|
259 |
+
*/
|
260 |
+
public function no_ssl_notice() {
|
261 |
+
echo wp_kses_post( '<div class="notice notice-error is-dismissible"><p>' . __( 'SSL is required for Express Pay Checkout.', 'checkout-plugins-stripe-woo' ) . '</p></div>' );
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Generates admin notice for apple pay registration failure
|
266 |
+
*
|
267 |
+
* @return void
|
268 |
+
*/
|
269 |
+
public function apple_pay_verification_failed() {
|
270 |
+
/* translators: %1s - %3s HTML Entities, %4s Error Message */
|
271 |
+
echo wp_kses_post( '<div class="notice notice-warning is-dismissible"><p>' . sprintf( __( '%1$1sApple Pay domain verification failed. %2$2sReason%3$3s: %4$4s', 'checkout-plugins-stripe-woo' ), '<b>', '<br/>', '</b>', $this->failure_message ) . '</p></div>' );
|
272 |
+
}
|
273 |
+
|
274 |
+
/**
|
275 |
+
* Returns live secret key for apple pay Verification
|
276 |
+
*
|
277 |
+
* @param string $secret_key current secret key as per mode.
|
278 |
+
* @return string
|
279 |
+
*/
|
280 |
+
public function get_live_secret_key( $secret_key ) {
|
281 |
+
return $this->secret_key;
|
282 |
+
}
|
283 |
+
}
|
gateway/stripe/card-payments.php
CHANGED
@@ -15,14 +15,12 @@ use CPSW\Inc\Traits\Subscriptions;
|
|
15 |
use CPSW\Gateway\Abstract_Payment_Gateway;
|
16 |
use CPSW\Gateway\Stripe\Frontend_Scripts;
|
17 |
use CPSW\Gateway\Stripe\Stripe_Api;
|
18 |
-
use WC_Order;
|
19 |
use WC_AJAX;
|
20 |
use WC_HTTPS;
|
21 |
use WC_Payment_Tokens;
|
22 |
use WC_Payment_Token_CC;
|
23 |
use Exception;
|
24 |
use WP_Error;
|
25 |
-
|
26 |
/**
|
27 |
* Card_Payments
|
28 |
*
|
@@ -46,6 +44,13 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
46 |
* @var array
|
47 |
*/
|
48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
/**
|
50 |
* Constructor
|
51 |
*
|
@@ -54,9 +59,7 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
54 |
public function __construct() {
|
55 |
add_filter( 'woocommerce_payment_gateways', [ $this, 'add_gateway_class' ] );
|
56 |
|
57 |
-
$this->
|
58 |
-
$this->stripe_api = Stripe_Api::get_instance();
|
59 |
-
$this->method_title = __( 'Stripe Card Payments', 'checkout-plugins-stripe-woo' );
|
60 |
$this->method_description = __( 'Accepts payments via Credit/Debit Cards', 'checkout-plugins-stripe-woo' );
|
61 |
$this->has_fields = true;
|
62 |
$this->init_supports();
|
@@ -78,7 +81,8 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
78 |
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, [ $this, 'process_admin_options' ] );
|
79 |
add_filter( 'woocommerce_payment_successful_result', [ $this, 'modify_successful_payment_result' ], 999, 2 );
|
80 |
add_action( 'wc_ajax_cpsw_verify_payment_intent', [ $this, 'verify_intent' ] );
|
81 |
-
|
|
|
82 |
}
|
83 |
|
84 |
/**
|
@@ -208,7 +212,7 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
208 |
'allowed_cards' => [
|
209 |
'title' => __( 'Allowed Cards', 'checkout-plugins-stripe-woo' ),
|
210 |
'type' => 'multiselect',
|
211 |
-
'class' => '
|
212 |
'desc_tip' => __( 'Accepts payments using selected cards. If empty all stripe cards are accepted.', 'checkout-plugins-stripe-woo' ),
|
213 |
'options' => [
|
214 |
'mastercard' => 'MasterCard',
|
@@ -221,6 +225,20 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
221 |
],
|
222 |
'default' => [],
|
223 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
'order_button_text' => [
|
225 |
'title' => __( 'Order Button Label', 'checkout-plugins-stripe-woo' ),
|
226 |
'type' => 'text',
|
@@ -266,7 +284,7 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
266 |
$data['statement_descriptor'] = $this->statement_descriptor;
|
267 |
}
|
268 |
|
269 |
-
if (
|
270 |
$data['setup_future_usage'] = 'off_session';
|
271 |
}
|
272 |
|
@@ -316,7 +334,8 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
316 |
try {
|
317 |
$order = wc_get_order( $order_id );
|
318 |
$token = $this->get_token_from_request( $_POST ); //phpcs:ignore WordPress.Security.NonceVerification.Missing
|
319 |
-
$
|
|
|
320 |
$payment_method = $response['success'] ? $response['data'] : false;
|
321 |
$prepared_payment_method = $this->prepare_payment_method( $payment_method, $token );
|
322 |
|
@@ -339,7 +358,7 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
339 |
$request['statement_descriptor'] = $this->statement_descriptor;
|
340 |
}
|
341 |
|
342 |
-
$response = $this->
|
343 |
|
344 |
if ( $response['success'] ) {
|
345 |
$intent = $response['data'];
|
@@ -409,6 +428,18 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
409 |
}
|
410 |
}
|
411 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
412 |
/**
|
413 |
* Process payment method functionality
|
414 |
*
|
@@ -427,7 +458,8 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
427 |
$customer_id = $this->get_customer_id();
|
428 |
|
429 |
$source = ! empty( $_POST['payment_method_created'] ) ? wc_clean( wp_unslash( $_POST['payment_method_created'] ) ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Missing
|
430 |
-
$
|
|
|
431 |
$source_object = $response['success'] ? $response['data'] : false;
|
432 |
|
433 |
if ( isset( $source_object ) ) {
|
@@ -441,10 +473,11 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
441 |
|
442 |
$source_id = $source_object->id;
|
443 |
}
|
444 |
-
$
|
445 |
-
$response
|
446 |
-
$
|
447 |
-
$
|
|
|
448 |
$this->create_payment_token_for_user( $user_id, $source_object );
|
449 |
|
450 |
if ( ! $response || is_wp_error( $response ) || ! empty( $response->error ) ) {
|
@@ -512,12 +545,14 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
512 |
|
513 |
/* translators: transaction id */
|
514 |
$message = sprintf( __( 'Stripe charge complete (Charge ID: %s)', 'checkout-plugins-stripe-woo' ), $response->id );
|
|
|
515 |
$order->add_order_note( $message );
|
516 |
}
|
517 |
|
518 |
if ( 'failed' === $response->status ) {
|
519 |
-
$
|
520 |
-
|
|
|
521 |
}
|
522 |
} else {
|
523 |
$order->set_transaction_id( $response->id );
|
@@ -620,8 +655,9 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
620 |
$client_secret = '';
|
621 |
|
622 |
if ( ! empty( $intent_secret ) ) {
|
623 |
-
$secret
|
624 |
-
$
|
|
|
625 |
if ( $response['success'] && 'success' === $response['data']->status ) {
|
626 |
wc_add_notice( __( 'An error has occurred internally, due to which you are not redirected to the order received page.', 'checkout-plugins-stripe-woo' ), $notice_type = 'error' );
|
627 |
wp_safe_redirect( wc_get_checkout_url() );
|
@@ -633,7 +669,8 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
633 |
[ 'idempotency_key' => $idempotency_key ],
|
634 |
];
|
635 |
|
636 |
-
$
|
|
|
637 |
|
638 |
if ( $response['success'] ) {
|
639 |
$intent = $response['data'];
|
@@ -666,7 +703,8 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
666 |
$order = wc_get_order( $order_id );
|
667 |
|
668 |
$intent_secret = get_post_meta( $order_id, '_cpsw_intent_secret', true );
|
669 |
-
$
|
|
|
670 |
$intent = $response['success'] ? $response['data'] : false;
|
671 |
|
672 |
if ( 'succeeded' === $intent->status || 'requires_capture' === $intent->status ) {
|
@@ -674,14 +712,13 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
674 |
$user = $order->get_id() ? $order->get_user() : wp_get_current_user();
|
675 |
$user_id = $user->ID;
|
676 |
$payment_method = $intent->payment_method;
|
677 |
-
$response = $
|
678 |
$payment_method = $response['success'] ? $response['data'] : false;
|
679 |
$token = $this->create_payment_token_for_user( $user_id, $payment_method );
|
680 |
/* translators: %1$1s order id, %2$2s token id */
|
681 |
Logger::info( sprintf( __( 'Payment method tokenized for Order id - %1$1s with token id - %2$2s', 'checkout-plugins-stripe-woo' ), $order_id, $token->get_id() ) );
|
682 |
$prepared_payment_method = $this->prepare_payment_method( $payment_method, $token );
|
683 |
$this->save_payment_method_to_order( $order, $prepared_payment_method );
|
684 |
-
|
685 |
}
|
686 |
$redirect_to = $this->process_order( end( $intent->charges->data ), $order_id );
|
687 |
$redirect_url = apply_filters( 'cpsw_redirect_order_url', ! empty( $redirect ) ? $redirect : $redirect_to, $order );
|
@@ -836,8 +873,9 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
836 |
];
|
837 |
}
|
838 |
|
839 |
-
$
|
840 |
-
$response
|
|
|
841 |
|
842 |
if ( empty( $response->id ) ) {
|
843 |
return false;
|
@@ -855,40 +893,18 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
855 |
* @return bool
|
856 |
*/
|
857 |
public function process_refund( $order_id, $amount = null, $reason = '' ) {
|
858 |
-
$client = $this->get_clients_details();
|
859 |
|
860 |
if ( 0 >= $amount ) {
|
861 |
return false;
|
862 |
}
|
863 |
|
864 |
try {
|
865 |
-
$intent_secret = get_post_meta( $order_id, '_cpsw_intent_secret', true );
|
866 |
-
$response = $this->stripe_api->payment_intents( 'retrieve', [ $intent_secret['id'] ] );
|
867 |
-
$status = $response['success'] ? $response['data']->charges->data[0]->captured : false;
|
868 |
|
869 |
-
|
870 |
-
|
871 |
-
return new WP_Error( 'error', __( 'Uncaptured Amount cannot be refunded', 'checkout-plugins-stripe-woo' ) );
|
872 |
-
}
|
873 |
|
874 |
-
$
|
875 |
-
$order = wc_get_order( $order_id );
|
876 |
-
$currency = $intent_response->currency;
|
877 |
-
|
878 |
-
$refund_params = [
|
879 |
-
'payment_intent' => $intent_secret['id'],
|
880 |
-
'amount' => $this->get_formatted_amount( $amount, $currency ),
|
881 |
-
'reason' => 'requested_by_customer',
|
882 |
-
'metadata' => [
|
883 |
-
'order_id' => $order->get_order_number(),
|
884 |
-
'Customer IP' => $client['IP'],
|
885 |
-
'Agent' => $client['Agent'],
|
886 |
-
'Referer' => $client['Referer'],
|
887 |
-
'Reason for Refund' => $reason,
|
888 |
-
],
|
889 |
-
];
|
890 |
|
891 |
-
$response = $this->stripe_api->refunds( 'create', [ $refund_params ] );
|
892 |
$refund_response = $response['success'] ? $response['data'] : false;
|
893 |
|
894 |
if ( $refund_response ) {
|
@@ -898,14 +914,57 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
898 |
return true;
|
899 |
} else {
|
900 |
$order->add_order_note( __( 'Reason : ', 'checkout-plugins-stripe-woo' ) . $reason . '.<br>' . __( 'Amount : ', 'checkout-plugins-stripe-woo' ) . get_woocommerce_currency_symbol() . $amount . '.<br>' . __( ' Status : Failed ', 'checkout-plugins-stripe-woo' ) );
|
901 |
-
Logger::error( $
|
902 |
-
return new WP_Error( 'error', $
|
903 |
}
|
904 |
} catch ( Exception $e ) {
|
905 |
Logger::error( $e->getMessage(), true );
|
906 |
}
|
907 |
}
|
908 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
909 |
/**
|
910 |
* Get stripe activated payment cards icon.
|
911 |
*/
|
@@ -1054,5 +1113,73 @@ class Card_Payments extends Abstract_Payment_Gateway {
|
|
1054 |
return $customer->id;
|
1055 |
}
|
1056 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1057 |
}
|
1058 |
|
15 |
use CPSW\Gateway\Abstract_Payment_Gateway;
|
16 |
use CPSW\Gateway\Stripe\Frontend_Scripts;
|
17 |
use CPSW\Gateway\Stripe\Stripe_Api;
|
|
|
18 |
use WC_AJAX;
|
19 |
use WC_HTTPS;
|
20 |
use WC_Payment_Tokens;
|
21 |
use WC_Payment_Token_CC;
|
22 |
use Exception;
|
23 |
use WP_Error;
|
|
|
24 |
/**
|
25 |
* Card_Payments
|
26 |
*
|
44 |
* @var array
|
45 |
*/
|
46 |
|
47 |
+
/**
|
48 |
+
* Gateway id
|
49 |
+
*
|
50 |
+
* @var string
|
51 |
+
*/
|
52 |
+
public $id = 'cpsw_stripe';
|
53 |
+
|
54 |
/**
|
55 |
* Constructor
|
56 |
*
|
59 |
public function __construct() {
|
60 |
add_filter( 'woocommerce_payment_gateways', [ $this, 'add_gateway_class' ] );
|
61 |
|
62 |
+
$this->method_title = __( 'Stripe Card Processing', 'checkout-plugins-stripe-woo' );
|
|
|
|
|
63 |
$this->method_description = __( 'Accepts payments via Credit/Debit Cards', 'checkout-plugins-stripe-woo' );
|
64 |
$this->has_fields = true;
|
65 |
$this->init_supports();
|
81 |
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, [ $this, 'process_admin_options' ] );
|
82 |
add_filter( 'woocommerce_payment_successful_result', [ $this, 'modify_successful_payment_result' ], 999, 2 );
|
83 |
add_action( 'wc_ajax_cpsw_verify_payment_intent', [ $this, 'verify_intent' ] );
|
84 |
+
add_filter( 'woocommerce_payment_complete_order_status', [ $this, 'cpsw_payment_complete_order_status' ], 10, 3 );
|
85 |
+
|
86 |
}
|
87 |
|
88 |
/**
|
212 |
'allowed_cards' => [
|
213 |
'title' => __( 'Allowed Cards', 'checkout-plugins-stripe-woo' ),
|
214 |
'type' => 'multiselect',
|
215 |
+
'class' => 'cpsw_select_woo',
|
216 |
'desc_tip' => __( 'Accepts payments using selected cards. If empty all stripe cards are accepted.', 'checkout-plugins-stripe-woo' ),
|
217 |
'options' => [
|
218 |
'mastercard' => 'MasterCard',
|
225 |
],
|
226 |
'default' => [],
|
227 |
],
|
228 |
+
'order_status' => [
|
229 |
+
'type' => 'select',
|
230 |
+
'title' => __( 'Order Status', 'checkout-plugins-stripe-woo' ),
|
231 |
+
'class' => 'cpsw_select_woo',
|
232 |
+
'options' => [
|
233 |
+
'' => __( 'Default', 'checkout-plugins-stripe-woo' ),
|
234 |
+
'wc-processing' => __( 'Processing', 'checkout-plugins-stripe-woo' ),
|
235 |
+
'wc-on-hold' => __( 'On Hold', 'checkout-plugins-stripe-woo' ),
|
236 |
+
'wc-completed' => __( 'Completed', 'checkout-plugins-stripe-woo' ),
|
237 |
+
],
|
238 |
+
'default' => '',
|
239 |
+
'tool_tip' => true,
|
240 |
+
'description' => __( 'This is the status of the order once payment is complete. If <b>Default</b> is selected, then WooCommerce will set the order status automatically based on internal logic which states if a product is virtual and downloadable then status is set to complete. Products that require shipping are set to Processing. Default is the recommended setting as it allows standard WooCommerce code to process the order status.', 'checkout-plugins-stripe-woo' ),
|
241 |
+
],
|
242 |
'order_button_text' => [
|
243 |
'title' => __( 'Order Button Label', 'checkout-plugins-stripe-woo' ),
|
244 |
'type' => 'text',
|
284 |
$data['statement_descriptor'] = $this->statement_descriptor;
|
285 |
}
|
286 |
|
287 |
+
if ( $this->should_save_card( $order_id ) ) {
|
288 |
$data['setup_future_usage'] = 'off_session';
|
289 |
}
|
290 |
|
334 |
try {
|
335 |
$order = wc_get_order( $order_id );
|
336 |
$token = $this->get_token_from_request( $_POST ); //phpcs:ignore WordPress.Security.NonceVerification.Missing
|
337 |
+
$stripe_api = new Stripe_Api();
|
338 |
+
$response = $stripe_api->payment_methods( 'retrieve', [ $token->get_token() ] );
|
339 |
$payment_method = $response['success'] ? $response['data'] : false;
|
340 |
$prepared_payment_method = $this->prepare_payment_method( $payment_method, $token );
|
341 |
|
358 |
$request['statement_descriptor'] = $this->statement_descriptor;
|
359 |
}
|
360 |
|
361 |
+
$response = $this->create_payment_for_saved_payment_method( $request );
|
362 |
|
363 |
if ( $response['success'] ) {
|
364 |
$intent = $response['data'];
|
428 |
}
|
429 |
}
|
430 |
|
431 |
+
/**
|
432 |
+
* Create payment for saved payment method.
|
433 |
+
*
|
434 |
+
* @param array $request_args arguments.
|
435 |
+
*
|
436 |
+
* @return array
|
437 |
+
*/
|
438 |
+
public function create_payment_for_saved_payment_method( $request_args ) {
|
439 |
+
$stripe_api = new Stripe_Api();
|
440 |
+
return $stripe_api->payment_intents( 'create', [ $request_args ] );
|
441 |
+
}
|
442 |
+
|
443 |
/**
|
444 |
* Process payment method functionality
|
445 |
*
|
458 |
$customer_id = $this->get_customer_id();
|
459 |
|
460 |
$source = ! empty( $_POST['payment_method_created'] ) ? wc_clean( wp_unslash( $_POST['payment_method_created'] ) ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Missing
|
461 |
+
$stripe_api = new Stripe_Api();
|
462 |
+
$response = $stripe_api->payment_methods( 'retrieve', [ $source ] );
|
463 |
$source_object = $response['success'] ? $response['data'] : false;
|
464 |
|
465 |
if ( isset( $source_object ) ) {
|
473 |
|
474 |
$source_id = $source_object->id;
|
475 |
}
|
476 |
+
$stripe_api = new Stripe_Api();
|
477 |
+
$response = $stripe_api->payment_methods( 'attach', [ $source_id, [ 'customer' => $customer_id ] ] );
|
478 |
+
$response = $response['success'] ? $response['data'] : false;
|
479 |
+
$user = wp_get_current_user();
|
480 |
+
$user_id = ( $user->ID && $user->ID > 0 ) ? $user->ID : false;
|
481 |
$this->create_payment_token_for_user( $user_id, $source_object );
|
482 |
|
483 |
if ( ! $response || is_wp_error( $response ) || ! empty( $response->error ) ) {
|
545 |
|
546 |
/* translators: transaction id */
|
547 |
$message = sprintf( __( 'Stripe charge complete (Charge ID: %s)', 'checkout-plugins-stripe-woo' ), $response->id );
|
548 |
+
Logger::info( $message, true );
|
549 |
$order->add_order_note( $message );
|
550 |
}
|
551 |
|
552 |
if ( 'failed' === $response->status ) {
|
553 |
+
$message = __( 'Payment processing failed. Please retry.', 'checkout-plugins-stripe-woo' );
|
554 |
+
Logger::error( $message, true );
|
555 |
+
$order->add_order_note( $message );
|
556 |
}
|
557 |
} else {
|
558 |
$order->set_transaction_id( $response->id );
|
655 |
$client_secret = '';
|
656 |
|
657 |
if ( ! empty( $intent_secret ) ) {
|
658 |
+
$secret = $intent_secret;
|
659 |
+
$stripe_api = new Stripe_Api();
|
660 |
+
$response = $stripe_api->payment_intents( 'retrieve', [ $secret['id'] ] );
|
661 |
if ( $response['success'] && 'success' === $response['data']->status ) {
|
662 |
wc_add_notice( __( 'An error has occurred internally, due to which you are not redirected to the order received page.', 'checkout-plugins-stripe-woo' ), $notice_type = 'error' );
|
663 |
wp_safe_redirect( wc_get_checkout_url() );
|
669 |
[ 'idempotency_key' => $idempotency_key ],
|
670 |
];
|
671 |
|
672 |
+
$stripe_api = new Stripe_Api();
|
673 |
+
$response = $stripe_api->payment_intents( 'create', $args );
|
674 |
|
675 |
if ( $response['success'] ) {
|
676 |
$intent = $response['data'];
|
703 |
$order = wc_get_order( $order_id );
|
704 |
|
705 |
$intent_secret = get_post_meta( $order_id, '_cpsw_intent_secret', true );
|
706 |
+
$stripe_api = new Stripe_Api();
|
707 |
+
$response = $stripe_api->payment_intents( 'retrieve', [ $intent_secret['id'] ] );
|
708 |
$intent = $response['success'] ? $response['data'] : false;
|
709 |
|
710 |
if ( 'succeeded' === $intent->status || 'requires_capture' === $intent->status ) {
|
712 |
$user = $order->get_id() ? $order->get_user() : wp_get_current_user();
|
713 |
$user_id = $user->ID;
|
714 |
$payment_method = $intent->payment_method;
|
715 |
+
$response = $stripe_api->payment_methods( 'retrieve', [ $payment_method ] );
|
716 |
$payment_method = $response['success'] ? $response['data'] : false;
|
717 |
$token = $this->create_payment_token_for_user( $user_id, $payment_method );
|
718 |
/* translators: %1$1s order id, %2$2s token id */
|
719 |
Logger::info( sprintf( __( 'Payment method tokenized for Order id - %1$1s with token id - %2$2s', 'checkout-plugins-stripe-woo' ), $order_id, $token->get_id() ) );
|
720 |
$prepared_payment_method = $this->prepare_payment_method( $payment_method, $token );
|
721 |
$this->save_payment_method_to_order( $order, $prepared_payment_method );
|
|
|
722 |
}
|
723 |
$redirect_to = $this->process_order( end( $intent->charges->data ), $order_id );
|
724 |
$redirect_url = apply_filters( 'cpsw_redirect_order_url', ! empty( $redirect ) ? $redirect : $redirect_to, $order );
|
873 |
];
|
874 |
}
|
875 |
|
876 |
+
$stripe_api = new Stripe_Api();
|
877 |
+
$response = $stripe_api->customers( 'create', [ $args ] );
|
878 |
+
$response = $response['success'] ? $response['data'] : false;
|
879 |
|
880 |
if ( empty( $response->id ) ) {
|
881 |
return false;
|
893 |
* @return bool
|
894 |
*/
|
895 |
public function process_refund( $order_id, $amount = null, $reason = '' ) {
|
|
|
896 |
|
897 |
if ( 0 >= $amount ) {
|
898 |
return false;
|
899 |
}
|
900 |
|
901 |
try {
|
|
|
|
|
|
|
902 |
|
903 |
+
$order = wc_get_order( $order_id );
|
904 |
+
$intent_secret = $order->get_meta( '_cpsw_intent_secret', true );
|
|
|
|
|
905 |
|
906 |
+
$response = $this->create_refund_request( $order, $amount, $reason, $intent_secret['id'] );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
907 |
|
|
|
908 |
$refund_response = $response['success'] ? $response['data'] : false;
|
909 |
|
910 |
if ( $refund_response ) {
|
914 |
return true;
|
915 |
} else {
|
916 |
$order->add_order_note( __( 'Reason : ', 'checkout-plugins-stripe-woo' ) . $reason . '.<br>' . __( 'Amount : ', 'checkout-plugins-stripe-woo' ) . get_woocommerce_currency_symbol() . $amount . '.<br>' . __( ' Status : Failed ', 'checkout-plugins-stripe-woo' ) );
|
917 |
+
Logger::error( $response['message'], true );
|
918 |
+
return new WP_Error( 'error', $response['message'] );
|
919 |
}
|
920 |
} catch ( Exception $e ) {
|
921 |
Logger::error( $e->getMessage(), true );
|
922 |
}
|
923 |
}
|
924 |
|
925 |
+
/**
|
926 |
+
* Create refund request.
|
927 |
+
*
|
928 |
+
* @param object $order order.
|
929 |
+
* @param string $amount refund amount.
|
930 |
+
* @param string $reason reason of refund.
|
931 |
+
* @param string $intent_secret_id secret key.
|
932 |
+
*
|
933 |
+
* @return array
|
934 |
+
*/
|
935 |
+
public function create_refund_request( $order, $amount, $reason, $intent_secret_id ) {
|
936 |
+
|
937 |
+
$client = $this->get_clients_details();
|
938 |
+
|
939 |
+
$stripe_api = new Stripe_Api();
|
940 |
+
$response = $stripe_api->payment_intents( 'retrieve', [ $intent_secret_id ] );
|
941 |
+
$status = $response['success'] ? $response['data']->charges->data[0]->captured : false;
|
942 |
+
|
943 |
+
if ( ! $status ) {
|
944 |
+
Logger::error( __( 'Uncaptured Amount cannot be refunded', 'checkout-plugins-stripe-woo' ), true );
|
945 |
+
return new WP_Error( 'error', __( 'Uncaptured Amount cannot be refunded', 'checkout-plugins-stripe-woo' ) );
|
946 |
+
}
|
947 |
+
|
948 |
+
$intent_response = $response['data'];
|
949 |
+
$currency = $intent_response->currency;
|
950 |
+
|
951 |
+
$refund_params = [
|
952 |
+
'payment_intent' => $intent_secret_id,
|
953 |
+
'amount' => $this->get_formatted_amount( $amount, $currency ),
|
954 |
+
'reason' => 'requested_by_customer',
|
955 |
+
'metadata' => [
|
956 |
+
'order_id' => $order->get_order_number(),
|
957 |
+
'Customer IP' => $client['IP'],
|
958 |
+
'Agent' => $client['Agent'],
|
959 |
+
'Referer' => $client['Referer'],
|
960 |
+
'Reason for Refund' => $reason,
|
961 |
+
],
|
962 |
+
];
|
963 |
+
|
964 |
+
$stripe_api = new Stripe_Api();
|
965 |
+
return $stripe_api->refunds( 'create', [ $refund_params ] );
|
966 |
+
}
|
967 |
+
|
968 |
/**
|
969 |
* Get stripe activated payment cards icon.
|
970 |
*/
|
1113 |
return $customer->id;
|
1114 |
}
|
1115 |
}
|
1116 |
+
|
1117 |
+
/**
|
1118 |
+
* Updates order status as per option 'order_status' set in card payment settings
|
1119 |
+
*
|
1120 |
+
* @param string $order_status default order status.
|
1121 |
+
* @param id $order_id current order id.
|
1122 |
+
* @param WC_Order $order current order.
|
1123 |
+
* @return string
|
1124 |
+
*/
|
1125 |
+
public function cpsw_payment_complete_order_status( $order_status, $order_id, $order = null ) {
|
1126 |
+
if ( $order && $order->get_payment_method() ) {
|
1127 |
+
$gateway = $order->get_payment_method();
|
1128 |
+
if ( 'cpsw_stripe' === $gateway && ! empty( $this->get_option( 'order_status' ) ) ) {
|
1129 |
+
$order_status = $this->get_option( 'order_status' );
|
1130 |
+
}
|
1131 |
+
}
|
1132 |
+
|
1133 |
+
return apply_filters( 'cpsw_payment_complete_order_status', $order_status );
|
1134 |
+
}
|
1135 |
+
|
1136 |
+
/**
|
1137 |
+
* Checks whether current page is a product pare or not
|
1138 |
+
*
|
1139 |
+
* @return boolean
|
1140 |
+
*/
|
1141 |
+
public function is_product() {
|
1142 |
+
return is_product() || wc_post_content_has_shortcode( 'product_page' );
|
1143 |
+
}
|
1144 |
+
|
1145 |
+
/**
|
1146 |
+
* Prepare Sorce for current order
|
1147 |
+
*
|
1148 |
+
* @param WC_Order $order Current order.
|
1149 |
+
* @return object
|
1150 |
+
*/
|
1151 |
+
public function prepare_order_source( $order = null ) {
|
1152 |
+
$stripe_customer = false;
|
1153 |
+
$stripe_source = false;
|
1154 |
+
$source_object = false;
|
1155 |
+
|
1156 |
+
if ( $order ) {
|
1157 |
+
|
1158 |
+
$stripe_customer_id = $this->get_cpsw_customer_id( $order );
|
1159 |
+
|
1160 |
+
if ( $stripe_customer_id ) {
|
1161 |
+
|
1162 |
+
$stripe_customer = [];
|
1163 |
+
$stripe_customer['id'] = $stripe_customer_id;
|
1164 |
+
}
|
1165 |
+
|
1166 |
+
$source_id = $order->get_meta( '_cpsw_source_id', true );
|
1167 |
+
|
1168 |
+
if ( $source_id ) {
|
1169 |
+
$stripe_source = $source_id;
|
1170 |
+
$stripe_api = new Stripe_Api();
|
1171 |
+
$response = $stripe_api->payment_methods( 'retrieve', [ $stripe_source ] );
|
1172 |
+
$source_object = $response['success'] ? $response['data'] : false;
|
1173 |
+
} elseif ( apply_filters( 'cpsw_use_default_customer_source', true ) ) {
|
1174 |
+
$stripe_source = '';
|
1175 |
+
}
|
1176 |
+
}
|
1177 |
+
|
1178 |
+
return (object) [
|
1179 |
+
'customer' => $stripe_customer ? $stripe_customer['id'] : false,
|
1180 |
+
'source' => $stripe_source,
|
1181 |
+
'source_object' => $source_object,
|
1182 |
+
];
|
1183 |
+
}
|
1184 |
}
|
1185 |
|
gateway/stripe/frontend-scripts.php
CHANGED
@@ -10,6 +10,7 @@ namespace CPSW\Gateway\Stripe;
|
|
10 |
|
11 |
use CPSW\Inc\Traits\Get_Instance;
|
12 |
use CPSW\Inc\Helper;
|
|
|
13 |
|
14 |
/**
|
15 |
* Consists frontend scripts for payment gateways
|
@@ -47,9 +48,15 @@ class Frontend_Scripts {
|
|
47 |
public function enqueue_scripts() {
|
48 |
|
49 |
$public_key = ( 'live' === Helper::get_payment_mode() ) ? Helper::get_setting( 'cpsw_pub_key' ) : Helper::get_setting( 'cpsw_test_pub_key' );
|
50 |
-
|
51 |
-
wp_enqueue_script( $this->prefix . 'stripe-
|
52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
wp_localize_script(
|
54 |
$this->prefix . 'stripe-elements',
|
55 |
'cpsw_global_settings',
|
@@ -73,5 +80,48 @@ class Frontend_Scripts {
|
|
73 |
'not_allowed_string' => __( 'is not allowed', 'checkout-plugins-stripe-woo' ),
|
74 |
]
|
75 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
}
|
77 |
}
|
10 |
|
11 |
use CPSW\Inc\Traits\Get_Instance;
|
12 |
use CPSW\Inc\Helper;
|
13 |
+
use WC_AJAX;
|
14 |
|
15 |
/**
|
16 |
* Consists frontend scripts for payment gateways
|
48 |
public function enqueue_scripts() {
|
49 |
|
50 |
$public_key = ( 'live' === Helper::get_payment_mode() ) ? Helper::get_setting( 'cpsw_pub_key' ) : Helper::get_setting( 'cpsw_test_pub_key' );
|
51 |
+
wp_register_script( $this->prefix . 'stripe-external', 'https://js.stripe.com/v3/', [], CPSW_VERSION, true );
|
52 |
+
wp_enqueue_script( $this->prefix . 'stripe-external' );
|
53 |
+
|
54 |
+
wp_register_script( $this->prefix . 'stripe-elements', $this->assets_url . 'js/stripe-elements.js', [ 'jquery', $this->prefix . 'stripe-external' ], CPSW_VERSION, true );
|
55 |
+
wp_enqueue_script( $this->prefix . 'stripe-elements' );
|
56 |
+
|
57 |
+
wp_register_style( $this->prefix . 'stripe-elements', $this->assets_url . 'css/stripe-elements.css', [], CPSW_VERSION );
|
58 |
+
wp_enqueue_style( $this->prefix . 'stripe-elements' );
|
59 |
+
|
60 |
wp_localize_script(
|
61 |
$this->prefix . 'stripe-elements',
|
62 |
'cpsw_global_settings',
|
80 |
'not_allowed_string' => __( 'is not allowed', 'checkout-plugins-stripe-woo' ),
|
81 |
]
|
82 |
);
|
83 |
+
|
84 |
+
if ( 'yes' === Helper::get_setting( 'express_checkout_enabled', 'cpsw_stripe' ) ) {
|
85 |
+
wp_register_script( $this->prefix . 'payment-request', $this->assets_url . 'js/payment-request.js', [ 'jquery', $this->prefix . 'stripe-external', $this->prefix . 'stripe-elements' ], CPSW_VERSION, true );
|
86 |
+
wp_enqueue_script( $this->prefix . 'payment-request' );
|
87 |
+
|
88 |
+
$needs_shipping = false;
|
89 |
+
if ( ! is_null( WC()->cart ) && WC()->cart->needs_shipping() ) {
|
90 |
+
$needs_shipping = true;
|
91 |
+
}
|
92 |
+
|
93 |
+
wp_localize_script(
|
94 |
+
$this->prefix . 'payment-request',
|
95 |
+
'cpsw_payment_request',
|
96 |
+
apply_filters(
|
97 |
+
'cpsw_payment_request_localization',
|
98 |
+
[
|
99 |
+
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
100 |
+
'ajax_endpoint' => WC_AJAX::get_endpoint( '%%endpoint%%' ),
|
101 |
+
'public_key' => $public_key,
|
102 |
+
'mode' => Helper::get_payment_mode(),
|
103 |
+
'currency_code' => strtolower( get_woocommerce_currency() ),
|
104 |
+
'country_code' => substr( get_option( 'woocommerce_default_country' ), 0, 2 ),
|
105 |
+
'needs_shipping' => $needs_shipping,
|
106 |
+
'phone_required' => 'required' === get_option( 'woocommerce_checkout_phone_field', 'required' ),
|
107 |
+
'nonce' => [
|
108 |
+
'checkout' => wp_create_nonce( 'cpsw_checkout' ),
|
109 |
+
'payment' => wp_create_nonce( 'cpsw_payment_request' ),
|
110 |
+
'add_to_cart' => wp_create_nonce( 'cpsw_add_to_cart' ),
|
111 |
+
'selected_product_data' => wp_create_nonce( 'cpsw_selected_product_data' ),
|
112 |
+
'shipping' => wp_create_nonce( 'cpsw_shipping_address' ),
|
113 |
+
'shipping_option' => wp_create_nonce( 'cpsw_shipping_option' ),
|
114 |
+
'js_nonce' => wp_create_nonce( 'cpsw_js_error_nonce' ),
|
115 |
+
],
|
116 |
+
'style' => [
|
117 |
+
'type' => Helper::get_setting( 'express_checkout_button_type', 'cpsw_stripe' ),
|
118 |
+
'theme' => Helper::get_setting( 'express_checkout_button_theme', 'cpsw_stripe' ),
|
119 |
+
'height' => (int) Helper::get_setting( 'express_checkout_button_height', 'cpsw_stripe' ),
|
120 |
+
],
|
121 |
+
'is_product_page' => is_product() || wc_post_content_has_shortcode( 'product_page' ),
|
122 |
+
]
|
123 |
+
)
|
124 |
+
);
|
125 |
+
}
|
126 |
}
|
127 |
}
|
gateway/stripe/payment-request-api.php
ADDED
@@ -0,0 +1,869 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Stripe Gateway
|
4 |
+
*
|
5 |
+
* @package checkout-plugins-stripe-woo
|
6 |
+
* @since 1.1.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
namespace CPSW\Gateway\Stripe;
|
10 |
+
|
11 |
+
use CPSW\Gateway\Stripe\Card_Payments;
|
12 |
+
use CPSW\Inc\Helper;
|
13 |
+
use CPSW\Inc\Traits\Get_Instance;
|
14 |
+
use WC_Data_Store;
|
15 |
+
use WC_Subscriptions_Product;
|
16 |
+
use WC_Validation;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Payment Request Api.
|
20 |
+
*/
|
21 |
+
class Payment_Request_Api extends Card_Payments {
|
22 |
+
|
23 |
+
use Get_Instance;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Constructor
|
27 |
+
*/
|
28 |
+
public function __construct() {
|
29 |
+
$settings = Helper::get_gateway_settings();
|
30 |
+
$this->express_checkout = $settings['express_checkout_enabled'];
|
31 |
+
if ( 'yes' !== $this->express_checkout || 'yes' !== $settings['enabled'] ) {
|
32 |
+
return;
|
33 |
+
}
|
34 |
+
$this->statement_descriptor = $this->clean_statement_descriptor( $this->get_option( 'statement_descriptor' ) );
|
35 |
+
|
36 |
+
$this->capture_method = Helper::get_setting( 'charge_type', 'cpsw_stripe' );
|
37 |
+
|
38 |
+
if ( 'above' === Helper::get_setting( 'express_checkout_product_page_position', 'cpsw_stripe' ) ) {
|
39 |
+
add_action( 'woocommerce_after_add_to_cart_quantity', [ $this, 'payment_request_button' ], 10 );
|
40 |
+
} else {
|
41 |
+
add_action( 'woocommerce_after_add_to_cart_button', [ $this, 'payment_request_button' ], 1 );
|
42 |
+
}
|
43 |
+
|
44 |
+
add_action( 'woocommerce_proceed_to_checkout', [ $this, 'payment_request_button' ], 1 );
|
45 |
+
|
46 |
+
add_action( 'woocommerce_checkout_before_customer_details', [ $this, 'payment_request_button' ], 5 );
|
47 |
+
|
48 |
+
add_filter( 'cpsw_payment_request_localization', [ $this, 'localize_product_data' ] );
|
49 |
+
|
50 |
+
add_action( 'wc_ajax_cpsw_payment_request_checkout', [ $this, 'ajax_checkout' ] );
|
51 |
+
add_action( 'wc_ajax_cpsw_get_cart_details', [ $this, 'ajax_get_cart_details' ] );
|
52 |
+
add_action( 'wc_ajax_cpsw_add_to_cart', [ $this, 'ajax_add_to_cart' ] );
|
53 |
+
add_action( 'wc_ajax_cpsw_selected_product_data', [ $this, 'ajax_selected_product_data' ] );
|
54 |
+
add_action( 'wc_ajax_cpsw_update_shipping_address', [ $this, 'ajax_update_shipping_address' ] );
|
55 |
+
add_action( 'wc_ajax_cpsw_update_shipping_option', [ $this, 'ajax_update_shipping_option' ] );
|
56 |
+
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Checks wheter current page is supported for express checkout
|
61 |
+
*
|
62 |
+
* @return boolean
|
63 |
+
*/
|
64 |
+
private function is_page_supported() {
|
65 |
+
return $this->is_product()
|
66 |
+
|| is_cart()
|
67 |
+
|| is_checkout()
|
68 |
+
|| isset( $_GET['pay_for_order'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Checks if current location is chosen to display express checkout button
|
73 |
+
*
|
74 |
+
* @return boolean
|
75 |
+
*/
|
76 |
+
private function is_selected_location() {
|
77 |
+
$location = Helper::get_setting( 'express_checkout_location', 'cpsw_stripe' );
|
78 |
+
if ( is_array( $location ) ) {
|
79 |
+
if ( empty( $location ) ) {
|
80 |
+
return true;
|
81 |
+
}
|
82 |
+
|
83 |
+
if ( $this->is_product() && in_array( 'product', $location, true ) ) {
|
84 |
+
return true;
|
85 |
+
}
|
86 |
+
|
87 |
+
if ( is_cart() && in_array( 'cart', $location, true ) ) {
|
88 |
+
return true;
|
89 |
+
}
|
90 |
+
|
91 |
+
if ( is_checkout() && in_array( 'checkout', $location, true ) ) {
|
92 |
+
return true;
|
93 |
+
}
|
94 |
+
}
|
95 |
+
|
96 |
+
return false;
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Creates container for payment request button
|
101 |
+
*
|
102 |
+
* @return void
|
103 |
+
*/
|
104 |
+
public function payment_request_button() {
|
105 |
+
$gateways = WC()->payment_gateways->get_available_payment_gateways();
|
106 |
+
|
107 |
+
if ( ! isset( $gateways['cpsw_stripe'] ) ) {
|
108 |
+
return;
|
109 |
+
}
|
110 |
+
|
111 |
+
if ( ! $this->is_page_supported() ) {
|
112 |
+
return;
|
113 |
+
}
|
114 |
+
|
115 |
+
if ( ! $this->is_selected_location() ) {
|
116 |
+
return;
|
117 |
+
}
|
118 |
+
|
119 |
+
if ( 'yes' === $this->express_checkout ) {
|
120 |
+
$container_class = '';
|
121 |
+
if ( $this->is_product() ) {
|
122 |
+
$container_class = 'product';
|
123 |
+
} elseif ( is_checkout() ) {
|
124 |
+
$container_class = 'checkout';
|
125 |
+
} elseif ( is_cart() ) {
|
126 |
+
$container_class = 'cart';
|
127 |
+
}
|
128 |
+
|
129 |
+
$separator_below = true;
|
130 |
+
$position_class = 'above';
|
131 |
+
|
132 |
+
if ( 'below' === Helper::get_setting( 'express_checkout_product_page_position', 'cpsw_stripe' ) && 'product' === $container_class ) {
|
133 |
+
$this->payment_request_button_separator();
|
134 |
+
$separator_below = false;
|
135 |
+
$position_class = 'below';
|
136 |
+
}
|
137 |
+
|
138 |
+
$options = Helper::get_gateway_settings( 'cpsw_stripe' );
|
139 |
+
|
140 |
+
$alignment_class = '';
|
141 |
+
$button_width = '';
|
142 |
+
|
143 |
+
if ( 'checkout' === $container_class ) {
|
144 |
+
if ( 'yes' === $options['express_checkout_product_checkout_page'] ) {
|
145 |
+
$alignment_class = $options['express_checkout_button_alignment'];
|
146 |
+
if ( ! empty( $options['express_checkout_button_width'] && $options['express_checkout_button_width'] > 0 ) ) {
|
147 |
+
$button_width = 'width:' . (int) $options['express_checkout_button_width'] . 'px';
|
148 |
+
}
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
if ( 'product' === $container_class ) {
|
153 |
+
if ( 'yes' === $options['express_checkout_product_sticky_footer'] ) {
|
154 |
+
$container_class .= ' sticky';
|
155 |
+
}
|
156 |
+
}
|
157 |
+
|
158 |
+
?>
|
159 |
+
<div id="cpsw-payment-request-wrapper" class="<?php echo esc_attr( $container_class . ' ' . $position_class . ' ' . $alignment_class ); ?>">
|
160 |
+
<div class="cpsw-payment-request-button-wrapper">
|
161 |
+
<?php
|
162 |
+
if ( ! empty( trim( $options['express_checkout_title'] ) && 'yes' === $options['express_checkout_product_checkout_page'] ) ) {
|
163 |
+
?>
|
164 |
+
<h3 id="cpsw-payment-request-title"><?php echo esc_html( Helper::get_setting( 'express_checkout_title', 'cpsw_stripe' ) ); ?></h3>
|
165 |
+
<?php
|
166 |
+
}
|
167 |
+
if ( ! empty( trim( $options['express_checkout_tagline'] ) && 'yes' === $options['express_checkout_product_checkout_page'] ) ) {
|
168 |
+
?>
|
169 |
+
<p id="cpsw-payment-request-tagline"><?php echo wp_kses_post( Helper::get_setting( 'express_checkout_tagline', 'cpsw_stripe' ) ); ?></p>
|
170 |
+
<?php
|
171 |
+
}
|
172 |
+
?>
|
173 |
+
|
174 |
+
<div id="cpsw-payment-request-button" style="<?php echo esc_html( $button_width ); ?>">
|
175 |
+
<!-- A Stripe Element will be inserted here. -->
|
176 |
+
</div>
|
177 |
+
</div>
|
178 |
+
<?php
|
179 |
+
if ( $separator_below ) {
|
180 |
+
$this->payment_request_button_separator();
|
181 |
+
}
|
182 |
+
?>
|
183 |
+
</div>
|
184 |
+
<?php
|
185 |
+
}
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Creates separator for payment request button
|
190 |
+
*
|
191 |
+
* @return void
|
192 |
+
*/
|
193 |
+
public function payment_request_button_separator() {
|
194 |
+
$gateways = WC()->payment_gateways->get_available_payment_gateways();
|
195 |
+
|
196 |
+
if ( ! isset( $gateways['cpsw_stripe'] ) ) {
|
197 |
+
return;
|
198 |
+
}
|
199 |
+
|
200 |
+
if ( ! $this->is_page_supported() ) {
|
201 |
+
return;
|
202 |
+
}
|
203 |
+
|
204 |
+
if ( ! $this->is_selected_location() ) {
|
205 |
+
return;
|
206 |
+
}
|
207 |
+
|
208 |
+
if ( 'yes' === $this->express_checkout ) {
|
209 |
+
$container_class = '';
|
210 |
+
if ( $this->is_product() ) {
|
211 |
+
$container_class = 'product';
|
212 |
+
} elseif ( is_checkout() ) {
|
213 |
+
$container_class = 'checkout';
|
214 |
+
} elseif ( is_cart() ) {
|
215 |
+
$container_class = 'cart';
|
216 |
+
}
|
217 |
+
|
218 |
+
$options = Helper::get_gateway_settings( 'cpsw_stripe' );
|
219 |
+
|
220 |
+
$alignment_class = '';
|
221 |
+
$separator_text = $options['express_checkout_separator'];
|
222 |
+
|
223 |
+
if ( 'checkout' === $container_class ) {
|
224 |
+
if ( 'yes' === $options['express_checkout_product_checkout_page'] ) {
|
225 |
+
$alignment_class = $options['express_checkout_button_alignment'];
|
226 |
+
if ( ! empty( $options['express_checkout_separator_checkout'] ) ) {
|
227 |
+
$separator_text = $options['express_checkout_separator_checkout'];
|
228 |
+
}
|
229 |
+
}
|
230 |
+
}
|
231 |
+
|
232 |
+
?>
|
233 |
+
<div id="cpsw-payment-request-separator" class="<?php echo esc_html( $container_class . ' ' . $alignment_class ); ?>">
|
234 |
+
<?php echo esc_html( $separator_text ); ?>
|
235 |
+
</div>
|
236 |
+
<?php
|
237 |
+
}
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Process chekout on payment request button click
|
242 |
+
*
|
243 |
+
* @return void
|
244 |
+
*/
|
245 |
+
public function ajax_checkout() {
|
246 |
+
check_ajax_referer( 'cpsw_checkout', 'checkout_nonce' );
|
247 |
+
|
248 |
+
if ( WC()->cart->is_empty() ) {
|
249 |
+
wp_send_json_error( __( 'Empty cart', 'checkout-plugins-stripe-woo' ) );
|
250 |
+
}
|
251 |
+
|
252 |
+
if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) {
|
253 |
+
define( 'WOOCOMMERCE_CHECKOUT', true );
|
254 |
+
}
|
255 |
+
// setting the checkout nonce to avoid exception.
|
256 |
+
$_REQUEST['_wpnonce'] = wp_create_nonce( 'woocommerce-process_checkout' );
|
257 |
+
$_POST['_wpnonce'] = $_REQUEST['_wpnonce'];
|
258 |
+
|
259 |
+
WC()->checkout()->process_checkout();
|
260 |
+
exit();
|
261 |
+
}
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Gets product data either form product page or page where shortcode is used
|
265 |
+
*
|
266 |
+
* @return object
|
267 |
+
*/
|
268 |
+
public function get_product() {
|
269 |
+
global $post;
|
270 |
+
if ( is_product() ) {
|
271 |
+
return wc_get_product( $post->ID );
|
272 |
+
} elseif ( wc_post_content_has_shortcode( 'product_page' ) ) {
|
273 |
+
// Get id from product_page shortcode.
|
274 |
+
preg_match( '/\[product_page id="(?<id>\d+)"\]/', $post->post_content, $shortcode_match );
|
275 |
+
|
276 |
+
if ( ! isset( $shortcode_match['id'] ) ) {
|
277 |
+
return false;
|
278 |
+
}
|
279 |
+
|
280 |
+
return wc_get_product( $shortcode_match['id'] );
|
281 |
+
}
|
282 |
+
|
283 |
+
return false;
|
284 |
+
}
|
285 |
+
|
286 |
+
/**
|
287 |
+
* Get price of selected product
|
288 |
+
*
|
289 |
+
* @param object $product Selected product data.
|
290 |
+
* @return string
|
291 |
+
*/
|
292 |
+
public function get_product_price( $product ) {
|
293 |
+
$product_price = $product->get_price();
|
294 |
+
// Add subscription sign-up fees to product price.
|
295 |
+
if ( 'subscription' === $product->get_type() && class_exists( 'WC_Subscriptions_Product' ) ) {
|
296 |
+
$product_price = $product->get_price() + WC_Subscriptions_Product::get_sign_up_fee( $product );
|
297 |
+
}
|
298 |
+
|
299 |
+
return $product_price;
|
300 |
+
}
|
301 |
+
|
302 |
+
/**
|
303 |
+
* Get data of selected product
|
304 |
+
*
|
305 |
+
* @return array
|
306 |
+
*/
|
307 |
+
public function get_product_data() {
|
308 |
+
if ( ! $this->is_product() ) {
|
309 |
+
return false;
|
310 |
+
}
|
311 |
+
|
312 |
+
$product = $this->get_product();
|
313 |
+
|
314 |
+
if ( 'variable' === $product->get_type() ) {
|
315 |
+
$variation_attributes = $product->get_variation_attributes();
|
316 |
+
$attributes = [];
|
317 |
+
|
318 |
+
foreach ( $variation_attributes as $attribute_name => $attribute_values ) {
|
319 |
+
$attribute_key = 'attribute_' . sanitize_title( $attribute_name );
|
320 |
+
|
321 |
+
$attributes[ $attribute_key ] = isset( $_GET[ $attribute_key ] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
322 |
+
? wc_clean( wp_unslash( $_GET[ $attribute_key ] ) ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
323 |
+
: $product->get_variation_default_attribute( $attribute_name );
|
324 |
+
}
|
325 |
+
|
326 |
+
$data_store = WC_Data_Store::load( 'product' );
|
327 |
+
$variation_id = $data_store->find_matching_product_variation( $product, $attributes );
|
328 |
+
|
329 |
+
if ( ! empty( $variation_id ) ) {
|
330 |
+
$product = wc_get_product( $variation_id );
|
331 |
+
}
|
332 |
+
}
|
333 |
+
|
334 |
+
$data = [];
|
335 |
+
$items = [];
|
336 |
+
|
337 |
+
if ( 'subscription' === $product->get_type() && class_exists( 'WC_Subscriptions_Product' ) ) {
|
338 |
+
$items[] = [
|
339 |
+
'label' => $product->get_name(),
|
340 |
+
'amount' => $this->get_formatted_amount( $product->get_price() ),
|
341 |
+
];
|
342 |
+
|
343 |
+
$items[] = [
|
344 |
+
'label' => __( 'Sign up Fee', 'checkout-plugins-stripe-woo' ),
|
345 |
+
'amount' => $this->get_formatted_amount( WC_Subscriptions_Product::get_sign_up_fee( $product ) ),
|
346 |
+
];
|
347 |
+
} else {
|
348 |
+
$items[] = [
|
349 |
+
'label' => $product->get_name(),
|
350 |
+
'amount' => $this->get_formatted_amount( $this->get_product_price( $product ) ),
|
351 |
+
];
|
352 |
+
}
|
353 |
+
|
354 |
+
if ( wc_tax_enabled() ) {
|
355 |
+
$items[] = [
|
356 |
+
'label' => __( 'Tax', 'checkout-plugins-stripe-woo' ),
|
357 |
+
'amount' => 0,
|
358 |
+
'pending' => true,
|
359 |
+
];
|
360 |
+
}
|
361 |
+
|
362 |
+
if ( wc_shipping_enabled() && $product->needs_shipping() ) {
|
363 |
+
$items[] = [
|
364 |
+
'label' => __( 'Shipping', 'checkout-plugins-stripe-woo' ),
|
365 |
+
'amount' => 0,
|
366 |
+
'pending' => true,
|
367 |
+
];
|
368 |
+
|
369 |
+
$data['shippingOptions'] = [
|
370 |
+
'id' => 'pending',
|
371 |
+
'label' => __( 'Pending', 'checkout-plugins-stripe-woo' ),
|
372 |
+
'detail' => '',
|
373 |
+
'amount' => 0,
|
374 |
+
];
|
375 |
+
}
|
376 |
+
|
377 |
+
$data['displayItems'] = $items;
|
378 |
+
$data['total'] = [
|
379 |
+
'label' => apply_filters( 'cpsw_payment_request_total_label', $this->statement_descriptor ),
|
380 |
+
'amount' => $this->get_formatted_amount( $this->get_product_price( $product ) ),
|
381 |
+
'pending' => true,
|
382 |
+
];
|
383 |
+
$data['requestShipping'] = ( wc_shipping_enabled() && $product->needs_shipping() && 0 !== wc_get_shipping_method_count( true ) );
|
384 |
+
return apply_filters( 'cpsw_payment_request_product_data', $data, $product );
|
385 |
+
}
|
386 |
+
|
387 |
+
/**
|
388 |
+
* Adds product data to locatized data via filter
|
389 |
+
*
|
390 |
+
* @param array $localized_data localized data.
|
391 |
+
* @return array
|
392 |
+
*/
|
393 |
+
public function localize_product_data( $localized_data ) {
|
394 |
+
return array_merge(
|
395 |
+
$localized_data,
|
396 |
+
[ 'product' => $this->get_product_data() ]
|
397 |
+
);
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* Format data to display in payment request cart form
|
402 |
+
*
|
403 |
+
* @param boolean $display_items show detailed view or not.
|
404 |
+
* @return array
|
405 |
+
*/
|
406 |
+
protected function build_display_items( $display_items = true ) {
|
407 |
+
if ( ! defined( 'WOOCOMMERCE_CART' ) ) {
|
408 |
+
define( 'WOOCOMMERCE_CART', true );
|
409 |
+
}
|
410 |
+
|
411 |
+
$items = [];
|
412 |
+
$lines = [];
|
413 |
+
$subtotal = 0;
|
414 |
+
$discounts = 0;
|
415 |
+
|
416 |
+
foreach ( WC()->cart->get_cart() as $item ) {
|
417 |
+
$subtotal += $item['line_subtotal'];
|
418 |
+
$amount = $item['line_subtotal'];
|
419 |
+
$quantity_label = 1 < $item['quantity'] ? ' (' . $item['quantity'] . ')' : '';
|
420 |
+
$product_name = $item['data']->get_name();
|
421 |
+
|
422 |
+
$lines[] = [
|
423 |
+
'label' => $product_name . $quantity_label,
|
424 |
+
'amount' => $this->get_formatted_amount( $amount ),
|
425 |
+
];
|
426 |
+
}
|
427 |
+
|
428 |
+
if ( $display_items ) {
|
429 |
+
$items = array_merge( $items, $lines );
|
430 |
+
} else {
|
431 |
+
// Default show only subtotal instead of itemization.
|
432 |
+
|
433 |
+
$items[] = [
|
434 |
+
'label' => 'Subtotal',
|
435 |
+
'amount' => $this->get_formatted_amount( $subtotal ),
|
436 |
+
];
|
437 |
+
}
|
438 |
+
|
439 |
+
if ( version_compare( WC_VERSION, '3.2', '<' ) ) {
|
440 |
+
$discounts = wc_format_decimal( WC()->cart->get_cart_discount_total(), WC()->cart->dp );
|
441 |
+
} else {
|
442 |
+
$applied_coupons = array_values( WC()->cart->get_coupon_discount_totals() );
|
443 |
+
|
444 |
+
foreach ( $applied_coupons as $amount ) {
|
445 |
+
$discounts += (float) $amount;
|
446 |
+
}
|
447 |
+
}
|
448 |
+
|
449 |
+
$discounts = wc_format_decimal( $discounts, WC()->cart->dp );
|
450 |
+
$tax = wc_format_decimal( WC()->cart->tax_total + WC()->cart->shipping_tax_total, WC()->cart->dp );
|
451 |
+
$shipping = wc_format_decimal( WC()->cart->shipping_total, WC()->cart->dp );
|
452 |
+
$items_total = wc_format_decimal( WC()->cart->cart_contents_total, WC()->cart->dp ) + $discounts;
|
453 |
+
$order_total = version_compare( WC_VERSION, '3.2', '<' ) ? wc_format_decimal( $items_total + $tax + $shipping - $discounts, WC()->cart->dp ) : WC()->cart->get_total( false );
|
454 |
+
|
455 |
+
if ( wc_tax_enabled() ) {
|
456 |
+
$items[] = [
|
457 |
+
'label' => esc_html( __( 'Tax', 'checkout-plugins-stripe-woo' ) ),
|
458 |
+
'amount' => $this->get_formatted_amount( $tax ),
|
459 |
+
];
|
460 |
+
}
|
461 |
+
|
462 |
+
if ( WC()->cart->needs_shipping() ) {
|
463 |
+
$items[] = [
|
464 |
+
'label' => esc_html( __( 'Shipping', 'checkout-plugins-stripe-woo' ) ),
|
465 |
+
'amount' => $this->get_formatted_amount( $shipping ),
|
466 |
+
];
|
467 |
+
}
|
468 |
+
|
469 |
+
if ( WC()->cart->has_discount() ) {
|
470 |
+
$items[] = [
|
471 |
+
'label' => esc_html( __( 'Discount', 'checkout-plugins-stripe-woo' ) ),
|
472 |
+
'amount' => $this->get_formatted_amount( $discounts ),
|
473 |
+
];
|
474 |
+
}
|
475 |
+
|
476 |
+
if ( version_compare( WC_VERSION, '3.2', '<' ) ) {
|
477 |
+
$cart_fees = WC()->cart->fees;
|
478 |
+
} else {
|
479 |
+
$cart_fees = WC()->cart->get_fees();
|
480 |
+
}
|
481 |
+
|
482 |
+
// Include fees and taxes as display items.
|
483 |
+
foreach ( $cart_fees as $fee ) {
|
484 |
+
$items[] = [
|
485 |
+
'label' => $fee->name,
|
486 |
+
'amount' => $this->get_formatted_amount( $fee->amount ),
|
487 |
+
];
|
488 |
+
}
|
489 |
+
|
490 |
+
return [
|
491 |
+
'displayItems' => $items,
|
492 |
+
'total' => [
|
493 |
+
'label' => apply_filters( 'cpsw_payment_request_total_label', $this->statement_descriptor ),
|
494 |
+
'amount' => max( 0, apply_filters( 'cpsw_stripe_calculated_total', $this->get_formatted_amount( $order_total ), $order_total, WC()->cart ) ),
|
495 |
+
'pending' => false,
|
496 |
+
],
|
497 |
+
];
|
498 |
+
}
|
499 |
+
|
500 |
+
/**
|
501 |
+
* Fetch cart details
|
502 |
+
*
|
503 |
+
* @return void
|
504 |
+
*/
|
505 |
+
public function ajax_get_cart_details() {
|
506 |
+
check_ajax_referer( 'cpsw_payment_request', 'cart_nonce' );
|
507 |
+
|
508 |
+
if ( ! defined( 'WOOCOMMERCE_CART' ) ) {
|
509 |
+
define( 'WOOCOMMERCE_CART', true );
|
510 |
+
}
|
511 |
+
|
512 |
+
WC()->cart->calculate_totals();
|
513 |
+
|
514 |
+
$currency = get_woocommerce_currency();
|
515 |
+
|
516 |
+
// Set mandatory payment details.
|
517 |
+
$data = [
|
518 |
+
'shipping_required' => WC()->cart->needs_shipping(),
|
519 |
+
'order_data' => [
|
520 |
+
'currency' => strtolower( $currency ),
|
521 |
+
'country_code' => substr( get_option( 'woocommerce_default_country' ), 0, 2 ),
|
522 |
+
],
|
523 |
+
];
|
524 |
+
|
525 |
+
$data['order_data'] += $this->build_display_items( true );
|
526 |
+
|
527 |
+
wp_send_json( $data );
|
528 |
+
}
|
529 |
+
|
530 |
+
/**
|
531 |
+
* Updates cart on product variant change
|
532 |
+
*
|
533 |
+
* @return void
|
534 |
+
*/
|
535 |
+
public function ajax_add_to_cart() {
|
536 |
+
check_ajax_referer( 'cpsw_add_to_cart', 'add_to_cart_nonce' );
|
537 |
+
|
538 |
+
if ( ! defined( 'WOOCOMMERCE_CART' ) ) {
|
539 |
+
define( 'WOOCOMMERCE_CART', true );
|
540 |
+
}
|
541 |
+
|
542 |
+
WC()->shipping->reset_shipping();
|
543 |
+
|
544 |
+
$product_id = isset( $_POST['product_id'] ) ? absint( $_POST['product_id'] ) : 0;
|
545 |
+
$qty = ! isset( $_POST['qty'] ) ? 1 : absint( $_POST['qty'] );
|
546 |
+
$product = wc_get_product( $product_id );
|
547 |
+
$product_type = $product->get_type();
|
548 |
+
|
549 |
+
// First empty the cart to prevent wrong calculation.
|
550 |
+
WC()->cart->empty_cart();
|
551 |
+
|
552 |
+
if ( ( 'variable' === $product_type || 'variable-subscription' === $product_type ) && isset( $_POST['attributes'] ) ) {
|
553 |
+
$attributes = wc_clean( wp_unslash( $_POST['attributes'] ) );
|
554 |
+
|
555 |
+
$data_store = WC_Data_Store::load( 'product' );
|
556 |
+
$variation_id = $data_store->find_matching_product_variation( $product, $attributes );
|
557 |
+
|
558 |
+
WC()->cart->add_to_cart( $product->get_id(), $qty, $variation_id, $attributes );
|
559 |
+
}
|
560 |
+
|
561 |
+
if ( 'simple' === $product_type || 'subscription' === $product_type ) {
|
562 |
+
WC()->cart->add_to_cart( $product->get_id(), $qty );
|
563 |
+
}
|
564 |
+
|
565 |
+
WC()->cart->calculate_totals();
|
566 |
+
|
567 |
+
$data = [];
|
568 |
+
$data += $this->build_display_items( true );
|
569 |
+
$data['result'] = 'success';
|
570 |
+
|
571 |
+
wp_send_json( $data );
|
572 |
+
}
|
573 |
+
|
574 |
+
/**
|
575 |
+
* Updates data as per selected product variant
|
576 |
+
*
|
577 |
+
* @throws Exception Error messages.
|
578 |
+
* @return void
|
579 |
+
*/
|
580 |
+
public function ajax_selected_product_data() {
|
581 |
+
check_ajax_referer( 'cpsw_selected_product_data', 'selected_product_nonce' );
|
582 |
+
|
583 |
+
try {
|
584 |
+
$product_id = isset( $_POST['product_id'] ) ? absint( $_POST['product_id'] ) : 0;
|
585 |
+
$qty = ! isset( $_POST['qty'] ) ? 1 : apply_filters( 'woocommerce_add_to_cart_quantity', absint( $_POST['qty'] ), $product_id );
|
586 |
+
$addon_value = isset( $_POST['addon_value'] ) ? max( floatval( $_POST['addon_value'] ), 0 ) : 0;
|
587 |
+
$product = wc_get_product( $product_id );
|
588 |
+
$variation_id = null;
|
589 |
+
|
590 |
+
if ( ! is_a( $product, 'WC_Product' ) ) {
|
591 |
+
/* translators: %d is the product Id */
|
592 |
+
throw new Exception( sprintf( __( 'Product with the ID (%d) cannot be found.', 'checkout-plugins-stripe-woo' ), $product_id ) );
|
593 |
+
}
|
594 |
+
|
595 |
+
$product_type = $product->get_type();
|
596 |
+
if ( ( 'variable' === $product_type || 'variable-subscription' === $product_type ) && isset( $_POST['attributes'] ) ) {
|
597 |
+
$attributes = wc_clean( wp_unslash( $_POST['attributes'] ) );
|
598 |
+
|
599 |
+
$data_store = WC_Data_Store::load( 'product' );
|
600 |
+
$variation_id = $data_store->find_matching_product_variation( $product, $attributes );
|
601 |
+
|
602 |
+
if ( ! empty( $variation_id ) ) {
|
603 |
+
$product = wc_get_product( $variation_id );
|
604 |
+
}
|
605 |
+
}
|
606 |
+
|
607 |
+
if ( $product->is_sold_individually() ) {
|
608 |
+
$qty = apply_filters( 'cpsw_payment_request_add_to_cart_sold_individually_quantity', 1, $qty, $product_id, $variation_id );
|
609 |
+
}
|
610 |
+
|
611 |
+
if ( ! $product->has_enough_stock( $qty ) ) {
|
612 |
+
/* translators: 1: product name 2: quantity in stock */
|
613 |
+
throw new Exception( sprintf( __( 'You cannot add that amount of "%1$s"; to the cart because there is not enough stock (%2$s remaining).', 'checkout-plugins-stripe-woo' ), $product->get_name(), wc_format_stock_quantity_for_display( $product->get_stock_quantity(), $product ) ) );
|
614 |
+
}
|
615 |
+
|
616 |
+
$total = $qty * $this->get_product_price( $product ) + $addon_value;
|
617 |
+
|
618 |
+
$quantity_label = 1 < $qty ? ' (' . $qty . ')' : '';
|
619 |
+
|
620 |
+
$data = [];
|
621 |
+
$items = [];
|
622 |
+
|
623 |
+
$items[] = [
|
624 |
+
'label' => $product->get_name() . $quantity_label,
|
625 |
+
'amount' => $this->get_formatted_amount( $total ),
|
626 |
+
];
|
627 |
+
|
628 |
+
if ( wc_tax_enabled() ) {
|
629 |
+
$items[] = [
|
630 |
+
'label' => __( 'Tax', 'checkout-plugins-stripe-woo' ),
|
631 |
+
'amount' => 0,
|
632 |
+
'pending' => true,
|
633 |
+
];
|
634 |
+
}
|
635 |
+
|
636 |
+
if ( wc_shipping_enabled() && $product->needs_shipping() ) {
|
637 |
+
$items[] = [
|
638 |
+
'label' => __( 'Shipping', 'checkout-plugins-stripe-woo' ),
|
639 |
+
'amount' => 0,
|
640 |
+
'pending' => true,
|
641 |
+
];
|
642 |
+
|
643 |
+
$data['shippingOptions'] = [
|
644 |
+
'id' => 'pending',
|
645 |
+
'label' => __( 'Pending', 'checkout-plugins-stripe-woo' ),
|
646 |
+
'detail' => '',
|
647 |
+
'amount' => 0,
|
648 |
+
];
|
649 |
+
}
|
650 |
+
|
651 |
+
$data['displayItems'] = $items;
|
652 |
+
$data['total'] = [
|
653 |
+
'label' => apply_filters( 'cpsw_payment_request_total_label', $this->statement_descriptor ),
|
654 |
+
'amount' => $this->get_formatted_amount( $total ),
|
655 |
+
'pending' => true,
|
656 |
+
];
|
657 |
+
|
658 |
+
$data['requestShipping'] = ( wc_shipping_enabled() && $product->needs_shipping() );
|
659 |
+
$data['currency'] = strtolower( get_woocommerce_currency() );
|
660 |
+
$data['country_code'] = substr( get_option( 'woocommerce_default_country' ), 0, 2 );
|
661 |
+
|
662 |
+
wp_send_json( $data );
|
663 |
+
} catch ( Exception $e ) {
|
664 |
+
wp_send_json( [ 'error' => wp_strip_all_tags( $e->getMessage() ) ] );
|
665 |
+
}
|
666 |
+
}
|
667 |
+
|
668 |
+
/**
|
669 |
+
* Updates shipping address
|
670 |
+
*
|
671 |
+
* @return void
|
672 |
+
*/
|
673 |
+
public function ajax_update_shipping_address() {
|
674 |
+
check_ajax_referer( 'cpsw_shipping_address', 'shipping_address_nonce' );
|
675 |
+
|
676 |
+
$shipping_address = filter_input_array(
|
677 |
+
INPUT_POST,
|
678 |
+
[
|
679 |
+
'country' => FILTER_SANITIZE_STRING,
|
680 |
+
'state' => FILTER_SANITIZE_STRING,
|
681 |
+
'postcode' => FILTER_SANITIZE_STRING,
|
682 |
+
'city' => FILTER_SANITIZE_STRING,
|
683 |
+
'address' => FILTER_SANITIZE_STRING,
|
684 |
+
'address_2' => FILTER_SANITIZE_STRING,
|
685 |
+
]
|
686 |
+
);
|
687 |
+
$product_view_options = filter_input_array( INPUT_POST, [ 'is_product_page' => FILTER_SANITIZE_STRING ] );
|
688 |
+
$should_show_itemized_view = ! isset( $product_view_options['is_product_page'] ) ? true : filter_var( $product_view_options['is_product_page'], FILTER_VALIDATE_BOOLEAN );
|
689 |
+
|
690 |
+
$data = $this->get_shipping_options( $shipping_address, $should_show_itemized_view );
|
691 |
+
wp_send_json( $data );
|
692 |
+
}
|
693 |
+
|
694 |
+
/**
|
695 |
+
* Updates shipping option
|
696 |
+
*
|
697 |
+
* @return void
|
698 |
+
*/
|
699 |
+
public function ajax_update_shipping_option() {
|
700 |
+
check_ajax_referer( 'cpsw_shipping_option', 'shipping_option_nonce' );
|
701 |
+
|
702 |
+
if ( ! defined( 'WOOCOMMERCE_CART' ) ) {
|
703 |
+
define( 'WOOCOMMERCE_CART', true );
|
704 |
+
}
|
705 |
+
|
706 |
+
$shipping_methods = filter_input( INPUT_POST, 'shipping_method', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
|
707 |
+
$this->update_shipping_method( $shipping_methods );
|
708 |
+
|
709 |
+
WC()->cart->calculate_totals();
|
710 |
+
|
711 |
+
$product_view_options = filter_input_array( INPUT_POST, [ 'is_product_page' => FILTER_SANITIZE_STRING ] );
|
712 |
+
$should_show_itemized_view = ! isset( $product_view_options['is_product_page'] ) ? true : filter_var( $product_view_options['is_product_page'], FILTER_VALIDATE_BOOLEAN );
|
713 |
+
|
714 |
+
$data = [];
|
715 |
+
$data += $this->build_display_items( $should_show_itemized_view );
|
716 |
+
$data['result'] = 'success';
|
717 |
+
|
718 |
+
wp_send_json( $data );
|
719 |
+
}
|
720 |
+
|
721 |
+
/**
|
722 |
+
* Fetch shipping options for selected shipping address
|
723 |
+
*
|
724 |
+
* @param array $shipping_address selected shipping address.
|
725 |
+
* @param boolean $itemized_display_items shows descriptive view.
|
726 |
+
* @throws Exception If shipping method is not found.
|
727 |
+
* @return array
|
728 |
+
*/
|
729 |
+
public function get_shipping_options( $shipping_address, $itemized_display_items = true ) {
|
730 |
+
try {
|
731 |
+
$data = [];
|
732 |
+
|
733 |
+
$chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
|
734 |
+
$this->calculate_shipping( apply_filters( 'cpsw_payment_request_shipping_posted_values', $shipping_address ) );
|
735 |
+
|
736 |
+
$packages = WC()->shipping->get_packages();
|
737 |
+
$shipping_rate_ids = [];
|
738 |
+
|
739 |
+
if ( ! empty( $packages ) && WC()->customer->has_calculated_shipping() ) {
|
740 |
+
foreach ( $packages as $package ) {
|
741 |
+
if ( empty( $package['rates'] ) ) {
|
742 |
+
throw new Exception( __( 'Unable to find shipping method for address.', 'checkout-plugins-stripe-woo' ) );
|
743 |
+
}
|
744 |
+
|
745 |
+
foreach ( $package['rates'] as $key => $rate ) {
|
746 |
+
if ( in_array( $rate->id, $shipping_rate_ids, true ) ) {
|
747 |
+
throw new Exception( __( 'Unable to provide shipping options for Payment Requests.', 'checkout-plugins-stripe-woo' ) );
|
748 |
+
}
|
749 |
+
$shipping_rate_ids[] = $rate->id;
|
750 |
+
$data['shipping_options'][] = [
|
751 |
+
'id' => $rate->id,
|
752 |
+
'label' => $rate->label,
|
753 |
+
'detail' => '',
|
754 |
+
'amount' => $this->get_formatted_amount( $rate->cost ),
|
755 |
+
];
|
756 |
+
}
|
757 |
+
}
|
758 |
+
} else {
|
759 |
+
throw new Exception( __( 'Unable to find shipping method for address.', 'checkout-plugins-stripe-woo' ) );
|
760 |
+
}
|
761 |
+
|
762 |
+
if ( isset( $data['shipping_options'][0] ) ) {
|
763 |
+
if ( isset( $chosen_shipping_methods[0] ) ) {
|
764 |
+
$chosen_method_id = $chosen_shipping_methods[0];
|
765 |
+
$compare_shipping_options = function ( $a, $b ) use ( $chosen_method_id ) {
|
766 |
+
if ( $a['id'] === $chosen_method_id ) {
|
767 |
+
return -1;
|
768 |
+
}
|
769 |
+
|
770 |
+
if ( $b['id'] === $chosen_method_id ) {
|
771 |
+
return 1;
|
772 |
+
}
|
773 |
+
|
774 |
+
return 0;
|
775 |
+
};
|
776 |
+
usort( $data['shipping_options'], $compare_shipping_options );
|
777 |
+
}
|
778 |
+
|
779 |
+
$first_shipping_method_id = $data['shipping_options'][0]['id'];
|
780 |
+
$this->update_shipping_method( [ $first_shipping_method_id ] );
|
781 |
+
}
|
782 |
+
|
783 |
+
WC()->cart->calculate_totals();
|
784 |
+
|
785 |
+
$data += $this->build_display_items( $itemized_display_items );
|
786 |
+
$data['result'] = 'success';
|
787 |
+
} catch ( Exception $e ) {
|
788 |
+
$data += $this->build_display_items( $itemized_display_items );
|
789 |
+
$data['result'] = 'invalid_shipping_address';
|
790 |
+
}
|
791 |
+
|
792 |
+
return $data;
|
793 |
+
}
|
794 |
+
|
795 |
+
/**
|
796 |
+
* Calculated shipping charges
|
797 |
+
*
|
798 |
+
* @param array $address updated address.
|
799 |
+
* @return void
|
800 |
+
*/
|
801 |
+
protected function calculate_shipping( $address = [] ) {
|
802 |
+
$country = $address['country'];
|
803 |
+
$state = $address['state'];
|
804 |
+
$postcode = $address['postcode'];
|
805 |
+
$city = $address['city'];
|
806 |
+
$address_1 = $address['address'];
|
807 |
+
$address_2 = $address['address_2'];
|
808 |
+
|
809 |
+
WC()->shipping->reset_shipping();
|
810 |
+
|
811 |
+
if ( $postcode && WC_Validation::is_postcode( $postcode, $country ) ) {
|
812 |
+
$postcode = wc_format_postcode( $postcode, $country );
|
813 |
+
}
|
814 |
+
|
815 |
+
if ( $country ) {
|
816 |
+
WC()->customer->set_location( $country, $state, $postcode, $city );
|
817 |
+
WC()->customer->set_shipping_location( $country, $state, $postcode, $city );
|
818 |
+
} else {
|
819 |
+
WC()->customer->set_billing_address_to_base();
|
820 |
+
WC()->customer->set_shipping_address_to_base();
|
821 |
+
}
|
822 |
+
|
823 |
+
WC()->customer->set_calculated_shipping( true );
|
824 |
+
WC()->customer->save();
|
825 |
+
|
826 |
+
$packages = [];
|
827 |
+
|
828 |
+
$packages[0]['contents'] = WC()->cart->get_cart();
|
829 |
+
$packages[0]['contents_cost'] = 0;
|
830 |
+
$packages[0]['applied_coupons'] = WC()->cart->applied_coupons;
|
831 |
+
$packages[0]['user']['ID'] = get_current_user_id();
|
832 |
+
$packages[0]['destination']['country'] = $country;
|
833 |
+
$packages[0]['destination']['state'] = $state;
|
834 |
+
$packages[0]['destination']['postcode'] = $postcode;
|
835 |
+
$packages[0]['destination']['city'] = $city;
|
836 |
+
$packages[0]['destination']['address'] = $address_1;
|
837 |
+
$packages[0]['destination']['address_2'] = $address_2;
|
838 |
+
|
839 |
+
foreach ( WC()->cart->get_cart() as $item ) {
|
840 |
+
if ( $item['data']->needs_shipping() ) {
|
841 |
+
if ( isset( $item['line_total'] ) ) {
|
842 |
+
$packages[0]['contents_cost'] += $item['line_total'];
|
843 |
+
}
|
844 |
+
}
|
845 |
+
}
|
846 |
+
|
847 |
+
$packages = apply_filters( 'woocommerce_cart_shipping_packages', $packages );
|
848 |
+
|
849 |
+
WC()->shipping->calculate_shipping( $packages );
|
850 |
+
}
|
851 |
+
|
852 |
+
/**
|
853 |
+
* Updates shipping method
|
854 |
+
*
|
855 |
+
* @param array $shipping_methods available shipping methods array.
|
856 |
+
* @return void
|
857 |
+
*/
|
858 |
+
public function update_shipping_method( $shipping_methods ) {
|
859 |
+
$chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
|
860 |
+
|
861 |
+
if ( is_array( $shipping_methods ) ) {
|
862 |
+
foreach ( $shipping_methods as $i => $value ) {
|
863 |
+
$chosen_shipping_methods[ $i ] = wc_clean( $value );
|
864 |
+
}
|
865 |
+
}
|
866 |
+
|
867 |
+
WC()->session->set( 'chosen_shipping_methods', $chosen_shipping_methods );
|
868 |
+
}
|
869 |
+
}
|
gateway/stripe/stripe-api.php
CHANGED
@@ -8,9 +8,7 @@
|
|
8 |
|
9 |
namespace CPSW\Gateway\Stripe;
|
10 |
|
11 |
-
use CPSW\Inc\Traits\Get_Instance;
|
12 |
use CPSW\Inc\Logger;
|
13 |
-
use CPSW\Inc\Helper;
|
14 |
use \Stripe\StripeClient;
|
15 |
|
16 |
/**
|
@@ -18,8 +16,6 @@ use \Stripe\StripeClient;
|
|
18 |
*/
|
19 |
class Stripe_Api {
|
20 |
|
21 |
-
use Get_Instance;
|
22 |
-
|
23 |
/**
|
24 |
* Instance of Stripe
|
25 |
*
|
@@ -33,7 +29,7 @@ class Stripe_Api {
|
|
33 |
* @since 0.0.1
|
34 |
*/
|
35 |
public function __construct() {
|
36 |
-
$secret_key = ( 'live' ===
|
37 |
if ( ! empty( $secret_key ) ) {
|
38 |
$this->stripe = new StripeClient(
|
39 |
[
|
@@ -53,7 +49,19 @@ class Stripe_Api {
|
|
53 |
* @return array
|
54 |
*/
|
55 |
private function execute( $api, $method, $args ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
$error_message = false;
|
|
|
|
|
57 |
try {
|
58 |
$response = $this->stripe->{$api}->{$method}( ...$args );
|
59 |
} catch ( \Stripe\Exception\CardException $e ) {
|
@@ -74,8 +82,8 @@ class Stripe_Api {
|
|
74 |
$error_message = $e->getError()->message;
|
75 |
} catch ( \Stripe\Exception\ApiConnectionException $e ) {
|
76 |
// Network communication with Stripe failed.
|
77 |
-
|
78 |
-
$error_message
|
79 |
} catch ( \Stripe\Exception\ApiErrorException $e ) {
|
80 |
Logger::error( $e->getError()->message, true );
|
81 |
$error_message = $e->getError()->message;
|
@@ -170,4 +178,15 @@ class Stripe_Api {
|
|
170 |
public function accounts( $method, $args ) {
|
171 |
return $this->execute( 'accounts', $method, $args );
|
172 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
}
|
8 |
|
9 |
namespace CPSW\Gateway\Stripe;
|
10 |
|
|
|
11 |
use CPSW\Inc\Logger;
|
|
|
12 |
use \Stripe\StripeClient;
|
13 |
|
14 |
/**
|
16 |
*/
|
17 |
class Stripe_Api {
|
18 |
|
|
|
|
|
19 |
/**
|
20 |
* Instance of Stripe
|
21 |
*
|
29 |
* @since 0.0.1
|
30 |
*/
|
31 |
public function __construct() {
|
32 |
+
$secret_key = apply_filters( 'cpsw_get_secret_key', ( 'live' === get_option( 'cpsw_mode' ) ) ? get_option( 'cpsw_secret_key' ) : get_option( 'cpsw_test_secret_key' ) );
|
33 |
if ( ! empty( $secret_key ) ) {
|
34 |
$this->stripe = new StripeClient(
|
35 |
[
|
49 |
* @return array
|
50 |
*/
|
51 |
private function execute( $api, $method, $args ) {
|
52 |
+
|
53 |
+
if ( is_null( $this->stripe ) ) {
|
54 |
+
$error_message = __( 'Stripe not initialized', 'checkout-plugins-stripe-woo' );
|
55 |
+
Logger::error( $error_message, true );
|
56 |
+
return [
|
57 |
+
'success' => false,
|
58 |
+
'message' => $error_message,
|
59 |
+
];
|
60 |
+
}
|
61 |
+
|
62 |
$error_message = false;
|
63 |
+
$response = false;
|
64 |
+
|
65 |
try {
|
66 |
$response = $this->stripe->{$api}->{$method}( ...$args );
|
67 |
} catch ( \Stripe\Exception\CardException $e ) {
|
82 |
$error_message = $e->getError()->message;
|
83 |
} catch ( \Stripe\Exception\ApiConnectionException $e ) {
|
84 |
// Network communication with Stripe failed.
|
85 |
+
$error_message = is_null( $e->getError() ) ? $e->getMessage() : $e->getError()->message;
|
86 |
+
Logger::error( $error_message, true );
|
87 |
} catch ( \Stripe\Exception\ApiErrorException $e ) {
|
88 |
Logger::error( $e->getError()->message, true );
|
89 |
$error_message = $e->getError()->message;
|
178 |
public function accounts( $method, $args ) {
|
179 |
return $this->execute( 'accounts', $method, $args );
|
180 |
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Executes Stripe apple pay domains query
|
184 |
+
*
|
185 |
+
* @param string $method method to be used.
|
186 |
+
* @param array $args parameter.
|
187 |
+
* @return array
|
188 |
+
*/
|
189 |
+
public function apple_pay_domains( $method, $args ) {
|
190 |
+
return $this->execute( 'applePayDomains', $method, $args );
|
191 |
+
}
|
192 |
}
|
inc/helper.php
CHANGED
@@ -8,48 +8,22 @@
|
|
8 |
|
9 |
namespace CPSW\Inc;
|
10 |
|
11 |
-
use CPSW\Inc\Traits\Get_Instance;
|
12 |
-
use CPSW\Inc\Logger;
|
13 |
-
use \Stripe\StripeClient;
|
14 |
-
|
15 |
/**
|
16 |
* Stripe Webhook.
|
17 |
*/
|
18 |
class Helper {
|
19 |
|
20 |
-
use Get_Instance;
|
21 |
-
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Instance of Stripe
|
25 |
-
*
|
26 |
-
* @var \Stripe\StripeClient
|
27 |
-
*/
|
28 |
-
public static $stripe;
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Options
|
32 |
-
*
|
33 |
-
* @var array
|
34 |
-
*/
|
35 |
-
public static $options;
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Options
|
39 |
-
*
|
40 |
-
* @var array
|
41 |
-
*/
|
42 |
-
public static $global_settings;
|
43 |
-
|
44 |
/**
|
45 |
-
* Default values
|
46 |
*
|
47 |
* @var array
|
48 |
*/
|
49 |
-
private static $
|
50 |
'woocommerce_cpsw_stripe_settings' => [
|
51 |
-
'
|
52 |
-
'
|
|
|
|
|
53 |
'mastercard',
|
54 |
'visa',
|
55 |
'diners',
|
@@ -58,18 +32,44 @@ class Helper {
|
|
58 |
'jcb',
|
59 |
'unionpay',
|
60 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
],
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
'
|
71 |
-
'
|
72 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
];
|
74 |
|
75 |
/**
|
@@ -78,56 +78,69 @@ class Helper {
|
|
78 |
* @since 0.0.1
|
79 |
*/
|
80 |
public function __construct() {
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
}
|
102 |
|
103 |
-
|
104 |
-
|
|
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
-
*
|
109 |
*
|
110 |
-
* @
|
|
|
|
|
111 |
*/
|
112 |
-
public static function
|
113 |
-
$
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
]
|
120 |
-
);
|
121 |
}
|
|
|
|
|
122 |
}
|
123 |
|
124 |
/**
|
125 |
-
*
|
126 |
*
|
127 |
-
* @
|
|
|
128 |
*/
|
129 |
-
public static function
|
130 |
-
|
|
|
131 |
}
|
132 |
|
133 |
/**
|
@@ -140,17 +153,11 @@ class Helper {
|
|
140 |
public static function get_setting( $key = '', $gateway = false ) {
|
141 |
$result = false;
|
142 |
if ( false !== $gateway ) {
|
143 |
-
$
|
144 |
-
if ( $options && array_key_exists( $key, $options[ 'woocommerce_' . $gateway . '_settings' ] ) ) {
|
145 |
-
$result = $options[ 'woocommerce_' . $gateway . '_settings' ][ $key ];
|
146 |
-
}
|
147 |
} else {
|
148 |
-
$
|
149 |
-
if ( $settings && array_key_exists( $key, $settings ) ) {
|
150 |
-
$result = $settings[ $key ];
|
151 |
-
}
|
152 |
}
|
153 |
-
return $result ? apply_filters( $key, $result ) : false;
|
154 |
}
|
155 |
|
156 |
/**
|
@@ -161,24 +168,4 @@ class Helper {
|
|
161 |
public static function get_payment_mode() {
|
162 |
return apply_filters( 'cpsw_payment_mode', self::get_setting( 'cpsw_mode' ) );
|
163 |
}
|
164 |
-
|
165 |
-
/**
|
166 |
-
* Logs js errors
|
167 |
-
*
|
168 |
-
* @return json
|
169 |
-
*/
|
170 |
-
public function js_errors() {
|
171 |
-
if ( ! isset( $_POST['_security'] ) || ! wp_verify_nonce( sanitize_text_field( $_POST['_security'] ), 'cpsw_js_error_nonce' ) ) {
|
172 |
-
return wp_send_json_error( [ 'message' => __( 'Invalid Nonce', 'checkout-plugins-stripe-woo' ) ] );
|
173 |
-
}
|
174 |
-
|
175 |
-
if ( isset( $_POST['error'] ) ) {
|
176 |
-
$error = $_POST['error'];
|
177 |
-
$error_message = $error['message'] . ' (' . $error['type'] . ')';
|
178 |
-
Logger::error( $error_message, true );
|
179 |
-
return wp_send_json_success( [ 'message' => $error_message ] );
|
180 |
-
}
|
181 |
-
exit();
|
182 |
-
}
|
183 |
-
|
184 |
}
|
8 |
|
9 |
namespace CPSW\Inc;
|
10 |
|
|
|
|
|
|
|
|
|
11 |
/**
|
12 |
* Stripe Webhook.
|
13 |
*/
|
14 |
class Helper {
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
/**
|
17 |
+
* Default gateway values
|
18 |
*
|
19 |
* @var array
|
20 |
*/
|
21 |
+
private static $gateway_defaults = [
|
22 |
'woocommerce_cpsw_stripe_settings' => [
|
23 |
+
'enabled' => 'no',
|
24 |
+
'inline_cc' => 'yes',
|
25 |
+
'order_status' => '',
|
26 |
+
'allowed_cards' => [
|
27 |
'mastercard',
|
28 |
'visa',
|
29 |
'diners',
|
32 |
'jcb',
|
33 |
'unionpay',
|
34 |
],
|
35 |
+
'express_checkout_location' => [
|
36 |
+
'product',
|
37 |
+
'cart',
|
38 |
+
'checkout',
|
39 |
+
],
|
40 |
+
'express_checkout_enabled' => 'no',
|
41 |
+
'express_checkout_button_type' => 'default',
|
42 |
+
'express_checkout_button_theme' => 'dark',
|
43 |
+
'express_checkout_button_height' => '40',
|
44 |
+
'express_checkout_title' => 'Express Checkout',
|
45 |
+
'express_checkout_tagline' => 'Checkout quickly to use you favourite tool.',
|
46 |
+
'express_checkout_product_page_position' => 'above',
|
47 |
+
'express_checkout_product_sticky_footer' => 'yes',
|
48 |
+
'express_checkout_separator' => 'OR',
|
49 |
+
'express_checkout_product_checkout_page' => 'no',
|
50 |
+
'express_checkout_button_width' => '',
|
51 |
+
'express_checkout_button_alignment' => 'left',
|
52 |
+
'express_checkout_separator_checkout' => 'OR',
|
53 |
],
|
54 |
+
];
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Default global values
|
58 |
+
*
|
59 |
+
* @var array
|
60 |
+
*/
|
61 |
+
private static $global_defaults = [
|
62 |
+
'cpsw_test_pub_key' => '',
|
63 |
+
'cpsw_pub_key' => '',
|
64 |
+
'cpsw_test_secret_key' => '',
|
65 |
+
'cpsw_secret_key' => '',
|
66 |
+
'cpsw_test_con_status' => '',
|
67 |
+
'cpsw_con_status' => '',
|
68 |
+
'cpsw_mode' => 'test',
|
69 |
+
'cpsw_live_webhook_secret' => '',
|
70 |
+
'cpsw_test_webhook_secret' => '',
|
71 |
+
'cpsw_account_id' => '',
|
72 |
+
'cpsw_debug_log' => 'no',
|
73 |
];
|
74 |
|
75 |
/**
|
78 |
* @since 0.0.1
|
79 |
*/
|
80 |
public function __construct() {
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Stripe get all settings
|
85 |
+
*
|
86 |
+
* @return $global_settings array It returns all stripe settings in an array.
|
87 |
+
*/
|
88 |
+
public static function get_settings() {
|
89 |
+
$response = [];
|
90 |
+
foreach ( self::$global_defaults as $key => $default_data ) {
|
91 |
+
$response[ $key ] = self::get_global_setting( $key );
|
92 |
+
}
|
93 |
+
return apply_filters( 'cpsw_settings', $response );
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Get all settings of a particular gateway
|
98 |
+
*
|
99 |
+
* @param string $gateway gateway id.
|
100 |
+
* @return array
|
101 |
+
*/
|
102 |
+
public static function get_gateway_settings( $gateway = 'cpsw_stripe' ) {
|
103 |
+
$default_settings = [];
|
104 |
+
$setting_name = 'woocommerce_' . $gateway . '_settings';
|
105 |
+
$saved_settings = get_option( $setting_name, [] );
|
106 |
+
|
107 |
+
if ( isset( self::$gateway_defaults[ $setting_name ] ) ) {
|
108 |
+
$default_settings = self::$gateway_defaults[ $setting_name ];
|
109 |
}
|
110 |
|
111 |
+
$settings = array_merge( $default_settings, $saved_settings );
|
112 |
+
|
113 |
+
return apply_filters( 'cpsw_gateway_settings', $settings );
|
114 |
}
|
115 |
|
116 |
/**
|
117 |
+
* Get value of gateway option parameter
|
118 |
*
|
119 |
+
* @param string $key key name.
|
120 |
+
* @param string $gateway gateway id.
|
121 |
+
* @return mixed
|
122 |
*/
|
123 |
+
public static function get_gateway_setting( $key = '', $gateway = 'cpsw_stripe' ) {
|
124 |
+
$settings = self::get_gateway_settings( $gateway );
|
125 |
+
|
126 |
+
$value = false;
|
127 |
+
|
128 |
+
if ( isset( $settings[ $key ] ) ) {
|
129 |
+
$value = $settings[ $key ];
|
|
|
|
|
130 |
}
|
131 |
+
|
132 |
+
return $value;
|
133 |
}
|
134 |
|
135 |
/**
|
136 |
+
* Get value of global option
|
137 |
*
|
138 |
+
* @param string $key value of global setting.
|
139 |
+
* @return mixed
|
140 |
*/
|
141 |
+
public static function get_global_setting( $key ) {
|
142 |
+
$db_data = get_option( $key );
|
143 |
+
return $db_data ? $db_data : self::$global_defaults[ $key ];
|
144 |
}
|
145 |
|
146 |
/**
|
153 |
public static function get_setting( $key = '', $gateway = false ) {
|
154 |
$result = false;
|
155 |
if ( false !== $gateway ) {
|
156 |
+
$result = self::get_gateway_setting( $key, $gateway );
|
|
|
|
|
|
|
157 |
} else {
|
158 |
+
$result = self::get_global_setting( $key );
|
|
|
|
|
|
|
159 |
}
|
160 |
+
return is_array( $result ) || $result ? apply_filters( $key, $result ) : false;
|
161 |
}
|
162 |
|
163 |
/**
|
168 |
public static function get_payment_mode() {
|
169 |
return apply_filters( 'cpsw_payment_mode', self::get_setting( 'cpsw_mode' ) );
|
170 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
}
|
inc/traits/subscriptions.php
CHANGED
@@ -8,9 +8,8 @@
|
|
8 |
namespace CPSW\Inc\Traits;
|
9 |
|
10 |
use CPSW\Inc\Traits\Subscription_Helper as SH;
|
11 |
-
use CPSW\
|
12 |
use CPSW\Inc\Logger;
|
13 |
-
use WC_Payment_Tokens;
|
14 |
use WC_Emails;
|
15 |
use WC_Subscriptions_Change_Payment_Gateway;
|
16 |
use Exception;
|
@@ -316,8 +315,9 @@ trait Subscriptions {
|
|
316 |
|
317 |
$order_id = $order->get_id();
|
318 |
Logger::info( "Stripe Payment initiated for order $order_id" );
|
319 |
-
$
|
320 |
-
$
|
|
|
321 |
|
322 |
if ( $intent ) {
|
323 |
$intent_data = [
|
@@ -409,8 +409,9 @@ trait Subscriptions {
|
|
409 |
}
|
410 |
|
411 |
if ( isset( $_POST['paymentMethod'] ) ) {
|
412 |
-
$
|
413 |
-
$response
|
|
|
414 |
return wp_send_json_success( [ 'client_secret' => $response->client_secret ] );
|
415 |
}
|
416 |
exit();
|
@@ -452,7 +453,8 @@ trait Subscriptions {
|
|
452 |
|
453 |
if ( $source_id ) {
|
454 |
$stripe_source = $source_id;
|
455 |
-
$
|
|
|
456 |
$source_object = $response['success'] ? $response['data'] : false;
|
457 |
} elseif ( apply_filters( 'cpsw_use_default_customer_source', true ) ) {
|
458 |
// Attempting with empty source id.
|
@@ -805,7 +807,8 @@ trait Subscriptions {
|
|
805 |
// New CC info was entered and we have a new source to process.
|
806 |
if ( ! empty( $_POST['payment_method_created'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
|
807 |
$stripe_source = wc_clean( wp_unslash( $_POST['payment_method_created'] ) ); //phpcs:ignore WordPress.Security.NonceVerification.Missing
|
808 |
-
$
|
|
|
809 |
$source_object = $response['success'] ? $response['data'] : false;
|
810 |
$source_id = $source_object->id;
|
811 |
|
@@ -814,7 +817,7 @@ trait Subscriptions {
|
|
814 |
|
815 |
// Either saved card is enabled or forced by flow.
|
816 |
if ( ( $user_id && $this->enable_saved_cards && $maybe_saved_card && 'reusable' === $source_object->usage ) || $force_save_source ) {
|
817 |
-
$
|
818 |
$this->create_payment_token_for_user( $user_id, $source_object );
|
819 |
if ( ! empty( $response->error ) ) {
|
820 |
throw new Exception( print_r( $response, true ), $this->get_localized_error_message_from_response( $response ) ); //phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
|
8 |
namespace CPSW\Inc\Traits;
|
9 |
|
10 |
use CPSW\Inc\Traits\Subscription_Helper as SH;
|
11 |
+
use CPSW\Gateway\Stripe\Stripe_Api;
|
12 |
use CPSW\Inc\Logger;
|
|
|
13 |
use WC_Emails;
|
14 |
use WC_Subscriptions_Change_Payment_Gateway;
|
15 |
use Exception;
|
315 |
|
316 |
$order_id = $order->get_id();
|
317 |
Logger::info( "Stripe Payment initiated for order $order_id" );
|
318 |
+
$stripe_api = new Stripe_Api();
|
319 |
+
$response = $stripe_api->payment_intents( 'create', [ $request ] );
|
320 |
+
$intent = $response['success'] ? $response['data'] : false;
|
321 |
|
322 |
if ( $intent ) {
|
323 |
$intent_data = [
|
409 |
}
|
410 |
|
411 |
if ( isset( $_POST['paymentMethod'] ) ) {
|
412 |
+
$stripe_api = new Stripe_Api();
|
413 |
+
$response = $stripe_api->setup_intents( 'create', [ [ 'payment_method_types' => [ 'card' ] ] ] );
|
414 |
+
$response = $response['success'] ? $response['data'] : false;
|
415 |
return wp_send_json_success( [ 'client_secret' => $response->client_secret ] );
|
416 |
}
|
417 |
exit();
|
453 |
|
454 |
if ( $source_id ) {
|
455 |
$stripe_source = $source_id;
|
456 |
+
$stripe_api = new Stripe_Api();
|
457 |
+
$response = $stripe_api->payment_methods( 'retrieve', [ $stripe_source ] );
|
458 |
$source_object = $response['success'] ? $response['data'] : false;
|
459 |
} elseif ( apply_filters( 'cpsw_use_default_customer_source', true ) ) {
|
460 |
// Attempting with empty source id.
|
807 |
// New CC info was entered and we have a new source to process.
|
808 |
if ( ! empty( $_POST['payment_method_created'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
|
809 |
$stripe_source = wc_clean( wp_unslash( $_POST['payment_method_created'] ) ); //phpcs:ignore WordPress.Security.NonceVerification.Missing
|
810 |
+
$stripe_api = new Stripe_Api();
|
811 |
+
$response = $stripe_api->payment_methods( 'retrieve', [ $stripe_source ] );
|
812 |
$source_object = $response['success'] ? $response['data'] : false;
|
813 |
$source_id = $source_object->id;
|
814 |
|
817 |
|
818 |
// Either saved card is enabled or forced by flow.
|
819 |
if ( ( $user_id && $this->enable_saved_cards && $maybe_saved_card && 'reusable' === $source_object->usage ) || $force_save_source ) {
|
820 |
+
$stripe_api->payment_methods( 'attach', [ $source_id, [ 'customer' => $customer_id ] ] );
|
821 |
$this->create_payment_token_for_user( $user_id, $source_object );
|
822 |
if ( ! empty( $response->error ) ) {
|
823 |
throw new Exception( print_r( $response, true ), $this->get_localized_error_message_from_response( $response ) ); //phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: brainstormforce
|
|
3 |
Tags: stripe, credit card
|
4 |
Requires at least: 5.4
|
5 |
Tested up to: 5.8
|
6 |
-
Stable tag: 1.
|
7 |
Requires PHP: 5.6
|
8 |
License: GPLv2 or later
|
9 |
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
@@ -36,12 +36,27 @@ The plugin supports WooCommerce Subscriptions where users can make recurring pay
|
|
36 |
= Does this plugin work with WooCommerce Subscriptions? =
|
37 |
Yes, the plugin supports all the functionality of WooCommerce Subscriptions.
|
38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
== Screenshots ==
|
40 |
|
41 |
1. API Settings
|
42 |
2. Card Payments Settings
|
|
|
|
|
43 |
|
44 |
== Changelog ==
|
45 |
|
|
|
|
|
|
|
46 |
= 1.0.0 – TUESDAY, 23RD NOVEMBER 2021 =
|
47 |
* Initial release
|
3 |
Tags: stripe, credit card
|
4 |
Requires at least: 5.4
|
5 |
Tested up to: 5.8
|
6 |
+
Stable tag: 1.1.0
|
7 |
Requires PHP: 5.6
|
8 |
License: GPLv2 or later
|
9 |
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
36 |
= Does this plugin work with WooCommerce Subscriptions? =
|
37 |
Yes, the plugin supports all the functionality of WooCommerce Subscriptions.
|
38 |
|
39 |
+
= I have an existing subscription with another Stripe Payment Gateway plugin. How can I switch to your plugin without losing my existing subscriptions? =
|
40 |
+
You can easily switch to Stripe for WooCommerce from your existing plugin without losing your subscription.
|
41 |
+
|
42 |
+
Here are easy steps
|
43 |
+
1. Install our plugin like any other WordPress plugin
|
44 |
+
2. Follow the documentation [here](https://checkoutplugins.com/docs/stripe-api-settings/) to setup the stripe account keys
|
45 |
+
3. Enable Stripe payment method from our plugin. This allows all your future transactions to be processed through the new Stripe gateway you set with our plugin.
|
46 |
+
4. Disable the existing Stripe method from WooCommerce payment settings.
|
47 |
+
NOTE: NOT to deactivate your old payment gateway plugin. Your old subscription's renewal will be processed through the old plugin automatically.
|
48 |
+
|
49 |
== Screenshots ==
|
50 |
|
51 |
1. API Settings
|
52 |
2. Card Payments Settings
|
53 |
+
3. Express Checkout - Admin Settings
|
54 |
+
4. Express Checkout Button on Checkout Page
|
55 |
|
56 |
== Changelog ==
|
57 |
|
58 |
+
= 1.1.0 – TUESDAY, 21ST DECEMBER 2021 =
|
59 |
+
* New: Express Checkout
|
60 |
+
|
61 |
= 1.0.0 – TUESDAY, 23RD NOVEMBER 2021 =
|
62 |
* Initial release
|