Completed
Pull Request — master (#2066)
by
unknown
07:45
created

WPSC_WorldPay_Payments_Order_Handler   B

Complexity

Total Complexity 47

Size/Duplication

Total Lines 388
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 1

Importance

Changes 11
Bugs 1 Features 1
Metric Value
wmc 47
c 11
b 1
f 1
lcom 2
cbo 1
dl 0
loc 388
rs 8.439

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A init() 0 5 1
A get_instance() 0 7 2
A set_purchase_log() 0 3 1
B order_actions() 0 35 6
A meta_box() 0 9 2
C authorization_box() 0 131 11
C refresh_transaction_info() 0 40 11
A void_payment() 0 21 3
B refund_payment() 0 24 3
A capture_payment() 0 21 3
A void_refund() 0 23 3

How to fix   Complexity   

Complex Class

Complex classes like WPSC_WorldPay_Payments_Order_Handler often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use WPSC_WorldPay_Payments_Order_Handler, and based on these observations, apply Extract Interface, too.

1
<?php
2
class WPSC_Payment_Gateway_WorldPay extends WPSC_Payment_Gateway {
3
4
	private $endpoints = array(
5
		'sandbox' => 'https://gwapi.demo.securenet.com/api/',
6
		'production' => 'https://gwapi.securenet.com/api/',
7
	);
8
9
	private $auth;
10
	private $payment_capture;
11
	private $order_handler;
12
	private $secure_net_id;
13
	private $secure_key;
14
	private $public_key;
15
	private $endpoint;
16
	private $sandbox;
17
18
	/**
19
	 * Constructor of WorldPay Payment Gateway
20
	 *
21
	 * @access public
22
	 * @since 3.9
23
	 */
24
	public function __construct() {
25
26
		parent::__construct();
27
28
		$this->title = __( 'WorldPay Payment Gateway', 'wp-e-commerce' );
29
		$this->supports = array( 'default_credit_card_form', 'tev1' );
30
31
		$this->order_handler	= WPSC_WorldPay_Payments_Order_Handler::get_instance( $this );
32
		
33
		// Define user set variables
34
		$this->secure_net_id	= $this->setting->get( 'secure_net_id' );
35
		$this->secure_key  		= $this->setting->get( 'secure_key' );
36
		$this->public_key  		= $this->setting->get( 'public_key' );
37
		$this->sandbox			= $this->setting->get( 'sandbox_mode' ) == '1' ? true : false;
38
		$this->endpoint			= $this->sandbox ? $this->endpoints['sandbox'] : $this->endpoints['production'];
39
		$this->payment_capture 	= $this->setting->get( 'payment_capture' ) !== null ? $this->setting->get( 'payment_capture' ) : '';
40
		$this->auth				= 'Basic ' . base64_encode( $this->setting->get( 'secure_net_id' ) . ':' . $this->setting->get( 'secure_key' ) );
41
	}
42
43
	/**
44
	 * Settings Form Template
45
	 *
46
	 * @since 3.9
47
	 */
48
	public function setup_form() {
49
?>
50
		<!-- Account Credentials -->
51
		<tr>
52
			<td colspan="2">
53
				<h4><?php _e( 'Account Credentials', 'wp-e-commerce' ); ?></h4>
54
			</td>
55
		</tr>
56
		<tr>
57
			<td>
58
				<label for="wpsc-worldpay-secure-net-id"><?php _e( 'SecureNet ID', 'wp-e-commerce' ); ?></label>
59
			</td>
60
			<td>
61
				<input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'secure_net_id' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'secure_net_id' ) ); ?>" id="wpsc-worldpay-secure-net-id" />
62
				<br><span class="small description"><?php _e( 'The SecureNet ID can be obtained from the email that you should have received during the sign-up process.', 'wp-e-commerce' ); ?></span>
63
			</td>
64
		</tr>
65
		<tr>
66
			<td>
67
				<label for="wpsc-worldpay-secure-key"><?php _e( 'Secure Key', 'wp-e-commerce' ); ?></label>
68
			</td>
69
			<td>
70
				<input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'secure_key' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'secure_key' ) ); ?>" id="wpsc-worldpay-secure-key" />
71
				<br><span class="small description"><?php _e( 'You can obtain the Secure Key by signing into the Virtual Terminal with the login credentials that you were emailed to you during the sign-up process. You will then need to navigate to Settings and click on the Obtain Secure Key link.', 'wp-e-commerce' ); ?></span>
72
			</td>
73
		</tr>
74
		<tr>
75
			<td>
76
				<label for="wpsc-worldpay-public-key"><?php _e( 'Public Key', 'wp-e-commerce' ); ?></label>
77
			</td>
78
			<td>
79
				<input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'public_key' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'public_key' ) ); ?>" id="wpsc-worldpay-public-key" />
80
				<br><span class="small description"><?php _e( 'You can obtain the Public Key by signing into the Virtual Terminal. You will then need to navigate to Settings and click on the Obtain Public Key link.', 'wp-e-commerce' ); ?></span>
81
			</td>
82
		</tr>
83
		<tr>
84
			<td>
85
				<label for="wpsc-worldpay-payment-capture"><?php _e( 'Payment Capture', 'wp-e-commerce' ); ?></label>
86
			</td>
87
			<td>
88
				<select id="wpsc-worldpay-payment-capture" name="<?php echo esc_attr( $this->setting->get_field_name( 'payment_capture' ) ); ?>">
89
					<option value='' <?php selected( '', $this->setting->get( 'payment_capture' ) ); ?>><?php _e( 'Authorize and capture the payment when the order is placed.', 'wp-e-commerce' )?></option>
90
					<option value='authorize' <?php selected( 'authorize', $this->setting->get( 'payment_capture' ) ); ?>><?php _e( 'Authorize the payment when the order is placed.', 'wp-e-commerce' )?></option>
91
				</select>
92
			</td>
93
		</tr>
94
		<tr>
95
			<td>
96
				<label><?php _e( 'Sandbox Mode', 'wp-e-commerce' ); ?></label>
97
			</td>
98
			<td>
99
				<label><input <?php checked( $this->setting->get( 'sandbox_mode' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'sandbox_mode' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wp-e-commerce' ); ?></label>&nbsp;&nbsp;&nbsp;
100
				<label><input <?php checked( (bool) $this->setting->get( 'sandbox_mode' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'sandbox_mode' ) ); ?>" value="0" /> <?php _e( 'No', 'wp-e-commerce' ); ?></label>
101
			</td>
102
		</tr>
103
		<!-- Error Logging -->
104
		<tr>
105
			<td colspan="2">
106
				<h4><?php _e( 'Error Logging', 'wp-e-commerce' ); ?></h4>
107
			</td>
108
		</tr>
109
		<tr>
110
			<td>
111
				<label><?php _e( 'Enable Debugging', 'wp-e-commerce' ); ?></label>
112
			</td>
113
			<td>
114
				<label><input <?php checked( $this->setting->get( 'debugging' ) ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'debugging' ) ); ?>" value="1" /> <?php _e( 'Yes', 'wp-e-commerce' ); ?></label>&nbsp;&nbsp;&nbsp;
115
				<label><input <?php checked( (bool) $this->setting->get( 'debugging' ), false ); ?> type="radio" name="<?php echo esc_attr( $this->setting->get_field_name( 'debugging' ) ); ?>" value="0" /> <?php _e( 'No', 'wp-e-commerce' ); ?></label>
116
			</td>
117
		</tr>
118
<?php
119
	}
120
121
	/**
122
	 * Add scripts
123
	 */
124
	public function scripts() {
125
126
		$js = $this->sandbox ? 'PayOSDev.js' : 'PayOS.js';
127
		wp_enqueue_script( 'worldpay_payos', WPSC_MERCHANT_V3_SDKS_URL . '/worldpay/assets/js/' . $js, '', WPSC_VERSION );
128
	}
129
130
	public function head_script() {
131
		?>
132
		<script type='text/javascript'>
133
134
			jQuery( document ).ready( function( $ ) {
135
				$( '.wpsc_checkout_forms' ).submit( function( e ) {
136
137
					e.preventDefault();
138
139
					var response = tokenizeCard(
140
						{
141
							"publicKey": '<?php echo $this->public_key; ?>',
142
							"card": {
143
								"number": document.getElementById('card_number').value,
144
								"cvv": document.getElementById('card_code').value,
145
							"expirationDate": document.getElementById('card_expiry_month').value + '/' + document.getElementById('card_expiry_year').value,
146
								"firstName": $( 'input[title="billingfirstname"]' ).val(),
147
								"lastName": $( 'input[title="billinglastname"]' ).val(),
148
								"address": {
149
									"line1": $( 'input[title="billingaddress"]' ).val(),
150
									"city": $( 'input[title="billingcity"]' ).val(),
151
									"state": $( 'input[title="billingstate"]' ).val(),
152
									"zip": $( 'input[title="billingpostcode"]' ).val()
153
								}
154
							},
155
							"addToVault": false,
156
							"developerApplication": {
157
								"developerId": 10000644,
158
								"version": '1.2'
159
160
							}
161
						}
162
					).done(function (result) {
163
164
						var responseObj = $.parseJSON(JSON.stringify(result));
165
166
						if (responseObj.success) {
167
168
							var $form = $( '.wpsc_checkout_forms' );
169
170
							var token = responseObj.token;
171
172
							$("#worldpay_pay_token").val(token);
173
							// and submit
174
							$form.get(0).submit();
175
176
							// do something with responseObj.token
177
						} else {
178
							alert("token was not created");
179
							// do something with responseObj.message
180
181
						}
182
183
					}).fail(function ( response ) {
184
						$( 'input[type="submit"]', this ).prop( { 'disabled': false } );
185
						console.log( response );
186
					});
187
				});
188
189
			});
190
191
		</script>
192
		<?php
193
	}
194
	
195
	public function te_v1_insert_hidden_field() {
196
		echo '<input type="hidden" id="worldpay_pay_token" name="worldpay_pay_token" value="" />';
197
	}
198
199
	public function init() {
200
201
		add_action( 'wp_enqueue_scripts', array( $this, 'scripts' ) );
202
		add_action( 'wp_head'           , array( $this, 'head_script' ) );
203
204
		add_action( 'wpsc_inside_shopping_cart', array( $this, 'te_v1_insert_hidden_field' ) );
205
		
206
		add_filter( 'wpsc_gateway_checkout_form_worldpay', array( $this, 'payment_fields' ) );
207
		//add_filter( 'wpsc_get_checkout_payment_method_form_args', array( $this, 'te_v2_show_payment_fields' ) );
208
	}
209
210
	public function te_v2_show_payment_fields( $args ) {
211
212
		$default = '<div class="wpsc-form-actions">';
213
		ob_start();
214
215
		$this->payment_fields();
216
		$fields = ob_get_clean();
217
218
		$args['before_form_actions'] = $fields . $default;
219
220
		return $args;
221
	}
222
223
	public function process() {
224
225
		$order = $this->purchase_log;
226
		
227
		$status = $this->payment_capture === '' ? WPSC_Purchase_Log::ACCEPTED_PAYMENT : WPSC_Purchase_Log::ORDER_RECEIVED;
228
		
229
		$order->set( 'processed', $status )->save();
230
		
231
		$card_token = isset( $_POST['worldpay_pay_token'] ) ? sanitize_text_field( $_POST['worldpay_pay_token'] ) : '';
232
	
233
		$this->order_handler->set_purchase_log( $order->get( 'id' ) );
234
		
235
		switch ( $this->payment_capture ) {
236
			case 'authorize' :
237
238
				// Authorize only
239
				$result = $this->authorize_payment( $card_token );
240
241
				if ( $result ) {
242
					// Mark as on-hold
243
					$order->set( 'worldpay-status', __( 'WorldPay order opened. Capture the payment below. Authorized payments must be captured within 7 days.', 'wp-e-commerce' ) )->save();
244
245
				} else {
246
					$order->set( 'processed', WPSC_Purchase_Log::PAYMENT_DECLINED )->save();
247
					$order->set( 'worldpay-status', __( 'Could not authorize WorldPay payment.', 'wp-e-commerce' ) )->save();
248
249
					//$this->handle_declined_transaction( $order );
250
				}
251
252
			break;
253
			default:
254
					
255
				// Capture
256
				$result = $this->capture_payment( $card_token );
257
258
				if ( $result ) {
259
					// Payment complete
260
					$order->set( 'worldpay-status', __( 'WorldPay order completed.  Funds have been authorized and captured.', 'wp-e-commerce' ) );
261
				} else {
262
					$order->set( 'processed', WPSC_Purchase_Log::PAYMENT_DECLINED );
263
					$order->set( 'worldpay-status', __( 'Could not authorize WorldPay payment.', 'wp-e-commerce' ) );
264
265
					//$this->handle_declined_transaction( $order );
266
				}	
267
				
268
			break;
269
		}
270
		
271
		$order->save();
272
		$this->go_to_transaction_results();
273
274
	}
275
	
276
	public function capture_payment( $token ) {
277
278
		if ( $this->purchase_log->get( 'gateway' ) == 'worldpay' ) {
279
			
280
			$order = $this->purchase_log;
281
			
282
			$params = array (
0 ignored issues
show
introduced by
There must be no space between the Array keyword and the opening parenthesis
Loading history...
283
				'amount'	=> $order->get( 'totalprice' ),
284
				'orderId'	=> $order->get( 'id' ),
285
				'invoiceNumber' => $order->get( 'sessionid' ),
286
				"addToVault" => false,
287
				"paymentVaultToken" => array(
288
					"paymentMethodId" => $token,
289
					"publicKey" => $this->public_key
290
				),
291
				"extendedInformation" => array(
292
					"typeOfGoods" => $this->type_of_goods( $order->get( 'id' ) )
293
				),
294
			);
295
296
			$response = $this->execute( 'Payments/Charge', $params );
297
298
			if ( is_wp_error( $response ) ) {
299
				throw new Exception( $response->get_error_message() );
300
			}
301
			
302
			if ( isset( $response['ResponseBody']->transaction->transactionId ) ) {
303
				$transaction_id = $response['ResponseBody']->transaction->transactionId;
304
				$auth_code = $response['ResponseBody']->transaction->authorizationCode;
305
			} else {
306
				return false;
307
			}
308
			
309
			// Store transaction ID and Auth code in the order
310
			$order->set( 'wp_transactionId', $transaction_id )->save();
311
			$order->set( 'wp_order_status', 'Completed' )->save();
312
			$order->set( 'wp_authcode', $auth_code )->save();
313
			$order->set( 'transactid', $transaction_id )->save();
314
			
315
			return true;
316
		}
317
		
318
		return false;
319
	}
320
321
	public function authorize_payment( $token ) {
322
323
		if ( $this->purchase_log->get( 'gateway' ) == 'worldpay' ) {
324
			
325
			$order = $this->purchase_log;
326
			
327
			$params = array (
0 ignored issues
show
introduced by
There must be no space between the Array keyword and the opening parenthesis
Loading history...
328
				'amount'	=> $order->get( 'totalprice' ),
329
				'orderId'	=> $order->get( 'id' ),
330
				'invoiceNumber' => $order->get( 'sessionid' ),
331
				"addToVault" => false,
332
				"paymentVaultToken" => array(
333
					"paymentMethodId" => $token,
334
					"publicKey" => $this->public_key,
335
				),
336
				"extendedInformation" => array(
337
					"typeOfGoods" => $this->type_of_goods( $order->get( 'id' ) )
338
				),
339
			);
340
		
341
			$response = $this->execute( 'Payments/Authorize', $params );
342
343
			if ( is_wp_error( $response ) ) {
344
				throw new Exception( $response->get_error_message() );
345
			}
346
			
347
			if ( isset( $response['ResponseBody']->transaction->transactionId ) ) {
348
				$transaction_id = $response['ResponseBody']->transaction->transactionId;
349
				$auth_code = $response['ResponseBody']->transaction->authorizationCode;
350
			} else {
351
				return false;
352
			}
353
			
354
			// Store transaction ID and Auth code in the order
355
			$order->set( 'wp_transactionId', $transaction_id )->save();
356
			$order->set( 'wp_order_status', 'Open' )->save();
357
			$order->set( 'wp_authcode', $auth_code )->save();
358
			$order->set( 'transactid', $transaction_id )->save();
359
360
			return true;
361
		}
362
		
363
		return false;
364
	}
365
	
366
	public function execute( $endpoint, $params = array(), $type = 'POST' ) {
367
       
368
	   // where we make the API petition
369
        $endpoint = $this->endpoint . $endpoint;
370
        
371
		if ( ! is_null( $params ) ) {
372
			$params += array(
373
				"developerApplication" => array(
374
					"developerId" => 10000644,
375
					"version" => "1.2"
376
				),
377
			);			
378
		}
379
			
380
		$data = json_encode( $params );
381
		
382
		$args = array (
0 ignored issues
show
introduced by
There must be no space between the Array keyword and the opening parenthesis
Loading history...
383
			'timeout' => 15,
384
			'headers' => array(
385
				'Authorization' => $this->auth,
386
				'Content-Type' => 'application/json',
387
			),
388
			'sslverify' => false,
389
			'body' => $data,
390
		);
391
		
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 3 empty lines
Loading history...
392
393
  	
394
		$request  = $type == 'GET' ? wp_safe_remote_get( $endpoint, $args ) : wp_safe_remote_post( $endpoint, $args );
395
        $response = wp_remote_retrieve_body( $request );
396
		
397
		if ( ! is_wp_error( $request ) ) {
398
399
			$response_object = array();
400
			$response_object['ResponseBody'] = json_decode( $response );
401
			$response_object['Status']       = wp_remote_retrieve_response_code( $request );
402
403
			$request = $response_object;
404
		}
405
		
406
		return $request;
407
    }
408
409
	public function type_of_goods( $log_id ) {
410
		$digital = 0;
411
412
		$log = new WPSC_Purchase_Log( $log_id );
413
		$cart = $log->get_cart_contents();
414
		
415
		foreach ( $cart as $cartitem ) {
416
			$product_meta = get_post_meta( $cartitem->prodid, '_wpsc_product_metadata' );
417
			
418
			if( isset( $product_meta[0]['no_shipping'] ) && $product_meta[0]['no_shipping'] == 1 ) {
419
				$digital++;
420
			}
421
		}
422
		
423
		if( $digital == count( $cart ) ) {
424
			//At least one item is downloadable
425
			$transtype = 'DIGITAL';
426
		} else {
427
			$transtype = 'PHYSICAL';
428
		}
429
		
430
		return $transtype;
431
	}
432
}
433
434
class WPSC_WorldPay_Payments_Order_Handler {
435
	
436
	private static $instance;
437
	private $log;
438
	private $gateway;
439
440
	public function __construct( &$gateway ) {
441
442
		$this->log     = $gateway->purchase_log;
443
		$this->gateway = $gateway;
444
445
		$this->init();
446
	}
447
448
	/**
449
	 * Constructor
450
	 */
451
	public function init() {
452
		add_action( 'wpsc_purchlogitem_metabox_start', array( $this, 'meta_box' ), 8 );
453
		add_action( 'wp_ajax_worldpay_order_action'    , array( $this, 'order_actions' ) );
454
455
	}
456
457
	public static function get_instance( $gateway ) {
458
		if ( is_null( self::$instance ) ) {
459
			self::$instance = new WPSC_WorldPay_Payments_Order_Handler( $gateway );
460
		}
461
462
		return self::$instance;
463
	}
464
465
	public function set_purchase_log( $id ) {
466
		$this->log = new WPSC_Purchase_Log( $id );
467
	}
468
	
469
	/**
470
	 * Perform order actions for amazon
471
	 */
472
	public function order_actions() {
473
		check_ajax_referer( 'wp_order_action', 'security' );
474
475
		$order_id = absint( $_POST['order_id'] );
476
		$id       = isset( $_POST['worldpay_id'] ) ? sanitize_text_field( $_POST['worldpay_id'] ) : '';
477
		$action   = sanitize_title( $_POST['worldpay_action'] );
478
479
		$this->set_purchase_log( $order_id );
480
481
		switch ( $action ) {
482
			case 'capture' :
483
				//Capture an AUTH
484
				$this->capture_payment($id);
485
			break;
486
			
487
			case 'void' :
488
				// void capture or auth before settled
489
				$this->void_payment( $id );
490
			break;
491
			
492
			case 'refund' :
493
				// refund a settled payment
494
				$this->refund_payment( $id );
495
			break;
496
			
497
			case 'void_refund' :
498
				// void a refund request
499
				$this->void_refund( $id );
500
			break;
501
		}
502
503
		echo json_encode( array( 'action' => $action, 'order_id' => $order_id, 'worldpay_id' => $id ) );
504
505
		die();
506
	}
507
	
508
	/**
509
	 * meta_box function.
510
	 *
511
	 * @access public
512
	 * @return void
513
	 */
514
	function meta_box( $log_id ) {
515
		$this->set_purchase_log( $log_id );
516
517
		$gateway = $this->log->get( 'gateway' );
518
519
		if ( $gateway == 'worldpay' ) {
520
			$this->authorization_box();
521
		}
522
	}
523
524
	/**
525
	 * pre_auth_box function.
526
	 *
527
	 * @access public
528
	 * @return void
529
	 */
530
	public function authorization_box() {
531
		
532
		$actions  = array();
533
		$order_id = $this->log->get( 'id' );
534
535
		// Get ids
536
		$wp_transaction_id 	= $this->log->get( 'wp_transactionId' );
537
		$wp_auth_code		= $this->log->get( 'wp_authcode' );
538
		$wp_order_status	= $this->log->get( 'wp_order_status' );
539
		
540
		//Don't change order status if a refund has been requested
541
		$wp_refund_set       = wpsc_get_purchase_meta( $order_id, 'worldpay_refunded', true );
542
		$order_info = $this->refresh_transaction_info( $wp_transaction_id, ! ( bool ) $wp_refund_set );
0 ignored issues
show
introduced by
Cast statements must not contain whitespace; expected "(bool)" but found "( bool )"
Loading history...
543
		?>
544
		
545
		<div class="metabox-holder">
546
			<div id="wpsc-worldpay-payments" class="postbox">
547
				<h3 class='hndle'><?php _e( 'WorldPay Payments' , 'wp-e-commerce' ); ?></h3>
548
				<div class='inside'>
549
					<p><?php
550
							_e( 'Current status: ', 'wp-e-commerce' );
551
							echo wp_kses_data( $this->log->get( 'worldpay-status' ) );
552
						?>
553
					</p>
554
					<p><?php
555
							_e( 'Transaction ID: ', 'wp-e-commerce' );
556
							echo wp_kses_data( $wp_transaction_id );
557
						?>
558
					</p>
559
		<?php
560
		
561
		//Show actions based on order status
562
		switch ( $wp_order_status ) {
563
			case 'Open' :
564
				//Order is only authorized and still not captured/voided
565
				$actions['capture'] = array(
566
					'id' => $wp_transaction_id,
567
					'button' => __( 'Capture funds', 'wp-e-commerce' )
568
				);
569
				
570
				//
571
				if ( ! $order_info['settled'] ) {
572
					//Void
573
					$actions['void'] = array(
574
						'id' => $wp_transaction_id,
575
						'button' => __( 'Void order', 'wp-e-commerce' )
576
					);					
577
				}
578
				
579
				break;
580
			case 'Completed' :
581
				//Order has been captured or its a direct payment
582
				if ( $order_info['settled'] ) {
583
					//Refund
584
					$actions['refund'] = array(
585
						'id' => $wp_transaction_id,
586
						'button' => __( 'Refund order', 'wp-e-commerce' )
587
					);
588
				} else {
589
					//Void
590
					$actions['void'] = array(
591
						'id' => $wp_transaction_id,
592
						'button' => __( 'Void order', 'wp-e-commerce' )
593
					);					
594
				}
595
				
596
			break;
597
			case 'Refunded' :
598
				//Order is settled and a refund has been requested
599
				$wp_refund_id       = wpsc_get_purchase_meta( $order_id, 'worldpay_refund_id', true );
600
				
601
				if ( $wp_refund_id ) {
602
					//Get refund order status to check if its eligible for a void (not settled)
603
					$refund_status = $this->refresh_transaction_info( $wp_refund_id, false );
604
					
605
					if ( ! $refund_status['settled'] ) {
606
						//Show void only if not settled.
607
						$actions['void_refund'] = array(
608
							'id' => $wp_refund_id,
609
							'button' => __( 'Void Refund request', 'wp-e-commerce' )
610
						);						
611
					}
612
				}
613
614
				break;
615
			case 'Voided' :
616
			break;
617
		}			
618
		
619
		if ( ! empty( $actions ) ) {
620
621
			echo '<p class="buttons">';
622
623
			foreach ( $actions as $action_name => $action ) {
624
				echo '<a href="#" class="button" data-action="' . $action_name . '" data-id="' . $action['id'] . '">' . $action['button'] . '</a> ';
625
			}
626
627
			echo '</p>';
628
629
		}		
630
		?>
631
		<script type="text/javascript">
632
		jQuery( document ).ready( function( $ ) {
633
			$('#wpsc-worldpay-payments').on( 'click', 'a.button, a.refresh', function( e ) {
634
				var $this = $( this );
635
				e.preventDefault();
636
637
				var data = {
638
					action: 		'worldpay_order_action',
639
					security: 		'<?php echo wp_create_nonce( "wp_order_action" ); ?>',
640
					order_id: 		'<?php echo $order_id; ?>',
641
					worldpay_action: 	$this.data('action'),
642
					worldpay_id: 		$this.data('id'),
643
					worldpay_refund_amount: $('.worldpay_refund_amount').val(),
644
				};
645
646
				// Ajax action
647
				$.post( ajaxurl, data, function( result ) {
648
						location.reload();
649
					}, 'json' );
650
651
				return false;
652
			});
653
		} );
654
655
		</script>
656
		</div>
657
		</div>
658
		</div>
659
		<?php
660
	}
661
662
    /**
663
     * Get the order status from API
664
     *
665
     * @param  string $transaction_id
666
     */	
667
	public function refresh_transaction_info( $transaction_id, $update = true ) {
668
		
669
		if ( $this->log->get( 'gateway' ) == 'worldpay' ) {
670
			
671
			$response = $this->gateway->execute( 'transactions/'. $transaction_id, null, 'GET' );
672
673
			if ( is_wp_error( $response ) ) {
674
				throw new Exception( $response->get_error_message() );
675
			}
676
			
677
			$response_object = array();
678
			$response_object['trans_type'] 	= $response['ResponseBody']->transactions[0]->transactionType;
679
			$response_object['settled'] 	= isset( $response['ResponseBody']->transactions[0]->settlementData ) ? true : false;
680
681
			//Recheck status and update if required
682
			if ( $update ) {
683
				switch ( $response_object['trans_type'] ) {
684
					case 'AUTH_ONLY' :
685
						$this->log->set( 'wp_order_status', 'Open' )->save();
686
					break;
687
					
688
					case 'VOID' :
689
						$this->log->set( 'wp_order_status', 'Voided' )->save();
690
					break;
691
					
692
					case 'REFUND' :
693
					case 'CREDIT' :
694
						$this->log->set( 'wp_order_status', 'Refunded' )->save();
695
					break;				
696
					
697
					case 'AUTH_CAPTURE' :
698
					case 'PRIOR_AUTH_CAPTURE' :
699
						$this->log->set( 'wp_order_status', 'Completed' )->save();
700
					break;
701
				}				
702
			}
703
704
		return $response_object;
705
		}
706
	}
707
	
708
	
709
    /**
710
     * Void auth/capture
711
     *
712
     * @param  string $transaction_id
713
     */
714
    public function void_payment( $transaction_id ) {
715
716
		if ( $this->log->get( 'gateway' ) == 'worldpay' ) {
717
			
718
			$params = array(
719
				'amount'		=>  $this->log->get( 'totalprice' ),
0 ignored issues
show
introduced by
Expected 1 space after "=>"; 2 found
Loading history...
720
				'transactionId' => $transaction_id,
721
			);
722
			
723
			$response = $this->gateway->execute( 'Payments/Void', $params );
724
725
			if ( is_wp_error( $response ) ) {
726
				throw new Exception( $response->get_error_message() );
727
			}
728
			
729
			$this->log->set( 'wp_order_status', 'Voided' )->save();
730
			$this->log->set( 'worldpay-status', sprintf( __( 'Authorization voided (Auth ID: %s)', 'wp-e-commerce' ), $response['ResponseBody']->transaction->authorizationCode ) )->save();
731
			$this->log->set( 'processed', WPSC_Purchase_Log::INCOMPLETE_SALE )->save();
732
			$this->log->set( 'transactid', $response['ResponseBody']->transaction->transactionId )->save();
733
		}
734
    }
735
	
736
    /**
737
     * Refund payment
738
     *
739
     * @param  string $transaction_id
740
     */
741
    public function refund_payment( $transaction_id ) {
742
743
		if ( $this->log->get( 'gateway' ) == 'worldpay' ) {
744
			
745
			$params = array(
746
				'amount'		=> $this->log->get( 'totalprice' ),
747
				'transactionId' => $transaction_id,
748
				
749
			);
750
			
751
			$response = $this->gateway->execute( 'Payments/Refund', $params );
752
		
753
			if ( is_wp_error( $response ) ) {
754
				throw new Exception( $response->get_error_message() );
755
			}
756
			
757
			wpsc_add_purchase_meta( $this->log->get( 'id' ), 'worldpay_refunded', true );
758
			wpsc_add_purchase_meta( $this->log->get( 'id' ), 'worldpay_refund_id', $response['ResponseBody']->transaction->transactionId );
759
			$this->log->set( 'worldpay-status', sprintf( __( 'Refunded (Transaction ID: %s)', 'wp-e-commerce' ), $response['ResponseBody']->transaction->transactionId ) )->save();
760
			$this->log->set( 'processed', WPSC_Purchase_Log::REFUNDED )->save();
761
			$this->log->set( 'wp_order_status', 'Refunded' )->save();
762
			$this->log->set( 'transactid', $response['ResponseBody']->transaction->transactionId )->save();
763
		}
764
    }
765
	
766
    /**
767
     * Capture authorized payment
768
     *
769
     * @param  string $transaction_id
770
     */
771
    public function capture_payment( $transaction_id ) {
772
773
		if ( $this->log->get( 'gateway' ) == 'worldpay' ) {
774
			
775
			$params = array(
776
				'amount'		=>  $this->log->get( 'totalprice' ),
0 ignored issues
show
introduced by
Expected 1 space after "=>"; 2 found
Loading history...
777
				'transactionId' => $transaction_id,
778
			);
779
			
780
			$response = $this->gateway->execute( 'Payments/Capture', $params );
781
782
			if ( is_wp_error( $response ) ) {
783
				throw new Exception( $response->get_error_message() );
784
			}
785
			
786
			$this->log->set( 'wp_order_status', 'Completed' )->save();
787
			$this->log->set( 'worldpay-status', sprintf( __( 'Authorization Captured (Auth ID: %s)', 'wp-e-commerce' ), $response['ResponseBody']->transaction->authorizationCode ) )->save();
788
			$this->log->set( 'processed', WPSC_Purchase_Log::ACCEPTED_PAYMENT )->save();
789
			$this->log->set( 'transactid', $response['ResponseBody']->transaction->transactionId )->save();
790
		}
791
    }
792
	
793
    /**
794
     * Void a refund request
795
     *
796
     * @param  string $transaction_id
797
     */
798
    public function void_refund( $transaction_id ) {
799
800
		if ( $this->log->get( 'gateway' ) == 'worldpay' ) {
801
			
802
			$params = array(
803
				'amount'		=>  $this->log->get( 'totalprice' ),
0 ignored issues
show
introduced by
Expected 1 space after "=>"; 2 found
Loading history...
804
				'transactionId' => $transaction_id,
805
			);
806
			
807
			$response = $this->gateway->execute( 'Payments/Void', $params );
808
809
			if ( is_wp_error( $response ) ) {
810
				throw new Exception( $response->get_error_message() );
811
			}
812
			
813
			wpsc_delete_purchase_meta( $this->log->get( 'id' ), 'worldpay_refunded' );
814
			wpsc_delete_purchase_meta( $this->log->get( 'id' ), 'worldpay_refund_id' );
815
			$this->log->set( 'processed', WPSC_Purchase_Log::ACCEPTED_PAYMENT )->save();
816
			$this->log->set( 'wp_order_status', 'Completed' )->save();
817
			$this->log->set( 'worldpay-status', sprintf( __( 'Refund Voided (Transaction ID: %s)', 'wp-e-commerce' ), $response['ResponseBody']->transaction->transactionId ) )->save();
818
			$this->log->set( 'transactid', $response['ResponseBody']->transaction->transactionId )->save();
819
		}
820
    }
821
}