Completed
Push — master ( f6cdcf...cb7011 )
by Roy
11s
created

WC_Gateway_Stripe_Bitcoin::process_payment()   D

Complexity

Conditions 9
Paths 468

Size

Total Lines 58
Code Lines 32

Duplication

Lines 4
Ratio 6.9 %

Importance

Changes 0
Metric Value
cc 9
eloc 32
nc 468
nop 3
dl 4
loc 58
rs 4.9066
c 0
b 0
f 0

How to fix   Long Method   

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
 * Class that handles Bitcoin payment method.
8
 *
9
 * @extends WC_Gateway_Stripe
10
 *
11
 * @since 4.0.0
12
 */
13
class WC_Gateway_Stripe_Bitcoin extends WC_Stripe_Payment_Gateway {
14
	/**
15
	 * Notices (array)
16
	 * @var array
17
	 */
18
	public $notices = array();
19
20
	/**
21
	 * Is test mode active?
22
	 *
23
	 * @var bool
24
	 */
25
	public $testmode;
26
27
	/**
28
	 * Alternate credit card statement name
29
	 *
30
	 * @var bool
31
	 */
32
	public $statement_descriptor;
33
34
	/**
35
	 * API access secret key
36
	 *
37
	 * @var string
38
	 */
39
	public $secret_key;
40
41
	/**
42
	 * Api access publishable key
43
	 *
44
	 * @var string
45
	 */
46
	public $publishable_key;
47
48
	/**
49
	 * Should we store the users credit cards?
50
	 *
51
	 * @var bool
52
	 */
53
	public $saved_cards;
54
55
	/**
56
	 * Instructions for Bitcoin payment.
57
	 *
58
	 * @var string
59
	 */
60
	public $instructions;
61
62
	/**
63
	 * Constructor
64
	 */
65
	public function __construct() {
66
		$this->id                   = 'stripe_bitcoin';
67
		$this->method_title         = __( 'Stripe Bitcoin', 'woocommerce-gateway-stripe' );
68
		/* translators: link */
69
		$this->method_description   = sprintf( __( 'All other general Stripe settings can be adjusted <a href="%s">here</a>.', 'woocommerce-gateway-stripe' ), admin_url( 'admin.php?page=wc-settings&tab=checkout&section=stripe' ) );
70
		$this->supports             = array(
71
			'products',
72
			'refunds',
73
		);
74
75
		// Load the form fields.
76
		$this->init_form_fields();
77
78
		// Load the settings.
79
		$this->init_settings();
80
81
		$main_settings              = get_option( 'woocommerce_stripe_settings' );
82
		$this->title                = $this->get_option( 'title' );
83
		$this->description          = $this->get_option( 'description' );
84
		$this->enabled              = $this->get_option( 'enabled' );
85
		$this->testmode             = ( ! empty( $main_settings['testmode'] ) && 'yes' === $main_settings['testmode'] ) ? true : false;
86
		$this->saved_cards          = ( ! empty( $main_settings['saved_cards'] ) && 'yes' === $main_settings['saved_cards'] ) ? true : false;
87
		$this->publishable_key      = ! empty( $main_settings['publishable_key'] ) ? $main_settings['publishable_key'] : '';
88
		$this->secret_key           = ! empty( $main_settings['secret_key'] ) ? $main_settings['secret_key'] : '';
89
		$this->statement_descriptor = ! empty( $main_settings['statement_descriptor'] ) ? $main_settings['statement_descriptor'] : '';
90
91
		if ( $this->testmode ) {
92
			$this->publishable_key = ! empty( $main_settings['test_publishable_key'] ) ? $main_settings['test_publishable_key'] : '';
93
			$this->secret_key      = ! empty( $main_settings['test_secret_key'] ) ? $main_settings['test_secret_key'] : '';
94
		}
95
96
		add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
97
		add_action( 'admin_notices', array( $this, 'check_environment' ) );
98
		add_action( 'admin_head', array( $this, 'remove_admin_notice' ) );
99
		add_action( 'wp_enqueue_scripts', array( $this, 'payment_scripts' ) );
100
		add_action( 'woocommerce_thankyou_stripe_bitcoin', array( $this, 'thankyou_page' ) );
101
102
		// Customer Emails.
103
		add_action( 'woocommerce_email_before_order_table', array( $this, 'email_instructions' ), 10, 3 );
104
	}
105
106
	/**
107
	 * Checks to make sure environment is setup correctly to use this payment method.
108
	 *
109
	 * @since 4.0.0
110
	 * @version 4.0.0
111
	 */
112
	public function check_environment() {
113
		if ( ! current_user_can( 'manage_woocommerce' ) ) {
114
			return;
115
		}
116
117
		$environment_warning = $this->get_environment_warning();
118
119
		if ( $environment_warning ) {
120
			$this->add_admin_notice( 'bad_environment', 'error', $environment_warning );
121
		}
122
123
		foreach ( (array) $this->notices as $notice_key => $notice ) {
124
			echo "<div class='" . esc_attr( $notice['class'] ) . "'><p>";
125
			echo wp_kses( $notice['message'], array( 'a' => array( 'href' => array() ) ) );
126
			echo '</p></div>';
127
		}
128
	}
129
130
	/**
131
	 * Checks the environment for compatibility problems. Returns a string with the first incompatibility
132
	 * found or false if the environment has no problems.
133
	 *
134
	 * @since 4.0.0
135
	 * @version 4.0.0
136
	 */
137
	public function get_environment_warning() {
138
		// Add deprecated notice to logs.
139
		if ( 'yes' === $this->enabled ) {
140
			WC_Stripe_Logger::log( 'DEPRECATED! Stripe will no longer support Bitcoin and will cease to function on April 23, 2018. Please plan accordingly.' );
141
		}
142
143
		if ( 'yes' === $this->enabled && ! in_array( get_woocommerce_currency(), $this->get_supported_currency() ) ) {
144
			$message = __( 'Bitcoin is enabled - it requires store currency to be set to USD.', 'woocommerce-gateway-stripe' );
145
146
			return $message;
147
		}
148
149
		return false;
150
	}
151
152
	/**
153
	 * Returns all supported currencies for this payment method.
154
	 *
155
	 * @since 4.0.0
156
	 * @version 4.0.0
157
	 * @return array
158
	 */
159
	public function get_supported_currency() {
160
		return apply_filters( 'wc_stripe_bitcoin_supported_currencies', array(
161
			'USD',
162
		) );
163
	}
164
165
	/**
166
	 * Checks to see if all criteria is met before showing payment method.
167
	 *
168
	 * @since 4.0.0
169
	 * @version 4.0.0
170
	 * @return bool
171
	 */
172
	public function is_available() {
173
		if ( ! in_array( get_woocommerce_currency(), $this->get_supported_currency() ) ) {
174
			return false;
175
		}
176
177
		return parent::is_available();
178
	}
179
180
	/**
181
	 * Get_icon function.
182
	 *
183
	 * @since 1.0.0
184
	 * @version 4.0.0
185
	 * @return string
186
	 */
187
	public function get_icon() {
188
		$icons = $this->payment_icons();
189
190
		$icons_str = '';
191
192
		$icons_str .= $icons['bitcoin'];
193
194
		return apply_filters( 'woocommerce_gateway_icon', $icons_str, $this->id );
195
	}
196
197
	/**
198
	 * payment_scripts function.
199
	 *
200
	 * Outputs scripts used for stripe payment
201
	 *
202
	 * @access public
203
	 */
204
	public function payment_scripts() {
205
		if ( ! is_cart() && ! is_checkout() && ! isset( $_GET['pay_for_order'] ) && ! is_add_payment_method_page() ) {
206
			return;
207
		}
208
209
		wp_enqueue_style( 'stripe_paymentfonts' );
210
		wp_enqueue_script( 'woocommerce_stripe' );
211
	}
212
213
	/**
214
	 * Initialize Gateway Settings Form Fields.
215
	 */
216
	public function init_form_fields() {
217
		$this->form_fields = require( WC_STRIPE_PLUGIN_PATH . '/includes/admin/stripe-bitcoin-settings.php' );
218
	}
219
220
	/**
221
	 * Payment form on checkout page
222
	 */
223
	public function payment_fields() {
224
		$user                 = wp_get_current_user();
0 ignored issues
show
Unused Code introduced by
$user 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...
225
		$total                = WC()->cart->total;
226
227
		// If paying from order, we need to get total from order not cart.
228
		if ( isset( $_GET['pay_for_order'] ) && ! empty( $_GET['key'] ) ) {
229
			$order = wc_get_order( wc_get_order_id_by_order_key( wc_clean( $_GET['key'] ) ) );
230
			$total = $order->get_total();
231
		}
232
233
		if ( is_add_payment_method_page() ) {
234
			$pay_button_text = __( 'Add Payment', 'woocommerce-gateway-stripe' );
0 ignored issues
show
Unused Code introduced by
$pay_button_text 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...
235
			$total        = '';
236
		} else {
237
			$pay_button_text = '';
0 ignored issues
show
Unused Code introduced by
$pay_button_text 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...
238
		}
239
240
		echo '<div
241
			id="stripe-bitcoin-payment-data"
242
			data-amount="' . esc_attr( WC_Stripe_Helper::get_stripe_amount( $total ) ) . '"
243
			data-currency="' . esc_attr( strtolower( get_woocommerce_currency() ) ) . '">';
244
245
		if ( $this->description ) {
246
			echo apply_filters( 'wc_stripe_description', wpautop( wp_kses_post( $this->description ) ) );
247
		}
248
249
		echo '</div>';
250
	}
251
252
	/**
253
	 * Output for the order received page.
254
	 *
255
	 * @param int $order_id
256
	 */
257
	public function thankyou_page( $order_id ) {
258
		$this->get_instructions( $order_id );
259
	}
260
261
	/**
262
	 * Add content to the WC emails.
263
	 *
264
	 * @since 4.0.0
265
	 * @version 4.0.0
266
	 * @param WC_Order $order
267
	 * @param bool $sent_to_admin
268
	 * @param bool $plain_text
269
	 */
270
	public function email_instructions( $order, $sent_to_admin, $plain_text = false ) {
271
		$order_id = WC_Stripe_Helper::is_pre_30() ? $order->id : $order->get_id();
272
273
		$payment_method = WC_Stripe_Helper::is_pre_30() ? $order->payment_method : $order->get_payment_method();
274
275
		if ( ! $sent_to_admin && 'stripe_bitcoin' === $payment_method && $order->has_status( 'on-hold' ) ) {
276
			$this->get_instructions( $order_id, $plain_text );
277
		}
278
	}
279
280
	/**
281
	 * Gets the Bitcoin instructions for customer to pay.
282
	 *
283
	 * @since 4.0.0
284
	 * @version 4.0.0
285
	 * @param int $order_id
286
	 */
287
	public function get_instructions( $order_id, $plain_text = false ) {
288
		$data = get_post_meta( $order_id, '_stripe_bitcoin', true );
289
290
		if ( $plain_text ) {
291
			esc_html_e( 'Please pay the following:', 'woocommerce-gateway-stripe' ) . "\n\n";
292
			echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
293
			esc_html_e( 'Bitcoin Amount:', 'woocommerce-gateway-stripe' ) . "\n\n";
294
			echo $data['amount'] . "\n\n";
295
			echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
296
			esc_html_e( 'Receiver:', 'woocommerce-gateway-stripe' ) . "\n\n";
297
			echo $data['address'] . "\n\n";
298
			echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
299
			esc_html_e( 'URI:', 'woocommerce-gateway-stripe' ) . "\n\n";
300
			echo $data['uri'] . "\n\n";
301
		} else {
302
			?>
303
			<h3><?php esc_html_e( 'Please pay the following:', 'woocommerce-gateway-stripe' ); ?></h3>
304
			<ul class="woocommerce-order-overview woocommerce-thankyou-order-details order_details">
305
			<li class="woocommerce-order-overview__order order">
306
				<?php esc_html_e( 'Bitcoin Amount:', 'woocommerce-gateway-stripe' ); ?>
307
				<strong><?php echo $data['amount']; ?></strong>
308
			</li>
309
			<li class="woocommerce-order-overview__order order">
310
				<?php esc_html_e( 'Receiver:', 'woocommerce-gateway-stripe' ); ?>
311
				<strong><?php echo $data['address']; ?></strong>
312
			</li>
313
			<li class="woocommerce-order-overview__order order">
314
				<?php esc_html_e( 'URI:', 'woocommerce-gateway-stripe' ); ?>
315
				<strong>
316
				<?php
317
				/* translators: link */
318
				printf( __( '<a href="%s">Pay Bitcoin</a>', 'woocommerce-gateway-stripe' ), $data['uri'] );
319
				?>
320
				</strong>
321
			</li>
322
			</ul>
323
			<?php
324
		}
325
	}
326
327
	/**
328
	 * Saves Bitcoin information to the order meta for later use.
329
	 *
330
	 * @since 4.0.0
331
	 * @version 4.0.0
332
	 * @param object $order
333
	 * @param object $source_object
334
	 */
335
	public function save_instructions( $order, $source_object ) {
336
		$data = array(
337
			'amount'  => $source_object->bitcoin->amount,
338
			'address' => $source_object->bitcoin->address,
339
			'uri'     => $source_object->bitcoin->uri,
340
		);
341
342
		$order_id = WC_Stripe_Helper::is_pre_30() ? $order->id : $order->get_id();
343
344
		update_post_meta( $order_id, '_stripe_bitcoin', $data );
345
	}
346
347
	/**
348
	 * Process the payment
349
	 *
350
	 * @param int  $order_id Reference.
351
	 * @param bool $retry Should we retry on fail.
352
	 * @param bool $force_save_source Force save the payment source.
353
	 *
354
	 * @throws Exception If payment will not be accepted.
355
	 *
356
	 * @return array|void
357
	 */
358
	public function process_payment( $order_id, $retry = true, $force_save_source = false ) {
359
		try {
360
			$order = wc_get_order( $order_id );
361
362
			// This comes from the create account checkbox in the checkout page.
363
			$create_account = ! empty( $_POST['createaccount'] ) ? true : false;
364
365
			if ( $create_account ) {
366
				$new_customer_id     = WC_Stripe_Helper::is_pre_30() ? $order->customer_user : $order->get_customer_id();
367
				$new_stripe_customer = new WC_Stripe_Customer( $new_customer_id );
368
				$new_stripe_customer->create_customer();
369
			}
370
371
			$source_id       = ! empty( $_POST['stripe_source'] ) ? wc_clean( $_POST['stripe_source'] ) : '';
372
			$prepared_source = $this->prepare_source( $this->get_source_object( $source_id ), get_current_user_id(), $force_save_source );
373
374 View Code Duplication
			if ( empty( $prepared_source->source ) ) {
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...
375
				$localized_message = __( 'Payment processing failed. Please retry.', 'woocommerce-gateway-stripe' );
376
				throw new WC_Stripe_Exception( print_r( $prepared_source, true ), $localized_message );
377
			}
378
379
			$this->save_source_to_order( $order, $prepared_source );
380
381
			// This will throw exception if not valid.
382
			$this->validate_minimum_order_amount( $order );
383
384
			$source_id = ! empty( $_POST['stripe_source'] ) ? wc_clean( $_POST['stripe_source'] ) : '';
385
			$this->save_instructions( $order, $this->get_source_object( $source_id ) );
386
387
			// Mark as on-hold (we're awaiting the payment).
388
			$order->update_status( 'on-hold', __( 'Awaiting Bitcoin payment', 'woocommerce-gateway-stripe' ) );
389
390
			wc_reduce_stock_levels( $order_id );
391
392
			// Remove cart.
393
			WC()->cart->empty_cart();
394
395
			// Return thankyou redirect.
396
			return array(
397
				'result'    => 'success',
398
				'redirect'  => $this->get_return_url( $order ),
399
			);
400
		} catch ( WC_Stripe_Exception $e ) {
401
			wc_add_notice( $e->getLocalizedMessage(), 'error' );
402
			WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
403
404
			do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );
405
406
			if ( $order->has_status( array( 'pending', 'failed' ) ) ) {
407
				$this->send_failed_order_email( $order_id );
408
			}
409
410
			return array(
411
				'result'   => 'fail',
412
				'redirect' => '',
413
			);
414
		}
415
	}
416
}
417