woocommerce /
woocommerce-gateway-stripe
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | if ( ! defined( 'ABSPATH' ) ) { |
||
| 3 | exit; |
||
| 4 | } |
||
| 5 | |||
| 6 | /** |
||
| 7 | * WC_Stripe_Apple_Pay class. |
||
| 8 | * |
||
| 9 | * @extends WC_Gateway_Stripe |
||
| 10 | */ |
||
| 11 | class WC_Stripe_Apple_Pay extends WC_Gateway_Stripe { |
||
| 12 | /** |
||
| 13 | * This Instance. |
||
| 14 | * |
||
| 15 | * @var |
||
| 16 | */ |
||
| 17 | private static $_this; |
||
| 18 | |||
| 19 | /** |
||
| 20 | * Gateway. |
||
| 21 | * |
||
| 22 | * @var |
||
| 23 | */ |
||
| 24 | private $_gateway; |
||
| 25 | |||
| 26 | /** |
||
| 27 | * Statement Description |
||
| 28 | * |
||
| 29 | * @var |
||
| 30 | */ |
||
| 31 | public $statement_descriptor; |
||
| 32 | |||
| 33 | /** |
||
| 34 | * Gateway settings. |
||
| 35 | * |
||
| 36 | * @var |
||
| 37 | */ |
||
| 38 | private $_gateway_settings; |
||
| 39 | |||
| 40 | /** |
||
| 41 | * Constructor. |
||
| 42 | * |
||
| 43 | * @access public |
||
| 44 | * @since 3.1.0 |
||
| 45 | * @version 3.1.0 |
||
| 46 | */ |
||
| 47 | public function __construct() { |
||
| 48 | self::$_this = $this; |
||
| 49 | |||
| 50 | $this->_gateway_settings = get_option( 'woocommerce_stripe_settings', '' ); |
||
| 51 | |||
| 52 | $this->statement_descriptor = ! empty( $this->_gateway_settings['statement_descriptor'] ) ? $this->_gateway_settings['statement_descriptor'] : wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ); |
||
| 53 | |||
| 54 | $this->init(); |
||
| 55 | } |
||
| 56 | |||
| 57 | public function instance() { |
||
| 58 | return self::$_this; |
||
| 59 | } |
||
| 60 | |||
| 61 | /** |
||
| 62 | * Initialize. |
||
| 63 | * |
||
| 64 | * @access public |
||
| 65 | * @since 3.1.0 |
||
| 66 | * @version 3.1.4 |
||
| 67 | */ |
||
| 68 | public function init() { |
||
| 69 | // If Apple Pay is not enabled no need to proceed further. |
||
| 70 | if ( 'yes' !== $this->_gateway_settings['apple_pay'] ) { |
||
| 71 | return; |
||
| 72 | } |
||
| 73 | |||
| 74 | add_action( 'wp_enqueue_scripts', array( $this, 'cart_scripts' ) ); |
||
| 75 | add_action( 'wp_enqueue_scripts', array( $this, 'single_scripts' ) ); |
||
| 76 | |||
| 77 | /** |
||
| 78 | * In order to display the Apple Pay button in the correct position, |
||
| 79 | * a new hook was added to WooCommerce 3.0. In older versions of WooCommerce, |
||
| 80 | * CSS is used to position the button. |
||
| 81 | */ |
||
| 82 | if ( version_compare( WC_VERSION, '3.0.0', '<' ) ) { |
||
| 83 | add_action( 'woocommerce_after_add_to_cart_button', array( $this, 'display_apple_pay_button' ), 1 ); |
||
| 84 | } else { |
||
| 85 | add_action( 'woocommerce_after_add_to_cart_quantity', array( $this, 'display_apple_pay_button' ), 1 ); |
||
| 86 | } |
||
| 87 | |||
| 88 | add_action( 'woocommerce_proceed_to_checkout', array( $this, 'display_apple_pay_button' ), 1 ); |
||
| 89 | add_action( 'woocommerce_proceed_to_checkout', array( $this, 'display_apple_pay_separator_html' ), 2 ); |
||
| 90 | add_action( 'woocommerce_checkout_before_customer_details', array( $this, 'display_apple_pay_button' ), 1 ); |
||
| 91 | add_action( 'woocommerce_checkout_before_customer_details', array( $this, 'display_apple_pay_separator_html' ), 2 ); |
||
| 92 | add_action( 'wc_ajax_wc_stripe_apple_pay', array( $this, 'process_apple_pay' ) ); |
||
| 93 | add_action( 'wc_ajax_wc_stripe_generate_apple_pay_cart', array( $this, 'generate_apple_pay_cart' ) ); |
||
| 94 | add_action( 'wc_ajax_wc_stripe_apple_pay_clear_cart', array( $this, 'clear_cart' ) ); |
||
| 95 | add_action( 'wc_ajax_wc_stripe_generate_apple_pay_single', array( $this, 'generate_apple_pay_single' ) ); |
||
| 96 | add_action( 'wc_ajax_wc_stripe_apple_pay_get_shipping_methods', array( $this, 'get_shipping_methods' ) ); |
||
| 97 | add_action( 'wc_ajax_wc_stripe_apple_pay_update_shipping_method', array( $this, 'update_shipping_method' ) ); |
||
| 98 | add_filter( 'woocommerce_gateway_title', array( $this, 'filter_gateway_title' ), 10, 2 ); |
||
| 99 | add_filter( 'woocommerce_validate_postcode', array( $this, 'postal_code_validation' ), 10, 3 ); |
||
| 100 | } |
||
| 101 | |||
| 102 | /** |
||
| 103 | * Filters the gateway title to reflect Apple Pay. |
||
| 104 | * |
||
| 105 | */ |
||
| 106 | public function filter_gateway_title( $title, $id ) { |
||
| 107 | global $post; |
||
| 108 | |||
| 109 | if ( ! is_object( $post ) ) { |
||
| 110 | return $title; |
||
| 111 | } |
||
| 112 | |||
| 113 | $method_title = get_post_meta( $post->ID, '_payment_method_title', true ); |
||
| 114 | |||
| 115 | if ( 'stripe' === $id && ! empty( $method_title ) ) { |
||
| 116 | return $method_title; |
||
| 117 | } |
||
| 118 | |||
| 119 | return $title; |
||
| 120 | } |
||
| 121 | |||
| 122 | /** |
||
| 123 | * Removes postal code validation from WC. |
||
| 124 | * |
||
| 125 | * @since 3.1.4 |
||
| 126 | * @version 3.1.4 |
||
| 127 | */ |
||
| 128 | public function postal_code_validation( $valid, $postcode, $country ) { |
||
| 129 | $gateways = WC()->payment_gateways->get_available_payment_gateways(); |
||
| 130 | |||
| 131 | if ( |
||
| 132 | 'yes' !== $this->_gateway_settings['apple_pay'] |
||
| 133 | || ! isset( $gateways['stripe'] ) |
||
| 134 | ) { |
||
| 135 | return $valid; |
||
| 136 | } |
||
| 137 | |||
| 138 | /** |
||
| 139 | * Currently Apple Pay truncates postal codes from UK and Canada to first 3 characters |
||
| 140 | * when passing it back from the shippingcontactselected object. This causes WC to invalidate |
||
| 141 | * the order and not let it go through. The remedy for now is just to remove this validation. |
||
| 142 | */ |
||
| 143 | if ( 'GB' === $country || 'CA' === $country ) { |
||
| 144 | return true; |
||
| 145 | } |
||
| 146 | |||
| 147 | return $valid; |
||
| 148 | } |
||
| 149 | |||
| 150 | /** |
||
| 151 | * Enqueue JS scripts and styles for single product page. |
||
| 152 | * |
||
| 153 | * @since 3.1.0 |
||
| 154 | * @version 3.1.4 |
||
| 155 | */ |
||
| 156 | public function single_scripts() { |
||
| 157 | if ( ! is_single() ) { |
||
| 158 | return; |
||
| 159 | } |
||
| 160 | |||
| 161 | global $post; |
||
| 162 | |||
| 163 | $product = wc_get_product( $post->ID ); |
||
| 164 | |||
| 165 | View Code Duplication | if ( ! is_object( $product ) || ! in_array( ( version_compare( WC_VERSION, '3.0.0', '<' ) ? $product->product_type : $product->get_type() ), $this->supported_product_types() ) ) { |
|
|
0 ignored issues
–
show
|
|||
| 166 | return; |
||
| 167 | } |
||
| 168 | |||
| 169 | $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; |
||
| 170 | |||
| 171 | wp_enqueue_style( 'stripe_apple_pay', plugins_url( 'assets/css/stripe-apple-pay.css', WC_STRIPE_MAIN_FILE ), array(), WC_STRIPE_VERSION ); |
||
| 172 | |||
| 173 | wp_enqueue_script( 'stripe', 'https://js.stripe.com/v2/', '', '1.0', true ); |
||
| 174 | wp_enqueue_script( 'woocommerce_stripe_apple_pay_single', plugins_url( 'assets/js/stripe-apple-pay-single' . $suffix . '.js', WC_STRIPE_MAIN_FILE ), array( 'stripe' ), WC_STRIPE_VERSION, true ); |
||
| 175 | |||
| 176 | $publishable_key = 'yes' === $this->_gateway_settings['testmode'] ? $this->_gateway_settings['test_publishable_key'] : $this->_gateway_settings['publishable_key']; |
||
| 177 | |||
| 178 | $stripe_params = array( |
||
| 179 | 'key' => $publishable_key, |
||
| 180 | 'currency_code' => get_woocommerce_currency(), |
||
| 181 | 'country_code' => substr( get_option( 'woocommerce_default_country' ), 0, 2 ), |
||
| 182 | 'label' => $this->statement_descriptor, |
||
| 183 | 'ajaxurl' => WC_AJAX::get_endpoint( '%%endpoint%%' ), |
||
| 184 | 'stripe_apple_pay_nonce' => wp_create_nonce( '_wc_stripe_apple_pay_nonce' ), |
||
| 185 | 'stripe_apple_pay_cart_nonce' => wp_create_nonce( '_wc_stripe_apple_pay_cart_nonce' ), |
||
| 186 | 'stripe_apple_pay_get_shipping_methods_nonce' => wp_create_nonce( '_wc_stripe_apple_pay_get_shipping_methods_nonce' ), |
||
| 187 | 'stripe_apple_pay_update_shipping_method_nonce' => wp_create_nonce( '_wc_stripe_apple_pay_update_shipping_method_nonce' ), |
||
| 188 | 'needs_shipping' => $product->needs_shipping() ? 'yes' : 'no', |
||
| 189 | 'i18n' => array( |
||
| 190 | 'sub_total' => __( 'Sub-Total', 'woocommerce-gateway-stripe' ), |
||
| 191 | ), |
||
| 192 | ); |
||
| 193 | |||
| 194 | wp_localize_script( 'woocommerce_stripe_apple_pay_single', 'wc_stripe_apple_pay_single_params', apply_filters( 'wc_stripe_apple_pay_single_params', $stripe_params ) ); |
||
| 195 | } |
||
| 196 | |||
| 197 | /** |
||
| 198 | * Enqueue JS scripts and styles for the cart/checkout. |
||
| 199 | * |
||
| 200 | * @since 3.1.0 |
||
| 201 | * @version 3.1.0 |
||
| 202 | */ |
||
| 203 | public function cart_scripts() { |
||
| 204 | if ( ! is_cart() && ! is_checkout() && ! isset( $_GET['pay_for_order'] ) ) { |
||
| 205 | return; |
||
| 206 | } |
||
| 207 | |||
| 208 | $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; |
||
| 209 | |||
| 210 | wp_enqueue_style( 'stripe_apple_pay', plugins_url( 'assets/css/stripe-apple-pay.css', WC_STRIPE_MAIN_FILE ), array(), WC_STRIPE_VERSION ); |
||
| 211 | |||
| 212 | wp_enqueue_script( 'stripe', 'https://js.stripe.com/v2/', '', '1.0', true ); |
||
| 213 | wp_enqueue_script( 'woocommerce_stripe_apple_pay', plugins_url( 'assets/js/stripe-apple-pay' . $suffix . '.js', WC_STRIPE_MAIN_FILE ), array( 'stripe' ), WC_STRIPE_VERSION, true ); |
||
| 214 | |||
| 215 | $publishable_key = 'yes' === $this->_gateway_settings['testmode'] ? $this->_gateway_settings['test_publishable_key'] : $this->_gateway_settings['publishable_key']; |
||
| 216 | |||
| 217 | $stripe_params = array( |
||
| 218 | 'key' => $publishable_key, |
||
| 219 | 'currency_code' => get_woocommerce_currency(), |
||
| 220 | 'country_code' => substr( get_option( 'woocommerce_default_country' ), 0, 2 ), |
||
| 221 | 'label' => $this->statement_descriptor, |
||
| 222 | 'ajaxurl' => WC_AJAX::get_endpoint( '%%endpoint%%' ), |
||
| 223 | 'stripe_apple_pay_nonce' => wp_create_nonce( '_wc_stripe_apple_pay_nonce' ), |
||
| 224 | 'stripe_apple_pay_cart_nonce' => wp_create_nonce( '_wc_stripe_apple_pay_cart_nonce' ), |
||
| 225 | 'stripe_apple_pay_get_shipping_methods_nonce' => wp_create_nonce( '_wc_stripe_apple_pay_get_shipping_methods_nonce' ), |
||
| 226 | 'stripe_apple_pay_update_shipping_method_nonce' => wp_create_nonce( '_wc_stripe_apple_pay_update_shipping_method_nonce' ), |
||
| 227 | 'needs_shipping' => WC()->cart->needs_shipping() ? 'yes' : 'no', |
||
| 228 | 'is_cart_page' => is_cart() ? 'yes' : 'no', |
||
| 229 | ); |
||
| 230 | |||
| 231 | wp_localize_script( 'woocommerce_stripe_apple_pay', 'wc_stripe_apple_pay_params', apply_filters( 'wc_stripe_apple_pay_params', $stripe_params ) ); |
||
| 232 | } |
||
| 233 | |||
| 234 | /** |
||
| 235 | * Checks to make sure product type is supported by Apple Pay. |
||
| 236 | * |
||
| 237 | */ |
||
| 238 | public function supported_product_types() { |
||
| 239 | return array( |
||
| 240 | 'simple', |
||
| 241 | 'variable', |
||
| 242 | ); |
||
| 243 | } |
||
| 244 | |||
| 245 | /** |
||
| 246 | * Display Apple Pay button on the cart page |
||
| 247 | * |
||
| 248 | * @since 3.1.0 |
||
| 249 | * @version 3.1.0 |
||
| 250 | */ |
||
| 251 | public function display_apple_pay_button() { |
||
| 252 | $gateways = WC()->payment_gateways->get_available_payment_gateways(); |
||
| 253 | |||
| 254 | /** |
||
| 255 | * In order for the Apple Pay button to show on product detail page, |
||
| 256 | * Apple Pay must be enabled and Stripe gateway must be enabled. |
||
| 257 | */ |
||
| 258 | if ( |
||
| 259 | 'yes' !== $this->_gateway_settings['apple_pay'] |
||
| 260 | || ! isset( $gateways['stripe'] ) |
||
| 261 | ) { |
||
| 262 | return; |
||
| 263 | } |
||
| 264 | |||
| 265 | if ( is_single() ) { |
||
| 266 | global $post; |
||
| 267 | |||
| 268 | $product = wc_get_product( $post->ID ); |
||
| 269 | |||
| 270 | View Code Duplication | if ( ! is_object( $product ) || ! in_array( ( version_compare( WC_VERSION, '3.0.0', '<' ) ? $product->product_type : $product->get_type() ), $this->supported_product_types() ) ) { |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
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. Loading history...
|
|||
| 271 | return; |
||
| 272 | } |
||
| 273 | } |
||
| 274 | |||
| 275 | $apple_pay_button = ! empty( $this->_gateway_settings['apple_pay_button'] ) ? $this->_gateway_settings['apple_pay_button'] : 'black'; |
||
| 276 | $button_lang = ! empty( $this->_gateway_settings['apple_pay_button_lang'] ) ? strtolower( $this->_gateway_settings['apple_pay_button_lang'] ) : 'en'; |
||
| 277 | ?> |
||
| 278 | <div class="apple-pay-button-wrapper"> |
||
| 279 | <button class="apple-pay-button" lang="<?php echo esc_attr( $button_lang ); ?>" style="-webkit-appearance: -apple-pay-button; -apple-pay-button-type: buy; -apple-pay-button-style: <?php echo esc_attr( $apple_pay_button ); ?>;"></button> |
||
| 280 | </div> |
||
| 281 | <?php |
||
| 282 | } |
||
| 283 | |||
| 284 | /** |
||
| 285 | * Display Apple Pay button on the cart page |
||
| 286 | * |
||
| 287 | * @since 3.1.0 |
||
| 288 | * @version 3.1.0 |
||
| 289 | */ |
||
| 290 | public function display_apple_pay_separator_html() { |
||
| 291 | $gateways = WC()->payment_gateways->get_available_payment_gateways(); |
||
| 292 | |||
| 293 | /** |
||
| 294 | * In order for the Apple Pay button to show on cart page, |
||
| 295 | * Apple Pay must be enabled and Stripe gateway must be enabled. |
||
| 296 | */ |
||
| 297 | if ( |
||
| 298 | 'yes' !== $this->_gateway_settings['apple_pay'] |
||
| 299 | || ! isset( $gateways['stripe'] ) |
||
| 300 | ) { |
||
| 301 | return; |
||
| 302 | } |
||
| 303 | |||
| 304 | if ( is_single() ) { |
||
| 305 | global $post; |
||
| 306 | |||
| 307 | $product = wc_get_product( $post->ID ); |
||
| 308 | |||
| 309 | View Code Duplication | if ( ! is_object( $product ) || ! in_array( ( version_compare( WC_VERSION, '3.0.0', '<' ) ? $product->product_type : $product->get_type() ), $this->supported_product_types() ) ) { |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
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. Loading history...
|
|||
| 310 | return; |
||
| 311 | } |
||
| 312 | } |
||
| 313 | ?> |
||
| 314 | <p class="apple-pay-button-checkout-separator">- <?php esc_html_e( 'Or', 'woocommerce-gateway-stripe' ); ?> -</p> |
||
| 315 | <?php |
||
| 316 | } |
||
| 317 | |||
| 318 | /** |
||
| 319 | * Generates the Apple Pay single cart. |
||
| 320 | * |
||
| 321 | * @since 3.1.0 |
||
| 322 | * @version 3.1.0 |
||
| 323 | */ |
||
| 324 | public function generate_apple_pay_single() { |
||
| 325 | if ( ! wp_verify_nonce( $_POST['nonce'], '_wc_stripe_apple_pay_cart_nonce' ) ) { |
||
| 326 | wp_die( __( 'Cheatin’ huh?', 'woocommerce-gateway-stripe' ) ); |
||
| 327 | } |
||
| 328 | |||
| 329 | if ( ! defined( 'WOOCOMMERCE_CART' ) ) { |
||
| 330 | define( 'WOOCOMMERCE_CART', true ); |
||
| 331 | } |
||
| 332 | |||
| 333 | WC()->shipping->reset_shipping(); |
||
| 334 | |||
| 335 | global $post; |
||
| 336 | |||
| 337 | $product = wc_get_product( $post->ID ); |
||
| 338 | $qty = ! isset( $_POST['qty'] ) ? 1 : absint( $_POST['qty'] ); |
||
| 339 | |||
| 340 | /** |
||
| 341 | * If this page is single product page, we need to simulate |
||
| 342 | * adding the product to the cart taken account if it is a |
||
| 343 | * simple or variable product. |
||
| 344 | */ |
||
| 345 | if ( is_single() ) { |
||
| 346 | // First empty the cart to prevent wrong calculation. |
||
| 347 | WC()->cart->empty_cart(); |
||
| 348 | |||
| 349 | if ( 'variable' === ( version_compare( WC_VERSION, '3.0.0', '<' ) ? $product->product_type : $product->get_type() ) && isset( $_POST['attributes'] ) ) { |
||
| 350 | $attributes = array_map( 'wc_clean', $_POST['attributes'] ); |
||
| 351 | |||
| 352 | if ( version_compare( WC_VERSION, '3.0.0', '<' ) ) { |
||
| 353 | $variation_id = $product->get_matching_variation( $attributes ); |
||
| 354 | } else { |
||
| 355 | $data_store = WC_Data_Store::load( 'product' ); |
||
| 356 | $variation_id = $data_store->find_matching_product_variation( $product, $attributes ); |
||
| 357 | } |
||
| 358 | |||
| 359 | WC()->cart->add_to_cart( $product->get_id(), $qty, $variation_id, $attributes ); |
||
| 360 | } |
||
| 361 | |||
| 362 | if ( 'simple' === ( version_compare( WC_VERSION, '3.0.0', '<' ) ? $product->product_type : $product->get_type() ) ) { |
||
| 363 | WC()->cart->add_to_cart( $product->get_id(), $qty ); |
||
| 364 | } |
||
| 365 | } |
||
| 366 | |||
| 367 | WC()->cart->calculate_totals(); |
||
| 368 | |||
| 369 | wp_send_json( array( 'line_items' => $this->build_line_items(), 'total' => WC()->cart->total ) ); |
||
| 370 | } |
||
| 371 | |||
| 372 | /** |
||
| 373 | * Generates the Apple Pay cart. |
||
| 374 | * |
||
| 375 | * @since 3.1.0 |
||
| 376 | * @version 3.1.0 |
||
| 377 | */ |
||
| 378 | public function generate_apple_pay_cart() { |
||
| 379 | if ( ! wp_verify_nonce( $_POST['nonce'], '_wc_stripe_apple_pay_cart_nonce' ) ) { |
||
| 380 | wp_die( __( 'Cheatin’ huh?', 'woocommerce-gateway-stripe' ) ); |
||
| 381 | } |
||
| 382 | |||
| 383 | wp_send_json( array( 'line_items' => $this->build_line_items(), 'total' => WC()->cart->total ) ); |
||
| 384 | } |
||
| 385 | |||
| 386 | /** |
||
| 387 | * Clears Apple Pay cart. |
||
| 388 | * |
||
| 389 | * @since 3.1.4 |
||
| 390 | * @version 3.1.4 |
||
| 391 | */ |
||
| 392 | public function clear_cart() { |
||
| 393 | WC()->cart->empty_cart(); |
||
| 394 | exit; |
||
| 395 | } |
||
| 396 | |||
| 397 | /** |
||
| 398 | * Calculate and set shipping method. |
||
| 399 | * |
||
| 400 | * @since 3.1.0 |
||
| 401 | * @version 3.1.0 |
||
| 402 | * @param array $address |
||
| 403 | */ |
||
| 404 | public function calculate_shipping( $address = array() ) { |
||
| 405 | $country = strtoupper( $address['countryCode'] ); |
||
| 406 | $state = strtoupper( $address['administrativeArea'] ); |
||
| 407 | $postcode = $address['postalCode']; |
||
| 408 | $city = $address['locality']; |
||
| 409 | |||
| 410 | WC()->shipping->reset_shipping(); |
||
| 411 | |||
| 412 | if ( $postcode && ! WC_Validation::is_postcode( $postcode, $country ) ) { |
||
| 413 | throw new Exception( __( 'Please enter a valid postcode/ZIP.', 'woocommerce-gateway-stripe' ) ); |
||
| 414 | } elseif ( $postcode ) { |
||
| 415 | $postcode = wc_format_postcode( $postcode, $country ); |
||
| 416 | } |
||
| 417 | |||
| 418 | View Code Duplication | if ( $country ) { |
|
| 419 | WC()->customer->set_location( $country, $state, $postcode, $city ); |
||
| 420 | WC()->customer->set_shipping_location( $country, $state, $postcode, $city ); |
||
| 421 | } else { |
||
| 422 | WC()->customer->set_to_base(); |
||
| 423 | WC()->customer->set_shipping_to_base(); |
||
| 424 | } |
||
| 425 | |||
| 426 | WC()->customer->calculated_shipping( true ); |
||
| 427 | |||
| 428 | /** |
||
| 429 | * Set the shipping package. |
||
| 430 | * |
||
| 431 | * Note that address lines are not provided at this point |
||
| 432 | * because Apple Pay does not supply that until after |
||
| 433 | * authentication via passcode or Touch ID. We will need to |
||
| 434 | * capture this information when we process the payment. |
||
| 435 | */ |
||
| 436 | |||
| 437 | $packages = array(); |
||
| 438 | |||
| 439 | $packages[0]['contents'] = WC()->cart->get_cart(); |
||
| 440 | $packages[0]['contents_cost'] = 0; |
||
| 441 | $packages[0]['applied_coupons'] = WC()->cart->applied_coupons; |
||
| 442 | $packages[0]['user']['ID'] = get_current_user_id(); |
||
| 443 | $packages[0]['destination']['country'] = $country; |
||
| 444 | $packages[0]['destination']['state'] = $state; |
||
| 445 | $packages[0]['destination']['postcode'] = $postcode; |
||
| 446 | $packages[0]['destination']['city'] = $city; |
||
| 447 | |||
| 448 | View Code Duplication | foreach ( WC()->cart->get_cart() as $item ) { |
|
| 449 | if ( $item['data']->needs_shipping() ) { |
||
| 450 | if ( isset( $item['line_total'] ) ) { |
||
| 451 | $packages[0]['contents_cost'] += $item['line_total']; |
||
| 452 | } |
||
| 453 | } |
||
| 454 | } |
||
| 455 | |||
| 456 | $packages = apply_filters( 'woocommerce_cart_shipping_packages', $packages ); |
||
| 457 | |||
| 458 | WC()->shipping->calculate_shipping( $packages ); |
||
| 459 | } |
||
| 460 | |||
| 461 | /** |
||
| 462 | * Gets shipping for Apple Pay Payment sheet. |
||
| 463 | * |
||
| 464 | * @since 3.1.0 |
||
| 465 | * @version 3.1.0 |
||
| 466 | */ |
||
| 467 | public function get_shipping_methods() { |
||
| 468 | if ( ! wp_verify_nonce( $_POST['nonce'], '_wc_stripe_apple_pay_get_shipping_methods_nonce' ) ) { |
||
| 469 | wp_die( __( 'Cheatin’ huh?', 'woocommerce-gateway-stripe' ) ); |
||
| 470 | } |
||
| 471 | |||
| 472 | if ( ! defined( 'WOOCOMMERCE_CART' ) ) { |
||
| 473 | define( 'WOOCOMMERCE_CART', true ); |
||
| 474 | } |
||
| 475 | |||
| 476 | try { |
||
| 477 | $address = array_map( 'wc_clean', $_POST['address'] ); |
||
| 478 | |||
| 479 | $this->calculate_shipping( $address ); |
||
| 480 | |||
| 481 | // Set the shipping options. |
||
| 482 | $currency = get_woocommerce_currency(); |
||
| 483 | $data = array(); |
||
| 484 | |||
| 485 | $packages = WC()->shipping->get_packages(); |
||
| 486 | |||
| 487 | if ( ! empty( $packages ) && WC()->customer->has_calculated_shipping() ) { |
||
| 488 | foreach ( $packages as $package_key => $package ) { |
||
| 489 | if ( empty( $package['rates'] ) ) { |
||
| 490 | throw new Exception( __( 'Unable to find shipping method for address.', 'woocommerce-gateway-stripe' ) ); |
||
| 491 | } |
||
| 492 | |||
| 493 | foreach ( $package['rates'] as $key => $rate ) { |
||
| 494 | $data[] = array( |
||
| 495 | 'id' => $rate->id, |
||
| 496 | 'label' => $rate->label, |
||
| 497 | 'amount' => array( |
||
| 498 | 'currency' => $currency, |
||
| 499 | 'value' => $rate->cost, |
||
| 500 | ), |
||
| 501 | 'selected' => false, |
||
| 502 | ); |
||
| 503 | } |
||
| 504 | } |
||
| 505 | |||
| 506 | // Auto select the first shipping method. |
||
| 507 | WC()->session->set( 'chosen_shipping_methods', array( $data[0]['id'] ) ); |
||
| 508 | |||
| 509 | WC()->cart->calculate_totals(); |
||
| 510 | |||
| 511 | wp_send_json( array( 'success' => 'true', 'shipping_methods' => $this->build_shipping_methods( $data ), 'line_items' => $this->build_line_items(), 'total' => WC()->cart->total ) ); |
||
| 512 | } else { |
||
| 513 | throw new Exception( __( 'Unable to find shipping method for address.', 'woocommerce-gateway-stripe' ) ); |
||
| 514 | } |
||
| 515 | } catch ( Exception $e ) { |
||
| 516 | wp_send_json( array( 'success' => 'false', 'shipping_methods' => array(), 'line_items' => $this->build_line_items(), 'total' => WC()->cart->total ) ); |
||
| 517 | } |
||
| 518 | } |
||
| 519 | |||
| 520 | /** |
||
| 521 | * Updates shipping method on cart session. |
||
| 522 | * |
||
| 523 | * @since 3.1.0 |
||
| 524 | * @version 3.1.0 |
||
| 525 | */ |
||
| 526 | public function update_shipping_method() { |
||
| 527 | if ( ! defined( 'WOOCOMMERCE_CART' ) ) { |
||
| 528 | define( 'WOOCOMMERCE_CART', true ); |
||
| 529 | } |
||
| 530 | |||
| 531 | if ( ! wp_verify_nonce( $_POST['nonce'], '_wc_stripe_apple_pay_update_shipping_method_nonce' ) ) { |
||
| 532 | wp_die( __( 'Cheatin’ huh?', 'woocommerce-gateway-stripe' ) ); |
||
| 533 | } |
||
| 534 | |||
| 535 | $selected_shipping_method = array_map( 'wc_clean', $_POST['selected_shipping_method'] ); |
||
| 536 | |||
| 537 | WC()->session->set( 'chosen_shipping_methods', array( $selected_shipping_method['identifier'] ) ); |
||
| 538 | |||
| 539 | WC()->cart->calculate_totals(); |
||
| 540 | |||
| 541 | // Send back the new cart total. |
||
| 542 | $currency = get_woocommerce_currency(); |
||
| 543 | $tax_total = max( 0, round( WC()->cart->tax_total + WC()->cart->shipping_tax_total, WC()->cart->dp ) ); |
||
| 544 | $data = array( |
||
| 545 | 'total' => WC()->cart->total, |
||
| 546 | ); |
||
| 547 | |||
| 548 | // Include fees and taxes as displayItems. |
||
| 549 | View Code Duplication | foreach ( WC()->cart->fees as $key => $fee ) { |
|
| 550 | $data['items'][] = array( |
||
| 551 | 'label' => $fee->name, |
||
| 552 | 'amount' => array( |
||
| 553 | 'currency' => $currency, |
||
| 554 | 'value' => $fee->amount, |
||
| 555 | ), |
||
| 556 | ); |
||
| 557 | } |
||
| 558 | View Code Duplication | if ( 0 < $tax_total ) { |
|
| 559 | $data['items'][] = array( |
||
| 560 | 'label' => __( 'Tax', 'woocommerce-gateway-stripe' ), |
||
| 561 | 'amount' => array( |
||
| 562 | 'currency' => $currency, |
||
| 563 | 'value' => $tax_total, |
||
| 564 | ), |
||
| 565 | ); |
||
| 566 | } |
||
| 567 | |||
| 568 | wp_send_json( array( 'success' => 'true', 'line_items' => $this->build_line_items(), 'total' => WC()->cart->total ) ); |
||
| 569 | } |
||
| 570 | |||
| 571 | /** |
||
| 572 | * Handles the Apple Pay processing via AJAX |
||
| 573 | * |
||
| 574 | * @access public |
||
| 575 | * @since 3.1.0 |
||
| 576 | * @version 3.1.0 |
||
| 577 | */ |
||
| 578 | public function process_apple_pay() { |
||
| 579 | if ( ! wp_verify_nonce( $_POST['nonce'], '_wc_stripe_apple_pay_nonce' ) ) { |
||
| 580 | wp_die( __( 'Cheatin’ huh?', 'woocommerce-gateway-stripe' ) ); |
||
| 581 | } |
||
| 582 | |||
| 583 | try { |
||
| 584 | $result = array_map( 'wc_clean', $_POST['result'] ); |
||
| 585 | |||
| 586 | $order = $this->create_order( $result ); |
||
| 587 | |||
| 588 | $order_id = version_compare( WC_VERSION, '3.0.0', '<' ) ? $order->id : $order->get_id(); |
||
| 589 | |||
| 590 | // Handle payment. |
||
| 591 | if ( $order->get_total() > 0 ) { |
||
| 592 | |||
| 593 | View Code Duplication | if ( $order->get_total() * 100 < WC_Stripe::get_minimum_amount() ) { |
|
| 594 | return new WP_Error( 'stripe_error', sprintf( __( 'Sorry, the minimum allowed order total is %1$s to use this payment method.', 'woocommerce-gateway-stripe' ), wc_price( WC_Stripe::get_minimum_amount() / 100 ) ) ); |
||
| 595 | } |
||
| 596 | |||
| 597 | WC_Stripe::log( "Info: Begin processing payment for order {$order_id} for the amount of {$order->get_total()}" ); |
||
| 598 | |||
| 599 | // Make the request. |
||
| 600 | $response = WC_Stripe_API::request( $this->generate_payment_request( $order, $result['token']['id'] ) ); |
||
| 601 | |||
| 602 | if ( is_wp_error( $response ) ) { |
||
| 603 | $localized_messages = $this->get_localized_messages(); |
||
| 604 | |||
| 605 | throw new Exception( ( isset( $localized_messages[ $response->get_error_code() ] ) ? $localized_messages[ $response->get_error_code() ] : $response->get_error_message() ) ); |
||
| 606 | } |
||
| 607 | |||
| 608 | // Process valid response. |
||
| 609 | $this->process_response( $response, $order ); |
||
| 610 | } else { |
||
| 611 | $order->payment_complete(); |
||
| 612 | } |
||
| 613 | |||
| 614 | // Remove cart. |
||
| 615 | WC()->cart->empty_cart(); |
||
| 616 | |||
| 617 | update_post_meta( $order_id, '_customer_user', get_current_user_id() ); |
||
| 618 | update_post_meta( $order_id, '_payment_method_title', __( 'Apple Pay (Stripe)', 'woocommerce-gateway-stripe' ) ); |
||
| 619 | |||
| 620 | // Return thank you page redirect. |
||
| 621 | wp_send_json( array( |
||
| 622 | 'success' => 'true', |
||
| 623 | 'redirect' => $this->get_return_url( $order ), |
||
| 624 | ) ); |
||
| 625 | |||
| 626 | } catch ( Exception $e ) { |
||
| 627 | WC()->session->set( 'refresh_totals', true ); |
||
| 628 | WC_Stripe::log( sprintf( __( 'Error: %s', 'woocommerce-gateway-stripe' ), $e->getMessage() ) ); |
||
| 629 | |||
| 630 | if ( is_object( $order ) && isset( $order_id ) && $order->has_status( array( 'pending', 'failed' ) ) ) { |
||
| 631 | $this->send_failed_order_email( $order_id ); |
||
| 632 | } |
||
| 633 | |||
| 634 | wp_send_json( array( 'success' => 'false', 'msg' => $e->getMessage() ) ); |
||
| 635 | } |
||
| 636 | } |
||
| 637 | |||
| 638 | /** |
||
| 639 | * Generate the request for the payment. |
||
| 640 | * @param WC_Order $order |
||
| 641 | * @param string $source token |
||
| 642 | * @return array() |
||
| 643 | */ |
||
| 644 | protected function generate_payment_request( $order, $source ) { |
||
| 645 | $post_data = array(); |
||
| 646 | $post_data['currency'] = strtolower( version_compare( WC_VERSION, '3.0.0', '<' ) ? $order->get_order_currency() : $order->get_currency() ); |
||
| 647 | $post_data['amount'] = $this->get_stripe_amount( $order->get_total(), $post_data['currency'] ); |
||
| 648 | $post_data['description'] = sprintf( __( '%1$s - Order %2$s', 'woocommerce-gateway-stripe' ), $this->statement_descriptor, $order->get_order_number() ); |
||
| 649 | $post_data['capture'] = 'yes' === $this->_gateway_settings['capture'] ? 'true' : 'false'; |
||
| 650 | |||
| 651 | $billing_email = version_compare( WC_VERSION, '3.0.0', '<' ) ? $order->billing_email : $order->get_billing_email(); |
||
| 652 | |||
| 653 | if ( ! empty( $billing_email ) && apply_filters( 'wc_stripe_send_stripe_receipt', false ) ) { |
||
| 654 | $post_data['receipt_email'] = $billing_email; |
||
| 655 | } |
||
| 656 | |||
| 657 | $post_data['expand[]'] = 'balance_transaction'; |
||
| 658 | $post_data['source'] = $source; |
||
| 659 | |||
| 660 | /** |
||
| 661 | * Filter the return value of the WC_Payment_Gateway_CC::generate_payment_request. |
||
| 662 | * |
||
| 663 | * @since 3.1.0 |
||
| 664 | * @param array $post_data |
||
| 665 | * @param WC_Order $order |
||
| 666 | * @param object $source |
||
| 667 | */ |
||
| 668 | return apply_filters( 'wc_stripe_generate_payment_request', $post_data, $order ); |
||
| 669 | } |
||
| 670 | |||
| 671 | /** |
||
| 672 | * Builds the shippings methods to pass to Apple Pay. |
||
| 673 | * |
||
| 674 | * @since 3.1.0 |
||
| 675 | * @version 3.1.0 |
||
| 676 | */ |
||
| 677 | public function build_shipping_methods( $shipping_methods ) { |
||
| 678 | if ( empty( $shipping_methods ) ) { |
||
| 679 | return array(); |
||
| 680 | } |
||
| 681 | |||
| 682 | $shipping = array(); |
||
| 683 | |||
| 684 | foreach ( $shipping_methods as $method ) { |
||
| 685 | $shipping[] = array( |
||
| 686 | 'label' => $method['label'], |
||
| 687 | 'detail' => '', |
||
| 688 | 'amount' => $method['amount']['value'], |
||
| 689 | 'identifier' => $method['id'], |
||
| 690 | ); |
||
| 691 | } |
||
| 692 | |||
| 693 | return $shipping; |
||
| 694 | } |
||
| 695 | |||
| 696 | /** |
||
| 697 | * Builds the line items to pass to Apple Pay. |
||
| 698 | * |
||
| 699 | * @since 3.1.0 |
||
| 700 | * @version 3.1.0 |
||
| 701 | */ |
||
| 702 | public function build_line_items() { |
||
| 703 | if ( ! defined( 'WOOCOMMERCE_CART' ) ) { |
||
| 704 | define( 'WOOCOMMERCE_CART', true ); |
||
| 705 | } |
||
| 706 | |||
| 707 | $decimals = apply_filters( 'wc_stripe_apple_pay_decimals', 2 ); |
||
| 708 | |||
| 709 | $items = array(); |
||
| 710 | $subtotal = 0; |
||
| 711 | |||
| 712 | foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) { |
||
| 713 | $amount = wc_format_decimal( $values['line_subtotal'], $decimals ); |
||
| 714 | $subtotal += $values['line_subtotal']; |
||
| 715 | $quantity_label = 1 < $values['quantity'] ? ' (x' . $values['quantity'] . ')' : ''; |
||
| 716 | |||
| 717 | $item = array( |
||
| 718 | 'type' => 'final', |
||
| 719 | 'label' => $values['data']->post->post_title . $quantity_label, |
||
| 720 | 'amount' => wc_format_decimal( $amount, $decimals ), |
||
| 721 | ); |
||
| 722 | |||
| 723 | $items[] = $item; |
||
| 724 | } |
||
| 725 | |||
| 726 | // Default show only subtotal instead of itemization. |
||
| 727 | if ( apply_filters( 'wc_stripe_apple_pay_disable_itemization', true ) ) { |
||
| 728 | $items = array(); |
||
| 729 | $items[] = array( |
||
| 730 | 'type' => 'final', |
||
| 731 | 'label' => __( 'Sub-Total', 'woocommerce-gateway-stripe' ), |
||
| 732 | 'amount' => wc_format_decimal( $subtotal, $decimals ), |
||
| 733 | ); |
||
| 734 | } |
||
| 735 | |||
| 736 | $discounts = wc_format_decimal( WC()->cart->get_cart_discount_total(), $decimals ); |
||
| 737 | $tax = wc_format_decimal( WC()->cart->tax_total + WC()->cart->shipping_tax_total, $decimals ); |
||
| 738 | $shipping = wc_format_decimal( WC()->cart->shipping_total, $decimals ); |
||
| 739 | $item_total = wc_format_decimal( WC()->cart->cart_contents_total, $decimals ) + $discounts; |
||
| 740 | $order_total = wc_format_decimal( $item_total + $tax + $shipping, $decimals ); |
||
| 741 | |||
| 742 | if ( wc_tax_enabled() ) { |
||
| 743 | $items[] = array( |
||
| 744 | 'type' => 'final', |
||
| 745 | 'label' => __( 'Tax', 'woocommerce-gateway-stripe' ), |
||
| 746 | 'amount' => $tax, |
||
| 747 | ); |
||
| 748 | } |
||
| 749 | |||
| 750 | View Code Duplication | if ( WC()->cart->needs_shipping() ) { |
|
| 751 | $items[] = array( |
||
| 752 | 'type' => 'final', |
||
| 753 | 'label' => __( 'Shipping', 'woocommerce-gateway-stripe' ), |
||
| 754 | 'amount' => $shipping, |
||
| 755 | ); |
||
| 756 | } |
||
| 757 | |||
| 758 | View Code Duplication | if ( WC()->cart->has_discount() ) { |
|
| 759 | $items[] = array( |
||
| 760 | 'type' => 'final', |
||
| 761 | 'label' => __( 'Discount', 'woocommerce-gateway-stripe' ), |
||
| 762 | 'amount' => '-' . $discounts, |
||
| 763 | ); |
||
| 764 | } |
||
| 765 | |||
| 766 | return $items; |
||
| 767 | } |
||
| 768 | |||
| 769 | /** |
||
| 770 | * Create order programatically. |
||
| 771 | * |
||
| 772 | * @since 3.1.0 |
||
| 773 | * @version 3.1.0 |
||
| 774 | * @param array $data |
||
| 775 | * @return object $order |
||
| 776 | */ |
||
| 777 | public function create_order( $data = array() ) { |
||
| 778 | if ( empty( $data ) ) { |
||
| 779 | throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-gateway-stripe' ), 520 ) ); |
||
| 780 | } |
||
| 781 | |||
| 782 | $order = wc_create_order(); |
||
| 783 | $order_id = version_compare( WC_VERSION, '3.0.0', '<' ) ? $order->id : $order->get_id(); |
||
| 784 | |||
| 785 | if ( is_wp_error( $order ) ) { |
||
| 786 | throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-gateway-stripe' ), 520 ) ); |
||
| 787 | } elseif ( false === $order ) { |
||
| 788 | throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-gateway-stripe' ), 521 ) ); |
||
| 789 | } else { |
||
| 790 | do_action( 'woocommerce_new_order', $order_id ); |
||
| 791 | } |
||
| 792 | |||
| 793 | // Store the line items to the new/resumed order |
||
| 794 | foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) { |
||
| 795 | $item_id = $order->add_product( |
||
| 796 | $values['data'], |
||
| 797 | $values['quantity'], |
||
| 798 | array( |
||
| 799 | 'variation' => $values['variation'], |
||
| 800 | 'totals' => array( |
||
| 801 | 'subtotal' => $values['line_subtotal'], |
||
| 802 | 'subtotal_tax' => $values['line_subtotal_tax'], |
||
| 803 | 'total' => $values['line_total'], |
||
| 804 | 'tax' => $values['line_tax'], |
||
| 805 | 'tax_data' => $values['line_tax_data'], // Since 2.2 |
||
| 806 | ), |
||
| 807 | ) |
||
| 808 | ); |
||
| 809 | |||
| 810 | if ( ! $item_id ) { |
||
| 811 | throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-gateway-stripe' ), 525 ) ); |
||
| 812 | } |
||
| 813 | |||
| 814 | // Allow plugins to add order item meta |
||
| 815 | View Code Duplication | if ( version_compare( WC_VERSION, '3.0', '<' ) ) { |
|
| 816 | do_action( 'woocommerce_add_order_item_meta', $item_id, $values, $cart_item_key ); |
||
| 817 | } else { |
||
| 818 | do_action( 'woocommerce_new_order_item', $item_id, wc_get_product( $item_id ), $order->get_id() ); |
||
| 819 | } |
||
| 820 | } |
||
| 821 | |||
| 822 | // Store fees |
||
| 823 | foreach ( WC()->cart->get_fees() as $fee_key => $fee ) { |
||
| 824 | if ( version_compare( WC_VERSION, '3.0', '<' ) ) { |
||
| 825 | $item_id = $order->add_fee( $fee ); |
||
| 826 | } else { |
||
| 827 | $item = new WC_Order_Item_Fee(); |
||
| 828 | $item->set_props( array( |
||
| 829 | 'name' => $fee->name, |
||
| 830 | 'tax_class' => $fee->taxable ? $fee->tax_class : 0, |
||
| 831 | 'total' => $fee->amount, |
||
| 832 | 'total_tax' => $fee->tax, |
||
| 833 | 'taxes' => array( |
||
| 834 | 'total' => $fee->tax_data, |
||
| 835 | ), |
||
| 836 | 'order_id' => $order->get_id(), |
||
| 837 | ) ); |
||
| 838 | $item_id = $item->save(); |
||
| 839 | $order->add_item( $item ); |
||
| 840 | } |
||
| 841 | |||
| 842 | if ( ! $item_id ) { |
||
| 843 | throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-gateway-stripe' ), 526 ) ); |
||
| 844 | } |
||
| 845 | |||
| 846 | // Allow plugins to add order item meta to fees |
||
| 847 | View Code Duplication | if ( version_compare( WC_VERSION, '3.0', '<' ) ) { |
|
| 848 | do_action( 'woocommerce_add_order_fee_meta', $order_id, $item_id, $fee, $fee_key ); |
||
| 849 | } else { |
||
| 850 | do_action( 'woocommerce_new_order_item', $item_id, $fee, $order->get_id() ); |
||
| 851 | } |
||
| 852 | } |
||
| 853 | |||
| 854 | // Store tax rows |
||
| 855 | foreach ( array_keys( WC()->cart->taxes + WC()->cart->shipping_taxes ) as $tax_rate_id ) { |
||
| 856 | $tax_amount = WC()->cart->get_tax_amount( $tax_rate_id ); |
||
| 857 | $shipping_tax_amount = WC()->cart->get_shipping_tax_amount( $tax_rate_id ); |
||
| 858 | |||
| 859 | if ( version_compare( WC_VERSION, '3.0', '<' ) ) { |
||
| 860 | $item_id = $order->add_tax( $tax_rate_id, $tax_amount, $shipping_tax_amount ); |
||
| 861 | } else { |
||
| 862 | $item = new WC_Order_Item_Tax(); |
||
| 863 | $item->set_props( array( |
||
| 864 | 'rate_id' => $tax_rate_id, |
||
| 865 | 'tax_total' => $tax_amount, |
||
| 866 | 'shipping_tax_total' => $shipping_tax_amount, |
||
| 867 | ) ); |
||
| 868 | $item->set_rate( $tax_rate_id ); |
||
| 869 | $item->set_order_id( $order->get_id() ); |
||
| 870 | $item_id = $item->save(); |
||
| 871 | $order->add_item( $item ); |
||
| 872 | } |
||
| 873 | |||
| 874 | if ( $tax_rate_id && ! $item_id && apply_filters( 'woocommerce_cart_remove_taxes_zero_rate_id', 'zero-rated' ) !== $tax_rate_id ) { |
||
| 875 | throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-gateway-stripe' ), 528 ) ); |
||
| 876 | } |
||
| 877 | } |
||
| 878 | |||
| 879 | // Store coupons |
||
| 880 | $discount = WC()->cart->get_coupon_discount_amount( $code ); |
||
| 881 | $discount_tax = WC()->cart->get_coupon_discount_tax_amount( $code ); |
||
| 882 | |||
| 883 | foreach ( WC()->cart->get_coupons() as $code => $coupon ) { |
||
| 884 | if ( version_compare( WC_VERSION, '3.0', '<' ) ) { |
||
| 885 | $coupon_id = $order->add_coupon( $code, $discount, $discount_tax ); |
||
| 886 | } else { |
||
| 887 | $item = new WC_Order_Item_Coupon(); |
||
| 888 | $item->set_props( array( |
||
| 889 | 'code' => $code, |
||
| 890 | 'discount' => $discount, |
||
| 891 | 'discount_tax' => $discount_tax, |
||
| 892 | 'order_id' => $order->get_id(), |
||
| 893 | ) ); |
||
| 894 | $coupon_id = $item->save(); |
||
| 895 | $order->add_item( $item ); |
||
| 896 | } |
||
| 897 | |||
| 898 | if ( ! $coupon_id ) { |
||
| 899 | throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-gateway-stripe' ), 529 ) ); |
||
| 900 | } |
||
| 901 | } |
||
| 902 | |||
| 903 | // Billing address |
||
| 904 | $billing_address = array(); |
||
| 905 | if ( ! empty( $data['token']['card'] ) ) { |
||
| 906 | // Name from Stripe is a full name string. |
||
| 907 | $name = explode( ' ', $data['token']['card']['name'] ); |
||
| 908 | $lastname = array_pop( $name ); |
||
| 909 | $firstname = implode( ' ', $name ); |
||
| 910 | $billing_address['first_name'] = $firstname; |
||
| 911 | $billing_address['last_name'] = $lastname; |
||
| 912 | $billing_address['email'] = $data['shippingContact']['emailAddress']; |
||
| 913 | $billing_address['phone'] = $data['shippingContact']['phoneNumber']; |
||
| 914 | $billing_address['country'] = $data['token']['card']['country']; |
||
| 915 | $billing_address['address_1'] = $data['token']['card']['address_line1']; |
||
| 916 | $billing_address['address_2'] = $data['token']['card']['address_line2']; |
||
| 917 | $billing_address['city'] = $data['token']['card']['address_city']; |
||
| 918 | $billing_address['state'] = $data['token']['card']['address_state']; |
||
| 919 | $billing_address['postcode'] = $data['token']['card']['address_zip']; |
||
| 920 | } |
||
| 921 | |||
| 922 | // Shipping address. |
||
| 923 | $shipping_address = array(); |
||
| 924 | if ( WC()->cart->needs_shipping() && ! empty( $data['shippingContact'] ) ) { |
||
| 925 | $shipping_address['first_name'] = $data['shippingContact']['givenName']; |
||
| 926 | $shipping_address['last_name'] = $data['shippingContact']['familyName']; |
||
| 927 | $shipping_address['email'] = $data['shippingContact']['emailAddress']; |
||
| 928 | $shipping_address['phone'] = $data['shippingContact']['phoneNumber']; |
||
| 929 | $shipping_address['country'] = $data['shippingContact']['countryCode']; |
||
| 930 | $shipping_address['address_1'] = $data['shippingContact']['addressLines'][0]; |
||
| 931 | $shipping_address['address_2'] = $data['shippingContact']['addressLines'][1]; |
||
| 932 | $shipping_address['city'] = $data['shippingContact']['locality']; |
||
| 933 | $shipping_address['state'] = $data['shippingContact']['administrativeArea']; |
||
| 934 | $shipping_address['postcode'] = $data['shippingContact']['postalCode']; |
||
| 935 | } elseif ( ! empty( $data['shippingContact'] ) ) { |
||
| 936 | $shipping_address['first_name'] = $firstname; |
||
| 937 | $shipping_address['last_name'] = $lastname; |
||
| 938 | $shipping_address['email'] = $data['shippingContact']['emailAddress']; |
||
| 939 | $shipping_address['phone'] = $data['shippingContact']['phoneNumber']; |
||
| 940 | $shipping_address['country'] = $data['token']['card']['country']; |
||
| 941 | $shipping_address['address_1'] = $data['token']['card']['address_line1']; |
||
| 942 | $shipping_address['address_2'] = $data['token']['card']['address_line2']; |
||
| 943 | $shipping_address['city'] = $data['token']['card']['address_city']; |
||
| 944 | $shipping_address['state'] = $data['token']['card']['address_state']; |
||
| 945 | $shipping_address['postcode'] = $data['token']['card']['address_zip']; |
||
| 946 | } |
||
| 947 | |||
| 948 | $order->set_address( $billing_address, 'billing' ); |
||
| 949 | $order->set_address( $shipping_address, 'shipping' ); |
||
| 950 | |||
| 951 | WC()->shipping->calculate_shipping( WC()->cart->get_shipping_packages() ); |
||
| 952 | |||
| 953 | // Get the rate object selected by user. |
||
| 954 | foreach ( WC()->shipping->get_packages() as $package_key => $package ) { |
||
| 955 | foreach ( $package['rates'] as $key => $rate ) { |
||
| 956 | // Loop through user chosen shipping methods. |
||
| 957 | foreach ( WC()->session->get( 'chosen_shipping_methods' ) as $method ) { |
||
| 958 | if ( $method === $key ) { |
||
| 959 | if ( version_compare( WC_VERSION, '3.0', '<' ) ) { |
||
| 960 | $order->add_shipping( $rate ); |
||
| 961 | } else { |
||
| 962 | $item = new WC_Order_Item_Shipping(); |
||
| 963 | $item->set_props( array( |
||
| 964 | 'method_title' => $rate->label, |
||
| 965 | 'method_id' => $rate->id, |
||
| 966 | 'total' => wc_format_decimal( $rate->cost ), |
||
| 967 | 'taxes' => $rate->taxes, |
||
| 968 | 'order_id' => $order->get_id(), |
||
| 969 | ) ); |
||
| 970 | foreach ( $rate->get_meta_data() as $key => $value ) { |
||
| 971 | $item->add_meta_data( $key, $value, true ); |
||
| 972 | } |
||
| 973 | $item->save(); |
||
| 974 | $order->add_item( $item ); |
||
| 975 | } |
||
| 976 | } |
||
| 977 | } |
||
| 978 | } |
||
| 979 | } |
||
| 980 | |||
| 981 | $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); |
||
| 982 | $order->set_payment_method( $available_gateways['stripe'] ); |
||
| 983 | $order->set_total( WC()->cart->shipping_total, 'shipping' ); |
||
| 984 | $order->set_total( WC()->cart->get_cart_discount_total(), 'cart_discount' ); |
||
| 985 | $order->set_total( WC()->cart->get_cart_discount_tax_total(), 'cart_discount_tax' ); |
||
| 986 | $order->set_total( WC()->cart->tax_total, 'tax' ); |
||
| 987 | $order->set_total( WC()->cart->shipping_tax_total, 'shipping_tax' ); |
||
| 988 | $order->set_total( WC()->cart->total ); |
||
| 989 | |||
| 990 | // If we got here, the order was created without problems! |
||
| 991 | wc_transaction_query( 'commit' ); |
||
| 992 | |||
| 993 | return $order; |
||
| 994 | } |
||
| 995 | } |
||
| 996 | |||
| 997 | new WC_Stripe_Apple_Pay(); |
||
| 998 |
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.