Completed
Push — master ( 9a3ee6...bca146 )
by Justin
05:42
created

WPSC_Pro_Pay_Hosted_Transaction_Results   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 25
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 10
c 0
b 0
f 0
wmc 4
lcom 1
cbo 3

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A create() 0 7 1
A get_response() 0 7 2
1
<?php
2
/**
3
 * @todo: Later,  Create a nice user sign-up flow, as a part of an overall onboarding experience
4
 * @todo: Later, integrate with subscriptions
5
 * @todo: Later, support capturing a different amount than originally authorized.
6
 * @todo: Abstract out config files, API objects, etc.
7
 */
8
class WPSC_Payment_Gateway_Pro_Pay extends WPSC_Payment_Gateway {
9
10
	private static $endpoints = array(
11
		// Posting URL for ProPay API real time processing
12
		'account-creation-endpoint' => array(
13
			'sandbox'    => 'https://xmltest.propay.com/api/propayapi.aspx',
14
			'production' => 'https://xml.propay.com/api/propayapi.aspx'
15
		),
16
		// (WSDL) URL for ProtectPay API (Calls preparatory to the PMI and for processing against a token once it is created)
17
		'wsdl-endpoint' => array(
18
			'sandbox'    => 'https://xmltestapi.propay.com/api/sps.svc?wsdl',
19
			'production' => 'https://xmlapi.propay.com/api/sps.svc?wsdl'
20
		),
21
		// URL for ProtectPay API (Calls preparatory to the PMI and for processing against a token once it is created)
22
		'payment-processing-endpoint' => array(
23
			'sandbox'    => 'https://xmltestapi.propay.com/api/sps.svc',
24
			'production' => 'https://xmlapi.propay.com/api/sps.svc'
25
		),
26
		// URL for ProtectPay PMI (tokenizing card numbers)
27
		'tokenization-endpoint-num-only' => array(
28
			'sandbox'    => 'https://protectpaytest.propay.com/pmi/cardnumonly.aspx',
29
			'production' => 'https://protectpay.propay.com/pmi/cardnumonly.aspx'
30
		),
31
		// URL for ProtectPay PMI (tokenizing cards)
32
		'tokenization-endpoint' => array(
33
			'sandbox'    => 'https://protectpaytest.propay.com/pmi/spr.aspx',
34
			'production' => 'https://protectpay.propay.com/pmi/spr.aspx'
35
		),
36
		// REST API endpoint
37
		'rest-api-endpoint' => array(
38
			'sandbox'    => 'https://sb01api.propay.com/protectpay',
39
			'production' => 'https://api.propay.com/protectpay',
40
		)
41
	);
42
43
	private $payment_capture;
44
	private $endpoint;
45
	private $sandbox;
46
47
	private $login_url = 'https://www.propay.com/?refid=WPECOMM';
48
	private $auth_token = 'd30280d2-74de-4418-ab3f-0f58055ee421';
49
50
	private $cert_string         = '2df3f9620654ee8a52b5b6d411c760';
51
	private $term_id             = '5b6d411c760';
52
	private $biller_account_id   = '7929812732866007';
53
	private $account_number      = '';
54
	private $merchant_profile_id = '';
55
56
	/**
57
	 * Constructor of ProPay Payment Gateway
58
	 *
59
	 * @access public
60
	 * @since 3.12.0
61
	 */
62
	public function __construct() {
63
64
		parent::__construct();
65
66
		$this->title    = __( 'ProPay (TSYS) Payment Gateway', 'wp-e-commerce' );
67
		$this->supports = array( 'tev1', 'refunds', 'partial-refunds', 'auth-capture' );
68
69
		// Define user set variables
70
		$this->account_number      = $this->setting->get( 'account_number' );
71
		$this->merchant_profile_id = $this->setting->get( 'merchant_profile_id' );
72
		$this->sandbox			   = $this->setting->get( 'sandbox_mode' ) == '1' ? true : false;
73
		$this->endpoint			   = $this->sandbox ? self::$endpoints['payment-processing-endpoint']['sandbox'] : self::$endpoints['payment-processing-endpoint']['production'];
74
		$this->payment_capture 	   = $this->setting->get( 'payment_capture' ) !== null ? $this->setting->get( 'payment_capture' ) : '';
75
76
		$this->admin_scripts();
77
	}
78
79
	public function admin_scripts() {
80
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
81
	}
82
83
	public function init() {
84
85
		parent::init();
86
87
		add_action( 'wp_enqueue_scripts'                  , array( $this, 'checkout_scripts' ) );
88
		add_action( 'wpsc_gateway_v2_inside_gateway_label', array( $this, 'add_spinner' ) );
89
		add_action( 'wpsc_inside_shopping_cart'           , array( $this, 'add_propay_iframe' ) );
90
91
		add_action( 'wp_ajax_propay_create_merchant_profile_id'  , array( $this, 'create_merchant_profile' ) );
92
93
		add_action( 'wp_ajax_create_payer_id'                    , array( $this, 'create_payer_id' ) );
94
		add_action( 'wp_ajax_nopriv_create_payer_id'             , array( $this, 'create_payer_id' ) );
95
96
		add_action( 'wp_ajax_create_hosted_transaction_id'       , array( $this, 'create_hosted_transaction_id' ) );
97
		add_action( 'wp_ajax_nopriv_create_hosted_transaction_id', array( $this, 'create_hosted_transaction_id' ) );
98
99
		add_action( 'wp_ajax_create_hosted_results'       , array( $this, 'create_hosted_results' ) );
100
		add_action( 'wp_ajax_nopriv_create_hosted_results', array( $this, 'create_hosted_results' ) );
101
102
		add_action( 'wpsc_get_form_output_after_form_fields', array( $this, 'add_propay_iframe' ) );
103
104
		add_filter( 'wpsc_form_input_append_to_label', array( $this, 'tev2_pro_pay_spinner' ), 10, 2 );
105
	}
106
107
	public function tev2_pro_pay_spinner( $label, $atts ) {
108
		$method  = isset( $atts['name'] )  && 'wpsc_payment_method' === $atts['name'];
109
		$pro_pay = isset( $atts['value'] ) && 'pro-pay' === $atts['value'];
110
111
		if ( $method && $pro_pay ) {
112
			ob_start();
113
114
			$this->add_spinner( 'pro-pay' );
115
			$spinner = ob_get_clean();
116
			$label = $spinner . $label;
117
		}
118
119
		return $label;
120
	}
121
122
	public function add_propay_iframe( $r = '' ) {
123
124
		$is_tev2_payment_page = ! empty( $r ) && 'wpsc-checkout-form' === $r['id'] && 'payment' === _wpsc_get_current_controller_slug();
125
		$is_tev1_payment_page = empty( $r );
126
127
		if ( ! $is_tev1_payment_page && ! $is_tev2_payment_page ) {
128
			return;
129
		}
130
		$this->loader();
0 ignored issues
show
Unused Code introduced by
The call to the method WPSC_Payment_Gateway_Pro_Pay::loader() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
131
		?>
132
		<style>
133
		.pro-pay-iframe {
134
			height: 640px;
135
			overflow:hidden;
136
			border: none;
137
			width: 100%;
138
			background: url(<?php echo admin_url( 'images/spinner.gif' ) ?>) no-repeat 50% 50%;
139
		}
140
141
		.pro-pay-frame.loaded {
142
			background: transparent;
143
		}
144
145
		</style>
146
		<iframe scrolling="no"  id="pro_pay_iframe" name="pro_pay_iframe" class="pro-pay-iframe"></iframe>
147
		<?php if ( defined( 'WPSC_DEBUG' ) && WPSC_DEBUG ) : ?>
148
			<div id="MessageLog" class="BrowserMessageBox"></div>
149
			<div id="BrowserLog" class="BrowserMessageBox"></div>
150
			<div id="ConsoleLog" class="BrowserMessageBox"></div>
151
		<?php
152
			endif;
153
	}
154
155
	public function loader() {
156
		?>
157
		<style>
158
		.wpsc-purchase-loader-container {
159
			position:absolute;
160
			display: none;
161
		}
162
163
		.wpsc-purchase-loader {
164
		  position: absolute;
165
		  top: calc( 50% - 18px );
166
		  width: 100%;
167
		}
168
169
		.blob {
170
		  position: absolute;
171
		  left: 50%;
172
		  top: 18px;
173
		  width: 3px;
174
		  height: 3px;
175
		  border-radius: 1.5px;
176
		  background-color: #00ffeb;
177
		  content: "";
178
		  -webkit-filter: blur(1px);
179
		          filter: blur(1px);
180
		  -webkit-transform: translateY(-10px);
181
		          transform: translateY(-10px);
182
		}
183
		.blob:nth-child(1) {
184
		  -webkit-animation: spin 1.25s infinite ease-in-out;
185
		          animation: spin 1.25s infinite ease-in-out;
186
		  -webkit-animation-delay: 0.1s;
187
		          animation-delay: 0.1s;
188
		}
189
		.blob:nth-child(2) {
190
		  -webkit-animation: spin 1.25s infinite ease-in-out;
191
		          animation: spin 1.25s infinite ease-in-out;
192
		  -webkit-animation-delay: 0.2s;
193
		          animation-delay: 0.2s;
194
		}
195
		.blob:nth-child(3) {
196
		  -webkit-animation: spin 1.25s infinite ease-in-out;
197
		          animation: spin 1.25s infinite ease-in-out;
198
		  -webkit-animation-delay: 0.3s;
199
		          animation-delay: 0.3s;
200
		}
201
		.blob:nth-child(4) {
202
		  -webkit-animation: spin 1.25s infinite ease-in-out;
203
		          animation: spin 1.25s infinite ease-in-out;
204
		  -webkit-animation-delay: 0.4s;
205
		          animation-delay: 0.4s;
206
		}
207
		.blob:nth-child(5) {
208
		  -webkit-animation: spin 1.25s infinite ease-in-out;
209
		          animation: spin 1.25s infinite ease-in-out;
210
		  -webkit-animation-delay: 0.5s;
211
		          animation-delay: 0.5s;
212
		}
213
		.blob:nth-child(6) {
214
		  -webkit-animation: spin 1.25s infinite ease-in-out;
215
		          animation: spin 1.25s infinite ease-in-out;
216
		  -webkit-animation-delay: 0.6s;
217
		          animation-delay: 0.6s;
218
		}
219
		.blob:nth-child(7) {
220
		  -webkit-animation: spin 1.25s infinite ease-in-out;
221
		          animation: spin 1.25s infinite ease-in-out;
222
		  -webkit-animation-delay: 0.7s;
223
		          animation-delay: 0.7s;
224
		}
225
226
		@-webkit-keyframes spin {
227
		  0% {
228
		    -webkit-transform: rotate(0deg) translateY(-10px) rotate(0deg);
229
		            transform: rotate(0deg) translateY(-10px) rotate(0deg);
230
		  }
231
		  70% {
232
		    -webkit-transform: rotate(360deg) translateY(-10px) rotate(-360deg);
233
		            transform: rotate(360deg) translateY(-10px) rotate(-360deg);
234
		  }
235
		}
236
237
		@keyframes spin {
238
		  0% {
239
		    -webkit-transform: rotate(0deg) translateY(-10px) rotate(0deg);
240
		            transform: rotate(0deg) translateY(-10px) rotate(0deg);
241
		  }
242
		  70% {
243
		    -webkit-transform: rotate(360deg) translateY(-10px) rotate(-360deg);
244
		            transform: rotate(360deg) translateY(-10px) rotate(-360deg);
245
		  }
246
		}
247
		</style>
248
		<div class='wpsc-purchase-loader-container'>
249
			<div class='wpsc-purchase-loader'>
250
			  <div class='blob'></div>
251
			  <div class='blob'></div>
252
			  <div class='blob'></div>
253
			  <div class='blob'></div>
254
			  <div class='blob'></div>
255
			  <div class='blob'></div>
256
			  <div class='blob'></div>
257
			</div>
258
		</div>
259
	<?php
260
	}
261
262
	/**
263
	 * Currently only functional for US.
264
	 *
265
	 * @return [type] [description]
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(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...
266
	 */
267
	public function load() {
268
		return 'USD' === wpsc_get_currency_code() && 'US' === wpsc_get_base_country();
269
	}
270
271
	public function add_spinner( $gateway ) {
272
		if ( 'pro-pay' !== $gateway ) {
273
			return;
274
		}
275
276
		?>
277
		<div class="spinner"></div>
278
		<style>
279
		.spinner {
280
			background: url(<?php echo admin_url( 'images/spinner.gif' ) ?>) no-repeat;
281
			-webkit-background-size: 20px 20px;
282
			background-size: 20px 20px;
283
			display: inline-block;
284
			vertical-align: middle;
285
			opacity: .7;
286
			filter: alpha(opacity=70);
287
			width: 20px;
288
			height: 20px;
289
			margin: 4px 10px 0;
290
			display: none;
291
		}
292
		@media print, (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 120dpi) {
293
			.spinner {
294
				background-image: url(<?php echo admin_url( 'images/spinner-2x.gif' ) ?>);
295
			}
296
		}
297
		</style>
298
		<?php
299
	}
300
301
	public function checkout_scripts() {
302
303
		$is_cart = wpsc_is_theme_engine( '1.0' ) ? wpsc_is_checkout() : ( wpsc_is_checkout() || wpsc_is_cart() );
304
305
		if ( $is_cart ) {
306
			wp_enqueue_script( 'pro-pay-signal-r', WPSC_MERCHANT_V3_SDKS_URL . '/pro-pay/js/signal-r.js', array( 'jquery' ), WPSC_VERSION );
307
			wp_enqueue_script( 'pro-pay-hpp', WPSC_MERCHANT_V3_SDKS_URL . '/pro-pay/js/hpp.js', array( 'jquery', 'pro-pay-signal-r' ), WPSC_VERSION );
308
			wp_enqueue_script( 'pro-pay-js', WPSC_MERCHANT_V3_SDKS_URL . '/pro-pay/js/pro-pay-checkout.js', array( 'jquery', 'pro-pay-hpp' ), WPSC_VERSION );
309
310
			wp_localize_script( 'pro-pay-hpp', 'WPSC_Pro_Pay_Checkout', array(
311
					'checkout_nonce' => wp_create_nonce( 'checkout_nonce' ),
312
					'ajaxurl'        => admin_url( 'admin-ajax.php', 'relative' ),
313
					'iframe_id'      => 'pro_pay_iframe',
314
					'base_uri'       => $this->get_hpp_base_uri(),
315
					'debug'          => WPSC_DEBUG,
316
					'checkout_data' => $this->get_checkout_details()
317
				)
318
			);
319
		}
320
	}
321
322
	private function get_checkout_details() {
323
		$details  = wpsc_get_customer_meta( 'checkout_details' );
324
		$checkout = WPSC_Checkout_Form::get();
325
326
		return array(
327
			'billingemail'     => $details[ $checkout->get_field_id_by_unique_name( 'billingemail' ) ],
328
			'billingfirstname' => $details[ $checkout->get_field_id_by_unique_name( 'billingfirstname' ) ],
329
			'billinglastname'  => $details[ $checkout->get_field_id_by_unique_name( 'billinglastname' ) ],
330
			'billingaddress'   => $details[ $checkout->get_field_id_by_unique_name( 'billingaddress' ) ],
331
			'billingcity'      => $details[ $checkout->get_field_id_by_unique_name( 'billingcity' ) ],
332
			'billingregion'    => wpsc_get_state_by_id( wpsc_get_customer_meta( '_wpsc_cart.delivery_region' ), 'code' ),
333
			'billingpostcode'  => $details[ $checkout->get_field_id_by_unique_name( 'billingpostcode' ) ],
334
			'billingcountry'   => $details[ $checkout->get_field_id_by_unique_name( 'billingcountry' ) ]
335
		);
336
	}
337
338
	private function get_hpp_base_uri() {
339
340
		$base_url = $this->sandbox ? 'https://sbprotectpay.propay.com' : 'https://protectpay.propay.com';
341
342
		return $base_url;
343
	}
344
345
	public function enqueue_admin_scripts( $hook ) {
346
347
		if ( 'settings_page_wpsc-settings' !== $hook ) {
348
			return;
349
		}
350
351
		wp_enqueue_script( 'pro-pay-admin-js', WPSC_MERCHANT_V3_SDKS_URL . '/pro-pay/js/pro-pay-admin.js', array( 'jquery' ), WPSC_VERSION, true );
352
		wp_localize_script( 'pro-pay-admin-js', 'WPSC_Pro_Pay', array(
353
				'merchant_profile_nonce'  => wp_create_nonce( 'wpsc_merchant_profile' ),
354
				'profile_id_success_text' => __( 'Congratulations, you now have a functional merchant profile ID!', 'wp-e-commerce' ),
355
				'profile_id_error_text'   => __( 'Unfortunately, there was an error with this process. Try again later.', 'wp-e-commerce' )
356
			)
357
		);
358
359
	}
360
361
	public static function get_endpoint( $type, $environment ) {
362
		// Default to a sane assumption of sandbox payment processing;
363
		$endpoint = self::$endpoints['payment-processing-endpoint']['sandbox'];
364
365
		if ( ! isset( self::$endpoints[ $type ] ) ) {
366
			return $endpoint;
367
		}
368
369
		if ( ! isset( self::$endpoints[ $type ][ $environment ] ) ) {
370
			return $endpoint;
371
		}
372
373
		return self::$endpoints[ $type ][ $environment ];
374
	}
375
376
	public function get_account_number_row( $hide = false ) {
377
		$hidden = $hide ? ' style="display:none;"' : '';
378
	?>
379
		<tr id="pro-pay-account-row"<?php echo $hidden; ?>>
380
			<td>
381
				<label for="wpsc-pro-pay-merchant-profile-id"><?php _e( 'Account Number', 'wp-e-commerce' ); ?></label>
382
			</td>
383
			<td>
384
				<input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'account_number' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'account_number' ) ); ?>" id="wpsc-pro-pay-account-number" />
385
				<br><span class="small description"><?php _e( 'The Account Number can be obtained from the email that you should have received during the sign-up process.', 'wp-e-commerce' ); ?></span>
386
			</td>
387
		</tr>
388
		<?php
389
	}
390
391
	/**
392
	 * Settings Form Template
393
	 *
394
	 * @since 3.12.0
395
	 */
396
	public function setup_form() {
397
		if ( empty( $this->account_number ) ) {
398
			?>
399
			<tr id="account-creation-pro-pay">
400
				<td></td>
401
				<td>
402
					<a class="button-primary" href="<?php echo esc_url( $this->login_url ); ?>"><?php _e( 'Create an Account?', 'wp-e-commerce' ); ?></a>
403
					<a class="button-secondary" href="#" onclick="jQuery( '#pro-pay-account-row' ).slideDown( 300 ); jQuery('#account-creation-pro-pay').slideUp(400); return false; "><?php _e( 'Already Have One?', 'wp-e-commerce' ); ?></a>
404
				</td>
405
			</tr>
406
		<?php
407
			$this->get_account_number_row( true );
408
		} else {
409
?>
410
		<!-- Account Credentials -->
411
		<tr>
412
			<td colspan="2">
413
				<h4><?php _e( 'Account Credentials', 'wp-e-commerce' ); ?></h4>
414
			</td>
415
		</tr>
416
		<?php $this->get_account_number_row(); ?>
417
		<tr>
418
			<td>
419
				<label for="wpsc-pro-pay-merchant-profile-id"><?php _e( 'Merchant Profile ID', 'wp-e-commerce' ); ?></label>
420
			</td>
421
			<td>
422
				<input type="text" name="<?php echo esc_attr( $this->setting->get_field_name( 'merchant_profile_id' ) ); ?>" value="<?php echo esc_attr( $this->setting->get( 'merchant_profile_id' ) ); ?>" id="wpsc-pro-pay-merchant-profile-id" />
423
				<?php if ( empty( $this->merchant_profile_id ) ) : ?>
424
				<div id="wpsc-propay-merchant-profile-create">
425
					<p><span class="small description"><?php _e( 'If you have not yet received a merchant profile ID, create one below.', 'wp-e-commerce' ); ?></span></p>
426
					<br /><a href="#" class="button-primary create-merchant-profile"><?php _e( 'Create Merchant Profile ID' ); ?></a><div class="spinner" style="float:none"></div>
427
				</div>
428
			<?php endif; ?>
429
			</td>
430
		</tr>
431
		<tr>
432
			<td>
433
				<label for="wpsc-pro-pay-payment-capture"><?php _e( 'Payment Capture', 'wp-e-commerce' ); ?></label>
434
			</td>
435
			<td>
436
				<select id="wpsc-pro-pay-payment-capture" name="<?php echo esc_attr( $this->setting->get_field_name( 'payment_capture' ) ); ?>">
437
					<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>
438
					<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>
439
				</select>
440
			</td>
441
		</tr>
442
		<tr>
443
			<td>
444
				<label><?php _e( 'Sandbox Mode', 'wp-e-commerce' ); ?></label>
445
			</td>
446
			<td>
447
				<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;
448
				<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>
449
			</td>
450
		</tr>
451
		<!-- Error Logging -->
452
		<tr>
453
			<td colspan="2">
454
				<h4><?php _e( 'Error Logging', 'wp-e-commerce' ); ?></h4>
455
			</td>
456
		</tr>
457
		<tr>
458
			<td>
459
				<label><?php _e( 'Enable Debugging', 'wp-e-commerce' ); ?></label>
460
			</td>
461
			<td>
462
				<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;
463
				<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>
464
			</td>
465
		</tr>
466
<?php
467
		}
468
	}
469
470
	public function create_merchant_profile() {
471
472
		if ( ! wp_verify_nonce( $_POST['nonce'] , 'wpsc_merchant_profile' ) ) {
473
			wp_send_json_error();
474
		}
475
476
		if ( ! wpsc_is_store_admin() ) {
477
			wp_send_json_error();
478
		}
479
480
		$config = new WPSC_Pro_Pay_Merchant_Profile_Config(
481
			array(
482
				'cert_string'       => $this->cert_string,
483
				'account_number'    => $this->account_number,
484
				'term_id'           => $this->term_id,
485
				'environment'       => $this->sandbox ? 'sandbox' : 'production',
486
				'biller_account_id' => $this->biller_account_id,
487
				'auth_token'        => $this->auth_token
488
			)
489
		);
490
491
		$profile = new WPSC_ProPay_Merchant_Profile( $config );
492
493
		$profile_id   = $profile->create()->get_profile_id();
494
495
		if ( $profile_id ) {
496
			$this->setting->set( 'merchant_profile_id', $profile_id );
497
			wp_send_json_success( array( 'profile_id' => $profile_id ) );
498
		} else {
499
			wp_send_json_error();
500
		}
501
	}
502
503
	public function create_payer_id() {
504
505
		if ( ! wp_verify_nonce( $_POST['nonce'] , 'checkout_nonce' ) ) {
506
			wp_send_json_error();
507
		}
508
509
		$payer_id = wpsc_get_customer_meta( 'pro_pay_payer_id' );
510
511
		if ( $payer_id ) {
512
			wp_send_json_success( array( 'payer' => $payer_id ) );
513
		}
514
515
		$name  = sanitize_text_field( $_POST['name'] );
516
		$email = sanitize_email( $_POST['email'] );
517
518
		$config = new WPSC_Pro_Pay_Payer_Id_Config(
519
			array(
520
				'environment'       => $this->sandbox ? 'sandbox' : 'production',
521
				'biller_account_id' => $this->biller_account_id,
522
				'auth_token'        => $this->auth_token,
523
				'name'              => $name,
524
				'email'             => $email
525
			)
526
		);
527
528
		$payer = new WPSC_ProPay_Payer_Id( $config );
529
530
		$payer_id = $payer->create()->get_payer_id();
531
532
		if ( $payer_id ) {
533
			wpsc_update_customer_meta( 'pro_pay_payer_id', $payer_id );
534
			wp_send_json_success( array( 'payer' => $payer_id ) );
535
		} else {
536
			wp_send_json_error();
537
		}
538
	}
539
540
	public function create_hosted_transaction_id() {
541
542
		if ( ! wp_verify_nonce( $_POST['nonce'] , 'checkout_nonce' ) ) {
543
			wp_send_json_error();
544
		}
545
546
		$name        = sanitize_text_field( $_POST['name'] );
547
		$address1    = sanitize_text_field( $_POST['address1'] );
548
		$address2    = sanitize_text_field( $_POST['address2'] );
549
		$city        = sanitize_text_field( $_POST['city'] );
550
		$state       = is_numeric( $_POST['state'] ) ? wpsc_get_state_by_id( $_POST['state'], 'code' ) : sanitize_text_field( $_POST['state'] );
551
		$zip         = sanitize_text_field( $_POST['zip'] );
552
		$country     = 'USA'; // Check if we can do international BUYERS. If so, we need 3-character ISO
553
554
		$config = new WPSC_Pro_Pay_Hosted_Transaction_Id_Config(
555
			array(
556
				'environment'         => $this->sandbox ? 'sandbox' : 'production',
557
				'biller_account_id'   => $this->biller_account_id,
558
				'auth_token'          => $this->auth_token,
559
				'name'                => $name,
560
				'address1'            => $address1,
561
				'address2'            => $address2,
562
				'city'                => $city,
563
				'state'               => $state,
564
				'zip'                 => $zip,
565
				'country'             => $country,
566
				'description'         => sprintf( __( 'Order from %s', 'wp-e-commerce' ), get_bloginfo( 'blogname' ) ),
567
				'merchant_profile_id' => $this->merchant_profile_id,
568
				'auth_only'           => 'authorize' === $this->payment_capture,
569
			)
570
		);
571
572
		$hosted = new WPSC_Pro_Pay_Hosted_Transaction_Id( $config );
573
574
		$token = $hosted->create()->get_transaction_id();
575
576
		if ( $token ) {
577
			wp_send_json_success( array( 'token' => $token ) );
578
		} else {
579
			wp_send_json_error();
580
		}
581
	}
582
583
	public function create_hosted_results() {
584
585
		if ( ! wp_verify_nonce( $_POST['nonce'] , 'checkout_nonce' ) ) {
586
			wp_send_json_error();
587
		}
588
589
		$config = new WPSC_Pro_Pay_Hosted_Transaction_Results_Config(
590
			array(
591
				'environment'         => $this->sandbox ? 'sandbox' : 'production',
592
				'biller_account_id'   => $this->biller_account_id,
593
				'auth_token'          => $this->auth_token,
594
				'id'                  => sanitize_text_field( $_POST['hosted_id'] )
595
			)
596
		);
597
598
		$hosted = new WPSC_Pro_Pay_Hosted_Transaction_Results( $config );
599
600
		$results = $hosted->create()->get_response();
601
602
		if ( $results ) {
603
			wp_send_json_success( array( 'results' => $results ) );
604
		} else {
605
			wp_send_json_error();
606
		}
607
	}
608
609
	public function process() {
610
611
		$token          = sanitize_text_field( $_POST['pro_pay_payment_method_token'] );
612
		$transaction_id = sanitize_text_field( $_POST['pro_pay_transaction_id'] );
613
		$last_four      = absint( substr( $_POST['pro_pay_obfs_acct_number'], 0, -4 ) );
614
		$type           = sanitize_text_field( $_POST['pro_pay_card_type'] );
615
		$order          = $this->purchase_log;
616
617
		$status = $this->payment_capture === '' ? WPSC_Purchase_Log::ACCEPTED_PAYMENT : WPSC_Purchase_Log::ORDER_RECEIVED;
618
619
		$order->set( 'processed', $status )->save();
620
		$order->set( 'token', $token )->save();
621
		$order->set( 'transactid', $transaction_id )->save();
622
		$order->set( 'last_four', $last_four )->save();
623
		$order->set( 'type', $type )->save();
624
625
		$this->go_to_transaction_results();
626
	}
627
628
	public function capture_payment( $log, $transaction_id ) {
629
630
		if ( $log->get( 'gateway' ) == 'pro-pay' ) {
631
632
			$config = new WPSC_Pro_Pay_Hosted_Capture_Payment_Config(
633
				array(
634
					'environment'         => $this->sandbox ? 'sandbox' : 'production',
635
					'biller_account_id'   => $this->biller_account_id,
636
					'auth_token'          => $this->auth_token,
637
					'merchant_profile_id' => $this->merchant_profile_id,
638
					'transaction_id'      => sanitize_text_field( $transaction_id ),
639
					'amount'              => $log->get( 'totalprice' ),
640
				)
641
			);
642
643
			$capture = new WPSC_Pro_Pay_Hosted_Capture_Payment( $config );
644
645
			$results = $capture->capture()->get_transaction_id();
646
647
			if ( empty( $results ) ) {
648
				throw new Exception( __( 'Could not generate a captured payment transaction ID.', 'wp-e-commerce' ) );
649
			}
650
651
			$log->set( 'processed', WPSC_Purchase_Log::ACCEPTED_PAYMENT )->save();
652
			$log->set( 'transactid', $results )->save();
653
			$log->set( 'pro_pay_capt_transactid', $transaction_id )->save();
654
655
			return true;
656
		}
657
658
		return false;
659
	}
660
661
	public function process_refund( $log, $amount = 0.00, $reason = '', $manual = false ) {
662
663
		if ( 0.00 == $amount ) {
664
			return new WP_Error( 'propay_refund_error', __( 'Refund Error: You need to specify a refund amount.', 'wp-e-commerce' ) );
665
		}
666
667
		$log = wpsc_get_order( $log );
668
669
		if ( ! $log->get( 'transactid' ) ) {
670
			return new WP_Error( 'error', __( 'Refund Failed: No transaction ID', 'wp-e-commerce' ) );
671
		}
672
673
		$max_refund  = $log->get( 'totalprice' ) - $log->get_total_refunded();
674
675
		if ( $amount && $max_refund < $amount || 0 > $amount ) {
676
			throw new Exception( __( 'Invalid refund amount', 'wp-e-commerce' ) );
677
		}
678
679
		if ( $manual ) {
680
			$current_refund = $log->get_total_refunded();
681
682
			// Set a log meta entry, and save log before adding refund note.
683
			$log->set( 'total_order_refunded' , $amount + $current_refund )->save();
684
685
			$log->add_refund_note(
686
				sprintf( __( 'Refunded %s via Manual Refund', 'wp-e-commerce' ), wpsc_currency_display( $amount ) ),
687
				$reason
688
			);
689
690
			return true;
691
		}
692
693
		$transaction_id = $log->get( 'transactid' );
694
695
		$options = new WPSC_Pro_Pay_Refund_Config( array(
696
			'amount'            => $amount,
697
			'reason'            => $reason,
698
			'transaction_id'    => $transaction_id,
699
			'merchant_id'       => $this->merchant_profile_id,
700
			'environment'       => $this->sandbox ? 'sandbox' : 'production',
701
			'biller_account_id' => $this->biller_account_id,
702
			'auth_token'        => $this->auth_token,
703
		) );
704
705
		// do API call
706
		$refund = new WPSC_Pro_Pay_Refund( $options );
707
		$refund = $refund->create()->get_refund();
708
709
		if ( $refund ) {
710
711
			if ( 'Success' == $refund->TransactionResult ) {
712
713
				$current_refund = $log->get_total_refunded();
714
715
				// Set a log meta entry, and save log before adding refund note.
716
				$log->set( 'total_order_refunded' , $amount + $current_refund )->save();
717
718
				$log->add_refund_note(
719
					sprintf( __( 'Refunded %s - Refund ID: %s', 'wp-e-commerce' ), wpsc_currency_display( $refund->CurrencyConvertedAmount / 100 ), $refund->TransactionHistoryId ),
720
					$reason
721
				);
722
723
				return true;
724
			}
725
		} else {
726
			return false;
727
		}
728
	}
729
}
730
731
class WPSC_ProPay_Request {
732
733
	protected $config;
734
	protected $method;
735
736
	public function __construct( $config, $method = 'PUT' ) {
737
		$this->config = $config;
738
		$this->method = $method;
739
	}
740
741
	public function request( $resource, $args = array() ) {
742
743
		$endpoint = WPSC_Payment_Gateway_Pro_Pay::get_endpoint( 'rest-api-endpoint', $this->config->environment );
744
745
		$url = $endpoint . '/'. ltrim( $resource, '/' );
746
747
		$args = wp_parse_args( $args, array(
748
			'timeout' => 60,
749
			'method'  => $this->method,
750
			'body'    => array(),
751
			'headers' => array(
752
				'content-type'  => 'application/json',
753
				'authorization' => self::generate_auth( $this->config->biller_account_id, $this->config->auth_token )
754
			)
755
		) );
756
757
		if ( ! empty( $args['body'] ) ) {
758
			$args['headers']['content-length'] = strlen( $args['body'] );
759
		}
760
761
		return new WPSC_ProPay_Response( wp_safe_remote_request( $url, $args ) );
762
	}
763
764
	private static function generate_auth( $id, $auth ) {
765
		return 'Basic ' . base64_encode( "{$id}:{$auth}" );
766
	}
767
}
768
769
class WPSC_ProPay_Response {
770
771
	public $response = null;
772
	protected $success = false;
773
774
	public function __construct( $response ) {
775
		$this->response = $response;
776
		$this->prepare_response();
777
	}
778
779
	public function prepare_response() {
780
781
		$response = json_decode( wp_remote_retrieve_body( $this->response ) );
782
		$code     = wp_remote_retrieve_response_code( $this->response );
783
784
		if ( isset( $response->RequestResult ) ) {
785
			$transaction_success = 'SUCCESS' === $response->RequestResult->ResultValue;
786
		} else {
787
			$transaction_success = 'SUCCESS' === $response->Result->ResultValue;
788
		}
789
790
		$success = 200 === $code && $transaction_success;
791
792
		if ( ! is_wp_error( $this->response ) && $success ) {
793
			$this->success = true;
794
			$this->response = $response;
795
		}
796
797
		return $this->response;
798
	}
799
800
	public function is_successful() {
801
		return $this->success;
802
	}
803
804
	public function get( $variable ) {
805
806
		if ( isset( $this->response->$variable ) ) {
807
			return $this->response->$variable;
808
		}
809
810
		return '';
811
	}
812
813
	/**
814
	 * Temp debug function.
815
	 *
816
	 * @return string [description]
817
	 */
818
	public function __toString() {
819
		return '<pre>' . print_r( $this->response, 1 ) . '</pre>';
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
820
	}
821
}
822
823
class WPSC_ProPay_Merchant_Profile {
824
825
	protected $config;
826
827
	public function __construct( WPSC_Pro_Pay_Merchant_Profile_Config $config ) {
828
		$this->config = $config;
829
	}
830
831
	public function create() {
832
		$request = new WPSC_ProPay_Request( $this->config );
833
834
		$body = json_encode( array(
835
			'ProfileName' => '',
836
			'PaymentProcessor' => 'LegacyProPay',
837
			'ProcessorData' => array(
838
				array(
839
					'ProcessorField' => 'certStr',
840
					'Value'          => $this->config->cert_string
841
				),
842
				array(
843
					'ProcessorField' => 'accountNum',
844
					'Value'          => $this->config->account_number
845
				),
846
				array(
847
					'ProcessorField' => 'termId',
848
					'Value'          => $this->config->term_id
849
				)
850
			),
851
		) );
852
853
		$this->response = $request->request( '/MerchantProfiles/', array( 'body' => $body ) );
0 ignored issues
show
Bug introduced by
The property response 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...
854
855
		return $this;
856
	}
857
858
	public function get_profile_id() {
859
860
		if ( $this->response->is_successful() ) {
861
			return $this->response->get( 'ProfileId' );
862
		}
863
864
		return '';
865
	}
866
}
867
868
class WPSC_Pro_Pay_Merchant_Profile_Config {
869
870
	public $cert_string;
871
	public $account_number;
872
	public $term_id;
873
	public $environment;
874
	public $biller_account_id;
875
	public $auth_token;
876
877
	public function __construct( $args ) {
878
		$this->args = (object) $args;
0 ignored issues
show
Bug introduced by
The property args 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...
879
880
		$this->cert_string       = $this->args->cert_string;
881
		$this->account_number    = $this->args->account_number;
882
		$this->term_id           = $this->args->term_id;
883
		$this->environment       = $this->args->environment;
884
		$this->biller_account_id = $this->args->biller_account_id;
885
		$this->auth_token        = $this->args->auth_token;
886
	}
887
}
888
889
class WPSC_ProPay_Payer_Id {
890
891
	protected $config;
892
	protected $response;
893
894
	public function __construct( WPSC_Pro_Pay_Payer_Id_Config $config ) {
895
		$this->config = $config;
896
	}
897
898
	public function create() {
899
		$request = new WPSC_ProPay_Request( $this->config );
900
901
		$body = json_encode( array(
902
			'Name'             => $this->config->name,
903
			'EmailAddress'     => $this->config->email,
904
		) );
905
906
		$this->response = $request->request( '/Payers/', array( 'body' => $body ) );
907
908
		return $this;
909
	}
910
911
	public function get_payer_id() {
912
		if ( $this->response->is_successful() ) {
913
			return $this->response->get( 'ExternalAccountID' );
914
		}
915
916
		return '';
917
	}
918
}
919
920
class WPSC_Pro_Pay_Payer_Id_Config {
921
922
	public $environment;
923
	public $biller_account_id;
924
	public $auth_token;
925
	public $name;
926
	public $email;
927
928
	public function __construct( $args ) {
929
		$this->args = (object) $args;
0 ignored issues
show
Bug introduced by
The property args 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...
930
931
		$this->environment       = $this->args->environment;
932
		$this->biller_account_id = $this->args->biller_account_id;
933
		$this->auth_token        = $this->args->auth_token;
934
		$this->name              = $this->args->name;
935
		$this->email             = $this->args->email;
936
	}
937
}
938
939
class WPSC_Pro_Pay_Hosted_Transaction_Id {
940
941
	protected $config;
942
	protected $response;
943
944
	public function __construct( WPSC_Pro_Pay_Hosted_Transaction_Id_Config $config ) {
945
		$this->config = $config;
946
	}
947
948
	public function create() {
949
		$request = new WPSC_ProPay_Request( $this->config );
950
951
		$body = json_encode( apply_filters( 'wpsc_pro_pay_default_hosted_transaction_args', array(
952
			'Name'              => $this->config->name,
953
			'Address1'          => $this->config->address1,
0 ignored issues
show
Bug introduced by
The property address1 does not seem to exist in WPSC_Pro_Pay_Hosted_Transaction_Id_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
954
			'Address2'          => $this->config->address2,
0 ignored issues
show
Bug introduced by
The property address2 does not seem to exist in WPSC_Pro_Pay_Hosted_Transaction_Id_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
955
			'City'              => $this->config->city,
0 ignored issues
show
Bug introduced by
The property city does not seem to exist in WPSC_Pro_Pay_Hosted_Transaction_Id_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
956
			'State'             => $this->config->state,
0 ignored issues
show
Bug introduced by
The property state does not seem to exist in WPSC_Pro_Pay_Hosted_Transaction_Id_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
957
			'ZipCode'           => $this->config->zip,
0 ignored issues
show
Bug introduced by
The property zip does not seem to exist in WPSC_Pro_Pay_Hosted_Transaction_Id_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
958
			'Country'           => $this->config->country,
0 ignored issues
show
Bug introduced by
The property country does not seem to exist in WPSC_Pro_Pay_Hosted_Transaction_Id_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
959
			'Description'       => $this->config->description,
0 ignored issues
show
Bug introduced by
The property description does not seem to exist in WPSC_Pro_Pay_Hosted_Transaction_Id_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
960
			'MerchantProfileId' => $this->config->merchant_profile_id,
0 ignored issues
show
Bug introduced by
The property merchant_profile_id does not seem to exist in WPSC_Pro_Pay_Hosted_Transaction_Id_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
961
			'AuthOnly'          => $this->config->auth_only,
0 ignored issues
show
Bug introduced by
The property auth_only does not seem to exist in WPSC_Pro_Pay_Hosted_Transaction_Id_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
962
			'ProcessCard'       => ! $this->config->auth_only,
963
			'Amount'            => wpsc_cart_total( false ) * 100,
964
			'PayerAccountId'    => wpsc_get_customer_meta( 'pro_pay_payer_id' ),
965
			'PaymentTypeId'     => '0',
966
			'CurrencyCode'      => 'USD',
967
			'InvoiceNumber'     => uniqid(),
968
			'AvsRequirementType'               => 1,
969
			'CardHolderNameRequirementType'    => 1,
970
			'SecurityCodeRequirementType'      => 1,
971
			'OnlyStoreCardOnSuccessfulProcess' => true,
972
		) ) );
973
974
		$this->response = $request->request( '/HostedTransactions/', array( 'body' => $body ) );
975
976
		return $this;
977
	}
978
979
	public function get_transaction_id() {
980
		if ( $this->response->is_successful() ) {
981
			return $this->response->get( 'HostedTransactionIdentifier' );
982
		}
983
984
		return '';
985
	}
986
}
987
988
class WPSC_Pro_Pay_Hosted_Transaction_Id_Config {
989
990
	public $environment;
991
	public $biller_account_id;
992
	public $auth_token;
993
	public $name;
994
995
	public function __construct( $args ) {
996
		$this->args = (object) $args;
0 ignored issues
show
Bug introduced by
The property args 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...
997
998
		$this->environment         = $this->args->environment;
999
		$this->biller_account_id   = $this->args->biller_account_id;
1000
		$this->auth_token          = $this->args->auth_token;
1001
		$this->name                = $this->args->name;
1002
		$this->address1            = $this->args->address1;
0 ignored issues
show
Bug introduced by
The property address1 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...
1003
		$this->address2            = $this->args->address2;
0 ignored issues
show
Bug introduced by
The property address2 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...
1004
		$this->city                = $this->args->city;
0 ignored issues
show
Bug introduced by
The property city 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...
1005
		$this->state               = $this->args->state;
0 ignored issues
show
Bug introduced by
The property state 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...
1006
		$this->zip                 = $this->args->zip;
0 ignored issues
show
Bug introduced by
The property zip 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...
1007
		$this->country             = $this->args->country;
0 ignored issues
show
Bug introduced by
The property country 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...
1008
		$this->description         = $this->args->description;
0 ignored issues
show
Bug introduced by
The property description 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...
1009
		$this->merchant_profile_id = $this->args->merchant_profile_id;
0 ignored issues
show
Bug introduced by
The property merchant_profile_id 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...
1010
		$this->auth_only           = $this->args->auth_only;
0 ignored issues
show
Bug introduced by
The property auth_only 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...
1011
	}
1012
}
1013
1014
class WPSC_Pro_Pay_Hosted_Transaction_Results {
1015
1016
	protected $config;
1017
	protected $response;
1018
1019
	public function __construct( WPSC_Pro_Pay_Hosted_Transaction_Results_Config $config ) {
1020
		$this->config = $config;
1021
	}
1022
1023
	public function create() {
1024
		$request = new WPSC_ProPay_Request( $this->config, 'GET' );
1025
1026
		$this->response = $request->request( "/HostedTransactionResults/{$this->config->id}" );
1027
1028
		return $this;
1029
	}
1030
1031
	public function get_response() {
1032
		if ( $this->response->is_successful() ) {
1033
			return $this->response;
1034
		}
1035
1036
		return '';
1037
	}
1038
}
1039
1040
class WPSC_Pro_Pay_Hosted_Transaction_Results_Config {
1041
1042
	public $environment;
1043
	public $biller_account_id;
1044
	public $auth_token;
1045
	public $id;
1046
1047
	public function __construct( $args ) {
1048
		$this->args = (object) $args;
0 ignored issues
show
Bug introduced by
The property args 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...
1049
1050
		$this->environment       = $this->args->environment;
1051
		$this->biller_account_id = $this->args->biller_account_id;
1052
		$this->auth_token        = $this->args->auth_token;
1053
		$this->id                = $this->args->id;
1054
	}
1055
}
1056
1057
class WPSC_Pro_Pay_Refund {
1058
1059
	protected $config;
1060
	protected $response;
1061
1062
	public function __construct( WPSC_Pro_Pay_Refund_Config $config ) {
1063
		$this->config = $config;
1064
	}
1065
1066
	public function create() {
1067
		$request = new WPSC_ProPay_Request( $this->config );
1068
1069
		$body = json_encode( array(
1070
			'CurrencyCode'         => 'USD',
1071
			'TransactionHistoryId' => $this->config->transaction_id,
0 ignored issues
show
Bug introduced by
The property transaction_id does not seem to exist in WPSC_Pro_Pay_Refund_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1072
			'Comment1'             => $this->config->reason,
0 ignored issues
show
Bug introduced by
The property reason does not seem to exist in WPSC_Pro_Pay_Refund_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1073
			'Amount'               => $this->config->amount * 100,
0 ignored issues
show
Bug introduced by
The property amount does not seem to exist in WPSC_Pro_Pay_Refund_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1074
			'MerchantProfileId'    => $this->config->merchant_id
0 ignored issues
show
Bug introduced by
The property merchant_id does not seem to exist in WPSC_Pro_Pay_Refund_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1075
		) );
1076
1077
		$this->response = $request->request( '/RefundTransaction/', array( 'body' => $body ) );
1078
1079
		return $this;
1080
	}
1081
1082
	public function get_refund() {
1083
		if ( $this->response->is_successful() ) {
1084
			return $this->response->get( 'TransactionDetail' );
1085
		}
1086
1087
		return '';
1088
	}
1089
}
1090
1091
class WPSC_Pro_Pay_Refund_Config {
1092
1093
	public $environment;
1094
	public $biller_account_id;
1095
	public $auth_token;
1096
	public $name;
1097
1098
	public function __construct( $args ) {
1099
		$this->args                = (object) $args;
0 ignored issues
show
Bug introduced by
The property args 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...
1100
		$this->environment         = $this->args->environment;
1101
		$this->biller_account_id   = $this->args->biller_account_id;
1102
		$this->auth_token          = $this->args->auth_token;
1103
		$this->transaction_id      = $this->args->transaction_id;
0 ignored issues
show
Bug introduced by
The property transaction_id 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...
1104
		$this->reason              = $this->args->reason;
0 ignored issues
show
Bug introduced by
The property reason 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...
1105
		$this->amount              = $this->args->amount;
0 ignored issues
show
Bug introduced by
The property amount 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...
1106
		$this->merchant_id         = $this->args->merchant_id;
0 ignored issues
show
Bug introduced by
The property merchant_id 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...
1107
1108
	}
1109
}
1110
1111
class WPSC_Pro_Pay_Hosted_Capture_Payment {
1112
1113
	protected $config;
1114
	protected $response;
1115
1116
	public function __construct( WPSC_Pro_Pay_Hosted_Capture_Payment_Config $config ) {
1117
		$this->config = $config;
1118
	}
1119
1120
	public function capture() {
1121
		$request = new WPSC_ProPay_Request( $this->config );
1122
1123
		$body = json_encode( array(
1124
			'TransactionHistoryId' => $this->config->transaction_id,
0 ignored issues
show
Bug introduced by
The property transaction_id does not seem to exist in WPSC_Pro_Pay_Hosted_Capture_Payment_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1125
			'MerchantProfileId'    => $this->config->merchant_profile_id,
0 ignored issues
show
Bug introduced by
The property merchant_profile_id does not seem to exist in WPSC_Pro_Pay_Hosted_Capture_Payment_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1126
			'Amount'               => $this->config->amount * 100,
0 ignored issues
show
Bug introduced by
The property amount does not seem to exist in WPSC_Pro_Pay_Hosted_Capture_Payment_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1127
			'CurrencyCode'         => 'USD'
1128
		) );
1129
1130
		$this->response = $request->request( '/PaymentMethods/CapturedTransactions/', array( 'body' => $body ) );
1131
1132
		trigger_error( var_export( $this->response, 1 ) );
1133
1134
		return $this;
1135
	}
1136
1137
	public function get_transaction_id() {
1138
1139
		if ( $this->response->is_successful() ) {
1140
			return $this->response->get( 'Transaction' )->TransactionHistoryId;
1141
		}
1142
1143
		return '';
1144
	}
1145
}
1146
1147
class WPSC_Pro_Pay_Hosted_Capture_Payment_Config {
1148
1149
	public $environment;
1150
	public $biller_account_id;
1151
	public $auth_token;
1152
	public $id;
1153
1154
	public function __construct( $args ) {
1155
		$this->args = (object) $args;
0 ignored issues
show
Bug introduced by
The property args 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...
1156
1157
		$this->environment         = $this->args->environment;
1158
		$this->biller_account_id   = $this->args->biller_account_id;
1159
		$this->auth_token          = $this->args->auth_token;
1160
		$this->transaction_id      = $this->args->transaction_id;
0 ignored issues
show
Bug introduced by
The property transaction_id 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...
1161
		$this->merchant_profile_id = $this->args->merchant_profile_id;
0 ignored issues
show
Bug introduced by
The property merchant_profile_id 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...
1162
		$this->amount              = $this->args->amount;
0 ignored issues
show
Bug introduced by
The property amount 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...
1163
	}
1164
}
1165