Completed
Pull Request — master (#91)
by Roy
02:17
created

WC_Stripe_Apple_Pay::payment_scripts()   D

Complexity

Conditions 10
Paths 34

Size

Total Lines 34
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 34
rs 4.8196
c 0
b 0
f 0
cc 10
eloc 23
nc 34
nop 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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;
0 ignored issues
show
Unused Code introduced by
The property $_gateway is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
25
26
	/**
27
	 * Gateway settings.
28
	 *
29
	 * @var
30
	 */
31
	private $_gateway_settings;
32
33
	/**
34
	 * Constructor.
35
	 *
36
	 * @access public
37
	 * @since 3.1.0
38
	 * @version 3.1.0
39
	 */
40
	public function __construct() {
41
		self::$_this = $this;
42
43
		$this->_gateway_settings = get_option( 'woocommerce_stripe_settings', '' );
44
45
		$this->init();
46
	}
47
48
	public function instance() {
49
		return self::$_this;
50
	}
51
52
	/**
53
	 * Initialize.
54
	 *
55
	 * @access public
56
	 * @since 3.1.0
57
	 * @version 3.1.0
58
	 */
59
	public function init() {
60
		add_action( 'wp_enqueue_scripts', array( $this, 'payment_scripts' ) );
61
		add_action( 'woocommerce_proceed_to_checkout', array( $this, 'display_apple_pay_button' ), 20 );
62
		add_action( 'woocommerce_review_order_before_payment', array( $this, 'display_apple_pay_button' ) );
63
		
64
		if ( is_admin() ) {
65
			add_action( 'wp_ajax_wc_stripe_apple_pay', array( $this, 'process_apple_pay' ) );
66
			add_action( 'wp_ajax_nopriv_wc_stripe_apple_pay', array( $this, 'process_apple_pay' ) );
67
			add_action( 'wp_ajax_wc_stripe_generate_apple_pay_cart', array( $this, 'generate_apple_pay_cart' ) );
68
			add_action( 'wp_ajax_nopriv_wc_stripe_generate_apple_pay_cart', array( $this, 'generate_apple_pay_cart' ) );
69
		}
70
	}
71
72
	/**
73
	 * Enqueue JS scripts and styles.
74
	 *
75
	 * @since 3.1.0
76
	 * @version 3.1.0
77
	 */
78
	public function payment_scripts() {
79
		if ( ! is_cart() && ! is_checkout() && ! isset( $_GET['pay_for_order'] ) ) {
80
			return;
81
		}
82
83
		if ( ! $this->is_supported_product_type() ) {
84
			return;
85
		}
86
		
87
		$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
88
		
89
		wp_enqueue_style( 'stripe_apple_pay', plugins_url( 'assets/css/stripe-apple-pay.css', WC_STRIPE_MAIN_FILE ), array(), WC_STRIPE_VERSION );
90
91
		wp_enqueue_script( 'stripe', 'https://js.stripe.com/v2/', '', '1.0', true );
92
		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 );
93
94
		$publishable_key = 'yes' === $this->_gateway_settings['testmode'] ? $this->_gateway_settings['test_publishable_key'] : $this->_gateway_settings['publishable_key'];
95
96
		$stripe_params = array(
97
			'key'                         => $publishable_key,
98
			'currency_code'               => get_woocommerce_currency(),
99
			'country_code'                => substr( get_option( 'woocommerce_default_country' ), 0, 2 ),
100
			'label'                       => get_bloginfo( 'name', 'display' ),
101
			'ajaxurl'                     => admin_url( 'admin-ajax.php' ),
102
			'stripe_apple_pay_nonce'      => wp_create_nonce( '_wc_stripe_apple_pay_nonce' ),
103
			'stripe_apple_pay_cart_nonce' => wp_create_nonce( '_wc_stripe_apple_pay_cart_nonce' ),
104
			'needs_shipping'              => WC()->cart->needs_shipping() ? 'yes' : 'no',
105
			'needs_shipping_msg'          => __( 'Please first calculate your shipping.', 'woocommerce-gateway-stripe' ),
106
			'is_cart_page'                => is_cart() ? 'yes' : 'no',
107
			'chosen_shipping'             => wc_get_chosen_shipping_method_ids(),
108
		);
109
110
		wp_localize_script( 'woocommerce_stripe_apple_pay', 'wc_stripe_apple_pay_params', apply_filters( 'wc_stripe_apple_pay_params', $stripe_params ) );
111
	}
112
		
113
	/**
114
	 * Checks to make sure product type is supported by Apple Pay.
115
	 *
116
	 */
117
	public function is_supported_product_type() {
118
		foreach( WC()->cart->get_cart() as $cart_item_key => $values ) {
119
			if ( 'subscription' === $values['data']->product_type ) {
120
				return false;
121
			}
122
		}
123
124
		return true;
125
	}
126
127
	/**
128
	 * Display Apple Pay button on the cart page
129
	 *
130
	 * @since 3.1.0
131
	 * @version 3.1.0
132
	 */
133
	public function display_apple_pay_button() {
134
		$gateways = WC()->payment_gateways->get_available_payment_gateways();
135
136
		/**
137
		 * In order for the Apple Pay button to show on cart page,
138
		 * Apple Pay must be enabled and Stripe gateway must be enabled.
139
		 */
140
		if ( 
141
			'yes' !== $this->_gateway_settings['apple_pay']
142
			|| ! isset( $gateways['stripe'] ) 
143
		) {
144
			return;
145
		}
146
147
		if ( ! $this->is_supported_product_type() ) {
148
			return;
149
		}
150
		?>
151
		<button id="apple-pay-button"></button>
152
		<?php
153
	}
154
155
	/**
156
	 * Generates the Apple Pay cart.
157
	 *
158
	 * @since 3.1.0
159
	 * @version 3.1.0
160
	 */
161
	public function generate_apple_pay_cart() {
162
		if ( ! defined( 'DOING_AJAX' ) ) {
163
			define( 'DOING_AJAX', true );
164
		}
165
166
		if ( ! wp_verify_nonce( $_POST['nonce'], '_wc_stripe_apple_pay_cart_nonce' ) ) {
167
			wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce-gateway-stripe' ) );
168
		}
169
170
		wp_send_json( array( 'line_items' => $this->build_line_items(), 'total' => WC()->cart->total, 'chosen_shipping' => wc_get_chosen_shipping_method_ids() ) );
171
	}
172
173
	/**
174
	 * Handles the Apple Pay processing via AJAX
175
	 *
176
	 * @access public
177
	 * @since 3.1.0
178
	 * @version 3.1.0
179
	 */
180
	public function process_apple_pay() {
181
		if ( ! defined( 'DOING_AJAX' ) ) {
182
			define( 'DOING_AJAX', true );
183
		}
184
185
		if ( ! wp_verify_nonce( $_POST['nonce'], '_wc_stripe_apple_pay_nonce' ) ) {
186
			wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce-gateway-stripe' ) );
187
		}
188
189
		try {
190
			$result = array_map( 'wc_clean', $_POST['result'] );
191
192
			$order = $this->create_order( $result );
193
194
			// Handle payment.
195
			if ( $order->get_total() > 0 ) {
196
197
				if ( $order->get_total() * 100 < 50 ) {
198
					throw new Exception( __( 'Sorry, the minimum allowed order total is 0.50 to use this payment method.', 'woocommerce-gateway-stripe' ) );
199
				}
200
201
				WC_Stripe::log( "Info: Begin processing payment for order $order->id for the amount of {$order->get_total()}" );
202
203
				// Make the request.
204
				$response = WC_Stripe_API::request( $this->generate_payment_request( $order, $result['token']['id'] ) );
205
206
				if ( is_wp_error( $response ) ) {
207
					$localized_messages = $this->get_localized_messages();
208
209
					throw new Exception( ( isset( $localized_messages[ $response->get_error_code() ] ) ? $localized_messages[ $response->get_error_code() ] : $response->get_error_message() ) );
210
				}
211
212
				// Process valid response.
213
				$this->process_response( $response, $order );
214
			} else {
215
				$order->payment_complete();
216
			}
217
218
			// Remove cart.
219
			WC()->cart->empty_cart();
220
221
			update_post_meta( $order->id, '_customer_user', get_current_user_id() );
222
223
			// Return thank you page redirect.
224
			wp_send_json( array(
225
				'success'  => 'true',
226
				'redirect' => $this->get_return_url( $order ),
227
			) );
228
229
		} catch ( Exception $e ) {
230
			WC()->session->set( 'refresh_totals', true );
231
			WC_Stripe::log( sprintf( __( 'Error: %s', 'woocommerce-gateway-stripe' ), $e->getMessage() ) );
232
233
			if ( $order->has_status( array( 'pending', 'failed' ) ) ) {
234
				$this->send_failed_order_email( $order->id );
0 ignored issues
show
Bug introduced by
The variable $order does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
235
			}
236
237
			wp_send_json( array( 'success' => 'false', 'msg' => $e->getMessage() ) );
238
		}
239
	}
240
241
	/**
242
	 * Generate the request for the payment.
243
	 * @param  WC_Order $order
244
	 * @param string $source token
245
	 * @return array()
0 ignored issues
show
Documentation introduced by
The doc-type array() could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
246
	 */
247
	protected function generate_payment_request( $order, $source ) {
248
		$post_data                = array();
249
		$post_data['currency']    = strtolower( $order->get_order_currency() ? $order->get_order_currency() : get_woocommerce_currency() );
250
		$post_data['amount']      = $this->get_stripe_amount( $order->get_total(), $post_data['currency'] );
251
		$post_data['description'] = sprintf( __( '%s - Order %s', 'woocommerce-gateway-stripe' ), wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ), $order->get_order_number() );
252
		$post_data['capture']     = 'yes' === $this->_gateway_settings['capture'] ? 'true' : 'false';
253
254
		if ( ! empty( $order->billing_email ) && apply_filters( 'wc_stripe_send_stripe_receipt', false ) ) {
255
			$post_data['receipt_email'] = $order->billing_email;
256
		}
257
258
		$post_data['expand[]']    = 'balance_transaction';
259
		$post_data['source']      = $source;
260
261
		/**
262
		 * Filter the return value of the WC_Payment_Gateway_CC::generate_payment_request.
263
		 *
264
		 * @since 3.1.0
265
		 * @param array $post_data
266
		 * @param WC_Order $order
267
		 * @param object $source
268
		 */
269
		return apply_filters( 'wc_stripe_generate_payment_request', $post_data, $order );
270
	}
271
272
	/**
273
	 * Builds the line items to pass to Apple Pay
274
	 *
275
	 * @since 3.1.0
276
	 * @version 3.1.0
277
	 */	
278
	public function build_line_items() {
279
		$decimals = apply_filters( 'wc_stripe_apple_pay_decimals', 2 );
280
281
		$items = array();
282
283
		foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
284
			$amount         = wc_format_decimal( $values['line_subtotal'], $decimals );
285
			$quantity_label = 1 < $values['quantity'] ? ' (x' . $values['quantity'] . ')' : '';
286
287
			$item = array(
288
				'type'   => 'final',
289
				'label'  => $values['data']->post->post_title . $quantity_label,
290
				'amount' => wc_format_decimal( $amount, $decimals ),
291
			);
292
293
			$items[] = $item;
294
		}
295
296
		$discounts   = wc_format_decimal( WC()->cart->get_cart_discount_total(), $decimals );
297
		$tax         = wc_format_decimal( WC()->cart->tax_total + WC()->cart->shipping_tax_total, $decimals );
298
		$shipping    = wc_format_decimal( WC()->cart->shipping_total, $decimals );
299
		$item_total  = wc_format_decimal( WC()->cart->cart_contents_total, $decimals ) + $discounts;
300
		$order_total = wc_format_decimal( $item_total + $tax + $shipping, $decimals );
0 ignored issues
show
Unused Code introduced by
$order_total is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
301
302
		if ( wc_tax_enabled() ) {
303
			$items[] = array(
304
				'type'   => 'final',
305
				'label'  => __( 'Tax', 'woocommerce-gateway-stripe' ),
306
				'amount' => $tax,
307
			);
308
		}
309
310 View Code Duplication
		if ( WC()->cart->needs_shipping() ) {
0 ignored issues
show
Duplication introduced by
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...
311
			$items[] = array(
312
				'type'   => 'final',
313
				'label'  => __( 'Shipping', 'woocommerce-gateway-stripe' ),
314
				'amount' => $shipping,
315
			);
316
		}
317
318 View Code Duplication
		if ( WC()->cart->has_discount() ) {
0 ignored issues
show
Duplication introduced by
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...
319
			$items[] = array(
320
				'type'   => 'final',
321
				'label'  => __( 'Discount', 'woocommerce-gateway-stripe' ),
322
				'amount' => $discounts,
323
			);
324
		}
325
326
		return $items;
327
	}
328
329
	/**
330
	 * Create order programatically.
331
	 *
332
	 * @since 3.1.0
333
	 * @version 3.1.0
334
	 * @param array $data
335
	 * @return object $order
336
	 */
337
	public function create_order( $data = array() ) {
338
		if ( empty( $data ) ) {
339
			throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-gateway-stripe' ), 520 ) );
340
		}
341
342
		$order = wc_create_order();
343
344
		if ( is_wp_error( $order ) ) {
345
			throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-gateway-stripe' ), 520 ) );
346
		} elseif ( false === $order ) {
347
			throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-gateway-stripe' ), 521 ) );
348
		} else {
349
			$order_id = $order->id;
350
			do_action( 'woocommerce_new_order', $order_id );
351
		}
352
353
		// Store the line items to the new/resumed order
354
		foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
355
			$item_id = $order->add_product(
356
				$values['data'],
357
				$values['quantity'],
358
				array(
359
					'variation' => $values['variation'],
360
					'totals'    => array(
361
						'subtotal'     => $values['line_subtotal'],
362
						'subtotal_tax' => $values['line_subtotal_tax'],
363
						'total'        => $values['line_total'],
364
						'tax'          => $values['line_tax'],
365
						'tax_data'     => $values['line_tax_data'] // Since 2.2
366
					)
367
				)
368
			);
369
370
			if ( ! $item_id ) {
371
				throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-gateway-stripe' ), 525 ) );
372
			}
373
374
			// Allow plugins to add order item meta
375
			do_action( 'woocommerce_add_order_item_meta', $item_id, $values, $cart_item_key );
376
		}
377
378
		// Store fees
379
		foreach ( WC()->cart->get_fees() as $fee_key => $fee ) {
380
			$item_id = $order->add_fee( $fee );
381
382
			if ( ! $item_id ) {
383
				throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-gateway-stripe' ), 526 ) );
384
			}
385
386
			// Allow plugins to add order item meta to fees
387
			do_action( 'woocommerce_add_order_fee_meta', $order_id, $item_id, $fee, $fee_key );
388
		}
389
390
		// Store tax rows
391
		foreach ( array_keys( WC()->cart->taxes + WC()->cart->shipping_taxes ) as $tax_rate_id ) {
392
			if ( $tax_rate_id && ! $order->add_tax( $tax_rate_id, WC()->cart->get_tax_amount( $tax_rate_id ), WC()->cart->get_shipping_tax_amount( $tax_rate_id ) ) && apply_filters( 'woocommerce_cart_remove_taxes_zero_rate_id', 'zero-rated' ) !== $tax_rate_id ) {
393
				throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-gateway-stripe' ), 528 ) );
394
			}
395
		}
396
397
		// Store coupons
398
		foreach ( WC()->cart->get_coupons() as $code => $coupon ) {
399
			if ( ! $order->add_coupon( $code, WC()->cart->get_coupon_discount_amount( $code ), WC()->cart->get_coupon_discount_tax_amount( $code ) ) ) {
400
				throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce-gateway-stripe' ), 529 ) );
401
			}
402
		}
403
404
		// Billing address
405
		$billing_address = array();
406
		if ( ! empty( $data['token']['card'] ) ) {
407
			// Name from Stripe is a full name string.
408
			$name                          = explode( ' ', $data['token']['card']['name'] );
409
			$lastname                      = array_pop( $name );
410
			$firstname                     = implode( ' ', $name );
411
			$billing_address['first_name'] = $firstname;
412
			$billing_address['last_name']  = $lastname;
413
			$billing_address['email']      = $data['shippingContact']['emailAddress'];
414
			$billing_address['phone']      = $data['shippingContact']['phoneNumber'];
415
			$billing_address['country']    = $data['token']['card']['country'];
416
			$billing_address['address_1']  = $data['token']['card']['address_line1'];
417
			$billing_address['address_2']  = $data['token']['card']['address_line2'];
418
			$billing_address['city']       = $data['token']['card']['address_city'];
419
			$billing_address['state']      = $data['token']['card']['address_state'];
420
			$billing_address['postcode']   = $data['token']['card']['address_zip'];
421
		}
422
423
		// Shipping address.
424
		$shipping_address = array();
425
		if ( WC()->cart->needs_shipping() && ! empty( $data['shippingContact'] ) ) {
426
			$shipping_address['first_name'] = $data['shippingContact']['givenName'];
427
			$shipping_address['last_name']  = $data['shippingContact']['familyName'];
428
			$shipping_address['email']      = $data['shippingContact']['emailAddress'];
429
			$shipping_address['phone']      = $data['shippingContact']['phoneNumber'];
430
			$shipping_address['country']    = $data['shippingContact']['countryCode'];
431
			$shipping_address['address_1']  = $data['shippingContact']['addressLines'][0];
432
			$shipping_address['state']      = $data['shippingContact']['locality'];
433
			$shipping_address['state']      = $data['shippingContact']['administrativeArea'];
434
			$shipping_address['postcode']   = $data['shippingContact']['postalCode'];
435
		} elseif ( ! empty( $data['shippingContact'] ) ) {
436
			$shipping_address['first_name'] = $firstname;
0 ignored issues
show
Bug introduced by
The variable $firstname does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
437
			$shipping_address['last_name']  = $lastname;
0 ignored issues
show
Bug introduced by
The variable $lastname does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
438
			$shipping_address['email']      = $data['shippingContact']['emailAddress'];
439
			$shipping_address['phone']      = $data['shippingContact']['phoneNumber'];
440
			$shipping_address['country']    = $data['token']['card']['country'];
441
			$shipping_address['address_1']  = $data['token']['card']['address_line1'];
442
			$shipping_address['address_2']  = $data['token']['card']['address_line2'];
443
			$shipping_address['city']       = $data['token']['card']['address_city'];
444
			$shipping_address['state']      = $data['token']['card']['address_state'];
445
			$shipping_address['postcode']   = $data['token']['card']['address_zip'];
446
		}
447
448
		$order->set_address( $billing_address, 'billing' );
449
		$order->set_address( $shipping_address, 'shipping' );
450
451
		WC()->shipping->calculate_shipping( WC()->cart->get_shipping_packages() );
452
		
453
		// Get the rate object selected by user.
454
		foreach ( WC()->shipping->get_packages() as $package_key => $package ) {
455
			foreach ( $package['rates'] as $key => $rate ) {
456
				// Loop through user chosen shipping methods.
457
				foreach( WC()->session->get( 'chosen_shipping_methods' ) as $method ) {
458
					if ( $method === $key ) {
459
						$order->add_shipping( $rate );
460
					}
461
				}
462
			}
463
		}
464
465
		$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
466
		$order->set_payment_method( $available_gateways['stripe'] );
467
		$order->set_total( WC()->cart->shipping_total, 'shipping' );
468
		$order->set_total( WC()->cart->get_cart_discount_total(), 'cart_discount' );
469
		$order->set_total( WC()->cart->get_cart_discount_tax_total(), 'cart_discount_tax' );
470
		$order->set_total( WC()->cart->tax_total, 'tax' );
471
		$order->set_total( WC()->cart->shipping_tax_total, 'shipping_tax' );
472
		$order->set_total( WC()->cart->total );
473
474
		// If we got here, the order was created without problems!
475
		wc_transaction_query( 'commit' );
476
477
		return $order;
478
	}
479
}
480
481
new WC_Stripe_Apple_Pay();
482
483