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

WPSC_Payment_Gateway_WorldPay   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 404
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 3

Importance

Changes 14
Bugs 0 Features 1
Metric Value
wmc 29
c 14
b 0
f 1
lcom 3
cbo 3
dl 0
loc 404
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 18 4
A setup_form() 0 72 1
A scripts() 0 5 2
A head_script() 0 64 1
A te_v1_insert_hidden_field() 0 3 1
A init() 0 10 1
A te_v2_show_payment_fields() 0 12 1
B process() 0 52 6
B capture_payment() 0 40 4
B authorize_payment() 0 40 4
B execute() 0 45 4
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
17
	
18
19
	/**
20
	 * Constructor of WorldPay Payment Gateway
21
	 *
22
	 * @access public
23
	 * @since 3.9
24
	 */
25
	public function __construct() {
26
27
		parent::__construct();
28
29
		$this->title = __( 'WorldPay Payment Gateway', 'wp-e-commerce' );
30
		$this->supports = array( 'default_credit_card_form', 'tev1' );
31
32
		$this->order_handler	= WPSC_WorldPay_Payments_Order_Handler::get_instance( $this );
33
		
34
		// Define user set variables
35
		$this->secure_net_id	= $this->setting->get( 'secure_net_id' );
36
		$this->secure_key  		= $this->setting->get( 'secure_key' );
37
		$this->public_key  		= $this->setting->get( 'public_key' );
38
		$this->sandbox			= $this->setting->get( 'sandbox_mode' ) == '1' ? true : false;
0 ignored issues
show
Bug introduced by
The property sandbox does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

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