|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* Stripe Payment Request API |
|
4
|
|
|
* |
|
5
|
|
|
* @package WooCommerce_Stripe/Classes/Payment_Request |
|
6
|
|
|
* @since 3.1.0 |
|
7
|
|
|
* @version 3.1.0 |
|
8
|
|
|
*/ |
|
9
|
|
|
|
|
10
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
|
11
|
|
|
exit; |
|
12
|
|
|
} |
|
13
|
|
|
|
|
14
|
|
|
/** |
|
15
|
|
|
* WC_Stripe_Payment_Request class. |
|
16
|
|
|
*/ |
|
17
|
|
|
class WC_Stripe_Payment_Request { |
|
18
|
|
|
|
|
19
|
|
|
/** |
|
20
|
|
|
* Initialize class actions. |
|
21
|
|
|
*/ |
|
22
|
|
|
public function __construct() { |
|
23
|
|
|
add_action( 'wp_enqueue_scripts', array( $this, 'scripts' ) ); |
|
24
|
|
|
|
|
25
|
|
|
add_action( 'wc_ajax_wc_stripe_get_cart_details', array( $this, 'ajax_get_cart_details' ) ); |
|
26
|
|
|
add_action( 'wc_ajax_wc_stripe_get_shipping_options', array( $this, 'ajax_get_shipping_options' ) ); |
|
27
|
|
|
add_action( 'wc_ajax_wc_stripe_update_shipping_method', array( $this, 'ajax_update_shipping_method' ) ); |
|
28
|
|
|
add_action( 'wc_ajax_wc_stripe_create_order', array( $this, 'ajax_create_order' ) ); |
|
29
|
|
|
} |
|
30
|
|
|
|
|
31
|
|
|
/** |
|
32
|
|
|
* Check if Stripe gateway is enabled. |
|
33
|
|
|
* |
|
34
|
|
|
* @return bool |
|
35
|
|
|
*/ |
|
36
|
|
|
protected function is_activated() { |
|
37
|
|
|
$options = get_option( 'woocommerce_stripe_settings', array() ); |
|
38
|
|
|
$enabled = isset( $options['enabled'] ) && 'yes' === $options['enabled']; |
|
39
|
|
|
$stripe_checkout = isset( $options['stripe_checkout'] ) && 'yes' !== $options['stripe_checkout']; |
|
40
|
|
|
$request_payment_api = isset( $options['request_payment_api'] ) && 'yes' === $options['request_payment_api']; |
|
41
|
|
|
|
|
42
|
|
|
return $enabled && $stripe_checkout && $request_payment_api && is_ssl(); |
|
43
|
|
|
} |
|
44
|
|
|
|
|
45
|
|
|
/** |
|
46
|
|
|
* Get publishable key. |
|
47
|
|
|
* |
|
48
|
|
|
* @return string |
|
49
|
|
|
*/ |
|
50
|
|
|
protected function get_publishable_key() { |
|
51
|
|
|
$options = get_option( 'woocommerce_stripe_settings', array() ); |
|
52
|
|
|
|
|
53
|
|
|
if ( empty( $options ) ) { |
|
54
|
|
|
return ''; |
|
55
|
|
|
} |
|
56
|
|
|
|
|
57
|
|
|
return 'yes' === $options['testmode'] ? $options['test_publishable_key'] : $options['publishable_key']; |
|
58
|
|
|
} |
|
59
|
|
|
|
|
60
|
|
|
/** |
|
61
|
|
|
* Load public scripts. |
|
62
|
|
|
*/ |
|
63
|
|
|
public function scripts() { |
|
64
|
|
|
// Load PaymentRequest only on cart for now. |
|
65
|
|
|
if ( ! is_cart() ) { |
|
66
|
|
|
return; |
|
67
|
|
|
} |
|
68
|
|
|
|
|
69
|
|
|
if ( ! $this->is_activated() ) { |
|
70
|
|
|
return; |
|
71
|
|
|
} |
|
72
|
|
|
|
|
73
|
|
|
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; |
|
74
|
|
|
|
|
75
|
|
|
wp_enqueue_script( 'stripe', 'https://js.stripe.com/v2/', '', '1.0', true ); |
|
76
|
|
|
wp_enqueue_script( 'google-payment-request-shim', 'https://storage.googleapis.com/prshim/v1/payment-shim.js', '', '1.0', false ); |
|
77
|
|
|
wp_enqueue_script( 'wc-stripe-payment-request', plugins_url( 'assets/js/payment-request' . $suffix . '.js', WC_STRIPE_MAIN_FILE ), array( 'jquery', 'stripe' ), WC_STRIPE_VERSION, true ); |
|
78
|
|
|
|
|
79
|
|
|
wp_localize_script( |
|
80
|
|
|
'wc-stripe-payment-request', |
|
81
|
|
|
'wcStripePaymentRequestParams', |
|
82
|
|
|
array( |
|
83
|
|
|
'ajax_url' => WC_AJAX::get_endpoint( '%%endpoint%%' ), |
|
84
|
|
|
'stripe' => array( |
|
85
|
|
|
'key' => $this->get_publishable_key(), |
|
86
|
|
|
'allow_prepaid_card' => apply_filters( 'wc_stripe_allow_prepaid_card', true ) ? 'yes' : 'no', |
|
87
|
|
|
), |
|
88
|
|
|
'nonce' => array( |
|
89
|
|
|
'payment' => wp_create_nonce( 'wc-stripe-payment-request' ), |
|
90
|
|
|
'shipping' => wp_create_nonce( 'wc-stripe-payment-request-shipping' ), |
|
91
|
|
|
'update_shipping' => wp_create_nonce( 'wc-stripe-update-shipping-method' ), |
|
92
|
|
|
'checkout' => wp_create_nonce( 'woocommerce-process_checkout' ), |
|
93
|
|
|
), |
|
94
|
|
|
'i18n' => array( |
|
95
|
|
|
'no_prepaid_card' => __( 'Sorry, we\'re not accepting prepaid cards at this time.', 'woocommerce-gateway-stripe' ), |
|
96
|
|
|
/* translators: Do not translate the [option] placeholder */ |
|
97
|
|
|
'unknown_shipping' => __( 'Unknown shipping option "[option]".', 'woocommerce-gateway-stripe' ), |
|
98
|
|
|
), |
|
99
|
|
|
) |
|
100
|
|
|
); |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
/** |
|
104
|
|
|
* Get cart details. |
|
105
|
|
|
*/ |
|
106
|
|
|
public function ajax_get_cart_details() { |
|
107
|
|
|
check_ajax_referer( 'wc-stripe-payment-request', 'security' ); |
|
108
|
|
|
|
|
109
|
|
|
if ( ! defined( 'WOOCOMMERCE_CART' ) ) { |
|
110
|
|
|
define( 'WOOCOMMERCE_CART', true ); |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
WC()->cart->calculate_totals(); |
|
114
|
|
|
|
|
115
|
|
|
$currency = get_woocommerce_currency(); |
|
116
|
|
|
|
|
117
|
|
|
// Set mandatory payment details. |
|
118
|
|
|
$data = array( |
|
119
|
|
|
'shipping_required' => WC()->cart->needs_shipping(), |
|
120
|
|
|
'order_data' => array( |
|
121
|
|
|
'total' => array( |
|
122
|
|
|
'label' => __( 'Total', 'woocommerce-gateway-stripe' ), |
|
123
|
|
|
'amount' => array( |
|
124
|
|
|
'value' => max( 0, apply_filters( 'woocommerce_calculated_total', round( WC()->cart->cart_contents_total + WC()->cart->fee_total, WC()->cart->dp ), WC()->cart ) ), |
|
125
|
|
|
'currency' => $currency, |
|
126
|
|
|
), |
|
127
|
|
|
), |
|
128
|
|
|
), |
|
129
|
|
|
); |
|
130
|
|
|
|
|
131
|
|
|
wp_send_json( $data ); |
|
132
|
|
|
} |
|
133
|
|
|
|
|
134
|
|
|
/** |
|
135
|
|
|
* Calculate and set shipping method. |
|
136
|
|
|
* |
|
137
|
|
|
* @since 3.1.0 |
|
138
|
|
|
* @version 3.1.0 |
|
139
|
|
|
* @param array $address |
|
140
|
|
|
*/ |
|
141
|
|
|
public function calculate_shipping( $address = array() ) { |
|
142
|
|
|
$country = $address['country']; |
|
143
|
|
|
$state = $address['state']; |
|
144
|
|
|
$postcode = $address['postcode']; |
|
145
|
|
|
$city = $address['city']; |
|
146
|
|
|
$address_1 = $address['address']; |
|
147
|
|
|
$address_2 = $address['address_2']; |
|
148
|
|
|
|
|
149
|
|
|
WC()->shipping->reset_shipping(); |
|
150
|
|
|
|
|
151
|
|
|
if ( $postcode && WC_Validation::is_postcode( $postcode, $country ) ) { |
|
152
|
|
|
$postcode = wc_format_postcode( $postcode, $country ); |
|
153
|
|
|
} |
|
154
|
|
|
|
|
155
|
|
View Code Duplication |
if ( $country ) { |
|
|
|
|
|
|
156
|
|
|
WC()->customer->set_location( $country, $state, $postcode, $city ); |
|
157
|
|
|
WC()->customer->set_shipping_location( $country, $state, $postcode, $city ); |
|
158
|
|
|
} else { |
|
159
|
|
|
WC()->customer->set_to_base(); |
|
160
|
|
|
WC()->customer->set_shipping_to_base(); |
|
161
|
|
|
} |
|
162
|
|
|
|
|
163
|
|
|
WC()->customer->calculated_shipping( true ); |
|
164
|
|
|
|
|
165
|
|
|
$packages = array(); |
|
166
|
|
|
|
|
167
|
|
|
$packages[0]['contents'] = WC()->cart->get_cart(); |
|
168
|
|
|
$packages[0]['contents_cost'] = 0; |
|
169
|
|
|
$packages[0]['applied_coupons'] = WC()->cart->applied_coupons; |
|
170
|
|
|
$packages[0]['user']['ID'] = get_current_user_id(); |
|
171
|
|
|
$packages[0]['destination']['country'] = $country; |
|
172
|
|
|
$packages[0]['destination']['state'] = $state; |
|
173
|
|
|
$packages[0]['destination']['postcode'] = $postcode; |
|
174
|
|
|
$packages[0]['destination']['city'] = $city; |
|
175
|
|
|
$packages[0]['destination']['address'] = $address_1; |
|
176
|
|
|
$packages[0]['destination']['address_2'] = $address_2; |
|
177
|
|
|
|
|
178
|
|
View Code Duplication |
foreach ( WC()->cart->get_cart() as $item ) { |
|
|
|
|
|
|
179
|
|
|
if ( $item['data']->needs_shipping() ) { |
|
180
|
|
|
if ( isset( $item['line_total'] ) ) { |
|
181
|
|
|
$packages[0]['contents_cost'] += $item['line_total']; |
|
182
|
|
|
} |
|
183
|
|
|
} |
|
184
|
|
|
} |
|
185
|
|
|
|
|
186
|
|
|
$packages = apply_filters( 'woocommerce_cart_shipping_packages', $packages ); |
|
187
|
|
|
|
|
188
|
|
|
WC()->shipping->calculate_shipping( $packages ); |
|
189
|
|
|
} |
|
190
|
|
|
|
|
191
|
|
|
/** |
|
192
|
|
|
* Get shipping options. |
|
193
|
|
|
* |
|
194
|
|
|
* @see WC_Cart::get_shipping_packages(). |
|
195
|
|
|
* @see WC_Shipping::calculate_shipping(). |
|
196
|
|
|
* @see WC_Shipping::get_packages(). |
|
197
|
|
|
*/ |
|
198
|
|
|
public function ajax_get_shipping_options() { |
|
199
|
|
|
check_ajax_referer( 'wc-stripe-payment-request-shipping', 'security' ); |
|
200
|
|
|
|
|
201
|
|
|
// Set the shipping package. |
|
202
|
|
|
$posted = filter_input_array( INPUT_POST, array( |
|
203
|
|
|
'country' => FILTER_SANITIZE_ENCODED, |
|
204
|
|
|
'state' => FILTER_SANITIZE_STRING, |
|
205
|
|
|
'postcode' => FILTER_SANITIZE_ENCODED, |
|
206
|
|
|
'city' => FILTER_SANITIZE_STRING, |
|
207
|
|
|
'address' => FILTER_SANITIZE_STRING, |
|
208
|
|
|
'address_2' => FILTER_SANITIZE_STRING, |
|
209
|
|
|
) ); |
|
210
|
|
|
|
|
211
|
|
|
$this->calculate_shipping( $posted ); |
|
212
|
|
|
|
|
213
|
|
|
// Set the shipping options. |
|
214
|
|
|
$currency = get_woocommerce_currency(); |
|
215
|
|
|
$data = array(); |
|
216
|
|
|
|
|
217
|
|
|
$packages = WC()->shipping->get_packages(); |
|
218
|
|
|
|
|
219
|
|
|
if ( ! empty( $packages ) && WC()->customer->has_calculated_shipping() ) { |
|
220
|
|
|
foreach ( $packages as $package_key => $package ) { |
|
221
|
|
|
if ( empty( $package['rates'] ) ) { |
|
222
|
|
|
break; |
|
223
|
|
|
} |
|
224
|
|
|
|
|
225
|
|
|
foreach ( $package['rates'] as $key => $rate ) { |
|
226
|
|
|
$data[] = array( |
|
227
|
|
|
'id' => $rate->id, |
|
228
|
|
|
'label' => $rate->label, |
|
229
|
|
|
'amount' => array( |
|
230
|
|
|
'currency' => $currency, |
|
231
|
|
|
'value' => $rate->cost, |
|
232
|
|
|
), |
|
233
|
|
|
'selected' => false, |
|
234
|
|
|
); |
|
235
|
|
|
} |
|
236
|
|
|
} |
|
237
|
|
|
} |
|
238
|
|
|
|
|
239
|
|
|
// Auto select when have only one shipping method available. |
|
240
|
|
|
if ( 1 === count( $data ) ) { |
|
241
|
|
|
$data[0]['selected'] = true; |
|
242
|
|
|
} |
|
243
|
|
|
|
|
244
|
|
|
wp_send_json( $data ); |
|
245
|
|
|
} |
|
246
|
|
|
|
|
247
|
|
|
/** |
|
248
|
|
|
* Update shipping method. |
|
249
|
|
|
*/ |
|
250
|
|
|
public function ajax_update_shipping_method() { |
|
251
|
|
|
check_ajax_referer( 'wc-stripe-update-shipping-method', 'security' ); |
|
252
|
|
|
|
|
253
|
|
|
if ( ! defined( 'WOOCOMMERCE_CART' ) ) { |
|
254
|
|
|
define( 'WOOCOMMERCE_CART', true ); |
|
255
|
|
|
} |
|
256
|
|
|
|
|
257
|
|
|
$chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' ); |
|
258
|
|
|
$shipping_method = filter_input( INPUT_POST, 'shipping_method', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY ); |
|
259
|
|
|
|
|
260
|
|
|
if ( is_array( $shipping_method ) ) { |
|
261
|
|
|
foreach ( $shipping_method as $i => $value ) { |
|
262
|
|
|
$chosen_shipping_methods[ $i ] = wc_clean( $value ); |
|
263
|
|
|
} |
|
264
|
|
|
} |
|
265
|
|
|
|
|
266
|
|
|
WC()->session->set( 'chosen_shipping_methods', $chosen_shipping_methods ); |
|
267
|
|
|
|
|
268
|
|
|
WC()->cart->calculate_totals(); |
|
269
|
|
|
|
|
270
|
|
|
// Send back the new cart total. |
|
271
|
|
|
$currency = get_woocommerce_currency(); |
|
272
|
|
|
$tax_total = max( 0, round( WC()->cart->tax_total + WC()->cart->shipping_tax_total, WC()->cart->dp ) ); |
|
273
|
|
|
$data = array( |
|
274
|
|
|
'total' => WC()->cart->total, |
|
275
|
|
|
); |
|
276
|
|
|
|
|
277
|
|
|
// Include fees and taxes as displayItems. |
|
278
|
|
View Code Duplication |
foreach ( WC()->cart->fees as $key => $fee ) { |
|
|
|
|
|
|
279
|
|
|
$data['items'][] = array( |
|
280
|
|
|
'label' => $fee->name, |
|
281
|
|
|
'amount' => array( |
|
282
|
|
|
'currency' => $currency, |
|
283
|
|
|
'value' => $fee->amount, |
|
284
|
|
|
), |
|
285
|
|
|
); |
|
286
|
|
|
} |
|
287
|
|
View Code Duplication |
if ( 0 < $tax_total ) { |
|
|
|
|
|
|
288
|
|
|
$data['items'][] = array( |
|
289
|
|
|
'label' => __( 'Tax', 'woocommerce-gateway-stripe' ), |
|
290
|
|
|
'amount' => array( |
|
291
|
|
|
'currency' => $currency, |
|
292
|
|
|
'value' => $tax_total, |
|
293
|
|
|
), |
|
294
|
|
|
); |
|
295
|
|
|
} |
|
296
|
|
|
|
|
297
|
|
|
wp_send_json( $data ); |
|
298
|
|
|
} |
|
299
|
|
|
|
|
300
|
|
|
/** |
|
301
|
|
|
* Create order. |
|
302
|
|
|
*/ |
|
303
|
|
|
public function ajax_create_order() { |
|
304
|
|
|
if ( WC()->cart->is_empty() ) { |
|
305
|
|
|
wp_send_json_error( __( 'Empty cart', 'woocommerce-gateway-stripe' ) ); |
|
306
|
|
|
} |
|
307
|
|
|
|
|
308
|
|
|
if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) { |
|
309
|
|
|
define( 'WOOCOMMERCE_CHECKOUT', true ); |
|
310
|
|
|
} |
|
311
|
|
|
|
|
312
|
|
|
WC()->checkout()->process_checkout(); |
|
313
|
|
|
|
|
314
|
|
|
die( 0 ); |
|
315
|
|
|
} |
|
316
|
|
|
} |
|
317
|
|
|
|
|
318
|
|
|
new WC_Stripe_Payment_Request(); |
|
319
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.