WooCommerce PayPal Express Checkout Payment Gateway - Version 2.0.3

Version Description

  • 2020-07-01 =
  • Fix - Records the proper refunded_amount to _woo_pp_txnData in the database PR#764
  • Fix - Redirect customers back to the original page they left on after closing PayPal modal PR#765
  • Fix - Preserve horizontal layout style setting when using standalone buttons PR#774
  • Fix - Smart payment buttons compatibility with older browsers PR#778
  • Tweak - Update the Require Phone Number field description PR#772
  • Dev - Make the SDK script args filterable PR#763
Download this release

Release Info

Developer woothemes
Plugin Icon 128x128 WooCommerce PayPal Express Checkout Payment Gateway
Version 2.0.3
Comparing to
See all releases

Code changes from version 2.0.2 to 2.0.3

Files changed (33) hide show
  1. assets/js/wc-gateway-ppec-smart-payment-buttons.js +5 -3
  2. changelog.txt +8 -0
  3. includes/abstracts/abstract-wc-gateway-ppec-client-credential.php +1 -1
  4. includes/abstracts/abstract-wc-gateway-ppec-paypal-request-handler.php +4 -2
  5. includes/abstracts/abstract-wc-gateway-ppec.php +45 -35
  6. includes/class-wc-gateway-ppec-address.php +114 -116
  7. includes/class-wc-gateway-ppec-admin-handler.php +33 -21
  8. includes/class-wc-gateway-ppec-api-error.php +5 -1
  9. includes/class-wc-gateway-ppec-cart-handler.php +81 -68
  10. includes/class-wc-gateway-ppec-checkout-details.php +101 -101
  11. includes/class-wc-gateway-ppec-checkout-handler.php +71 -65
  12. includes/class-wc-gateway-ppec-client-credential-certificate.php +5 -3
  13. includes/class-wc-gateway-ppec-client-credential-signature.php +1 -1
  14. includes/class-wc-gateway-ppec-client.php +84 -72
  15. includes/class-wc-gateway-ppec-gateway-loader.php +7 -7
  16. includes/class-wc-gateway-ppec-ipn-handler.php +28 -16
  17. includes/class-wc-gateway-ppec-ips-handler.php +10 -14
  18. includes/class-wc-gateway-ppec-payment-details.php +108 -108
  19. includes/class-wc-gateway-ppec-plugin.php +25 -23
  20. includes/class-wc-gateway-ppec-privacy.php +14 -10
  21. includes/class-wc-gateway-ppec-refund.php +1 -1
  22. includes/class-wc-gateway-ppec-session-data.php +11 -8
  23. includes/class-wc-gateway-ppec-settings.php +20 -13
  24. includes/class-wc-gateway-ppec-with-paypal-addons.php +9 -7
  25. includes/class-wc-gateway-ppec-with-paypal-credit.php +2 -2
  26. includes/class-wc-gateway-ppec-with-spb-addons.php +3 -3
  27. includes/class-wc-gateway-ppec-with-spb.php +3 -3
  28. includes/exceptions/class-wc-gateway-ppec-api-exception.php +2 -2
  29. includes/functions.php +13 -13
  30. includes/settings/settings-ppec.php +53 -33
  31. languages/woocommerce-gateway-paypal-express-checkout.pot +334 -292
  32. readme.txt +11 -3
  33. woocommerce-gateway-paypal-express-checkout.php +4 -4
assets/js/wc-gateway-ppec-smart-payment-buttons.js CHANGED
@@ -141,10 +141,12 @@
141
  if ( ! wc_ppec_context.use_checkout_js ) {
142
  return fetch( wc_ppec_context.start_checkout_url, {
143
  method: 'post',
 
 
144
  headers: {
145
  'Content-Type': 'application/x-www-form-urlencoded',
146
  },
147
- body: data,
148
  } ).then( function ( response ) {
149
  return response.json();
150
  } ).then( request_callback );
@@ -177,7 +179,7 @@
177
  },
178
 
179
  onCancel: function( data, actions ) {
180
- if ( 'orderID' in data ) {
181
  const query_args = '?woo-paypal-cancel=true&token=' + data.orderID;
182
  return actions.redirect( cancel_url + query_args );
183
  }
@@ -222,7 +224,7 @@
222
  onError: button_args.onError,
223
  onCancel: button_args.onCancel,
224
  fundingSource: fundingSource,
225
- style: ( paypal.FUNDING.PAYPAL === fundingSource ) ? button_args.style : {}
226
  };
227
 
228
  var button = paypal.Buttons( buttonSettings );
141
  if ( ! wc_ppec_context.use_checkout_js ) {
142
  return fetch( wc_ppec_context.start_checkout_url, {
143
  method: 'post',
144
+ cache: 'no-cache',
145
+ credentials: 'same-origin',
146
  headers: {
147
  'Content-Type': 'application/x-www-form-urlencoded',
148
  },
149
+ body: data
150
  } ).then( function ( response ) {
151
  return response.json();
152
  } ).then( request_callback );
179
  },
180
 
181
  onCancel: function( data, actions ) {
182
+ if ( cancel_url && 'orderID' in data ) {
183
  const query_args = '?woo-paypal-cancel=true&token=' + data.orderID;
184
  return actions.redirect( cancel_url + query_args );
185
  }
224
  onError: button_args.onError,
225
  onCancel: button_args.onCancel,
226
  fundingSource: fundingSource,
227
+ style: ( paypal.FUNDING.PAYPAL === fundingSource ) ? button_args.style : { layout: button_args.style.layout }
228
  };
229
 
230
  var button = paypal.Buttons( buttonSettings );
changelog.txt CHANGED
@@ -1,5 +1,13 @@
1
  *** Changelog ***
2
 
 
 
 
 
 
 
 
 
3
  = 2.0.2 - 2020-05-28 =
4
  * Fix - Javascript errors during checkout when the Payment Action is set to Authorize. PR#754
5
  * Fix - Style the Smart Payment Buttons according to the chosen button size setting. PR#753
1
  *** Changelog ***
2
 
3
+ = 2.0.3 - 2020-07-01 =
4
+ * Fix - Records the proper refunded_amount to _woo_pp_txnData in the database PR#764
5
+ * Fix - Redirect customers back to the original page they left on after closing PayPal modal PR#765
6
+ * Fix - Preserve horizontal layout style setting when using standalone buttons PR#774
7
+ * Fix - Smart payment buttons compatibility with older browsers PR#778
8
+ * Tweak - Update the Require Phone Number field description PR#772
9
+ * Dev - Make the SDK script args filterable PR#763
10
+
11
  = 2.0.2 - 2020-05-28 =
12
  * Fix - Javascript errors during checkout when the Payment Action is set to Authorize. PR#754
13
  * Fix - Style the Smart Payment Buttons according to the chosen button size setting. PR#753
includes/abstracts/abstract-wc-gateway-ppec-client-credential.php CHANGED
@@ -96,6 +96,6 @@ abstract class WC_Gateway_PPEC_Client_Credential {
96
  * @return void
97
  */
98
  public function configure_curl( $handle, $r, $url ) {
99
- curl_setopt( $handle, CURLOPT_CAINFO, wc_gateway_ppec()->includes_path . 'pem/bundle.pem' );
100
  }
101
  }
96
  * @return void
97
  */
98
  public function configure_curl( $handle, $r, $url ) {
99
+ curl_setopt( $handle, CURLOPT_CAINFO, wc_gateway_ppec()->includes_path . 'pem/bundle.pem' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt
100
  }
101
  }
includes/abstracts/abstract-wc-gateway-ppec-paypal-request-handler.php CHANGED
@@ -37,7 +37,8 @@ abstract class WC_Gateway_PPEC_PayPal_Request_Handler {
37
  */
38
  protected function get_paypal_order( $raw_custom ) {
39
  // We have the data in the correct format, so get the order.
40
- if ( ( $custom = json_decode( $raw_custom ) ) && is_object( $custom ) ) {
 
41
  $order_id = $custom->order_id;
42
  $order_key = $custom->order_key;
43
  } else {
@@ -45,7 +46,8 @@ abstract class WC_Gateway_PPEC_PayPal_Request_Handler {
45
  return false;
46
  }
47
 
48
- if ( ! $order = wc_get_order( $order_id ) ) {
 
49
  // We have an invalid $order_id, probably because invoice_prefix has changed.
50
  $order_id = wc_get_order_id_by_order_key( $order_key );
51
  $order = wc_get_order( $order_id );
37
  */
38
  protected function get_paypal_order( $raw_custom ) {
39
  // We have the data in the correct format, so get the order.
40
+ $custom = json_decode( $raw_custom );
41
+ if ( $custom && is_object( $custom ) ) {
42
  $order_id = $custom->order_id;
43
  $order_key = $custom->order_key;
44
  } else {
46
  return false;
47
  }
48
 
49
+ $order = wc_get_order( $order_id );
50
+ if ( ! $order ) {
51
  // We have an invalid $order_id, probably because invoice_prefix has changed.
52
  $order_id = wc_get_order_id_by_order_key( $order_key );
53
  $order = wc_get_order( $order_id );
includes/abstracts/abstract-wc-gateway-ppec.php CHANGED
@@ -55,7 +55,7 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
55
  $this->subtotal_mismatch_behavior = $this->get_option( 'subtotal_mismatch_behavior', 'add' );
56
  $this->use_ppc = false;
57
 
58
- if ( empty( $_GET['woo-paypal-return'] ) && 'yes' !== $this->get_option( 'use_spb', 'yes' ) ) {
59
  $this->order_button_text = __( 'Continue to payment', 'woocommerce-gateway-paypal-express-checkout' );
60
  }
61
 
@@ -64,8 +64,8 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
64
  // Change gateway name if session is active
65
  if ( ! is_admin() ) {
66
  if ( wc_gateway_ppec()->checkout->is_started_from_checkout_page() ) {
67
- $this->title = $this->get_option( 'title' );
68
- $this->description = $this->get_option( 'description' );
69
  }
70
  } else {
71
  add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
@@ -82,7 +82,7 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
82
  * @return string
83
  */
84
  public function pass_return_args_to_ajax( $request ) {
85
- if ( isset( $_GET['woo-paypal-return'] ) ) {
86
  $request .= '&woo-paypal-return=1';
87
  }
88
 
@@ -101,7 +101,7 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
101
  $screen = get_current_screen();
102
 
103
  // Only enqueue the setting scripts on the PayPal Checkout settings screen.
104
- if ( $screen && 'woocommerce_page_wc-settings' === $screen->id && isset( $_GET['tab'], $_GET['section'] ) && 'checkout' === $_GET['tab'] && 'ppec_paypal' === $_GET['section'] ) {
105
  wp_enqueue_script( 'wc-gateway-ppec-settings', wc_gateway_ppec()->plugin_url . 'assets/js/wc-gateway-ppec-settings.js', array( 'jquery' ), wc_gateway_ppec()->version, true );
106
  }
107
  }
@@ -110,7 +110,7 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
110
  * Initialise Gateway Settings Form Fields.
111
  */
112
  public function init_form_fields() {
113
- $this->form_fields = include( dirname( dirname( __FILE__ ) ) . '/settings/settings-ppec.php' );
114
  }
115
 
116
  /**
@@ -142,7 +142,7 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
142
  $checkout_details = $checkout->get_checkout_details( $session->token );
143
 
144
  $checkout_context = array(
145
- 'order_id' => $order_id,
146
  );
147
  if ( $checkout->needs_billing_agreement_creation( $checkout_context ) ) {
148
  $checkout->create_billing_agreement( $order, $checkout_details );
@@ -174,7 +174,7 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
174
  // them pick out a new funding method.
175
  $error_codes = wp_list_pluck( $e->errors, 'error_code' );
176
 
177
- if ( in_array( '10486', $error_codes ) || in_array( '10422', $error_codes ) ) {
178
  $session->checkout_completed = false;
179
  $session->source = 'order';
180
  $session->order_id = $order_id;
@@ -208,11 +208,13 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
208
 
209
  if ( $cert_info ) {
210
  $valid_until = $cert_info['validTo_time_t'];
211
- $expires = __( 'expires on %s (%s)', 'woocommerce-gateway-paypal-express-checkout' );
 
212
 
213
  if ( $valid_until < time() ) {
214
  // Display in red if the cert is already expired
215
- $expires = '<span style="color: red;">' . __( 'expired on %s (%s)', 'woocommerce-gateway-paypal-express-checkout' ) . '</span>';
 
216
  } elseif ( $valid_until < ( time() - ( 30 * DAY_IN_SECONDS ) ) ) {
217
  // Also display in red if the cert is going to expire in the next 30 days
218
  $expires = '<span style="color: red;">' . $expires . '</span>';
@@ -222,7 +224,8 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
222
  $expiry_date->setTimezone( wp_timezone() );
223
 
224
  $expires = sprintf( $expires, date_i18n( get_option( 'date_format' ), $expiry_date->getTimestamp() + $expiry_date->getOffset() ), $expiry_date->format( 'T' ) );
225
- $output = sprintf( __( 'Certificate belongs to API username %1$s; %2$s.', 'woocommerce-gateway-paypal-express-checkout' ), $cert_info['subject']['CN'], $expires );
 
226
  } else {
227
  $output = __( 'The certificate on file is not valid.', 'woocommerce-gateway-paypal-express-checkout' );
228
  }
@@ -238,14 +241,14 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
238
  if ( array_key_exists( 'woocommerce_ppec_paypal_api_certificate', $_FILES )
239
  && array_key_exists( 'tmp_name', $_FILES['woocommerce_ppec_paypal_api_certificate'] )
240
  && array_key_exists( 'size', $_FILES['woocommerce_ppec_paypal_api_certificate'] )
241
- && $_FILES['woocommerce_ppec_paypal_api_certificate']['size'] ) {
242
 
243
- $_POST['woocommerce_ppec_paypal_api_certificate'] = base64_encode( file_get_contents( $_FILES['woocommerce_ppec_paypal_api_certificate']['tmp_name'] ) );
244
- unlink( $_FILES['woocommerce_ppec_paypal_api_certificate']['tmp_name'] );
245
  unset( $_FILES['woocommerce_ppec_paypal_api_certificate'] );
246
- } elseif ( isset( $_POST['woocommerce_ppec_delete_live_api_certificate'] ) ) {
247
  $_POST['woocommerce_ppec_paypal_api_certificate'] = '';
248
- unset( $_POST['woocommerce_ppec_delete_live_api_certificate'] );
249
  } else {
250
  $_POST['woocommerce_ppec_paypal_api_certificate'] = $this->get_option( 'api_certificate' );
251
  }
@@ -253,14 +256,14 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
253
  if ( array_key_exists( 'woocommerce_ppec_paypal_sandbox_api_certificate', $_FILES )
254
  && array_key_exists( 'tmp_name', $_FILES['woocommerce_ppec_paypal_sandbox_api_certificate'] )
255
  && array_key_exists( 'size', $_FILES['woocommerce_ppec_paypal_sandbox_api_certificate'] )
256
- && $_FILES['woocommerce_ppec_paypal_sandbox_api_certificate']['size'] ) {
257
 
258
- $_POST['woocommerce_ppec_paypal_sandbox_api_certificate'] = base64_encode( file_get_contents( $_FILES['woocommerce_ppec_paypal_sandbox_api_certificate']['tmp_name'] ) );
259
- unlink( $_FILES['woocommerce_ppec_paypal_sandbox_api_certificate']['tmp_name'] );
260
  unset( $_FILES['woocommerce_ppec_paypal_sandbox_api_certificate'] );
261
- } elseif ( isset( $_POST['woocommerce_ppec_delete_sandbox_api_certificate'] ) ) {
262
  $_POST['woocommerce_ppec_paypal_sandbox_api_certificate'] = '';
263
- unset( $_POST['woocommerce_ppec_delete_sandbox_api_certificate'] );
264
  } else {
265
  $_POST['woocommerce_ppec_paypal_sandbox_api_certificate'] = $this->get_option( 'sandbox_api_certificate' );
266
  }
@@ -380,7 +383,7 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
380
  public function process_refund( $order_id, $amount = null, $reason = '' ) {
381
  $order = wc_get_order( $order_id );
382
 
383
- if ( 0 == $amount || null == $amount ) {
384
  return new WP_Error( 'paypal_refund_error', __( 'Refund Error: You need to specify a refund amount.', 'woocommerce-gateway-paypal-express-checkout' ) );
385
  }
386
 
@@ -388,28 +391,30 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
388
  // loop through each transaction to compile list of txns that are able to be refunded
389
  // process refunds against each txn in the list until full amount of refund is reached
390
  // first loop through, try to find a transaction that equals the refund amount being requested
391
- $old_wc = version_compare( WC_VERSION, '3.0', '<' );
392
- $txn_data = $old_wc ? get_post_meta( $order_id, '_woo_pp_txnData', true ) : $order->get_meta( '_woo_pp_txnData', true );
393
  $order_currency = $old_wc ? $order->order_currency : $order->get_currency();
394
 
395
- if( ! isset($txn_data['refundable_txns'] ) ) {
396
  return new WP_Error( 'paypal_refund_error', __( 'Refund Error: Sorry! This is not a refundable transaction.', 'woocommerce-gateway-paypal-express-checkout' ) );
397
  }
398
 
399
  foreach ( $txn_data['refundable_txns'] as $key => $value ) {
400
  $refundable_amount = $value['amount'] - $value['refunded_amount'];
401
 
402
- if ( $amount == $refundable_amount ) {
403
- $refund_type = ( 0 == $value['refunded_amount'] ) ? 'Full' : 'Partial';
404
 
405
  try {
406
  $refund_txn_id = WC_Gateway_PPEC_Refund::refund_order( $order, $amount, $refund_type, $reason, $order_currency );
407
  $txn_data['refundable_txns'][ $key ]['refunded_amount'] += $amount;
 
408
  $order->add_order_note( sprintf( __( 'PayPal refund completed; transaction ID = %s', 'woocommerce-gateway-paypal-express-checkout' ), $refund_txn_id ) );
409
  if ( $old_wc ) {
410
  update_post_meta( $order_id, '_woo_pp_txnData', $txn_data );
411
  } else {
412
  $order->update_meta_data( '_woo_pp_txnData', $txn_data );
 
413
  }
414
 
415
  return true;
@@ -428,11 +433,13 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
428
  try {
429
  $refund_txn_id = WC_Gateway_PPEC_Refund::refund_order( $order, $amount, 'Partial', $reason, $order_currency );
430
  $txn_data['refundable_txns'][ $key ]['refunded_amount'] += $amount;
 
431
  $order->add_order_note( sprintf( __( 'PayPal refund completed; transaction ID = %s', 'woocommerce-gateway-paypal-express-checkout' ), $refund_txn_id ) );
432
  if ( $old_wc ) {
433
  update_post_meta( $order_id, '_woo_pp_txnData', $txn_data );
434
  } else {
435
  $order->update_meta_data( '_woo_pp_txnData', $txn_data );
 
436
  }
437
 
438
  return true;
@@ -440,20 +447,20 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
440
  } catch ( PayPal_API_Exception $e ) {
441
  return new WP_Error( 'paypal_refund_error', $e->getMessage() );
442
  }
443
-
444
  }
445
  }
446
 
447
  $total_refundable_amount = 0;
448
  foreach ( $txn_data['refundable_txns'] as $key => $value ) {
449
- $refundable_amount = $value['amount'] - $value['refunded_amount'];
450
  $total_refundable_amount += $refundable_amount;
451
  }
452
 
453
  if ( $total_refundable_amount < $amount ) {
454
- if ( 0 == $total_refundable_amount ) {
455
  return new WP_Error( 'paypal_refund_error', __( 'Refund Error: All transactions have been fully refunded. There is no amount left to refund', 'woocommerce-gateway-paypal-express-checkout' ) );
456
  } else {
 
457
  return new WP_Error( 'paypal_refund_error', sprintf( __( 'Refund Error: The requested refund amount is too large. The refund amount must be less than or equal to %s.', 'woocommerce-gateway-paypal-express-checkout' ), html_entity_decode( get_woocommerce_currency_symbol() ) . $total_refundable_amount ) );
458
  }
459
  } else {
@@ -470,19 +477,21 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
470
 
471
  if ( 0 < $amount_to_refund ) {
472
  $refund_type = 'Partial';
473
- if ( 0 == $value['refunded_amount'] && $amount_to_refund == $value['amount'] ) {
474
  $refund_type = 'Full';
475
  }
476
 
477
  try {
478
- $refund_txn_id = WC_Gateway_PPEC_Refund::refund_order( $order, $amount_to_refund, $refund_type, $reason, $order_currency );
479
  $total_to_refund -= $amount_to_refund;
480
  $txn_data['refundable_txns'][ $key ]['refunded_amount'] += $amount_to_refund;
 
481
  $order->add_order_note( sprintf( __( 'PayPal refund completed; transaction ID = %s', 'woocommerce-gateway-paypal-express-checkout' ), $refund_txn_id ) );
482
  if ( $old_wc ) {
483
  update_post_meta( $order_id, '_woo_pp_txnData', $txn_data );
484
  } else {
485
  $order->update_meta_data( '_woo_pp_txnData', $txn_data );
 
486
  }
487
 
488
  return true;
@@ -548,7 +557,7 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
548
  $maybe_hide_remove_style = '';
549
 
550
  // For backwards compatibility (customers that already have set a url)
551
- $value_is_url = filter_var( $value, FILTER_VALIDATE_URL ) !== false;
552
 
553
  if ( empty( $value ) || $value_is_url ) {
554
  $maybe_hide_remove_style = 'display: none;';
@@ -560,7 +569,7 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
560
  ?>
561
  <tr valign="top">
562
  <th scope="row" class="titledesc">
563
- <label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?> <?php echo $this->get_tooltip_html( $data ); ?></label>
564
  </th>
565
 
566
  <td class="image-component-wrapper">
@@ -569,7 +578,8 @@ abstract class WC_Gateway_PPEC extends WC_Payment_Gateway {
569
  if ( ! $value_is_url ) {
570
  echo wp_get_attachment_image( $value, 'thumbnail' );
571
  } else {
572
- echo sprintf( __( 'Already using URL as image: %s', 'woocommerce-gateway-paypal-express-checkout' ), $value );
 
573
  }
574
  ?>
575
  </div>
55
  $this->subtotal_mismatch_behavior = $this->get_option( 'subtotal_mismatch_behavior', 'add' );
56
  $this->use_ppc = false;
57
 
58
+ if ( empty( $_GET['woo-paypal-return'] ) && 'yes' !== $this->get_option( 'use_spb', 'yes' ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
59
  $this->order_button_text = __( 'Continue to payment', 'woocommerce-gateway-paypal-express-checkout' );
60
  }
61
 
64
  // Change gateway name if session is active
65
  if ( ! is_admin() ) {
66
  if ( wc_gateway_ppec()->checkout->is_started_from_checkout_page() ) {
67
+ $this->title = $this->get_option( 'title' );
68
+ $this->description = $this->get_option( 'description' );
69
  }
70
  } else {
71
  add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
82
  * @return string
83
  */
84
  public function pass_return_args_to_ajax( $request ) {
85
+ if ( isset( $_GET['woo-paypal-return'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
86
  $request .= '&woo-paypal-return=1';
87
  }
88
 
101
  $screen = get_current_screen();
102
 
103
  // Only enqueue the setting scripts on the PayPal Checkout settings screen.
104
+ if ( $screen && 'woocommerce_page_wc-settings' === $screen->id && isset( $_GET['tab'], $_GET['section'] ) && 'checkout' === $_GET['tab'] && 'ppec_paypal' === $_GET['section'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
105
  wp_enqueue_script( 'wc-gateway-ppec-settings', wc_gateway_ppec()->plugin_url . 'assets/js/wc-gateway-ppec-settings.js', array( 'jquery' ), wc_gateway_ppec()->version, true );
106
  }
107
  }
110
  * Initialise Gateway Settings Form Fields.
111
  */
112
  public function init_form_fields() {
113
+ $this->form_fields = include dirname( dirname( __FILE__ ) ) . '/settings/settings-ppec.php';
114
  }
115
 
116
  /**
142
  $checkout_details = $checkout->get_checkout_details( $session->token );
143
 
144
  $checkout_context = array(
145
+ 'order_id' => $order_id,
146
  );
147
  if ( $checkout->needs_billing_agreement_creation( $checkout_context ) ) {
148
  $checkout->create_billing_agreement( $order, $checkout_details );
174
  // them pick out a new funding method.
175
  $error_codes = wp_list_pluck( $e->errors, 'error_code' );
176
 
177
+ if ( in_array( '10486', $error_codes ) || in_array( '10422', $error_codes ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
178
  $session->checkout_completed = false;
179
  $session->source = 'order';
180
  $session->order_id = $order_id;
208
 
209
  if ( $cert_info ) {
210
  $valid_until = $cert_info['validTo_time_t'];
211
+ // Translators: placeholders are a date in local format and its timezone.
212
+ $expires = __( 'expires on %1$s (%2$s)', 'woocommerce-gateway-paypal-express-checkout' );
213
 
214
  if ( $valid_until < time() ) {
215
  // Display in red if the cert is already expired
216
+ // Translators: placeholders are a date in local format and its timezone.
217
+ $expires = '<span style="color: red;">' . __( 'expired on %1$s (%2$s)', 'woocommerce-gateway-paypal-express-checkout' ) . '</span>';
218
  } elseif ( $valid_until < ( time() - ( 30 * DAY_IN_SECONDS ) ) ) {
219
  // Also display in red if the cert is going to expire in the next 30 days
220
  $expires = '<span style="color: red;">' . $expires . '</span>';
224
  $expiry_date->setTimezone( wp_timezone() );
225
 
226
  $expires = sprintf( $expires, date_i18n( get_option( 'date_format' ), $expiry_date->getTimestamp() + $expiry_date->getOffset() ), $expiry_date->format( 'T' ) );
227
+ // Translators: 1) is a certificate's CN, 2) is the expiration date.
228
+ $output = sprintf( __( 'Certificate belongs to API username %1$s; %2$s.', 'woocommerce-gateway-paypal-express-checkout' ), $cert_info['subject']['CN'], $expires );
229
  } else {
230
  $output = __( 'The certificate on file is not valid.', 'woocommerce-gateway-paypal-express-checkout' );
231
  }
241
  if ( array_key_exists( 'woocommerce_ppec_paypal_api_certificate', $_FILES )
242
  && array_key_exists( 'tmp_name', $_FILES['woocommerce_ppec_paypal_api_certificate'] )
243
  && array_key_exists( 'size', $_FILES['woocommerce_ppec_paypal_api_certificate'] )
244
+ && $_FILES['woocommerce_ppec_paypal_api_certificate']['size'] ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
245
 
246
+ $_POST['woocommerce_ppec_paypal_api_certificate'] = base64_encode( file_get_contents( $_FILES['woocommerce_ppec_paypal_api_certificate']['tmp_name'] ) ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents,WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
247
+ unlink( $_FILES['woocommerce_ppec_paypal_api_certificate']['tmp_name'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
248
  unset( $_FILES['woocommerce_ppec_paypal_api_certificate'] );
249
+ } elseif ( isset( $_POST['woocommerce_ppec_delete_live_api_certificate'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
250
  $_POST['woocommerce_ppec_paypal_api_certificate'] = '';
251
+ unset( $_POST['woocommerce_ppec_delete_live_api_certificate'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
252
  } else {
253
  $_POST['woocommerce_ppec_paypal_api_certificate'] = $this->get_option( 'api_certificate' );
254
  }
256
  if ( array_key_exists( 'woocommerce_ppec_paypal_sandbox_api_certificate', $_FILES )
257
  && array_key_exists( 'tmp_name', $_FILES['woocommerce_ppec_paypal_sandbox_api_certificate'] )
258
  && array_key_exists( 'size', $_FILES['woocommerce_ppec_paypal_sandbox_api_certificate'] )
259
+ && $_FILES['woocommerce_ppec_paypal_sandbox_api_certificate']['size'] ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
260
 
261
+ $_POST['woocommerce_ppec_paypal_sandbox_api_certificate'] = base64_encode( file_get_contents( $_FILES['woocommerce_ppec_paypal_sandbox_api_certificate']['tmp_name'] ) ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents,WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
262
+ unlink( $_FILES['woocommerce_ppec_paypal_sandbox_api_certificate']['tmp_name'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
263
  unset( $_FILES['woocommerce_ppec_paypal_sandbox_api_certificate'] );
264
+ } elseif ( isset( $_POST['woocommerce_ppec_delete_sandbox_api_certificate'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
265
  $_POST['woocommerce_ppec_paypal_sandbox_api_certificate'] = '';
266
+ unset( $_POST['woocommerce_ppec_delete_sandbox_api_certificate'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
267
  } else {
268
  $_POST['woocommerce_ppec_paypal_sandbox_api_certificate'] = $this->get_option( 'sandbox_api_certificate' );
269
  }
383
  public function process_refund( $order_id, $amount = null, $reason = '' ) {
384
  $order = wc_get_order( $order_id );
385
 
386
+ if ( 0 == $amount || null == $amount ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
387
  return new WP_Error( 'paypal_refund_error', __( 'Refund Error: You need to specify a refund amount.', 'woocommerce-gateway-paypal-express-checkout' ) );
388
  }
389
 
391
  // loop through each transaction to compile list of txns that are able to be refunded
392
  // process refunds against each txn in the list until full amount of refund is reached
393
  // first loop through, try to find a transaction that equals the refund amount being requested
394
+ $old_wc = version_compare( WC_VERSION, '3.0', '<' );
395
+ $txn_data = $old_wc ? get_post_meta( $order_id, '_woo_pp_txnData', true ) : $order->get_meta( '_woo_pp_txnData', true );
396
  $order_currency = $old_wc ? $order->order_currency : $order->get_currency();
397
 
398
+ if ( ! isset( $txn_data['refundable_txns'] ) ) {
399
  return new WP_Error( 'paypal_refund_error', __( 'Refund Error: Sorry! This is not a refundable transaction.', 'woocommerce-gateway-paypal-express-checkout' ) );
400
  }
401
 
402
  foreach ( $txn_data['refundable_txns'] as $key => $value ) {
403
  $refundable_amount = $value['amount'] - $value['refunded_amount'];
404
 
405
+ if ( $amount == $refundable_amount ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
406
+ $refund_type = ( 0 == $value['refunded_amount'] ) ? 'Full' : 'Partial'; // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
407
 
408
  try {
409
  $refund_txn_id = WC_Gateway_PPEC_Refund::refund_order( $order, $amount, $refund_type, $reason, $order_currency );
410
  $txn_data['refundable_txns'][ $key ]['refunded_amount'] += $amount;
411
+ // Translators: placeholder is a transaction ID.
412
  $order->add_order_note( sprintf( __( 'PayPal refund completed; transaction ID = %s', 'woocommerce-gateway-paypal-express-checkout' ), $refund_txn_id ) );
413
  if ( $old_wc ) {
414
  update_post_meta( $order_id, '_woo_pp_txnData', $txn_data );
415
  } else {
416
  $order->update_meta_data( '_woo_pp_txnData', $txn_data );
417
+ $order->save();
418
  }
419
 
420
  return true;
433
  try {
434
  $refund_txn_id = WC_Gateway_PPEC_Refund::refund_order( $order, $amount, 'Partial', $reason, $order_currency );
435
  $txn_data['refundable_txns'][ $key ]['refunded_amount'] += $amount;
436
+ // Translators: placeholder is a transaction ID.
437
  $order->add_order_note( sprintf( __( 'PayPal refund completed; transaction ID = %s', 'woocommerce-gateway-paypal-express-checkout' ), $refund_txn_id ) );
438
  if ( $old_wc ) {
439
  update_post_meta( $order_id, '_woo_pp_txnData', $txn_data );
440
  } else {
441
  $order->update_meta_data( '_woo_pp_txnData', $txn_data );
442
+ $order->save();
443
  }
444
 
445
  return true;
447
  } catch ( PayPal_API_Exception $e ) {
448
  return new WP_Error( 'paypal_refund_error', $e->getMessage() );
449
  }
 
450
  }
451
  }
452
 
453
  $total_refundable_amount = 0;
454
  foreach ( $txn_data['refundable_txns'] as $key => $value ) {
455
+ $refundable_amount = $value['amount'] - $value['refunded_amount'];
456
  $total_refundable_amount += $refundable_amount;
457
  }
458
 
459
  if ( $total_refundable_amount < $amount ) {
460
+ if ( 0 == $total_refundable_amount ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
461
  return new WP_Error( 'paypal_refund_error', __( 'Refund Error: All transactions have been fully refunded. There is no amount left to refund', 'woocommerce-gateway-paypal-express-checkout' ) );
462
  } else {
463
+ // Translators: placeholder is an amount (with currency symbol).
464
  return new WP_Error( 'paypal_refund_error', sprintf( __( 'Refund Error: The requested refund amount is too large. The refund amount must be less than or equal to %s.', 'woocommerce-gateway-paypal-express-checkout' ), html_entity_decode( get_woocommerce_currency_symbol() ) . $total_refundable_amount ) );
465
  }
466
  } else {
477
 
478
  if ( 0 < $amount_to_refund ) {
479
  $refund_type = 'Partial';
480
+ if ( 0 == $value['refunded_amount'] && $amount_to_refund == $value['amount'] ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
481
  $refund_type = 'Full';
482
  }
483
 
484
  try {
485
+ $refund_txn_id = WC_Gateway_PPEC_Refund::refund_order( $order, $amount_to_refund, $refund_type, $reason, $order_currency );
486
  $total_to_refund -= $amount_to_refund;
487
  $txn_data['refundable_txns'][ $key ]['refunded_amount'] += $amount_to_refund;
488
+ // Translators: placeholder is a transaction ID.
489
  $order->add_order_note( sprintf( __( 'PayPal refund completed; transaction ID = %s', 'woocommerce-gateway-paypal-express-checkout' ), $refund_txn_id ) );
490
  if ( $old_wc ) {
491
  update_post_meta( $order_id, '_woo_pp_txnData', $txn_data );
492
  } else {
493
  $order->update_meta_data( '_woo_pp_txnData', $txn_data );
494
+ $order->save();
495
  }
496
 
497
  return true;
557
  $maybe_hide_remove_style = '';
558
 
559
  // For backwards compatibility (customers that already have set a url)
560
+ $value_is_url = filter_var( $value, FILTER_VALIDATE_URL ) !== false;
561
 
562
  if ( empty( $value ) || $value_is_url ) {
563
  $maybe_hide_remove_style = 'display: none;';
569
  ?>
570
  <tr valign="top">
571
  <th scope="row" class="titledesc">
572
+ <label for="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?> <?php echo $this->get_tooltip_html( $data ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></label>
573
  </th>
574
 
575
  <td class="image-component-wrapper">
578
  if ( ! $value_is_url ) {
579
  echo wp_get_attachment_image( $value, 'thumbnail' );
580
  } else {
581
+ // Translators: placeholder is an image's URL.
582
+ echo sprintf( esc_html__( 'Already using URL as image: %s', 'woocommerce-gateway-paypal-express-checkout' ), esc_attr( $value ) );
583
  }
584
  ?>
585
  </div>
includes/class-wc-gateway-ppec-address.php CHANGED
@@ -16,9 +16,9 @@ class PayPal_Address {
16
  protected $_addressOwner;
17
  protected $_addressStatus;
18
 
19
- const AddressStatusNone = 'none';
20
- const AddressStatusConfirmed = 'Confirmed';
21
- const AddressStatusUnconfirmed = 'Unconfirmed';
22
 
23
  public function setName( $name ) {
24
  $this->_name = $name;
@@ -333,7 +333,7 @@ class PayPal_Address {
333
  'yemen' => 'YE',
334
  'zambia' => 'ZM',
335
  // This one is here because some carts will make the mistake of using 'uk' instead of 'gb'.
336
- 'uk' => 'GB'
337
  );
338
 
339
  // And now, the actual translation is as simple as...
@@ -357,7 +357,7 @@ class PayPal_Address {
357
 
358
  $translation_table = array();
359
 
360
- if ( 'AR' == $this->_country ) {
361
  $translation_table = array(
362
  'ciudad autónoma de buenos aires' => 'C',
363
  'buenos aires' => 'B',
@@ -384,7 +384,7 @@ class PayPal_Address {
384
  'tierra del fuego' => 'V',
385
  'tucumán' => 'T',
386
  );
387
- } elseif ( 'CA' == $this->_country ) {
388
  $translation_table = array(
389
  'alberta' => 'AB',
390
  'british columbia' => 'BC',
@@ -400,99 +400,99 @@ class PayPal_Address {
400
  'saskatchewan' => 'SK',
401
  'yukon' => 'YT',
402
  // This derivation doesn't show up on the list, but seems obvious
403
- 'yukon territory' => 'YT'
404
  );
405
- } elseif ( 'CN' == $this->_country ) {
406
  $translation_table = array(
407
- 'cn-yn' => 'CN1',
408
- 'cn-bj' => 'CN2',
409
- 'cn-tj' => 'CN3',
410
- 'cn-he' => 'CN4',
411
- 'cn-sx' => 'CN5',
412
- 'cn-nm' => 'CN6',
413
- 'cn-ln' => 'CN7',
414
- 'cn-jl' => 'CN8',
415
- 'cn-hl' => 'CN9',
416
- 'cn-sh' => 'CN10',
417
- 'cn-js' => 'CN11',
418
- 'cn-zj' => 'CN12',
419
- 'cn-ah' => 'CN13',
420
- 'cn-fj' => 'CN14',
421
- 'cn-jx' => 'CN15',
422
- 'cn-sd' => 'CN16',
423
- 'cn-ha' => 'CN17',
424
- 'cn-hb' => 'CN18',
425
- 'cn-hn' => 'CN19',
426
- 'cn-gd' => 'CN20',
427
- 'cn-gx' => 'CN21',
428
- 'cn-hi' => 'CN22',
429
- 'cn-cq' => 'CN23',
430
- 'cn-sc' => 'CN24',
431
- 'cn-gz' => 'CN25',
432
- 'cn-sn' => 'CN26',
433
- 'cn-gs' => 'CN27',
434
- 'cn-qh' => 'CN28',
435
- 'cn-nx' => 'CN29',
436
- 'cn-mo' => 'CN30',
437
- 'cn-xz' => 'CN31',
438
- 'cn-xj' => 'CN32',
439
  );
440
- } elseif ( 'ES' == $this->_country ) {
441
  $translation_table = array(
442
- 'a coruÑa' =>'C',
443
- 'araba/Álava' =>'VI',
444
- 'albacete' =>'AB',
445
- 'alicante' =>'A' ,
446
- 'almerÍa' =>'AL',
447
- 'asturias' =>'O' ,
448
- 'Ávila' =>'AV',
449
- 'badajoz' =>'BA',
450
- 'baleares' =>'PM',
451
- 'barcelona' =>'B' ,
452
- 'burgos' =>'BU',
453
- 'cÁceres' =>'CC',
454
- 'cÁdiz' =>'CA',
455
- 'cantabria' =>'S' ,
456
- 'castellÓn' =>'CS',
457
- 'ceuta' =>'CE',
458
- 'ciudad real' =>'CR',
459
- 'cÓrdoba' =>'CO',
460
- 'cuenca' =>'CU',
461
- 'girona' =>'GI',
462
- 'granada' =>'GR',
463
- 'guadalajara' =>'GU',
464
- 'gipuzkoa' =>'SS',
465
- 'huelva' =>'H' ,
466
- 'huesca' =>'HU',
467
- 'jaÉn' =>'J',
468
- 'la rioja' =>'LO',
469
- 'las palmas' =>'GC',
470
- 'leÓn' =>'LE',
471
- 'lleida' =>'L' ,
472
- 'lugo' =>'LU',
473
- 'madrid' =>'M' ,
474
- 'mÁlaga' =>'MA',
475
- 'melilla' =>'ML',
476
- 'murcia' =>'MU',
477
- 'navarra' =>'NA',
478
- 'ourense' =>'OR',
479
- 'palencia' =>'P' ,
480
- 'pontevedra' =>'PO',
481
- 'salamanca' =>'SA',
482
- 'santa cruz de tenerife' =>'TF',
483
- 'segovia' =>'SG',
484
- 'sevilla' =>'SE',
485
- 'soria' =>'SO',
486
- 'tarragona' =>'T' ,
487
- 'teruel' =>'TE',
488
- 'toledo' =>'TO',
489
- 'valencia' =>'V' ,
490
- 'valladolid' =>'VA',
491
- 'bizkaia' =>'BI',
492
- 'zamora' =>'ZA',
493
- 'zaragoza' =>'Z' ,
494
  );
495
- } elseif ( 'IE' == $this->_country ) {
496
  $translation_table = array(
497
  'co clare' => 'CE',
498
  'co cork' => 'CK',
@@ -545,7 +545,7 @@ class PayPal_Address {
545
  'co wicklow' => 'WW',
546
  'co wexford' => 'WX',
547
  );
548
- } elseif ( 'ID' == $this->_country ) {
549
  $translation_table = array(
550
  'id-ac' => 'AC',
551
  'id-ba' => 'BA',
@@ -582,11 +582,10 @@ class PayPal_Address {
582
  'id-su' => 'SU',
583
  'id-yo' => 'YO',
584
  );
585
- } elseif ( 'IN' == $this->_country ) {
586
  $translation_table = array(
587
  'andaman and nicobar islands' => 'AN',
588
  'andhra pradesh' => 'AP',
589
- //'apo' => '',
590
  'arunachal pradesh' => 'AR',
591
  'assam' => 'AS',
592
  'bihar' => 'BR',
@@ -622,7 +621,7 @@ class PayPal_Address {
622
  'uttarakhand' => 'UK',
623
  'west bengal' => 'WB',
624
  );
625
- } elseif ( 'IT' == $this->_country ) {
626
  $translation_table = array(
627
  'agrigento' => 'AG',
628
  'alessandria' => 'AL',
@@ -732,9 +731,9 @@ class PayPal_Address {
732
  'verona' => 'VR',
733
  'vibo valentia' => 'VV',
734
  'vicenza' => 'VI',
735
- 'viterbo' => 'VT'
736
  );
737
- } elseif ( 'JP' == $this->_country ) {
738
  $translation_table = array(
739
  'hokkaido' => 'JP01',
740
  'aomori-ken' => 'JP02',
@@ -784,7 +783,7 @@ class PayPal_Address {
784
  'kagoshima-ken' => 'JP46',
785
  'okinawa-ken' => 'JP47',
786
  );
787
- } elseif ( 'MX' == $this->_country ) {
788
  $translation_table = array(
789
  'ags' => 'AG',
790
  'bc' => 'BC',
@@ -820,7 +819,7 @@ class PayPal_Address {
820
  'yuc' => 'YU',
821
  'zac' => 'ZA',
822
  );
823
- } elseif ( 'NL' == $this->_country ) {
824
  $translation_table = array(
825
  'drenthe' => 'DR',
826
  'flevoland' => 'FL',
@@ -833,9 +832,9 @@ class PayPal_Address {
833
  'overijssel' => 'OV',
834
  'utrecht' => 'UT',
835
  'zeeland' => 'ZE',
836
- 'zuid-holland' => 'ZH'
837
  );
838
- } elseif ( 'TH' == $this->_country ) {
839
  $translation_table = array(
840
  'amnat charoen' => 'TH-37',
841
  'ang thong' => 'TH-15',
@@ -914,9 +913,8 @@ class PayPal_Address {
914
  'uttaradit' => 'TH-53',
915
  'yala' => 'TH-95',
916
  'yasothon' => 'TH-35',
917
- //'phatthaya' => '',
918
  );
919
- } elseif ( 'US' == $this->_country ) {
920
  $translation_table = array(
921
  'alabama' => 'AL',
922
  'alaska' => 'AK',
@@ -993,7 +991,7 @@ class PayPal_Address {
993
  'us virgin islands' => 'VI',
994
  'u.s. virgin islands' => 'VI',
995
  'u s virgin islands' => 'VI',
996
- 'u. s. virgin islands' => 'VI'
997
  );
998
  }
999
 
@@ -1009,14 +1007,14 @@ class PayPal_Address {
1009
 
1010
  public function getAddressParams( $prefix = '' ) {
1011
  $params = array(
1012
- $prefix . 'NAME' => $this->_name,
1013
- $prefix . 'STREET' => $this->_street1,
1014
- $prefix . 'STREET2' => $this->_street2,
1015
- $prefix . 'CITY' => $this->_city,
1016
- $prefix . 'STATE' => $this->_state,
1017
- $prefix . 'ZIP' => $this->_zip,
1018
  $prefix . 'COUNTRYCODE' => $this->_country,
1019
- $prefix . 'PHONENUM' => $this->_phoneNumber,
1020
  );
1021
 
1022
  return $params;
@@ -1032,7 +1030,7 @@ class PayPal_Address {
1032
  'ZIP' => '_zip',
1033
  'PHONENUM' => '_phoneNumber',
1034
  'ADDRESSSTATUS' => '_addressStatus',
1035
- 'ADDRESSOWNER' => '_addressOwner'
1036
  );
1037
 
1038
  if ( $isBillingAddress ) {
@@ -1050,7 +1048,7 @@ class PayPal_Address {
1050
  // ADDRESSSTATUS is returned whether or not a billing address is requested, so we don't want
1051
  // the presence of this variable alone be enough to trigger recognition of a complete
1052
  // billing address.
1053
- if ( 'ADDRESSSTATUS' != $index || ! $isBillingAddress ) {
1054
  $found_any = true;
1055
  }
1056
  }
16
  protected $_addressOwner;
17
  protected $_addressStatus;
18
 
19
+ const AddressStatusNone = 'none';
20
+ const AddressStatusConfirmed = 'Confirmed';
21
+ const AddressStatusUnconfirmed = 'Unconfirmed';
22
 
23
  public function setName( $name ) {
24
  $this->_name = $name;
333
  'yemen' => 'YE',
334
  'zambia' => 'ZM',
335
  // This one is here because some carts will make the mistake of using 'uk' instead of 'gb'.
336
+ 'uk' => 'GB',
337
  );
338
 
339
  // And now, the actual translation is as simple as...
357
 
358
  $translation_table = array();
359
 
360
+ if ( 'AR' === $this->_country ) {
361
  $translation_table = array(
362
  'ciudad autónoma de buenos aires' => 'C',
363
  'buenos aires' => 'B',
384
  'tierra del fuego' => 'V',
385
  'tucumán' => 'T',
386
  );
387
+ } elseif ( 'CA' === $this->_country ) {
388
  $translation_table = array(
389
  'alberta' => 'AB',
390
  'british columbia' => 'BC',
400
  'saskatchewan' => 'SK',
401
  'yukon' => 'YT',
402
  // This derivation doesn't show up on the list, but seems obvious
403
+ 'yukon territory' => 'YT',
404
  );
405
+ } elseif ( 'CN' === $this->_country ) {
406
  $translation_table = array(
407
+ 'cn-yn' => 'CN1',
408
+ 'cn-bj' => 'CN2',
409
+ 'cn-tj' => 'CN3',
410
+ 'cn-he' => 'CN4',
411
+ 'cn-sx' => 'CN5',
412
+ 'cn-nm' => 'CN6',
413
+ 'cn-ln' => 'CN7',
414
+ 'cn-jl' => 'CN8',
415
+ 'cn-hl' => 'CN9',
416
+ 'cn-sh' => 'CN10',
417
+ 'cn-js' => 'CN11',
418
+ 'cn-zj' => 'CN12',
419
+ 'cn-ah' => 'CN13',
420
+ 'cn-fj' => 'CN14',
421
+ 'cn-jx' => 'CN15',
422
+ 'cn-sd' => 'CN16',
423
+ 'cn-ha' => 'CN17',
424
+ 'cn-hb' => 'CN18',
425
+ 'cn-hn' => 'CN19',
426
+ 'cn-gd' => 'CN20',
427
+ 'cn-gx' => 'CN21',
428
+ 'cn-hi' => 'CN22',
429
+ 'cn-cq' => 'CN23',
430
+ 'cn-sc' => 'CN24',
431
+ 'cn-gz' => 'CN25',
432
+ 'cn-sn' => 'CN26',
433
+ 'cn-gs' => 'CN27',
434
+ 'cn-qh' => 'CN28',
435
+ 'cn-nx' => 'CN29',
436
+ 'cn-mo' => 'CN30',
437
+ 'cn-xz' => 'CN31',
438
+ 'cn-xj' => 'CN32',
439
  );
440
+ } elseif ( 'ES' === $this->_country ) {
441
  $translation_table = array(
442
+ 'a coruÑa' => 'C',
443
+ 'araba/Álava' => 'VI',
444
+ 'albacete' => 'AB',
445
+ 'alicante' => 'A',
446
+ 'almerÍa' => 'AL',
447
+ 'asturias' => 'O',
448
+ 'Ávila' => 'AV',
449
+ 'badajoz' => 'BA',
450
+ 'baleares' => 'PM',
451
+ 'barcelona' => 'B',
452
+ 'burgos' => 'BU',
453
+ 'cÁceres' => 'CC',
454
+ 'cÁdiz' => 'CA',
455
+ 'cantabria' => 'S',
456
+ 'castellÓn' => 'CS',
457
+ 'ceuta' => 'CE',
458
+ 'ciudad real' => 'CR',
459
+ 'cÓrdoba' => 'CO',
460
+ 'cuenca' => 'CU',
461
+ 'girona' => 'GI',
462
+ 'granada' => 'GR',
463
+ 'guadalajara' => 'GU',
464
+ 'gipuzkoa' => 'SS',
465
+ 'huelva' => 'H',
466
+ 'huesca' => 'HU',
467
+ 'jaÉn' => 'J',
468
+ 'la rioja' => 'LO',
469
+ 'las palmas' => 'GC',
470
+ 'leÓn' => 'LE',
471
+ 'lleida' => 'L',
472
+ 'lugo' => 'LU',
473
+ 'madrid' => 'M',
474
+ 'mÁlaga' => 'MA',
475
+ 'melilla' => 'ML',
476
+ 'murcia' => 'MU',
477
+ 'navarra' => 'NA',
478
+ 'ourense' => 'OR',
479
+ 'palencia' => 'P',
480
+ 'pontevedra' => 'PO',
481
+ 'salamanca' => 'SA',
482
+ 'santa cruz de tenerife' => 'TF',
483
+ 'segovia' => 'SG',
484
+ 'sevilla' => 'SE',
485
+ 'soria' => 'SO',
486
+ 'tarragona' => 'T',
487
+ 'teruel' => 'TE',
488
+ 'toledo' => 'TO',
489
+ 'valencia' => 'V',
490
+ 'valladolid' => 'VA',
491
+ 'bizkaia' => 'BI',
492
+ 'zamora' => 'ZA',
493
+ 'zaragoza' => 'Z',
494
  );
495
+ } elseif ( 'IE' === $this->_country ) {
496
  $translation_table = array(
497
  'co clare' => 'CE',
498
  'co cork' => 'CK',
545
  'co wicklow' => 'WW',
546
  'co wexford' => 'WX',
547
  );
548
+ } elseif ( 'ID' === $this->_country ) {
549
  $translation_table = array(
550
  'id-ac' => 'AC',
551
  'id-ba' => 'BA',
582
  'id-su' => 'SU',
583
  'id-yo' => 'YO',
584
  );
585
+ } elseif ( 'IN' === $this->_country ) {
586
  $translation_table = array(
587
  'andaman and nicobar islands' => 'AN',
588
  'andhra pradesh' => 'AP',
 
589
  'arunachal pradesh' => 'AR',
590
  'assam' => 'AS',
591
  'bihar' => 'BR',
621
  'uttarakhand' => 'UK',
622
  'west bengal' => 'WB',
623
  );
624
+ } elseif ( 'IT' === $this->_country ) {
625
  $translation_table = array(
626
  'agrigento' => 'AG',
627
  'alessandria' => 'AL',
731
  'verona' => 'VR',
732
  'vibo valentia' => 'VV',
733
  'vicenza' => 'VI',
734
+ 'viterbo' => 'VT',
735
  );
736
+ } elseif ( 'JP' === $this->_country ) {
737
  $translation_table = array(
738
  'hokkaido' => 'JP01',
739
  'aomori-ken' => 'JP02',
783
  'kagoshima-ken' => 'JP46',
784
  'okinawa-ken' => 'JP47',
785
  );
786
+ } elseif ( 'MX' === $this->_country ) {
787
  $translation_table = array(
788
  'ags' => 'AG',
789
  'bc' => 'BC',
819
  'yuc' => 'YU',
820
  'zac' => 'ZA',
821
  );
822
+ } elseif ( 'NL' === $this->_country ) {
823
  $translation_table = array(
824
  'drenthe' => 'DR',
825
  'flevoland' => 'FL',
832
  'overijssel' => 'OV',
833
  'utrecht' => 'UT',
834
  'zeeland' => 'ZE',
835
+ 'zuid-holland' => 'ZH',
836
  );
837
+ } elseif ( 'TH' === $this->_country ) {
838
  $translation_table = array(
839
  'amnat charoen' => 'TH-37',
840
  'ang thong' => 'TH-15',
913
  'uttaradit' => 'TH-53',
914
  'yala' => 'TH-95',
915
  'yasothon' => 'TH-35',
 
916
  );
917
+ } elseif ( 'US' === $this->_country ) {
918
  $translation_table = array(
919
  'alabama' => 'AL',
920
  'alaska' => 'AK',
991
  'us virgin islands' => 'VI',
992
  'u.s. virgin islands' => 'VI',
993
  'u s virgin islands' => 'VI',
994
+ 'u. s. virgin islands' => 'VI',
995
  );
996
  }
997
 
1007
 
1008
  public function getAddressParams( $prefix = '' ) {
1009
  $params = array(
1010
+ $prefix . 'NAME' => $this->_name,
1011
+ $prefix . 'STREET' => $this->_street1,
1012
+ $prefix . 'STREET2' => $this->_street2,
1013
+ $prefix . 'CITY' => $this->_city,
1014
+ $prefix . 'STATE' => $this->_state,
1015
+ $prefix . 'ZIP' => $this->_zip,
1016
  $prefix . 'COUNTRYCODE' => $this->_country,
1017
+ $prefix . 'PHONENUM' => $this->_phoneNumber,
1018
  );
1019
 
1020
  return $params;
1030
  'ZIP' => '_zip',
1031
  'PHONENUM' => '_phoneNumber',
1032
  'ADDRESSSTATUS' => '_addressStatus',
1033
+ 'ADDRESSOWNER' => '_addressOwner',
1034
  );
1035
 
1036
  if ( $isBillingAddress ) {
1048
  // ADDRESSSTATUS is returned whether or not a billing address is requested, so we don't want
1049
  // the presence of this variable alone be enough to trigger recognition of a complete
1050
  // billing address.
1051
+ if ( 'ADDRESSSTATUS' !== $index || ! $isBillingAddress ) {
1052
  $found_any = true;
1053
  }
1054
  }
includes/class-wc-gateway-ppec-admin-handler.php CHANGED
@@ -35,11 +35,11 @@ class WC_Gateway_PPEC_Admin_Handler {
35
  }
36
 
37
  public function add_capture_charge_order_action( $actions ) {
38
- if ( ! isset( $_REQUEST['post'] ) ) {
39
  return $actions;
40
  }
41
 
42
- $order = wc_get_order( $_REQUEST['post'] );
43
 
44
  if ( empty( $order ) ) {
45
  return $actions;
@@ -83,7 +83,7 @@ class WC_Gateway_PPEC_Admin_Handler {
83
  ?>
84
  <div class="updated fade">
85
  <p>
86
- <strong><?php _e( 'NOTE: PayPal does not accept decimal places for the currency in which you are transacting. The "Number of Decimals" option in WooCommerce has automatically been set to 0 for you.', 'woocommerce-gateway-paypal-express-checkout' ); ?></strong>
87
  </p>
88
  </div>
89
  <?php
@@ -109,11 +109,11 @@ class WC_Gateway_PPEC_Admin_Handler {
109
  'wc_gateway_ppec_with_paypal_credit',
110
  );
111
 
112
- $current_section = isset( $_GET['section'] ) ? $_GET['section'] : '';
113
 
114
  // If the current section is a paypal section, remove the card section,
115
  // otherwise, remove the paypal section
116
- $sections_to_remove = in_array( $current_section, $paypal_sections ) ? $card_sections : $paypal_sections;
117
 
118
  // And, let's also remove simplify commerce from the sections if it is not enabled and it is not the
119
  // current section. (Note: The option will be empty if it has never been enabled)
@@ -186,6 +186,7 @@ class WC_Gateway_PPEC_Admin_Handler {
186
  update_post_meta( $order_id, '_transaction_id', $result['TRANSACTIONID'] );
187
  }
188
 
 
189
  $order->add_order_note( sprintf( __( 'PayPal Checkout charge complete (Charge ID: %s)', 'woocommerce-gateway-paypal-express-checkout' ), $transaction_id ) );
190
  }
191
  }
@@ -213,13 +214,13 @@ class WC_Gateway_PPEC_Admin_Handler {
213
  * @param int $order_id
214
  */
215
  public function cancel_authorization( $order_id ) {
216
- $order = wc_get_order( $order_id );
217
- $old_wc = version_compare( WC_VERSION, '3.0', '<' );
218
  $payment_method = $old_wc ? $order->payment_method : $order->get_payment_method();
219
 
220
  if ( 'ppec_paypal' === $payment_method ) {
221
 
222
- $trans_id = get_post_meta( $order_id, '_transaction_id', true );
223
  $trans_details = wc_gateway_ppec()->client->get_transaction_details( array( 'TRANSACTIONID' => $trans_id ) );
224
 
225
  if ( $trans_id && $this->is_authorized_only( $trans_details ) ) {
@@ -230,6 +231,7 @@ class WC_Gateway_PPEC_Admin_Handler {
230
  if ( is_wp_error( $result ) ) {
231
  $order->add_order_note( __( 'Unable to void charge!', 'woocommerce-gateway-paypal-express-checkout' ) . ' ' . $result->get_error_message() );
232
  } else {
 
233
  $order->add_order_note( sprintf( __( 'PayPal Checkout charge voided (Charge ID: %s)', 'woocommerce-gateway-paypal-express-checkout' ), $trans_id ) );
234
  }
235
  }
@@ -260,11 +262,11 @@ class WC_Gateway_PPEC_Admin_Handler {
260
  return;
261
  }
262
 
263
- if ( empty( $_GET['tab'] ) || empty( $_GET['section'] ) ) {
264
  return;
265
  }
266
 
267
- if ( 'checkout' === $_GET['tab'] && 'wc_gateway_paypal' === $_GET['section'] ) {
268
  $redirect = add_query_arg( array( 'section' => 'wc_gateway_ppec_with_paypal' ) );
269
  wp_safe_redirect( $redirect );
270
  }
@@ -286,19 +288,19 @@ class WC_Gateway_PPEC_Admin_Handler {
286
  return;
287
  }
288
 
289
- if ( empty( $_GET['reset_nonce'] ) || ! wp_verify_nonce( $_GET['reset_nonce'], 'reset_ppec_api_credentials' ) ) {
290
  return;
291
  }
292
 
293
  $settings = wc_gateway_ppec()->settings;
294
  $env = $settings->_environment;
295
  if ( ! empty( $_GET['environment'] ) ) {
296
- $env = $_GET['environment'];
297
  }
298
  $prefix = 'sandbox' === $env ? 'sandbox_' : '';
299
 
300
  foreach ( array( 'api_username', 'api_password', 'api_signature', 'api_certificate' ) as $key ) {
301
- $key = $prefix . $key;
302
  $settings->{$key} = '';
303
  }
304
 
@@ -342,7 +344,7 @@ class WC_Gateway_PPEC_Admin_Handler {
342
  </td>
343
  <td width="1%"></td>
344
  <td class="total">
345
- -&nbsp;<?php echo wc_price( $paypal_fee, array( 'currency' => $order_currency ) ); ?>
346
  </td>
347
  </tr>
348
  <tr>
@@ -352,7 +354,7 @@ class WC_Gateway_PPEC_Admin_Handler {
352
  </td>
353
  <td width="1%"></td>
354
  <td class="total">
355
- <?php echo wc_price( $net, array( 'currency' => $order_currency ) ); ?>
356
  </td>
357
  </tr>
358
 
@@ -373,7 +375,7 @@ class WC_Gateway_PPEC_Admin_Handler {
373
 
374
  // Check if the notice needs to be dismissed.
375
  $wc_updated = version_compare( WC_VERSION, '3.0', '>=' );
376
- $dismissed = isset( $_GET['wc_ppec_hide_3_0_notice'], $_GET['_wc_ppec_notice_nonce'] ) && wp_verify_nonce( $_GET['_wc_ppec_notice_nonce'], 'wc_ppec_hide_wc_notice_nonce' );
377
 
378
  if ( $wc_updated || $dismissed ) {
379
  delete_option( 'wc_ppec_display_wc_3_0_warning' );
@@ -383,12 +385,22 @@ class WC_Gateway_PPEC_Admin_Handler {
383
  <div class="error">
384
  <a href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wc_ppec_hide_3_0_notice', 'true' ), 'wc_ppec_hide_wc_notice_nonce', '_wc_ppec_notice_nonce' ) ); ?>" class="woocommerce-message-close notice-dismiss" style="position:relative;float:right;padding:9px 0px 9px 9px 9px;text-decoration:none;"></a>
385
  <p>
386
- <?php printf( __(
387
- '%1$sWarning!%2$s PayPal Checkout will drop support for WooCommerce %3$s in a soon to be released update. To continue using PayPal Checkout please %4$supdate to %1$sWooCommerce 3.0%2$s or greater%5$s.', 'woocommerce-gateway-paypal-express-checkout' ),
388
- '<strong>', '</strong>',
 
 
 
 
 
 
 
389
  WC_VERSION,
390
- '<a href="' . admin_url( 'plugins.php' ) . '">', '</a>'
391
- ); ?>
 
 
 
392
  </p>
393
  </div>
394
  <?php
35
  }
36
 
37
  public function add_capture_charge_order_action( $actions ) {
38
+ if ( ! isset( $_REQUEST['post'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
39
  return $actions;
40
  }
41
 
42
+ $order = wc_get_order( $_REQUEST['post'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
43
 
44
  if ( empty( $order ) ) {
45
  return $actions;
83
  ?>
84
  <div class="updated fade">
85
  <p>
86
+ <strong><?php esc_html_e( 'NOTE: PayPal does not accept decimal places for the currency in which you are transacting. The "Number of Decimals" option in WooCommerce has automatically been set to 0 for you.', 'woocommerce-gateway-paypal-express-checkout' ); ?></strong>
87
  </p>
88
  </div>
89
  <?php
109
  'wc_gateway_ppec_with_paypal_credit',
110
  );
111
 
112
+ $current_section = isset( $_GET['section'] ) ? $_GET['section'] : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
113
 
114
  // If the current section is a paypal section, remove the card section,
115
  // otherwise, remove the paypal section
116
+ $sections_to_remove = in_array( $current_section, $paypal_sections, true ) ? $card_sections : $paypal_sections;
117
 
118
  // And, let's also remove simplify commerce from the sections if it is not enabled and it is not the
119
  // current section. (Note: The option will be empty if it has never been enabled)
186
  update_post_meta( $order_id, '_transaction_id', $result['TRANSACTIONID'] );
187
  }
188
 
189
+ // Translators: %s is a transaction ID.
190
  $order->add_order_note( sprintf( __( 'PayPal Checkout charge complete (Charge ID: %s)', 'woocommerce-gateway-paypal-express-checkout' ), $transaction_id ) );
191
  }
192
  }
214
  * @param int $order_id
215
  */
216
  public function cancel_authorization( $order_id ) {
217
+ $order = wc_get_order( $order_id );
218
+ $old_wc = version_compare( WC_VERSION, '3.0', '<' );
219
  $payment_method = $old_wc ? $order->payment_method : $order->get_payment_method();
220
 
221
  if ( 'ppec_paypal' === $payment_method ) {
222
 
223
+ $trans_id = get_post_meta( $order_id, '_transaction_id', true );
224
  $trans_details = wc_gateway_ppec()->client->get_transaction_details( array( 'TRANSACTIONID' => $trans_id ) );
225
 
226
  if ( $trans_id && $this->is_authorized_only( $trans_details ) ) {
231
  if ( is_wp_error( $result ) ) {
232
  $order->add_order_note( __( 'Unable to void charge!', 'woocommerce-gateway-paypal-express-checkout' ) . ' ' . $result->get_error_message() );
233
  } else {
234
+ // Translators: %s is a transaction ID.
235
  $order->add_order_note( sprintf( __( 'PayPal Checkout charge voided (Charge ID: %s)', 'woocommerce-gateway-paypal-express-checkout' ), $trans_id ) );
236
  }
237
  }
262
  return;
263
  }
264
 
265
+ if ( empty( $_GET['tab'] ) || empty( $_GET['section'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
266
  return;
267
  }
268
 
269
+ if ( 'checkout' === $_GET['tab'] && 'wc_gateway_paypal' === $_GET['section'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
270
  $redirect = add_query_arg( array( 'section' => 'wc_gateway_ppec_with_paypal' ) );
271
  wp_safe_redirect( $redirect );
272
  }
288
  return;
289
  }
290
 
291
+ if ( empty( $_GET['reset_nonce'] ) || ! wp_verify_nonce( $_GET['reset_nonce'], 'reset_ppec_api_credentials' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
292
  return;
293
  }
294
 
295
  $settings = wc_gateway_ppec()->settings;
296
  $env = $settings->_environment;
297
  if ( ! empty( $_GET['environment'] ) ) {
298
+ $env = $_GET['environment']; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
299
  }
300
  $prefix = 'sandbox' === $env ? 'sandbox_' : '';
301
 
302
  foreach ( array( 'api_username', 'api_password', 'api_signature', 'api_certificate' ) as $key ) {
303
+ $key = $prefix . $key;
304
  $settings->{$key} = '';
305
  }
306
 
344
  </td>
345
  <td width="1%"></td>
346
  <td class="total">
347
+ -&nbsp;<?php echo wc_price( $paypal_fee, array( 'currency' => $order_currency ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
348
  </td>
349
  </tr>
350
  <tr>
354
  </td>
355
  <td width="1%"></td>
356
  <td class="total">
357
+ <?php echo wc_price( $net, array( 'currency' => $order_currency ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
358
  </td>
359
  </tr>
360
 
375
 
376
  // Check if the notice needs to be dismissed.
377
  $wc_updated = version_compare( WC_VERSION, '3.0', '>=' );
378
+ $dismissed = isset( $_GET['wc_ppec_hide_3_0_notice'], $_GET['_wc_ppec_notice_nonce'] ) && wp_verify_nonce( $_GET['_wc_ppec_notice_nonce'], 'wc_ppec_hide_wc_notice_nonce' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
379
 
380
  if ( $wc_updated || $dismissed ) {
381
  delete_option( 'wc_ppec_display_wc_3_0_warning' );
385
  <div class="error">
386
  <a href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wc_ppec_hide_3_0_notice', 'true' ), 'wc_ppec_hide_wc_notice_nonce', '_wc_ppec_notice_nonce' ) ); ?>" class="woocommerce-message-close notice-dismiss" style="position:relative;float:right;padding:9px 0px 9px 9px 9px;text-decoration:none;"></a>
387
  <p>
388
+ <?php
389
+ // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
390
+ printf(
391
+ /* Translators: %1$ <strong> tag, %2$ </strong> closing tag, %3$ WooCommerce version, %4$ <a> tag linking to Plugins screen, %5$ </a> closing tag. */
392
+ __(
393
+ '%1$sWarning!%2$s PayPal Checkout will drop support for WooCommerce %3$s in a soon to be released update. To continue using PayPal Checkout please %4$supdate to %1$sWooCommerce 3.0%2$s or greater%5$s.',
394
+ 'woocommerce-gateway-paypal-express-checkout'
395
+ ),
396
+ '<strong>',
397
+ '</strong>',
398
  WC_VERSION,
399
+ '<a href="' . admin_url( 'plugins.php' ) . '">',
400
+ '</a>'
401
+ );
402
+ // phpcs:enable
403
+ ?>
404
  </p>
405
  </div>
406
  <?php
includes/class-wc-gateway-ppec-api-error.php CHANGED
@@ -19,6 +19,7 @@ class PayPal_API_Error {
19
 
20
  public function mapToBuyerFriendlyError() {
21
  switch ( $this->error_code ) {
 
22
  case '-1': return __( 'Unable to communicate with PayPal. Please try your payment again.', 'woocommerce-gateway-paypal-express-checkout' );
23
  case '10407': return __( 'PayPal rejected your email address because it is not valid. Please double-check your email address and try again.', 'woocommerce-gateway-paypal-express-checkout' );
24
  case '10409':
@@ -52,7 +53,10 @@ class PayPal_API_Error {
52
  case '17203':
53
  case '17204':
54
  case '17200': return __( 'Your funding instrument is invalid. Please check out again and select a new funding source.', 'woocommerce-gateway-paypal-express-checkout' );
55
- default: return sprintf( __( 'An error (%s) occurred while processing your PayPal payment. Please contact the store owner for assistance.', 'woocommerce-gateway-paypal-express-checkout' ), $this->error_code );
 
 
 
56
  }
57
  }
58
  }
19
 
20
  public function mapToBuyerFriendlyError() {
21
  switch ( $this->error_code ) {
22
+ // phpcs:disable PSR2.ControlStructures.SwitchDeclaration.BodyOnNextLineCASE
23
  case '-1': return __( 'Unable to communicate with PayPal. Please try your payment again.', 'woocommerce-gateway-paypal-express-checkout' );
24
  case '10407': return __( 'PayPal rejected your email address because it is not valid. Please double-check your email address and try again.', 'woocommerce-gateway-paypal-express-checkout' );
25
  case '10409':
53
  case '17203':
54
  case '17204':
55
  case '17200': return __( 'Your funding instrument is invalid. Please check out again and select a new funding source.', 'woocommerce-gateway-paypal-express-checkout' );
56
+ default:
57
+ /* Translators: placeholder is an error code. */
58
+ return sprintf( __( 'An error (%s) occurred while processing your PayPal payment. Please contact the store owner for assistance.', 'woocommerce-gateway-paypal-express-checkout' ), $this->error_code );
59
+ // phpcs:enable
60
  }
61
  }
62
  }
includes/class-wc-gateway-ppec-cart-handler.php CHANGED
@@ -51,7 +51,7 @@ class WC_Gateway_PPEC_Cart_Handler {
51
  */
52
  public function before_cart_totals() {
53
  // If there then call start_checkout() else do nothing so page loads as normal.
54
- if ( ! empty( $_GET['startcheckout'] ) && 'true' === $_GET['startcheckout'] ) {
55
  // Trying to prevent auto running checkout when back button is pressed from PayPal page.
56
  $_GET['startcheckout'] = 'false';
57
  woo_pp_start_checkout();
@@ -67,8 +67,8 @@ class WC_Gateway_PPEC_Cart_Handler {
67
  public function wc_ajax_generate_cart() {
68
  global $post;
69
 
70
- if ( ! wp_verify_nonce( $_POST['nonce'], '_wc_ppec_generate_cart_nonce' ) ) {
71
- wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce-gateway-paypal-express-checkout' ) );
72
  }
73
 
74
  if ( ! defined( 'WOOCOMMERCE_CART' ) ) {
@@ -88,7 +88,7 @@ class WC_Gateway_PPEC_Cart_Handler {
88
  * simple or variable product.
89
  */
90
  if ( $product ) {
91
- $qty = ! isset( $_POST['quantity'] ) ? 1 : absint( $_POST['quantity'] );
92
  wc_empty_cart();
93
 
94
  if ( $product->is_type( 'variable' ) ) {
@@ -116,7 +116,7 @@ class WC_Gateway_PPEC_Cart_Handler {
116
  if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
117
  $variation_id = $product->get_matching_variation( $attributes );
118
  } else {
119
- $data_store = WC_Data_Store::load( 'product' );
120
  $variation_id = $data_store->find_matching_product_variation( $product, $attributes );
121
  }
122
 
@@ -137,8 +137,8 @@ class WC_Gateway_PPEC_Cart_Handler {
137
  * @since 1.4.0
138
  */
139
  public function wc_ajax_update_shipping_costs() {
140
- if ( ! wp_verify_nonce( $_POST['nonce'], '_wc_ppec_update_shipping_costs_nonce' ) ) {
141
- wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce-gateway-paypal-express-checkout' ) );
142
  }
143
 
144
  if ( ! defined( 'WOOCOMMERCE_CART' ) ) {
@@ -158,8 +158,8 @@ class WC_Gateway_PPEC_Cart_Handler {
158
  * @since 1.6.0
159
  */
160
  public function wc_ajax_start_checkout() {
161
- if ( ! wp_verify_nonce( $_POST['nonce'], '_wc_ppec_start_checkout_nonce' ) ) {
162
- wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce-gateway-paypal-express-checkout' ) );
163
  }
164
 
165
  if ( isset( $_POST['from_checkout'] ) && 'yes' === $_POST['from_checkout'] ) {
@@ -186,7 +186,7 @@ class WC_Gateway_PPEC_Cart_Handler {
186
  }
187
 
188
  if ( empty( $error_messages ) ) {
189
- $this->set_customer_data( $_POST );
190
  $this->start_checkout( false );
191
  } else {
192
  wp_send_json_error( array( 'messages' => $error_messages ) );
@@ -205,7 +205,7 @@ class WC_Gateway_PPEC_Cart_Handler {
205
  try {
206
  wc_gateway_ppec()->checkout->start_checkout_from_cart( $skip_checkout );
207
  wp_send_json_success( array( 'token' => WC()->session->paypal->token ) );
208
- } catch( PayPal_API_Exception $e ) {
209
  wp_send_json_error( array( 'messages' => array( $e->getMessage() ) ) );
210
  }
211
  }
@@ -218,26 +218,30 @@ class WC_Gateway_PPEC_Cart_Handler {
218
  protected function set_customer_data( $data ) {
219
  $customer = WC()->customer;
220
 
221
- $billing_first_name = empty( $data[ 'billing_first_name' ] ) ? '' : wc_clean( $data[ 'billing_first_name' ] );
222
- $billing_last_name = empty( $data[ 'billing_last_name' ] ) ? '' : wc_clean( $data[ 'billing_last_name' ] );
223
- $billing_country = empty( $data[ 'billing_country' ] ) ? '' : wc_clean( $data[ 'billing_country' ] );
224
- $billing_address_1 = empty( $data[ 'billing_address_1' ] ) ? '' : wc_clean( $data[ 'billing_address_1' ] );
225
- $billing_address_2 = empty( $data[ 'billing_address_2' ] ) ? '' : wc_clean( $data[ 'billing_address_2' ] );
226
- $billing_city = empty( $data[ 'billing_city' ] ) ? '' : wc_clean( $data[ 'billing_city' ] );
227
- $billing_state = empty( $data[ 'billing_state' ] ) ? '' : wc_clean( $data[ 'billing_state' ] );
228
- $billing_postcode = empty( $data[ 'billing_postcode' ] ) ? '' : wc_clean( $data[ 'billing_postcode' ] );
229
- $billing_phone = empty( $data[ 'billing_phone' ] ) ? '' : wc_clean( $data[ 'billing_phone' ] );
230
- $billing_email = empty( $data[ 'billing_email' ] ) ? '' : wc_clean( $data[ 'billing_email' ] );
 
 
231
 
232
  if ( isset( $data['ship_to_different_address'] ) ) {
233
- $shipping_first_name = empty( $data[ 'shipping_first_name' ] ) ? '' : wc_clean( $data[ 'shipping_first_name' ] );
234
- $shipping_last_name = empty( $data[ 'shipping_last_name' ] ) ? '' : wc_clean( $data[ 'shipping_last_name' ] );
235
- $shipping_country = empty( $data[ 'shipping_country' ] ) ? '' : wc_clean( $data[ 'shipping_country' ] );
236
- $shipping_address_1 = empty( $data[ 'shipping_address_1' ] ) ? '' : wc_clean( $data[ 'shipping_address_1' ] );
237
- $shipping_address_2 = empty( $data[ 'shipping_address_2' ] ) ? '' : wc_clean( $data[ 'shipping_address_2' ] );
238
- $shipping_city = empty( $data[ 'shipping_city' ] ) ? '' : wc_clean( $data[ 'shipping_city' ] );
239
- $shipping_state = empty( $data[ 'shipping_state' ] ) ? '' : wc_clean( $data[ 'shipping_state' ] );
240
- $shipping_postcode = empty( $data[ 'shipping_postcode' ] ) ? '' : wc_clean( $data[ 'shipping_postcode' ] );
 
 
241
  } else {
242
  $shipping_first_name = $billing_first_name;
243
  $shipping_last_name = $billing_last_name;
@@ -258,9 +262,9 @@ class WC_Gateway_PPEC_Cart_Handler {
258
 
259
  if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
260
  $customer->shipping_first_name = $shipping_first_name;
261
- $customer->shipping_last_name = $shipping_last_name;
262
- $customer->billing_first_name = $billing_first_name;
263
- $customer->billing_last_name = $billing_last_name;
264
 
265
  $customer->set_country( $billing_country );
266
  $customer->set_address( $billing_address_1 );
@@ -311,20 +315,24 @@ class WC_Gateway_PPEC_Cart_Handler {
311
 
312
  ?>
313
  <div class="wcppec-checkout-buttons woo_pp_cart_buttons_div">
314
- <?php if ( 'yes' === $settings->use_spb ) :
315
- wp_enqueue_script( 'wc-gateway-ppec-smart-payment-buttons' ); ?>
 
 
316
  <div id="woo_pp_ec_button_product"></div>
317
  <?php else : ?>
318
 
319
  <a href="<?php echo esc_url( add_query_arg( array( 'startcheckout' => 'true' ), wc_get_page_permalink( 'cart' ) ) ); ?>" id="woo_pp_ec_button_product" class="wcppec-checkout-buttons__button">
320
- <img src="<?php echo esc_url( $express_checkout_img_url ); ?>" alt="<?php _e( 'Check out with PayPal', 'woocommerce-gateway-paypal-express-checkout' ); ?>" style="width: auto; height: auto;">
321
  </a>
322
  <?php endif; ?>
323
  </div>
324
  <?php
325
 
326
  wp_enqueue_script( 'wc-gateway-ppec-generate-cart', wc_gateway_ppec()->plugin_url . 'assets/js/wc-gateway-ppec-generate-cart.js', array( 'jquery' ), wc_gateway_ppec()->version, true );
327
- wp_localize_script( 'wc-gateway-ppec-generate-cart', 'wc_ppec_generate_cart_context',
 
 
328
  array(
329
  'generate_cart_nonce' => wp_create_nonce( '_wc_ppec_generate_cart_nonce' ),
330
  'ajaxurl' => WC_AJAX::get_endpoint( 'wc_ppec_generate_cart' ),
@@ -354,20 +362,22 @@ class WC_Gateway_PPEC_Cart_Handler {
354
  <div class="wcppec-checkout-buttons__separator">&mdash; <?php esc_html_e( 'OR', 'woocommerce-gateway-paypal-express-checkout' ); ?> &mdash;</div>
355
  <?php endif; ?>
356
 
357
- <?php if ( 'yes' === $settings->use_spb ) :
358
- wp_enqueue_script( 'wc-gateway-ppec-smart-payment-buttons' ); ?>
 
 
359
  <div id="woo_pp_ec_button_cart"></div>
360
  <?php else : ?>
361
 
362
  <a href="<?php echo esc_url( add_query_arg( array( 'startcheckout' => 'true' ), wc_get_page_permalink( 'cart' ) ) ); ?>" id="woo_pp_ec_button" class="wcppec-checkout-buttons__button">
363
- <img src="<?php echo esc_url( $express_checkout_img_url ); ?>" alt="<?php _e( 'Check out with PayPal', 'woocommerce-gateway-paypal-express-checkout' ); ?>" style="width: auto; height: auto;">
364
  </a>
365
 
366
- <?php if ( $settings->is_credit_enabled() ) : ?>
367
- <a href="<?php echo esc_url( add_query_arg( array( 'startcheckout' => 'true', 'use-ppc' => 'true' ), wc_get_page_permalink( 'cart' ) ) ); ?>" id="woo_pp_ppc_button" class="wcppec-checkout-buttons__button">
368
- <img src="<?php echo esc_url( $paypal_credit_img_url ); ?>" alt="<?php _e( 'Pay with PayPal Credit', 'woocommerce-gateway-paypal-express-checkout' ); ?>" style="width: auto; height: auto;">
369
  </a>
370
- <?php endif; ?>
371
 
372
  <?php endif; ?>
373
  </div>
@@ -395,7 +405,7 @@ class WC_Gateway_PPEC_Cart_Handler {
395
  <?php else : ?>
396
 
397
  <a href="<?php echo esc_url( add_query_arg( array( 'startcheckout' => 'true' ), wc_get_page_permalink( 'cart' ) ) ); ?>" id="woo_pp_ec_button" class="wcppec-cart-widget-button">
398
- <img src="<?php echo esc_url( 'https://www.paypalobjects.com/webstatic/en_US/i/btn/png/gold-rect-paypalcheckout-26px.png' ); ?>" alt="<?php _e( 'Check out with PayPal', 'woocommerce-gateway-paypal-express-checkout' ); ?>" style="width: auto; height: auto;">
399
  </a>
400
  <?php endif; ?>
401
  <?php
@@ -408,9 +418,9 @@ class WC_Gateway_PPEC_Cart_Handler {
408
  if ( isset( $gateways['ppec_paypal'] ) && 'yes' === $settings->cart_checkout_enabled && 'yes' === $settings->use_spb ) {
409
  wp_enqueue_script( 'wc-gateway-ppec-smart-payment-buttons' );
410
  }
411
- }
412
  return $widget_title;
413
- }
414
 
415
  /**
416
  * Convert from settings to values expected by PayPal Button API:
@@ -427,7 +437,7 @@ class WC_Gateway_PPEC_Cart_Handler {
427
  */
428
  protected function get_button_settings( $settings, $context = '' ) {
429
  $prefix = $context ? $context . '_' : $context;
430
- $data = array(
431
  'button_layout' => $settings->{ $prefix . 'button_layout' },
432
  'button_size' => $settings->{ $prefix . 'button_size' },
433
  'button_label' => $settings->{ $prefix . 'button_label' },
@@ -435,8 +445,8 @@ class WC_Gateway_PPEC_Cart_Handler {
435
  'credit_enabled' => $settings->{ $prefix . 'credit_enabled' },
436
  );
437
 
438
- $button_layout = $data['button_layout'];
439
- $data['button_size'] = 'vertical' === $button_layout && 'small' === $data['button_size']
440
  ? 'medium'
441
  : $data['button_size'];
442
 
@@ -444,7 +454,7 @@ class WC_Gateway_PPEC_Cart_Handler {
444
  $data['credit_enabled'] = 'no';
445
  if ( ! is_array( $data['hide_funding_methods'] ) ) {
446
  $data['hide_funding_methods'] = array( 'CREDIT' );
447
- } elseif ( ! in_array( 'CREDIT', $data['hide_funding_methods'] ) ) {
448
  $data['hide_funding_methods'][] = 'CREDIT';
449
  }
450
  }
@@ -469,7 +479,7 @@ class WC_Gateway_PPEC_Cart_Handler {
469
  $settings = wc_gateway_ppec()->settings;
470
  $client = wc_gateway_ppec()->client;
471
 
472
- wp_enqueue_style( 'wc-gateway-ppec-frontend', wc_gateway_ppec()->plugin_url . 'assets/css/wc-gateway-ppec-frontend.css' );
473
 
474
  $is_cart = is_cart() && ! WC()->cart->is_empty() && 'yes' === $settings->cart_checkout_enabled;
475
  $is_product = ( is_product() || wc_post_content_has_shortcode( 'product_page' ) ) && 'yes' === $settings->checkout_on_single_product_enabled;
@@ -477,17 +487,19 @@ class WC_Gateway_PPEC_Cart_Handler {
477
  $page = $is_cart ? 'cart' : ( $is_product ? 'product' : ( $is_checkout ? 'checkout' : null ) );
478
 
479
  if ( 'yes' !== $settings->use_spb && $is_cart ) {
480
- wp_enqueue_script( 'paypal-checkout-js', 'https://www.paypalobjects.com/api/checkout.js', array(), null, true );
481
  wp_enqueue_script( 'wc-gateway-ppec-frontend-in-context-checkout', wc_gateway_ppec()->plugin_url . 'assets/js/wc-gateway-ppec-frontend-in-context-checkout.js', array( 'jquery' ), wc_gateway_ppec()->version, true );
482
- wp_localize_script( 'wc-gateway-ppec-frontend-in-context-checkout', 'wc_ppec_context',
 
 
483
  array(
484
- 'payer_id' => $client->get_payer_id(),
485
- 'environment' => $settings->get_environment(),
486
- 'locale' => $settings->get_paypal_locale(),
487
- 'start_flow' => esc_url( add_query_arg( array( 'startcheckout' => 'true' ), wc_get_page_permalink( 'cart' ) ) ),
488
- 'show_modal' => apply_filters( 'woocommerce_paypal_express_checkout_show_cart_modal', true ),
489
  'update_shipping_costs_nonce' => wp_create_nonce( '_wc_ppec_update_shipping_costs_nonce' ),
490
- 'ajaxurl' => WC_AJAX::get_endpoint( 'wc_ppec_update_shipping_costs' ),
491
  )
492
  );
493
 
@@ -504,7 +516,7 @@ class WC_Gateway_PPEC_Cart_Handler {
504
  'start_checkout_nonce' => wp_create_nonce( '_wc_ppec_start_checkout_nonce' ),
505
  'start_checkout_url' => WC_AJAX::get_endpoint( 'wc_ppec_start_checkout' ),
506
  'return_url' => wc_get_checkout_url(),
507
- 'cancel_url' => wc_get_cart_url(),
508
  'generic_error_msg' => wp_kses( __( 'An error occurred while processing your PayPal payment. Please contact the store owner for assistance.', 'woocommerce-gateway-paypal-express-checkout' ), array() ),
509
  );
510
 
@@ -522,8 +534,7 @@ class WC_Gateway_PPEC_Cart_Handler {
522
 
523
  $settings_toggle = 'yes' === $settings->mini_cart_settings_toggle;
524
  $mini_cart_data = $this->get_button_settings( $settings, $settings_toggle ? 'mini_cart' : '' );
525
-
526
- foreach( $mini_cart_data as $key => $value ) {
527
  unset( $mini_cart_data[ $key ] );
528
  $mini_cart_data[ 'mini_cart_' . $key ] = $value;
529
  }
@@ -542,18 +553,20 @@ class WC_Gateway_PPEC_Cart_Handler {
542
  'currency' => get_woocommerce_currency(),
543
  );
544
 
545
- wp_register_script( 'paypal-checkout-sdk', add_query_arg( $script_args, 'https://www.paypal.com/sdk/js' ), array(), null, true );
 
 
546
  $spb_script_dependencies[] = 'paypal-checkout-sdk';
547
 
548
  // register the fetch/promise polyfills files so the new PayPal Checkout SDK works with IE
549
  if ( $is_IE ) {
550
- wp_register_script( 'wc-gateway-ppec-promise-polyfill', wc_gateway_ppec()->plugin_url . 'assets/js/dist/promise-polyfill.min.js', array(), null, true );
551
- wp_register_script( 'wc-gateway-ppec-fetch-polyfill', wc_gateway_ppec()->plugin_url . 'assets/js/dist/fetch-polyfill.min.js', array(), null, true );
552
 
553
  $spb_script_dependencies = array_merge( $spb_script_dependencies, array( 'wc-gateway-ppec-fetch-polyfill', 'wc-gateway-ppec-promise-polyfill' ) );
554
  }
555
  } else {
556
- wp_register_script( 'paypal-checkout-js', 'https://www.paypalobjects.com/api/checkout.js', array(), null, true );
557
  $spb_script_dependencies[] = 'paypal-checkout-js';
558
  }
559
 
@@ -612,7 +625,7 @@ class WC_Gateway_PPEC_Cart_Handler {
612
  $needs_billing_agreement = wc_gateway_ppec()->checkout->needs_billing_agreement_creation( array() );
613
 
614
  // Mini-cart handling. By default an empty string is passed if no methods are disallowed, therefore we need to check for non array formats too.
615
- if ( $needs_billing_agreement && ( ! is_array( $payment_button_data['mini_cart_disallowed_methods'] ) || ! in_array( 'CARD', $payment_button_data['mini_cart_disallowed_methods'] ) ) ) {
616
  $payment_button_data['mini_cart_disallowed_methods'] = ! is_array( $payment_button_data['mini_cart_disallowed_methods'] ) ? array() : $payment_button_data['mini_cart_disallowed_methods'];
617
  $payment_button_data['mini_cart_disallowed_methods'][] = 'CARD';
618
  }
@@ -628,7 +641,7 @@ class WC_Gateway_PPEC_Cart_Handler {
628
  }
629
 
630
  // By default an empty string is passed if no methods are disallowed, therefore we need to check for non array formats too.
631
- if ( $needs_billing_agreement && ( ! isset( $payment_button_data['disallowed_methods'] ) || ! is_array( $payment_button_data['disallowed_methods'] ) || ! in_array( 'CARD', $payment_button_data['disallowed_methods'] ) ) ) {
632
  $payment_button_data['disallowed_methods'] = ( ! isset( $payment_button_data['disallowed_methods'] ) || ! is_array( $payment_button_data['disallowed_methods'] ) ) ? array() : $payment_button_data['disallowed_methods'];
633
  $payment_button_data['disallowed_methods'][] = 'CARD';
634
  }
51
  */
52
  public function before_cart_totals() {
53
  // If there then call start_checkout() else do nothing so page loads as normal.
54
+ if ( ! empty( $_GET['startcheckout'] ) && 'true' === $_GET['startcheckout'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
55
  // Trying to prevent auto running checkout when back button is pressed from PayPal page.
56
  $_GET['startcheckout'] = 'false';
57
  woo_pp_start_checkout();
67
  public function wc_ajax_generate_cart() {
68
  global $post;
69
 
70
+ if ( empty( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], '_wc_ppec_generate_cart_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
71
+ wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce-gateway-paypal-express-checkout' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
72
  }
73
 
74
  if ( ! defined( 'WOOCOMMERCE_CART' ) ) {
88
  * simple or variable product.
89
  */
90
  if ( $product ) {
91
+ $qty = ! isset( $_POST['quantity'] ) ? 1 : absint( $_POST['quantity'] );
92
  wc_empty_cart();
93
 
94
  if ( $product->is_type( 'variable' ) ) {
116
  if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
117
  $variation_id = $product->get_matching_variation( $attributes );
118
  } else {
119
+ $data_store = WC_Data_Store::load( 'product' );
120
  $variation_id = $data_store->find_matching_product_variation( $product, $attributes );
121
  }
122
 
137
  * @since 1.4.0
138
  */
139
  public function wc_ajax_update_shipping_costs() {
140
+ if ( empty( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], '_wc_ppec_update_shipping_costs_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
141
+ wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce-gateway-paypal-express-checkout' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
142
  }
143
 
144
  if ( ! defined( 'WOOCOMMERCE_CART' ) ) {
158
  * @since 1.6.0
159
  */
160
  public function wc_ajax_start_checkout() {
161
+ if ( empty( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], '_wc_ppec_start_checkout_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
162
+ wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce-gateway-paypal-express-checkout' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
163
  }
164
 
165
  if ( isset( $_POST['from_checkout'] ) && 'yes' === $_POST['from_checkout'] ) {
186
  }
187
 
188
  if ( empty( $error_messages ) ) {
189
+ $this->set_customer_data( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
190
  $this->start_checkout( false );
191
  } else {
192
  wp_send_json_error( array( 'messages' => $error_messages ) );
205
  try {
206
  wc_gateway_ppec()->checkout->start_checkout_from_cart( $skip_checkout );
207
  wp_send_json_success( array( 'token' => WC()->session->paypal->token ) );
208
+ } catch ( PayPal_API_Exception $e ) {
209
  wp_send_json_error( array( 'messages' => array( $e->getMessage() ) ) );
210
  }
211
  }
218
  protected function set_customer_data( $data ) {
219
  $customer = WC()->customer;
220
 
221
+ // phpcs:disable WordPress.WhiteSpace.OperatorSpacing.SpacingBefore
222
+ $billing_first_name = empty( $data['billing_first_name'] ) ? '' : wc_clean( $data['billing_first_name'] );
223
+ $billing_last_name = empty( $data['billing_last_name'] ) ? '' : wc_clean( $data['billing_last_name'] );
224
+ $billing_country = empty( $data['billing_country'] ) ? '' : wc_clean( $data['billing_country'] );
225
+ $billing_address_1 = empty( $data['billing_address_1'] ) ? '' : wc_clean( $data['billing_address_1'] );
226
+ $billing_address_2 = empty( $data['billing_address_2'] ) ? '' : wc_clean( $data['billing_address_2'] );
227
+ $billing_city = empty( $data['billing_city'] ) ? '' : wc_clean( $data['billing_city'] );
228
+ $billing_state = empty( $data['billing_state'] ) ? '' : wc_clean( $data['billing_state'] );
229
+ $billing_postcode = empty( $data['billing_postcode'] ) ? '' : wc_clean( $data['billing_postcode'] );
230
+ $billing_phone = empty( $data['billing_phone'] ) ? '' : wc_clean( $data['billing_phone'] );
231
+ $billing_email = empty( $data['billing_email'] ) ? '' : wc_clean( $data['billing_email'] );
232
+ // phpcs:enable
233
 
234
  if ( isset( $data['ship_to_different_address'] ) ) {
235
+ // phpcs:disable WordPress.WhiteSpace.OperatorSpacing.SpacingBefore
236
+ $shipping_first_name = empty( $data['shipping_first_name'] ) ? '' : wc_clean( $data['shipping_first_name'] );
237
+ $shipping_last_name = empty( $data['shipping_last_name'] ) ? '' : wc_clean( $data['shipping_last_name'] );
238
+ $shipping_country = empty( $data['shipping_country'] ) ? '' : wc_clean( $data['shipping_country'] );
239
+ $shipping_address_1 = empty( $data['shipping_address_1'] ) ? '' : wc_clean( $data['shipping_address_1'] );
240
+ $shipping_address_2 = empty( $data['shipping_address_2'] ) ? '' : wc_clean( $data['shipping_address_2'] );
241
+ $shipping_city = empty( $data['shipping_city'] ) ? '' : wc_clean( $data['shipping_city'] );
242
+ $shipping_state = empty( $data['shipping_state'] ) ? '' : wc_clean( $data['shipping_state'] );
243
+ $shipping_postcode = empty( $data['shipping_postcode'] ) ? '' : wc_clean( $data['shipping_postcode'] );
244
+ // phpcs:enable
245
  } else {
246
  $shipping_first_name = $billing_first_name;
247
  $shipping_last_name = $billing_last_name;
262
 
263
  if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
264
  $customer->shipping_first_name = $shipping_first_name;
265
+ $customer->shipping_last_name = $shipping_last_name;
266
+ $customer->billing_first_name = $billing_first_name;
267
+ $customer->billing_last_name = $billing_last_name;
268
 
269
  $customer->set_country( $billing_country );
270
  $customer->set_address( $billing_address_1 );
315
 
316
  ?>
317
  <div class="wcppec-checkout-buttons woo_pp_cart_buttons_div">
318
+ <?php
319
+ if ( 'yes' === $settings->use_spb ) :
320
+ wp_enqueue_script( 'wc-gateway-ppec-smart-payment-buttons' );
321
+ ?>
322
  <div id="woo_pp_ec_button_product"></div>
323
  <?php else : ?>
324
 
325
  <a href="<?php echo esc_url( add_query_arg( array( 'startcheckout' => 'true' ), wc_get_page_permalink( 'cart' ) ) ); ?>" id="woo_pp_ec_button_product" class="wcppec-checkout-buttons__button">
326
+ <img src="<?php echo esc_url( $express_checkout_img_url ); ?>" alt="<?php esc_attr_e( 'Check out with PayPal', 'woocommerce-gateway-paypal-express-checkout' ); ?>" style="width: auto; height: auto;">
327
  </a>
328
  <?php endif; ?>
329
  </div>
330
  <?php
331
 
332
  wp_enqueue_script( 'wc-gateway-ppec-generate-cart', wc_gateway_ppec()->plugin_url . 'assets/js/wc-gateway-ppec-generate-cart.js', array( 'jquery' ), wc_gateway_ppec()->version, true );
333
+ wp_localize_script(
334
+ 'wc-gateway-ppec-generate-cart',
335
+ 'wc_ppec_generate_cart_context',
336
  array(
337
  'generate_cart_nonce' => wp_create_nonce( '_wc_ppec_generate_cart_nonce' ),
338
  'ajaxurl' => WC_AJAX::get_endpoint( 'wc_ppec_generate_cart' ),
362
  <div class="wcppec-checkout-buttons__separator">&mdash; <?php esc_html_e( 'OR', 'woocommerce-gateway-paypal-express-checkout' ); ?> &mdash;</div>
363
  <?php endif; ?>
364
 
365
+ <?php
366
+ if ( 'yes' === $settings->use_spb ) :
367
+ wp_enqueue_script( 'wc-gateway-ppec-smart-payment-buttons' );
368
+ ?>
369
  <div id="woo_pp_ec_button_cart"></div>
370
  <?php else : ?>
371
 
372
  <a href="<?php echo esc_url( add_query_arg( array( 'startcheckout' => 'true' ), wc_get_page_permalink( 'cart' ) ) ); ?>" id="woo_pp_ec_button" class="wcppec-checkout-buttons__button">
373
+ <img src="<?php echo esc_url( $express_checkout_img_url ); ?>" alt="<?php esc_attr_e( 'Check out with PayPal', 'woocommerce-gateway-paypal-express-checkout' ); ?>" style="width: auto; height: auto;">
374
  </a>
375
 
376
+ <?php if ( $settings->is_credit_enabled() ) : ?>
377
+ <a href="<?php echo esc_url( add_query_arg( array( 'startcheckout' => 'true', 'use-ppc' => 'true' ), wc_get_page_permalink( 'cart' ) ) ); // phpcs:ignore WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound ?>" id="woo_pp_ppc_button" class="wcppec-checkout-buttons__button">
378
+ <img src="<?php echo esc_url( $paypal_credit_img_url ); ?>" alt="<?php esc_attr_e( 'Pay with PayPal Credit', 'woocommerce-gateway-paypal-express-checkout' ); ?>" style="width: auto; height: auto;">
379
  </a>
380
+ <?php endif; ?>
381
 
382
  <?php endif; ?>
383
  </div>
405
  <?php else : ?>
406
 
407
  <a href="<?php echo esc_url( add_query_arg( array( 'startcheckout' => 'true' ), wc_get_page_permalink( 'cart' ) ) ); ?>" id="woo_pp_ec_button" class="wcppec-cart-widget-button">
408
+ <img src="<?php echo esc_url( 'https://www.paypalobjects.com/webstatic/en_US/i/btn/png/gold-rect-paypalcheckout-26px.png' ); ?>" alt="<?php esc_attr_e( 'Check out with PayPal', 'woocommerce-gateway-paypal-express-checkout' ); ?>" style="width: auto; height: auto;">
409
  </a>
410
  <?php endif; ?>
411
  <?php
418
  if ( isset( $gateways['ppec_paypal'] ) && 'yes' === $settings->cart_checkout_enabled && 'yes' === $settings->use_spb ) {
419
  wp_enqueue_script( 'wc-gateway-ppec-smart-payment-buttons' );
420
  }
421
+ }
422
  return $widget_title;
423
+ }
424
 
425
  /**
426
  * Convert from settings to values expected by PayPal Button API:
437
  */
438
  protected function get_button_settings( $settings, $context = '' ) {
439
  $prefix = $context ? $context . '_' : $context;
440
+ $data = array(
441
  'button_layout' => $settings->{ $prefix . 'button_layout' },
442
  'button_size' => $settings->{ $prefix . 'button_size' },
443
  'button_label' => $settings->{ $prefix . 'button_label' },
445
  'credit_enabled' => $settings->{ $prefix . 'credit_enabled' },
446
  );
447
 
448
+ $button_layout = $data['button_layout'];
449
+ $data['button_size'] = 'vertical' === $button_layout && 'small' === $data['button_size']
450
  ? 'medium'
451
  : $data['button_size'];
452
 
454
  $data['credit_enabled'] = 'no';
455
  if ( ! is_array( $data['hide_funding_methods'] ) ) {
456
  $data['hide_funding_methods'] = array( 'CREDIT' );
457
+ } elseif ( ! in_array( 'CREDIT', $data['hide_funding_methods'], true ) ) {
458
  $data['hide_funding_methods'][] = 'CREDIT';
459
  }
460
  }
479
  $settings = wc_gateway_ppec()->settings;
480
  $client = wc_gateway_ppec()->client;
481
 
482
+ wp_enqueue_style( 'wc-gateway-ppec-frontend', wc_gateway_ppec()->plugin_url . 'assets/css/wc-gateway-ppec-frontend.css', array(), wc_gateway_ppec()->version );
483
 
484
  $is_cart = is_cart() && ! WC()->cart->is_empty() && 'yes' === $settings->cart_checkout_enabled;
485
  $is_product = ( is_product() || wc_post_content_has_shortcode( 'product_page' ) ) && 'yes' === $settings->checkout_on_single_product_enabled;
487
  $page = $is_cart ? 'cart' : ( $is_product ? 'product' : ( $is_checkout ? 'checkout' : null ) );
488
 
489
  if ( 'yes' !== $settings->use_spb && $is_cart ) {
490
+ wp_enqueue_script( 'paypal-checkout-js', 'https://www.paypalobjects.com/api/checkout.js', array(), null, true ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion
491
  wp_enqueue_script( 'wc-gateway-ppec-frontend-in-context-checkout', wc_gateway_ppec()->plugin_url . 'assets/js/wc-gateway-ppec-frontend-in-context-checkout.js', array( 'jquery' ), wc_gateway_ppec()->version, true );
492
+ wp_localize_script(
493
+ 'wc-gateway-ppec-frontend-in-context-checkout',
494
+ 'wc_ppec_context',
495
  array(
496
+ 'payer_id' => $client->get_payer_id(),
497
+ 'environment' => $settings->get_environment(),
498
+ 'locale' => $settings->get_paypal_locale(),
499
+ 'start_flow' => esc_url( add_query_arg( array( 'startcheckout' => 'true' ), wc_get_page_permalink( 'cart' ) ) ),
500
+ 'show_modal' => apply_filters( 'woocommerce_paypal_express_checkout_show_cart_modal', true ),
501
  'update_shipping_costs_nonce' => wp_create_nonce( '_wc_ppec_update_shipping_costs_nonce' ),
502
+ 'ajaxurl' => WC_AJAX::get_endpoint( 'wc_ppec_update_shipping_costs' ),
503
  )
504
  );
505
 
516
  'start_checkout_nonce' => wp_create_nonce( '_wc_ppec_start_checkout_nonce' ),
517
  'start_checkout_url' => WC_AJAX::get_endpoint( 'wc_ppec_start_checkout' ),
518
  'return_url' => wc_get_checkout_url(),
519
+ 'cancel_url' => '',
520
  'generic_error_msg' => wp_kses( __( 'An error occurred while processing your PayPal payment. Please contact the store owner for assistance.', 'woocommerce-gateway-paypal-express-checkout' ), array() ),
521
  );
522
 
534
 
535
  $settings_toggle = 'yes' === $settings->mini_cart_settings_toggle;
536
  $mini_cart_data = $this->get_button_settings( $settings, $settings_toggle ? 'mini_cart' : '' );
537
+ foreach ( $mini_cart_data as $key => $value ) {
 
538
  unset( $mini_cart_data[ $key ] );
539
  $mini_cart_data[ 'mini_cart_' . $key ] = $value;
540
  }
553
  'currency' => get_woocommerce_currency(),
554
  );
555
 
556
+ $script_args = apply_filters( 'woocommerce_paypal_express_checkout_sdk_script_args', $script_args, $settings, $client );
557
+
558
+ wp_register_script( 'paypal-checkout-sdk', add_query_arg( $script_args, 'https://www.paypal.com/sdk/js' ), array(), null, true ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion
559
  $spb_script_dependencies[] = 'paypal-checkout-sdk';
560
 
561
  // register the fetch/promise polyfills files so the new PayPal Checkout SDK works with IE
562
  if ( $is_IE ) {
563
+ wp_register_script( 'wc-gateway-ppec-promise-polyfill', wc_gateway_ppec()->plugin_url . 'assets/js/dist/promise-polyfill.min.js', array(), wc_gateway_ppec()->version, true );
564
+ wp_register_script( 'wc-gateway-ppec-fetch-polyfill', wc_gateway_ppec()->plugin_url . 'assets/js/dist/fetch-polyfill.min.js', array(), wc_gateway_ppec()->version, true );
565
 
566
  $spb_script_dependencies = array_merge( $spb_script_dependencies, array( 'wc-gateway-ppec-fetch-polyfill', 'wc-gateway-ppec-promise-polyfill' ) );
567
  }
568
  } else {
569
+ wp_register_script( 'paypal-checkout-js', 'https://www.paypalobjects.com/api/checkout.js', array(), null, true ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion
570
  $spb_script_dependencies[] = 'paypal-checkout-js';
571
  }
572
 
625
  $needs_billing_agreement = wc_gateway_ppec()->checkout->needs_billing_agreement_creation( array() );
626
 
627
  // Mini-cart handling. By default an empty string is passed if no methods are disallowed, therefore we need to check for non array formats too.
628
+ if ( $needs_billing_agreement && ( ! is_array( $payment_button_data['mini_cart_disallowed_methods'] ) || ! in_array( 'CARD', $payment_button_data['mini_cart_disallowed_methods'], true ) ) ) {
629
  $payment_button_data['mini_cart_disallowed_methods'] = ! is_array( $payment_button_data['mini_cart_disallowed_methods'] ) ? array() : $payment_button_data['mini_cart_disallowed_methods'];
630
  $payment_button_data['mini_cart_disallowed_methods'][] = 'CARD';
631
  }
641
  }
642
 
643
  // By default an empty string is passed if no methods are disallowed, therefore we need to check for non array formats too.
644
+ if ( $needs_billing_agreement && ( ! isset( $payment_button_data['disallowed_methods'] ) || ! is_array( $payment_button_data['disallowed_methods'] ) || ! in_array( 'CARD', $payment_button_data['disallowed_methods'], true ) ) ) {
645
  $payment_button_data['disallowed_methods'] = ( ! isset( $payment_button_data['disallowed_methods'] ) || ! is_array( $payment_button_data['disallowed_methods'] ) ) ? array() : $payment_button_data['disallowed_methods'];
646
  $payment_button_data['disallowed_methods'][] = 'CARD';
647
  }
includes/class-wc-gateway-ppec-checkout-details.php CHANGED
@@ -10,42 +10,42 @@ if ( ! defined( 'ABSPATH' ) ) {
10
 
11
  $includes_path = wc_gateway_ppec()->includes_path;
12
 
13
- require_once( $includes_path . 'class-wc-gateway-ppec-address.php' );
14
 
15
  class PayPal_Checkout_Details {
16
- public $raw_response = array();
17
- public $token = false;
18
- public $custom = false;
19
- public $invnum = false;
20
- public $phone_number = false;
21
- public $billing_agreement_accepted = false;
22
 
23
- const BillingAgreementNotAccepted = '0';
24
- const BillingAgreementAccepted = '1';
25
 
26
  public $paypal_adjustment = false;
27
  public $redirect_required_after_payment = false;
28
  public $checkout_status = false;
29
 
30
- const PaymentNotAttempted = 'PaymentActionNotInitiated';
31
- const PaymentFailed = 'PaymentActionFailed';
32
- const PaymentInProgress = 'PaymentActionInProgress';
33
- const PaymentCompleted = 'PaymentActionCompleted';
34
 
35
- public $gift_details = false;
36
 
37
- public $buyer_marketing_email = false;
38
- public $survey_question = false;
39
- public $survey_choice_selected = false;
40
 
41
- public $payer_details = false;
42
- public $wallets = false;
43
 
44
- public $instrument_details = false;
45
 
46
- public $shipping_option_details = false;
47
 
48
- public $payments = false;
49
 
50
  public function loadFromGetECResponse( $getECResponse ) {
51
  $this->raw_response = $getECResponse;
@@ -61,7 +61,7 @@ class PayPal_Checkout_Details {
61
  'CHECKOUTSTATUS' => 'checkout_status',
62
  'BUYERMARKETINGEMAIL' => 'buyer_marketing_email',
63
  'SURVEYQUESTION' => 'survey_question',
64
- 'SURVEYCHOICESELECTED' => 'survey_choice_selected'
65
  );
66
 
67
  foreach ( $getECResponse as $index => $value ) {
@@ -77,7 +77,7 @@ class PayPal_Checkout_Details {
77
 
78
  $this->payer_details = new PayPal_Checkout_Payer_Details();
79
  if ( ! $this->payer_details->loadFromGetECResponse( $getECResponse ) ) {
80
- wc_gateway_ppec_log( sprintf( 'PayPal response did not include the payer billing details: %s', print_r( $getECResponse, true ) ) );
81
  $this->payer_details = false;
82
  }
83
 
@@ -91,7 +91,7 @@ class PayPal_Checkout_Details {
91
  $this->shipping_option_details = false;
92
  }
93
 
94
- $max_wallet_num = -1;
95
  $max_payment_num = -1;
96
  foreach ( $getECResponse as $index => $value ) {
97
  if ( preg_match( '/^(WALLETTYPE|WALLETID|WALLETDESCRIPTION)(\d+)$/', $index, $matches ) ) {
@@ -127,43 +127,43 @@ class PayPal_Checkout_Details {
127
  }
128
 
129
  class PayPal_Checkout_Payment_Details {
130
- public $shipping_address = false;
131
- public $shipping_address_confirmed = false;
132
 
133
  public $shipping_address_normalization_status = false;
134
 
135
- const AddressNormalizationNone = 'None';
136
- const AddressNormalizationNormalized = 'Normalized';
137
- const AddressNormalizationUnnormalized = 'Unnormalized';
138
- const AddressNormalizationUserPreferred = 'UserPreferred';
139
 
140
- public $amount = false;
141
- public $currency_code = false;
142
 
143
- public $item_amount = false;
144
- public $shipping_amount = false;
145
- public $insurance_amount = false;
146
- public $shipping_discount_amount = false;
147
- public $insurance_option_offered = false;
148
- public $handling_amount = false;
149
- public $tax_amount = false;
150
- public $description = false;
151
- public $custom = false;
152
- public $invoice_number = false;
153
- public $notify_url = false;
154
- public $note_text = false;
155
- public $transaction_id = false;
156
- public $allowed_payment_method = false;
157
 
158
- const AllowedPaymentMethodInstantPaymentOnly = 'InstantPaymentOnly';
159
 
160
- public $payment_request_id = false;
161
- public $bucket_category_type = false;
162
 
163
- const BucketCategoryInternationalShipping = '1';
164
- const BucketCategoryLocalDelivery = '2';
165
 
166
- public $items = false;
167
 
168
  public function loadFromGetECResponse( $getECResponse, $bucketNum ) {
169
  $map = array(
@@ -185,7 +185,7 @@ class PayPal_Checkout_Payment_Details {
185
  'ALLOWEDPAYMENTMETHOD' => 'allowed_payment_method',
186
  'PAYMENTREQUESTID' => 'payment_request_id',
187
  'BUCKETCATEGORYTYPE' => 'bucket_category_type',
188
- 'ADDRESSNORMALIZATIONSTATUS' => 'shipping_address_normalization_status'
189
  );
190
 
191
  $found_any = false;
@@ -193,7 +193,7 @@ class PayPal_Checkout_Payment_Details {
193
  $var_name = 'PAYMENTREQUEST_' . $bucketNum . '_' . $index;
194
  if ( array_key_exists( $var_name, $getECResponse ) ) {
195
  $this->{ $value } = $getECResponse[ $var_name ];
196
- $found_any = true;
197
  }
198
  }
199
 
@@ -208,7 +208,7 @@ class PayPal_Checkout_Payment_Details {
208
  }
209
 
210
  if ( $max_line_item_num > -1 ) {
211
- $found_any = true;
212
  $this->items = array();
213
  for ( $i = 0; $i <= $max_line_item_num; $i++ ) {
214
  $items[ $i ] = new PayPal_Checkout_Payment_Item_Details();
@@ -228,14 +228,14 @@ class PayPal_Checkout_Payment_Details {
228
  }
229
 
230
  class PayPal_Checkout_Payment_Item_Details {
231
- public $name = false;
232
  public $description = false;
233
- public $amount = false;
234
  public $item_number = false;
235
- public $quantity = false;
236
- public $tax_amount = false;
237
 
238
- public $physical_details = false;
239
  public $ebay_item_details = false;
240
 
241
  public function loadFromGetECResponse( $getECResponse, $bucketNum, $itemNum ) {
@@ -281,7 +281,7 @@ class PayPal_Checkout_Payment_Item_Physical_Details {
281
  public $height_units;
282
 
283
  public function loadFromGetECResponse( $getECResponse, $bucketNum, $itemNum ) {
284
- $map = array(
285
  'WEIGHTVALUE' => 'weight',
286
  'WEIGHTUNIT' => 'weight_units',
287
  'LENGTHVALUE' => 'length',
@@ -289,7 +289,7 @@ class PayPal_Checkout_Payment_Item_Physical_Details {
289
  'WIDTHVALUE' => 'width',
290
  'WIDTHUNIT' => 'width_units',
291
  'HEIGHTVALUE' => 'height',
292
- 'HEIGHTUNIT' => 'height_units'
293
  );
294
  $found_any = false;
295
 
@@ -297,7 +297,7 @@ class PayPal_Checkout_Payment_Item_Physical_Details {
297
  $var_name = 'L_PAYMENTREQUEST_' . $bucketNum . '_ITEM' . $index . $itemNum;
298
  if ( array_key_exists( $var_name, $getECResponse ) ) {
299
  $this->{ $value } = $getECResponse[ $var_name ];
300
- $found_any = true;
301
  }
302
  }
303
 
@@ -316,7 +316,7 @@ class PayPal_Checkout_Payment_Item_Ebay_Item_Details {
316
  'ITEMNUMBER' => 'item_number',
317
  'AUCTIONTXNID' => 'auction_transaction_id',
318
  'ORDERID' => 'order_id',
319
- 'CARTID' => 'cart_id'
320
  );
321
 
322
  $found_any = false;
@@ -324,7 +324,7 @@ class PayPal_Checkout_Payment_Item_Ebay_Item_Details {
324
  $var_name = 'L_PAYMENTREQUEST_' . $bucketNum . '_' . $index . $itemNum;
325
  if ( array_key_exists( $var_name, $getECResponse ) ) {
326
  $this->{ $value } = $getECResponse[ $var_name ];
327
- $found_any = true;
328
  }
329
  }
330
 
@@ -333,7 +333,7 @@ class PayPal_Checkout_Payment_Item_Ebay_Item_Details {
333
  }
334
 
335
  class PayPal_Checkout_Shipping_Option_Details {
336
- public $calculation_mode = false;
337
 
338
  const CalculationModeCallback = 'Callback';
339
  const CalculationModeFlatrate = 'FlatRate';
@@ -346,18 +346,18 @@ class PayPal_Checkout_Shipping_Option_Details {
346
  // Returns true to indicate that the getECResponse array contained variables that were pertinent to this object.
347
  // If not, it returns false to indicate that the caller can destroy this object.
348
  public function loadFromGetECResponse( $getECResponse ) {
349
- $map = array(
350
  'SHIPPINGCALCULATIONMODE' => 'calculation_mode',
351
  'INSURANCEOPTIONSELECTED' => 'insurance_option_selected',
352
  'SHIPPINGOPTIONISDEFAULT' => 'shipping_option_is_default',
353
  'SHIPPINGOPTIONAMOUNT' => 'shipping_option_amount',
354
- 'SHIPPINGOPTIONNAME' => 'shipping_option_name'
355
  );
356
  $found_any = false;
357
  foreach ( $getECResponse as $index => $value ) {
358
  if ( array_key_exists( $index, $map ) ) {
359
  $this->{ $map[ $index ] } = $value;
360
- $found_any = true;
361
  }
362
  }
363
 
@@ -366,26 +366,26 @@ class PayPal_Checkout_Shipping_Option_Details {
366
  }
367
 
368
  class PayPal_Checkout_Instrument_Details {
369
- public $instrument_category = false;
370
 
371
  const InstrumentCategoryPayPalCredit = '1';
372
  const InstrumentCategoryPrivateCard = '2';
373
 
374
- public $instrument_id = false;
375
 
376
  // Returns true to indicate that the getECResponse array contained variables that were pertinent to this object.
377
  // If not, it returns false to indicate that the caller can destroy this object.
378
  public function loadFromGetECResponse( $getECResponse ) {
379
- $map = array(
380
  'INSTRUMENTCATEGORY' => 'instrument_category',
381
- 'INSTRUMENTID' => 'instrument_id'
382
  );
383
  $found_any = false;
384
 
385
  foreach ( $getECResponse as $index => $value ) {
386
  if ( array_key_exists( $index, $map ) ) {
387
  $this->{ $map[ $index ] } = $value;
388
- $found_any = true;
389
  }
390
  }
391
 
@@ -394,14 +394,14 @@ class PayPal_Checkout_Instrument_Details {
394
  }
395
 
396
  class PayPal_Checkout_Wallet_Details {
397
- public $wallet_type = false;
398
 
399
  const WalletTypeLoyaltyCard = 'LOYALTY_CARD';
400
  const WalletTypeMerchantCoupon = 'MERCHANT_COUPON';
401
  const WalletTypeMerchantClosedLoopOffer = 'MERCHANT_CLOSED_LOOP_OFFER';
402
 
403
- public $wallet_id = false;
404
- public $wallet_description = false;
405
 
406
  public function __construct( $wallet_type = false, $wallet_id = false, $wallet_description = false ) {
407
  $this->wallet_type = $wallet_type;
@@ -414,15 +414,15 @@ class PayPal_Checkout_Wallet_Details {
414
  public function loadFromGetECResponse( $getECResponse, $wallet_num ) {
415
  $found_any = false;
416
  foreach ( $getECResponse as $index => $value ) {
417
- if ( ( 'WALLETTYPE' . $wallet_num ) == $index ) {
418
  $this->wallet_type = $value;
419
- $found_any = true;
420
- } elseif ( ( 'WALLETID' . $wallet_num ) == $index ) {
421
  $this->wallet_id = $value;
422
- $found_any = true;
423
- } elseif ( ( 'WALLETDESCRIPTION' . $wallet_num ) == $index ) {
424
  $this->wallet_description = $value;
425
- $found_any = true;
426
  }
427
  }
428
 
@@ -431,27 +431,27 @@ class PayPal_Checkout_Wallet_Details {
431
  }
432
 
433
  class PayPal_Checkout_Payer_Details {
434
- public $phone_number = false;
435
- public $email = false;
436
- public $payer_id = false;
437
- public $payer_status = false;
438
 
439
  const PayerStatusVerified = 'verified';
440
  const PayerStatusUnverified = 'unverified';
441
 
442
- public $country = false;
443
- public $business_name = false;
444
- public $first_name = false;
445
- public $last_name = false;
446
- public $middle_name = false;
447
- public $suffix = false;
448
 
449
- public $billing_address = false;
450
 
451
  // Returns true to indicate that the getECResponse array contained variables that were pertinent to this object.
452
  // If not, it returns false to indicate that the caller can destroy this object.
453
  public function loadFromGetECResponse( $getECResponse ) {
454
- $map = array(
455
  'PHONENUM' => 'phone_number',
456
  'EMAIL' => 'email',
457
  'PAYERID' => 'payer_id',
@@ -461,7 +461,7 @@ class PayPal_Checkout_Payer_Details {
461
  'FIRSTNAME' => 'first_name',
462
  'MIDDLENAME' => 'middle_name',
463
  'LASTNAME' => 'last_name',
464
- 'SUFFIX' => 'suffix'
465
  );
466
  $found_any = false;
467
 
@@ -471,7 +471,7 @@ class PayPal_Checkout_Payer_Details {
471
  foreach ( $getECResponse as $index => $value ) {
472
  if ( array_key_exists( $index, $map ) ) {
473
  $this->{ $map[ $index ] } = $value;
474
- $found_any = true;
475
  }
476
  if ( preg_match( '/^BILLTONAME|STREET|STREET2|CITY|STATE|ZIP|COUNTRY|COUNTRYNAME|ADDRESSOWNER|ADDRESSSTATUS$/', $index ) ) {
477
  $billing_address_present = true;
@@ -501,18 +501,18 @@ class PayPal_Checkout_Gift_Details {
501
  // Returns true to indicate that the getECResponse array contained variables that were pertinent to this object.
502
  // If not, it returns false to indicate that the caller can destroy this object.
503
  public function loadFromGetECResponse( $getECResponse ) {
504
- $map = array(
505
  'GIFTMESSAGE' => 'gift_message',
506
  'GIFTWRAPNAME' => 'gift_wrap_name',
507
  'GIFTRECEIPTENABLE' => 'gift_receipt_enabled',
508
- 'GIFTWRAPAMOUNT' => 'gift_wrap_amount'
509
  );
510
  $found_any = false;
511
 
512
  foreach ( $getECResponse as $index => $value ) {
513
  if ( array_key_exists( $index, $map ) ) {
514
  $this->{ $map[ $index ] } = $value;
515
- $found_any = true;
516
  }
517
  }
518
 
10
 
11
  $includes_path = wc_gateway_ppec()->includes_path;
12
 
13
+ require_once $includes_path . 'class-wc-gateway-ppec-address.php';
14
 
15
  class PayPal_Checkout_Details {
16
+ public $raw_response = array();
17
+ public $token = false;
18
+ public $custom = false;
19
+ public $invnum = false;
20
+ public $phone_number = false;
21
+ public $billing_agreement_accepted = false;
22
 
23
+ const BillingAgreementNotAccepted = '0';
24
+ const BillingAgreementAccepted = '1';
25
 
26
  public $paypal_adjustment = false;
27
  public $redirect_required_after_payment = false;
28
  public $checkout_status = false;
29
 
30
+ const PaymentNotAttempted = 'PaymentActionNotInitiated';
31
+ const PaymentFailed = 'PaymentActionFailed';
32
+ const PaymentInProgress = 'PaymentActionInProgress';
33
+ const PaymentCompleted = 'PaymentActionCompleted';
34
 
35
+ public $gift_details = false;
36
 
37
+ public $buyer_marketing_email = false;
38
+ public $survey_question = false;
39
+ public $survey_choice_selected = false;
40
 
41
+ public $payer_details = false;
42
+ public $wallets = false;
43
 
44
+ public $instrument_details = false;
45
 
46
+ public $shipping_option_details = false;
47
 
48
+ public $payments = false;
49
 
50
  public function loadFromGetECResponse( $getECResponse ) {
51
  $this->raw_response = $getECResponse;
61
  'CHECKOUTSTATUS' => 'checkout_status',
62
  'BUYERMARKETINGEMAIL' => 'buyer_marketing_email',
63
  'SURVEYQUESTION' => 'survey_question',
64
+ 'SURVEYCHOICESELECTED' => 'survey_choice_selected',
65
  );
66
 
67
  foreach ( $getECResponse as $index => $value ) {
77
 
78
  $this->payer_details = new PayPal_Checkout_Payer_Details();
79
  if ( ! $this->payer_details->loadFromGetECResponse( $getECResponse ) ) {
80
+ wc_gateway_ppec_log( sprintf( 'PayPal response did not include the payer billing details: %s', print_r( $getECResponse, true ) ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
81
  $this->payer_details = false;
82
  }
83
 
91
  $this->shipping_option_details = false;
92
  }
93
 
94
+ $max_wallet_num = -1;
95
  $max_payment_num = -1;
96
  foreach ( $getECResponse as $index => $value ) {
97
  if ( preg_match( '/^(WALLETTYPE|WALLETID|WALLETDESCRIPTION)(\d+)$/', $index, $matches ) ) {
127
  }
128
 
129
  class PayPal_Checkout_Payment_Details {
130
+ public $shipping_address = false;
131
+ public $shipping_address_confirmed = false;
132
 
133
  public $shipping_address_normalization_status = false;
134
 
135
+ const AddressNormalizationNone = 'None';
136
+ const AddressNormalizationNormalized = 'Normalized';
137
+ const AddressNormalizationUnnormalized = 'Unnormalized';
138
+ const AddressNormalizationUserPreferred = 'UserPreferred';
139
 
140
+ public $amount = false;
141
+ public $currency_code = false;
142
 
143
+ public $item_amount = false;
144
+ public $shipping_amount = false;
145
+ public $insurance_amount = false;
146
+ public $shipping_discount_amount = false;
147
+ public $insurance_option_offered = false;
148
+ public $handling_amount = false;
149
+ public $tax_amount = false;
150
+ public $description = false;
151
+ public $custom = false;
152
+ public $invoice_number = false;
153
+ public $notify_url = false;
154
+ public $note_text = false;
155
+ public $transaction_id = false;
156
+ public $allowed_payment_method = false;
157
 
158
+ const AllowedPaymentMethodInstantPaymentOnly = 'InstantPaymentOnly';
159
 
160
+ public $payment_request_id = false;
161
+ public $bucket_category_type = false;
162
 
163
+ const BucketCategoryInternationalShipping = '1';
164
+ const BucketCategoryLocalDelivery = '2';
165
 
166
+ public $items = false;
167
 
168
  public function loadFromGetECResponse( $getECResponse, $bucketNum ) {
169
  $map = array(
185
  'ALLOWEDPAYMENTMETHOD' => 'allowed_payment_method',
186
  'PAYMENTREQUESTID' => 'payment_request_id',
187
  'BUCKETCATEGORYTYPE' => 'bucket_category_type',
188
+ 'ADDRESSNORMALIZATIONSTATUS' => 'shipping_address_normalization_status',
189
  );
190
 
191
  $found_any = false;
193
  $var_name = 'PAYMENTREQUEST_' . $bucketNum . '_' . $index;
194
  if ( array_key_exists( $var_name, $getECResponse ) ) {
195
  $this->{ $value } = $getECResponse[ $var_name ];
196
+ $found_any = true;
197
  }
198
  }
199
 
208
  }
209
 
210
  if ( $max_line_item_num > -1 ) {
211
+ $found_any = true;
212
  $this->items = array();
213
  for ( $i = 0; $i <= $max_line_item_num; $i++ ) {
214
  $items[ $i ] = new PayPal_Checkout_Payment_Item_Details();
228
  }
229
 
230
  class PayPal_Checkout_Payment_Item_Details {
231
+ public $name = false;
232
  public $description = false;
233
+ public $amount = false;
234
  public $item_number = false;
235
+ public $quantity = false;
236
+ public $tax_amount = false;
237
 
238
+ public $physical_details = false;
239
  public $ebay_item_details = false;
240
 
241
  public function loadFromGetECResponse( $getECResponse, $bucketNum, $itemNum ) {
281
  public $height_units;
282
 
283
  public function loadFromGetECResponse( $getECResponse, $bucketNum, $itemNum ) {
284
+ $map = array(
285
  'WEIGHTVALUE' => 'weight',
286
  'WEIGHTUNIT' => 'weight_units',
287
  'LENGTHVALUE' => 'length',
289
  'WIDTHVALUE' => 'width',
290
  'WIDTHUNIT' => 'width_units',
291
  'HEIGHTVALUE' => 'height',
292
+ 'HEIGHTUNIT' => 'height_units',
293
  );
294
  $found_any = false;
295
 
297
  $var_name = 'L_PAYMENTREQUEST_' . $bucketNum . '_ITEM' . $index . $itemNum;
298
  if ( array_key_exists( $var_name, $getECResponse ) ) {
299
  $this->{ $value } = $getECResponse[ $var_name ];
300
+ $found_any = true;
301
  }
302
  }
303
 
316
  'ITEMNUMBER' => 'item_number',
317
  'AUCTIONTXNID' => 'auction_transaction_id',
318
  'ORDERID' => 'order_id',
319
+ 'CARTID' => 'cart_id',
320
  );
321
 
322
  $found_any = false;
324
  $var_name = 'L_PAYMENTREQUEST_' . $bucketNum . '_' . $index . $itemNum;
325
  if ( array_key_exists( $var_name, $getECResponse ) ) {
326
  $this->{ $value } = $getECResponse[ $var_name ];
327
+ $found_any = true;
328
  }
329
  }
330
 
333
  }
334
 
335
  class PayPal_Checkout_Shipping_Option_Details {
336
+ public $calculation_mode = false;
337
 
338
  const CalculationModeCallback = 'Callback';
339
  const CalculationModeFlatrate = 'FlatRate';
346
  // Returns true to indicate that the getECResponse array contained variables that were pertinent to this object.
347
  // If not, it returns false to indicate that the caller can destroy this object.
348
  public function loadFromGetECResponse( $getECResponse ) {
349
+ $map = array(
350
  'SHIPPINGCALCULATIONMODE' => 'calculation_mode',
351
  'INSURANCEOPTIONSELECTED' => 'insurance_option_selected',
352
  'SHIPPINGOPTIONISDEFAULT' => 'shipping_option_is_default',
353
  'SHIPPINGOPTIONAMOUNT' => 'shipping_option_amount',
354
+ 'SHIPPINGOPTIONNAME' => 'shipping_option_name',
355
  );
356
  $found_any = false;
357
  foreach ( $getECResponse as $index => $value ) {
358
  if ( array_key_exists( $index, $map ) ) {
359
  $this->{ $map[ $index ] } = $value;
360
+ $found_any = true;
361
  }
362
  }
363
 
366
  }
367
 
368
  class PayPal_Checkout_Instrument_Details {
369
+ public $instrument_category = false;
370
 
371
  const InstrumentCategoryPayPalCredit = '1';
372
  const InstrumentCategoryPrivateCard = '2';
373
 
374
+ public $instrument_id = false;
375
 
376
  // Returns true to indicate that the getECResponse array contained variables that were pertinent to this object.
377
  // If not, it returns false to indicate that the caller can destroy this object.
378
  public function loadFromGetECResponse( $getECResponse ) {
379
+ $map = array(
380
  'INSTRUMENTCATEGORY' => 'instrument_category',
381
+ 'INSTRUMENTID' => 'instrument_id',
382
  );
383
  $found_any = false;
384
 
385
  foreach ( $getECResponse as $index => $value ) {
386
  if ( array_key_exists( $index, $map ) ) {
387
  $this->{ $map[ $index ] } = $value;
388
+ $found_any = true;
389
  }
390
  }
391
 
394
  }
395
 
396
  class PayPal_Checkout_Wallet_Details {
397
+ public $wallet_type = false;
398
 
399
  const WalletTypeLoyaltyCard = 'LOYALTY_CARD';
400
  const WalletTypeMerchantCoupon = 'MERCHANT_COUPON';
401
  const WalletTypeMerchantClosedLoopOffer = 'MERCHANT_CLOSED_LOOP_OFFER';
402
 
403
+ public $wallet_id = false;
404
+ public $wallet_description = false;
405
 
406
  public function __construct( $wallet_type = false, $wallet_id = false, $wallet_description = false ) {
407
  $this->wallet_type = $wallet_type;
414
  public function loadFromGetECResponse( $getECResponse, $wallet_num ) {
415
  $found_any = false;
416
  foreach ( $getECResponse as $index => $value ) {
417
+ if ( ( 'WALLETTYPE' . $wallet_num ) == $index ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
418
  $this->wallet_type = $value;
419
+ $found_any = true;
420
+ } elseif ( ( 'WALLETID' . $wallet_num ) == $index ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
421
  $this->wallet_id = $value;
422
+ $found_any = true;
423
+ } elseif ( ( 'WALLETDESCRIPTION' . $wallet_num ) == $index ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
424
  $this->wallet_description = $value;
425
+ $found_any = true;
426
  }
427
  }
428
 
431
  }
432
 
433
  class PayPal_Checkout_Payer_Details {
434
+ public $phone_number = false;
435
+ public $email = false;
436
+ public $payer_id = false;
437
+ public $payer_status = false;
438
 
439
  const PayerStatusVerified = 'verified';
440
  const PayerStatusUnverified = 'unverified';
441
 
442
+ public $country = false;
443
+ public $business_name = false;
444
+ public $first_name = false;
445
+ public $last_name = false;
446
+ public $middle_name = false;
447
+ public $suffix = false;
448
 
449
+ public $billing_address = false;
450
 
451
  // Returns true to indicate that the getECResponse array contained variables that were pertinent to this object.
452
  // If not, it returns false to indicate that the caller can destroy this object.
453
  public function loadFromGetECResponse( $getECResponse ) {
454
+ $map = array(
455
  'PHONENUM' => 'phone_number',
456
  'EMAIL' => 'email',
457
  'PAYERID' => 'payer_id',
461
  'FIRSTNAME' => 'first_name',
462
  'MIDDLENAME' => 'middle_name',
463
  'LASTNAME' => 'last_name',
464
+ 'SUFFIX' => 'suffix',
465
  );
466
  $found_any = false;
467
 
471
  foreach ( $getECResponse as $index => $value ) {
472
  if ( array_key_exists( $index, $map ) ) {
473
  $this->{ $map[ $index ] } = $value;
474
+ $found_any = true;
475
  }
476
  if ( preg_match( '/^BILLTONAME|STREET|STREET2|CITY|STATE|ZIP|COUNTRY|COUNTRYNAME|ADDRESSOWNER|ADDRESSSTATUS$/', $index ) ) {
477
  $billing_address_present = true;
501
  // Returns true to indicate that the getECResponse array contained variables that were pertinent to this object.
502
  // If not, it returns false to indicate that the caller can destroy this object.
503
  public function loadFromGetECResponse( $getECResponse ) {
504
+ $map = array(
505
  'GIFTMESSAGE' => 'gift_message',
506
  'GIFTWRAPNAME' => 'gift_wrap_name',
507
  'GIFTRECEIPTENABLE' => 'gift_receipt_enabled',
508
+ 'GIFTWRAPAMOUNT' => 'gift_wrap_amount',
509
  );
510
  $found_any = false;
511
 
512
  foreach ( $getECResponse as $index => $value ) {
513
  if ( array_key_exists( $index, $map ) ) {
514
  $this->{ $map[ $index ] } = $value;
515
+ $found_any = true;
516
  }
517
  }
518
 
includes/class-wc-gateway-ppec-checkout-handler.php CHANGED
@@ -11,16 +11,16 @@ $includes_path = wc_gateway_ppec()->includes_path;
11
 
12
  // TODO: Use spl autoload to require on-demand maybe?
13
 
14
- require_once( $includes_path . 'class-wc-gateway-ppec-settings.php' );
15
- require_once( $includes_path . 'class-wc-gateway-ppec-session-data.php' );
16
- require_once( $includes_path . 'class-wc-gateway-ppec-checkout-details.php' );
17
 
18
- require_once( $includes_path . 'class-wc-gateway-ppec-api-error.php' );
19
- require_once( $includes_path . 'exceptions/class-wc-gateway-ppec-api-exception.php' );
20
- require_once( $includes_path . 'exceptions/class-wc-gateway-ppec-missing-session-exception.php' );
21
 
22
- require_once( $includes_path . 'class-wc-gateway-ppec-payment-details.php' );
23
- require_once( $includes_path . 'class-wc-gateway-ppec-address.php' );
24
 
25
  class WC_Gateway_PPEC_Checkout_Handler {
26
 
@@ -62,7 +62,7 @@ class WC_Gateway_PPEC_Checkout_Handler {
62
  } else {
63
  add_filter( 'woocommerce_get_script_data', array( $this, 'filter_wc_checkout_params' ), 10, 2 );
64
  }
65
- if ( isset( $_GET['startcheckout'] ) && 'true' === $_GET['startcheckout'] ) {
66
  ob_start();
67
  }
68
  }
@@ -89,7 +89,7 @@ class WC_Gateway_PPEC_Checkout_Handler {
89
  *
90
  * @param WC_Checkout $checkout
91
  */
92
- function checkout_init( $checkout ) {
93
  if ( ! $this->has_active_session() ) {
94
  return;
95
  }
@@ -190,14 +190,14 @@ class WC_Gateway_PPEC_Checkout_Handler {
190
  }
191
 
192
  // Make sure the selected payment method is ppec_paypal
193
- if ( ! isset( $_POST['payment_method'] ) || ( 'ppec_paypal' !== $_POST['payment_method'] ) ) {
194
  return;
195
  }
196
 
197
  // Get the buyer details from PayPal
198
  try {
199
  $session = WC()->session->get( 'paypal' );
200
- $token = isset( $_GET['token'] ) ? $_GET['token'] : $session->token;
201
  $checkout_details = $this->get_checkout_details( $token );
202
  } catch ( PayPal_API_Exception $e ) {
203
  wc_add_notice( $e->getMessage(), 'error' );
@@ -240,8 +240,8 @@ class WC_Gateway_PPEC_Checkout_Handler {
240
  * Is hooked to woocommerce_checkout_billing action by checkout_init
241
  */
242
  public function paypal_billing_details() {
243
- $session = WC()->session->get( 'paypal' );
244
- $token = isset( $_GET['token'] ) ? $_GET['token'] : $session->token;
245
  try {
246
  $checkout_details = $this->get_checkout_details( $token );
247
  } catch ( PayPal_API_Exception $e ) {
@@ -255,22 +255,22 @@ class WC_Gateway_PPEC_Checkout_Handler {
255
  $fields = WC()->checkout->get_checkout_fields( 'billing' );
256
  }
257
  ?>
258
- <h3><?php _e( 'Billing details', 'woocommerce-gateway-paypal-express-checkout' ); ?></h3>
259
  <ul>
260
  <?php if ( ! empty( $checkout_details->payer_details->billing_address ) ) : ?>
261
- <li><strong><?php _e( 'Address:', 'woocommerce-gateway-paypal-express-checkout' ) ?></strong></br><?php echo WC()->countries->get_formatted_address( $this->get_mapped_billing_address( $checkout_details ) ); ?></li>
262
  <?php elseif ( ! empty( $checkout_details->payer_details->first_name ) && ! empty( $checkout_details->payer_details->last_name ) ) : ?>
263
- <li><strong><?php _e( 'Name:', 'woocommerce-gateway-paypal-express-checkout' ) ?></strong> <?php echo esc_html( $checkout_details->payer_details->first_name . ' ' . $checkout_details->payer_details->last_name ); ?></li>
264
  <?php endif; ?>
265
 
266
  <?php if ( ! empty( $checkout_details->payer_details->email ) ) : ?>
267
- <li><strong><?php _e( 'Email:', 'woocommerce-gateway-paypal-express-checkout' ) ?></strong> <?php echo esc_html( $checkout_details->payer_details->email ); ?></li>
268
  <?php else : ?>
269
  <li><?php woocommerce_form_field( 'billing_email', $fields['billing_email'], WC()->checkout->get_value( 'billing_email' ) ); ?></li>
270
  <?php endif; ?>
271
 
272
  <?php if ( ! empty( $checkout_details->payer_details->phone_number ) ) : ?>
273
- <li><strong><?php _e( 'Phone:', 'woocommerce-gateway-paypal-express-checkout' ) ?></strong> <?php echo esc_html( $checkout_details->payer_details->phone_number ); ?></li>
274
  <?php elseif ( 'yes' === wc_gateway_ppec()->settings->require_phone_number ) : ?>
275
  <li><?php woocommerce_form_field( 'billing_phone', $fields['billing_phone'], WC()->checkout->get_value( 'billing_phone' ) ); ?></li>
276
  <?php endif; ?>
@@ -294,7 +294,7 @@ class WC_Gateway_PPEC_Checkout_Handler {
294
  if ( $checkout->enable_guest_checkout ) {
295
  ?>
296
  <p class="form-row form-row-wide create-account">
297
- <input class="input-checkbox" id="createaccount" <?php checked( ( true === $checkout->get_value( 'createaccount' ) || ( true === apply_filters( 'woocommerce_create_account_default_checked', false ) ) ), true) ?> type="checkbox" name="createaccount" value="1" /> <label for="createaccount" class="checkbox"><?php _e( 'Create an account?', 'woocommerce-gateway-paypal-express-checkout' ); ?></label>
298
  </p>
299
  <?php
300
  }
@@ -303,7 +303,7 @@ class WC_Gateway_PPEC_Checkout_Handler {
303
  ?>
304
  <div class="create-account">
305
 
306
- <p><?php _e( 'Create an account by entering the information below. If you are a returning customer please login at the top of the page.', 'woocommerce-gateway-paypal-express-checkout' ); ?></p>
307
 
308
  <?php foreach ( $checkout->checkout_fields['account'] as $key => $field ) : ?>
309
 
@@ -316,7 +316,6 @@ class WC_Gateway_PPEC_Checkout_Handler {
316
  </div>
317
  <?php
318
  }
319
-
320
  }
321
  }
322
 
@@ -328,8 +327,8 @@ class WC_Gateway_PPEC_Checkout_Handler {
328
  * Is hooked to woocommerce_checkout_shipping action by checkout_init
329
  */
330
  public function paypal_shipping_details() {
331
- $session = WC()->session->get( 'paypal' );
332
- $token = isset( $_GET['token'] ) ? $_GET['token'] : $session->token;
333
 
334
  try {
335
  $checkout_details = $this->get_checkout_details( $token );
@@ -343,9 +342,9 @@ class WC_Gateway_PPEC_Checkout_Handler {
343
  }
344
 
345
  ?>
346
- <h3><?php _e( 'Shipping details', 'woocommerce-gateway-paypal-express-checkout' ); ?></h3>
347
  <?php
348
- echo WC()->countries->get_formatted_address( $this->get_mapped_shipping_address( $checkout_details ) );
349
  }
350
 
351
  /**
@@ -370,8 +369,8 @@ class WC_Gateway_PPEC_Checkout_Handler {
370
 
371
  if ( ! empty( $checkout_details->payer_details->phone_number ) ) {
372
  $phone = $checkout_details->payer_details->phone_number;
373
- } elseif ( 'yes' === wc_gateway_ppec()->settings->require_phone_number && ! empty( $_POST['billing_phone'] ) ) {
374
- $phone = wc_clean( $_POST['billing_phone'] );
375
  }
376
 
377
  return array(
@@ -403,15 +402,15 @@ class WC_Gateway_PPEC_Checkout_Handler {
403
  $name = explode( ' ', $checkout_details->payments[0]->shipping_address->getName() );
404
  $first_name = array_shift( $name );
405
  $last_name = implode( ' ', $name );
406
- $result = array(
407
- 'first_name' => $first_name,
408
- 'last_name' => $last_name,
409
- 'address_1' => $checkout_details->payments[0]->shipping_address->getStreet1(),
410
- 'address_2' => $checkout_details->payments[0]->shipping_address->getStreet2(),
411
- 'city' => $checkout_details->payments[0]->shipping_address->getCity(),
412
- 'state' => $checkout_details->payments[0]->shipping_address->getState(),
413
- 'postcode' => $checkout_details->payments[0]->shipping_address->getZip(),
414
- 'country' => $checkout_details->payments[0]->shipping_address->getCountry(),
415
  );
416
  if ( ! empty( $checkout_details->payer_details ) && property_exists( $checkout_details->payer_details, 'business_name' ) ) {
417
  $result['company'] = $checkout_details->payer_details->business_name;
@@ -423,6 +422,7 @@ class WC_Gateway_PPEC_Checkout_Handler {
423
  * Checks data is correctly set when returning from PayPal Checkout
424
  */
425
  public function maybe_return_from_paypal() {
 
426
  if (
427
  isset( $_GET['woo-paypal-return'] )
428
  && isset( $_GET['update_subscription_payment_method'] )
@@ -436,7 +436,7 @@ class WC_Gateway_PPEC_Checkout_Handler {
436
  return;
437
  }
438
 
439
- $token = $_GET['token'];
440
  $create_billing_agreement = ! empty( $_GET['create-billing-agreement'] );
441
  $session = WC()->session->get( 'paypal' );
442
 
@@ -450,12 +450,13 @@ class WC_Gateway_PPEC_Checkout_Handler {
450
  $session->token = $token;
451
 
452
  if ( ! empty( $_GET['PayerID'] ) ) {
453
- $session->payer_id = $_GET['PayerID'];
454
  } elseif ( $create_billing_agreement ) {
455
  $session->create_billing_agreement = true;
456
  } else {
457
  return;
458
  }
 
459
 
460
  // Update customer addresses here from PayPal selection so they can be used to calculate local taxes.
461
  $this->update_customer_addresses_from_paypal( $token );
@@ -486,7 +487,7 @@ class WC_Gateway_PPEC_Checkout_Handler {
486
  WC()->cart->empty_cart();
487
 
488
  // Redirect
489
- wp_redirect( $order->get_checkout_order_received_url() );
490
  exit;
491
  }
492
  } catch ( PayPal_API_Exception $e ) {
@@ -566,9 +567,8 @@ class WC_Gateway_PPEC_Checkout_Handler {
566
  unset( $gateways[ $id ] );
567
  }
568
  }
569
-
570
- // If using PayPal standard (this is admin choice) we don't need to also show PayPal EC on checkout.
571
  } elseif ( is_checkout() && ( isset( $gateways['paypal'] ) || 'no' === wc_gateway_ppec()->settings->mark_enabled ) ) {
 
572
  unset( $gateways['ppec_paypal'] );
573
  }
574
 
@@ -609,6 +609,7 @@ class WC_Gateway_PPEC_Checkout_Handler {
609
  * Clears the session data and display notice.
610
  */
611
  public function maybe_cancel_checkout_with_paypal() {
 
612
  if (
613
  isset( $_GET['update_subscription_payment_method'] )
614
  && 'true' === $_GET['update_subscription_payment_method']
@@ -617,11 +618,12 @@ class WC_Gateway_PPEC_Checkout_Handler {
617
  $this->handle_subscription_payment_change_failure();
618
  return;
619
  }
 
620
 
621
- if ( is_cart() && ! empty( $_GET['wc-gateway-ppec-clear-session'] ) ) {
622
  $this->maybe_clear_session_data();
623
 
624
- $notice = __( 'You have cancelled Checkout with PayPal. Please try to process your order again.', 'woocommerce-gateway-paypal-express-checkout' );
625
  if ( ! wc_has_notice( $notice, 'notice' ) ) {
626
  wc_add_notice( $notice, 'notice' );
627
  }
@@ -722,8 +724,9 @@ class WC_Gateway_PPEC_Checkout_Handler {
722
  * @return string Redirect URL.
723
  */
724
  protected function start_checkout( $context_args, $session_data_args ) {
725
- $settings = wc_gateway_ppec()->settings;
726
- $client = wc_gateway_ppec()->client;
 
727
  $context_args['create_billing_agreement'] = $this->needs_billing_agreement_creation( $context_args );
728
 
729
  $params = $client->get_set_express_checkout_params( $context_args );
@@ -746,7 +749,7 @@ class WC_Gateway_PPEC_Checkout_Handler {
746
  * @return string Redirect URL.
747
  */
748
  public function start_checkout_from_cart( $skip_checkout = true ) {
749
- $settings = wc_gateway_ppec()->settings;
750
 
751
  $context_args = array(
752
  'skip_checkout' => $skip_checkout,
@@ -770,7 +773,7 @@ class WC_Gateway_PPEC_Checkout_Handler {
770
  * @return string Redirect URL.
771
  */
772
  public function start_checkout_from_order( $order_id, $use_ppc ) {
773
- $settings = wc_gateway_ppec()->settings;
774
 
775
  $context_args = array(
776
  'skip_checkout' => false,
@@ -830,8 +833,8 @@ class WC_Gateway_PPEC_Checkout_Handler {
830
  return $this->_checkout_details;
831
  }
832
 
833
- if ( false === $token && ! empty( $_GET['token'] ) ) {
834
- $token = $_GET['token'];
835
  }
836
 
837
  $client = wc_gateway_ppec()->client;
@@ -871,7 +874,7 @@ class WC_Gateway_PPEC_Checkout_Handler {
871
  throw new PayPal_API_Exception( $resp );
872
  }
873
 
874
- $old_wc = version_compare( WC_VERSION, '3.0', '<' );
875
  $order_id = $old_wc ? $order->id : $order->get_id();
876
  if ( $old_wc ) {
877
  update_post_meta( $order_id, '_ppec_billing_agreement_id', $resp['BILLINGAGREEMENTID'] );
@@ -903,14 +906,16 @@ class WC_Gateway_PPEC_Checkout_Handler {
903
  throw new PayPal_Missing_Session_Exception();
904
  }
905
 
906
- $client = wc_gateway_ppec()->client;
907
- $old_wc = version_compare( WC_VERSION, '3.0', '<' );
908
  $order_id = $old_wc ? $order->id : $order->get_id();
909
- $params = $client->get_do_express_checkout_params( array(
910
- 'order_id' => $order_id,
911
- 'token' => $token,
912
- 'payer_id' => $payer_id,
913
- ) );
 
 
914
 
915
  $response = $client->do_express_checkout_payment( $params );
916
 
@@ -943,13 +948,14 @@ class WC_Gateway_PPEC_Checkout_Handler {
943
  // Handle $payment response
944
  if ( 'completed' === strtolower( $payment->payment_status ) ) {
945
  $order->payment_complete( $payment->transaction_id );
946
- if ( isset( $payment->fee_amount ) ){
947
  wc_gateway_ppec_set_transaction_fee( $order, $payment->fee_amount );
948
  }
949
  } else {
950
  if ( 'authorization' === $payment->pending_reason ) {
951
  $order->update_status( 'on-hold', __( 'Payment authorized. Change payment status to processing or complete to capture funds.', 'woocommerce-gateway-paypal-express-checkout' ) );
952
  } else {
 
953
  $order->update_status( 'on-hold', sprintf( __( 'Payment pending (%s).', 'woocommerce-gateway-paypal-express-checkout' ), $payment->pending_reason ) );
954
  }
955
  if ( $old_wc ) {
@@ -972,13 +978,13 @@ class WC_Gateway_PPEC_Checkout_Handler {
972
  * @return mixed
973
  */
974
  public function maybe_add_shipping_information( $packages ) {
975
- if ( empty( $_GET['woo-paypal-return'] ) || empty( $_GET['token'] ) || empty( $_GET['PayerID'] ) ) {
976
  return $packages;
977
  }
978
 
979
  // Shipping details from PayPal
980
  try {
981
- $checkout_details = $this->get_checkout_details( wc_clean( $_GET['token'] ) );
982
  } catch ( PayPal_API_Exception $e ) {
983
  return $packages;
984
  }
@@ -1087,8 +1093,8 @@ class WC_Gateway_PPEC_Checkout_Handler {
1087
  $params['wc_ajax_url'] = remove_query_arg( 'wc-ajax', $params['wc_ajax_url'] );
1088
 
1089
  foreach ( $fields as $field ) {
1090
- if ( ! empty( $_GET[ $field ] ) ) {
1091
- $params['wc_ajax_url'] = add_query_arg( $field, $_GET[ $field ], $params['wc_ajax_url'] );
1092
  }
1093
  }
1094
 
@@ -1110,8 +1116,8 @@ class WC_Gateway_PPEC_Checkout_Handler {
1110
  try {
1111
  $session = WC()->session->get( 'paypal' );
1112
 
1113
- if ( isset( $_GET['token'] ) ) {
1114
- $token = sanitize_text_field( wp_unslash( $_GET['token'] ) );
1115
  } elseif ( isset( $session->token ) ) {
1116
  $token = $session->token;
1117
  }
11
 
12
  // TODO: Use spl autoload to require on-demand maybe?
13
 
14
+ require_once $includes_path . 'class-wc-gateway-ppec-settings.php';
15
+ require_once $includes_path . 'class-wc-gateway-ppec-session-data.php';
16
+ require_once $includes_path . 'class-wc-gateway-ppec-checkout-details.php';
17
 
18
+ require_once $includes_path . 'class-wc-gateway-ppec-api-error.php';
19
+ require_once $includes_path . 'exceptions/class-wc-gateway-ppec-api-exception.php';
20
+ require_once $includes_path . 'exceptions/class-wc-gateway-ppec-missing-session-exception.php';
21
 
22
+ require_once $includes_path . 'class-wc-gateway-ppec-payment-details.php';
23
+ require_once $includes_path . 'class-wc-gateway-ppec-address.php';
24
 
25
  class WC_Gateway_PPEC_Checkout_Handler {
26
 
62
  } else {
63
  add_filter( 'woocommerce_get_script_data', array( $this, 'filter_wc_checkout_params' ), 10, 2 );
64
  }
65
+ if ( isset( $_GET['startcheckout'] ) && 'true' === $_GET['startcheckout'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
66
  ob_start();
67
  }
68
  }
89
  *
90
  * @param WC_Checkout $checkout
91
  */
92
+ public function checkout_init( $checkout ) {
93
  if ( ! $this->has_active_session() ) {
94
  return;
95
  }
190
  }
191
 
192
  // Make sure the selected payment method is ppec_paypal
193
+ if ( ! isset( $_POST['payment_method'] ) || ( 'ppec_paypal' !== $_POST['payment_method'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
194
  return;
195
  }
196
 
197
  // Get the buyer details from PayPal
198
  try {
199
  $session = WC()->session->get( 'paypal' );
200
+ $token = isset( $_GET['token'] ) ? $_GET['token'] : $session->token; // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
201
  $checkout_details = $this->get_checkout_details( $token );
202
  } catch ( PayPal_API_Exception $e ) {
203
  wc_add_notice( $e->getMessage(), 'error' );
240
  * Is hooked to woocommerce_checkout_billing action by checkout_init
241
  */
242
  public function paypal_billing_details() {
243
+ $session = WC()->session->get( 'paypal' );
244
+ $token = isset( $_GET['token'] ) ? $_GET['token'] : $session->token; // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
245
  try {
246
  $checkout_details = $this->get_checkout_details( $token );
247
  } catch ( PayPal_API_Exception $e ) {
255
  $fields = WC()->checkout->get_checkout_fields( 'billing' );
256
  }
257
  ?>
258
+ <h3><?php esc_html_e( 'Billing details', 'woocommerce-gateway-paypal-express-checkout' ); ?></h3>
259
  <ul>
260
  <?php if ( ! empty( $checkout_details->payer_details->billing_address ) ) : ?>
261
+ <li><strong><?php esc_html_e( 'Address:', 'woocommerce-gateway-paypal-express-checkout' ); ?></strong></br><?php echo WC()->countries->get_formatted_address( $this->get_mapped_billing_address( $checkout_details ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></li>
262
  <?php elseif ( ! empty( $checkout_details->payer_details->first_name ) && ! empty( $checkout_details->payer_details->last_name ) ) : ?>
263
+ <li><strong><?php esc_html_e( 'Name:', 'woocommerce-gateway-paypal-express-checkout' ); ?></strong> <?php echo esc_html( $checkout_details->payer_details->first_name . ' ' . $checkout_details->payer_details->last_name ); ?></li>
264
  <?php endif; ?>
265
 
266
  <?php if ( ! empty( $checkout_details->payer_details->email ) ) : ?>
267
+ <li><strong><?php esc_html_e( 'Email:', 'woocommerce-gateway-paypal-express-checkout' ); ?></strong> <?php echo esc_html( $checkout_details->payer_details->email ); ?></li>
268
  <?php else : ?>
269
  <li><?php woocommerce_form_field( 'billing_email', $fields['billing_email'], WC()->checkout->get_value( 'billing_email' ) ); ?></li>
270
  <?php endif; ?>
271
 
272
  <?php if ( ! empty( $checkout_details->payer_details->phone_number ) ) : ?>
273
+ <li><strong><?php esc_html_e( 'Phone:', 'woocommerce-gateway-paypal-express-checkout' ); ?></strong> <?php echo esc_html( $checkout_details->payer_details->phone_number ); ?></li>
274
  <?php elseif ( 'yes' === wc_gateway_ppec()->settings->require_phone_number ) : ?>
275
  <li><?php woocommerce_form_field( 'billing_phone', $fields['billing_phone'], WC()->checkout->get_value( 'billing_phone' ) ); ?></li>
276
  <?php endif; ?>
294
  if ( $checkout->enable_guest_checkout ) {
295
  ?>
296
  <p class="form-row form-row-wide create-account">
297
+ <input class="input-checkbox" id="createaccount" <?php checked( ( true === $checkout->get_value( 'createaccount' ) || ( true === apply_filters( 'woocommerce_create_account_default_checked', false ) ) ), true ); ?> type="checkbox" name="createaccount" value="1" /> <label for="createaccount" class="checkbox"><?php esc_html_e( 'Create an account?', 'woocommerce-gateway-paypal-express-checkout' ); ?></label>
298
  </p>
299
  <?php
300
  }
303
  ?>
304
  <div class="create-account">
305
 
306
+ <p><?php esc_html_e( 'Create an account by entering the information below. If you are a returning customer please login at the top of the page.', 'woocommerce-gateway-paypal-express-checkout' ); ?></p>
307
 
308
  <?php foreach ( $checkout->checkout_fields['account'] as $key => $field ) : ?>
309
 
316
  </div>
317
  <?php
318
  }
 
319
  }
320
  }
321
 
327
  * Is hooked to woocommerce_checkout_shipping action by checkout_init
328
  */
329
  public function paypal_shipping_details() {
330
+ $session = WC()->session->get( 'paypal' );
331
+ $token = isset( $_GET['token'] ) ? $_GET['token'] : $session->token; // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
332
 
333
  try {
334
  $checkout_details = $this->get_checkout_details( $token );
342
  }
343
 
344
  ?>
345
+ <h3><?php esc_html_e( 'Shipping details', 'woocommerce-gateway-paypal-express-checkout' ); ?></h3>
346
  <?php
347
+ echo WC()->countries->get_formatted_address( $this->get_mapped_shipping_address( $checkout_details ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
348
  }
349
 
350
  /**
369
 
370
  if ( ! empty( $checkout_details->payer_details->phone_number ) ) {
371
  $phone = $checkout_details->payer_details->phone_number;
372
+ } elseif ( 'yes' === wc_gateway_ppec()->settings->require_phone_number && ! empty( $_POST['billing_phone'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
373
+ $phone = wc_clean( $_POST['billing_phone'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
374
  }
375
 
376
  return array(
402
  $name = explode( ' ', $checkout_details->payments[0]->shipping_address->getName() );
403
  $first_name = array_shift( $name );
404
  $last_name = implode( ' ', $name );
405
+ $result = array(
406
+ 'first_name' => $first_name,
407
+ 'last_name' => $last_name,
408
+ 'address_1' => $checkout_details->payments[0]->shipping_address->getStreet1(),
409
+ 'address_2' => $checkout_details->payments[0]->shipping_address->getStreet2(),
410
+ 'city' => $checkout_details->payments[0]->shipping_address->getCity(),
411
+ 'state' => $checkout_details->payments[0]->shipping_address->getState(),
412
+ 'postcode' => $checkout_details->payments[0]->shipping_address->getZip(),
413
+ 'country' => $checkout_details->payments[0]->shipping_address->getCountry(),
414
  );
415
  if ( ! empty( $checkout_details->payer_details ) && property_exists( $checkout_details->payer_details, 'business_name' ) ) {
416
  $result['company'] = $checkout_details->payer_details->business_name;
422
  * Checks data is correctly set when returning from PayPal Checkout
423
  */
424
  public function maybe_return_from_paypal() {
425
+ // phpcs:disable WordPress.Security.NonceVerification.Recommended
426
  if (
427
  isset( $_GET['woo-paypal-return'] )
428
  && isset( $_GET['update_subscription_payment_method'] )
436
  return;
437
  }
438
 
439
+ $token = $_GET['token']; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
440
  $create_billing_agreement = ! empty( $_GET['create-billing-agreement'] );
441
  $session = WC()->session->get( 'paypal' );
442
 
450
  $session->token = $token;
451
 
452
  if ( ! empty( $_GET['PayerID'] ) ) {
453
+ $session->payer_id = $_GET['PayerID']; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
454
  } elseif ( $create_billing_agreement ) {
455
  $session->create_billing_agreement = true;
456
  } else {
457
  return;
458
  }
459
+ // phpcs:enable
460
 
461
  // Update customer addresses here from PayPal selection so they can be used to calculate local taxes.
462
  $this->update_customer_addresses_from_paypal( $token );
487
  WC()->cart->empty_cart();
488
 
489
  // Redirect
490
+ wp_redirect( $order->get_checkout_order_received_url() ); // phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect
491
  exit;
492
  }
493
  } catch ( PayPal_API_Exception $e ) {
567
  unset( $gateways[ $id ] );
568
  }
569
  }
 
 
570
  } elseif ( is_checkout() && ( isset( $gateways['paypal'] ) || 'no' === wc_gateway_ppec()->settings->mark_enabled ) ) {
571
+ // If using PayPal standard (this is admin choice) we don't need to also show PayPal EC on checkout.
572
  unset( $gateways['ppec_paypal'] );
573
  }
574
 
609
  * Clears the session data and display notice.
610
  */
611
  public function maybe_cancel_checkout_with_paypal() {
612
+ // phpcs:disable WordPress.Security.NonceVerification.Recommended
613
  if (
614
  isset( $_GET['update_subscription_payment_method'] )
615
  && 'true' === $_GET['update_subscription_payment_method']
618
  $this->handle_subscription_payment_change_failure();
619
  return;
620
  }
621
+ // phpcs:enable
622
 
623
+ if ( is_cart() && ! empty( $_GET['wc-gateway-ppec-clear-session'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
624
  $this->maybe_clear_session_data();
625
 
626
+ $notice = __( 'You have cancelled Checkout with PayPal. Please try to process your order again.', 'woocommerce-gateway-paypal-express-checkout' );
627
  if ( ! wc_has_notice( $notice, 'notice' ) ) {
628
  wc_add_notice( $notice, 'notice' );
629
  }
724
  * @return string Redirect URL.
725
  */
726
  protected function start_checkout( $context_args, $session_data_args ) {
727
+ $settings = wc_gateway_ppec()->settings;
728
+ $client = wc_gateway_ppec()->client;
729
+
730
  $context_args['create_billing_agreement'] = $this->needs_billing_agreement_creation( $context_args );
731
 
732
  $params = $client->get_set_express_checkout_params( $context_args );
749
  * @return string Redirect URL.
750
  */
751
  public function start_checkout_from_cart( $skip_checkout = true ) {
752
+ $settings = wc_gateway_ppec()->settings;
753
 
754
  $context_args = array(
755
  'skip_checkout' => $skip_checkout,
773
  * @return string Redirect URL.
774
  */
775
  public function start_checkout_from_order( $order_id, $use_ppc ) {
776
+ $settings = wc_gateway_ppec()->settings;
777
 
778
  $context_args = array(
779
  'skip_checkout' => false,
833
  return $this->_checkout_details;
834
  }
835
 
836
+ if ( false === $token && ! empty( $_GET['token'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
837
+ $token = $_GET['token']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
838
  }
839
 
840
  $client = wc_gateway_ppec()->client;
874
  throw new PayPal_API_Exception( $resp );
875
  }
876
 
877
+ $old_wc = version_compare( WC_VERSION, '3.0', '<' );
878
  $order_id = $old_wc ? $order->id : $order->get_id();
879
  if ( $old_wc ) {
880
  update_post_meta( $order_id, '_ppec_billing_agreement_id', $resp['BILLINGAGREEMENTID'] );
906
  throw new PayPal_Missing_Session_Exception();
907
  }
908
 
909
+ $client = wc_gateway_ppec()->client;
910
+ $old_wc = version_compare( WC_VERSION, '3.0', '<' );
911
  $order_id = $old_wc ? $order->id : $order->get_id();
912
+ $params = $client->get_do_express_checkout_params(
913
+ array(
914
+ 'order_id' => $order_id,
915
+ 'token' => $token,
916
+ 'payer_id' => $payer_id,
917
+ )
918
+ );
919
 
920
  $response = $client->do_express_checkout_payment( $params );
921
 
948
  // Handle $payment response
949
  if ( 'completed' === strtolower( $payment->payment_status ) ) {
950
  $order->payment_complete( $payment->transaction_id );
951
+ if ( isset( $payment->fee_amount ) ) {
952
  wc_gateway_ppec_set_transaction_fee( $order, $payment->fee_amount );
953
  }
954
  } else {
955
  if ( 'authorization' === $payment->pending_reason ) {
956
  $order->update_status( 'on-hold', __( 'Payment authorized. Change payment status to processing or complete to capture funds.', 'woocommerce-gateway-paypal-express-checkout' ) );
957
  } else {
958
+ // Translators: placeholder is a reason (from PayPal) for the payment to be pending.
959
  $order->update_status( 'on-hold', sprintf( __( 'Payment pending (%s).', 'woocommerce-gateway-paypal-express-checkout' ), $payment->pending_reason ) );
960
  }
961
  if ( $old_wc ) {
978
  * @return mixed
979
  */
980
  public function maybe_add_shipping_information( $packages ) {
981
+ if ( empty( $_GET['woo-paypal-return'] ) || empty( $_GET['token'] ) || empty( $_GET['PayerID'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
982
  return $packages;
983
  }
984
 
985
  // Shipping details from PayPal
986
  try {
987
+ $checkout_details = $this->get_checkout_details( wc_clean( $_GET['token'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
988
  } catch ( PayPal_API_Exception $e ) {
989
  return $packages;
990
  }
1093
  $params['wc_ajax_url'] = remove_query_arg( 'wc-ajax', $params['wc_ajax_url'] );
1094
 
1095
  foreach ( $fields as $field ) {
1096
+ if ( ! empty( $_GET[ $field ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1097
+ $params['wc_ajax_url'] = add_query_arg( $field, $_GET[ $field ], $params['wc_ajax_url'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
1098
  }
1099
  }
1100
 
1116
  try {
1117
  $session = WC()->session->get( 'paypal' );
1118
 
1119
+ if ( isset( $_GET['token'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1120
+ $token = sanitize_text_field( wp_unslash( $_GET['token'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1121
  } elseif ( isset( $session->token ) ) {
1122
  $token = $session->token;
1123
  }
includes/class-wc-gateway-ppec-client-credential-certificate.php CHANGED
@@ -62,11 +62,11 @@ class WC_Gateway_PPEC_Client_Credential_Certificate extends WC_Gateway_PPEC_Clie
62
  $password = uniqid();
63
  $certificate_file = $this->_maybe_create_certificate_file( $password );
64
 
65
- if ( false === curl_setopt( $handle, CURLOPT_SSLCERT, $certificate_file ) ) {
66
  throw new Exception( __( 'Unable to accept certificate during cURL configuration', 'woocommerce-gateway-paypal-express-checkout' ), WC_Gateway_PPEC_Client::INVALID_ENVIRONMENT_ERROR );
67
  }
68
 
69
- if ( $this->_use_secure_transport() && false === curl_setopt( $handle, CURLOPT_SSLCERTPASSWD, $password ) ) {
70
  throw new Exception( __( 'Unable to accept certificate password during cURL configuration', 'woocommerce-gateway-paypal-express-checkout' ), WC_Gateway_PPEC_Client::INVALID_ENVIRONMENT_ERROR );
71
  }
72
  }
@@ -84,6 +84,7 @@ class WC_Gateway_PPEC_Client_Credential_Certificate extends WC_Gateway_PPEC_Clie
84
  protected function _maybe_create_certificate_file( $password ) {
85
  $temp_file = tempnam( sys_get_temp_dir(), 'pptmp_' );
86
  if ( ! $temp_file ) {
 
87
  throw new Exception( sprintf( __( 'Unable to write certificate file %s during cURL configuration', 'woocommerce-gateway-paypal-express-checkout' ), $temp_file ), WC_Gateway_PPEC_Client::INVALID_ENVIRONMENT_ERROR );
88
  }
89
 
@@ -129,7 +130,8 @@ class WC_Gateway_PPEC_Client_Credential_Certificate extends WC_Gateway_PPEC_Clie
129
  * @return void
130
  */
131
  protected function _maybe_create_non_secure_certificate_file( $temp_file ) {
132
- if ( false === file_put_contents( $temp_file, $this->_certificate ) ) {
 
133
  throw new Exception( sprintf( __( 'Unable to write certificate file %s during cURL configuration', 'woocommerce-gateway-paypal-express-checkout' ), $temp_file ), WC_Gateway_PPEC_Client::INVALID_ENVIRONMENT_ERROR );
134
  }
135
  }
62
  $password = uniqid();
63
  $certificate_file = $this->_maybe_create_certificate_file( $password );
64
 
65
+ if ( false === curl_setopt( $handle, CURLOPT_SSLCERT, $certificate_file ) ) { // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt
66
  throw new Exception( __( 'Unable to accept certificate during cURL configuration', 'woocommerce-gateway-paypal-express-checkout' ), WC_Gateway_PPEC_Client::INVALID_ENVIRONMENT_ERROR );
67
  }
68
 
69
+ if ( $this->_use_secure_transport() && false === curl_setopt( $handle, CURLOPT_SSLCERTPASSWD, $password ) ) { // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt
70
  throw new Exception( __( 'Unable to accept certificate password during cURL configuration', 'woocommerce-gateway-paypal-express-checkout' ), WC_Gateway_PPEC_Client::INVALID_ENVIRONMENT_ERROR );
71
  }
72
  }
84
  protected function _maybe_create_certificate_file( $password ) {
85
  $temp_file = tempnam( sys_get_temp_dir(), 'pptmp_' );
86
  if ( ! $temp_file ) {
87
+ // Translators: %s is a filepath.
88
  throw new Exception( sprintf( __( 'Unable to write certificate file %s during cURL configuration', 'woocommerce-gateway-paypal-express-checkout' ), $temp_file ), WC_Gateway_PPEC_Client::INVALID_ENVIRONMENT_ERROR );
89
  }
90
 
130
  * @return void
131
  */
132
  protected function _maybe_create_non_secure_certificate_file( $temp_file ) {
133
+ if ( false === file_put_contents( $temp_file, $this->_certificate ) ) { // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_file_put_contents
134
+ // Translators: %s is a filepath.
135
  throw new Exception( sprintf( __( 'Unable to write certificate file %s during cURL configuration', 'woocommerce-gateway-paypal-express-checkout' ), $temp_file ), WC_Gateway_PPEC_Client::INVALID_ENVIRONMENT_ERROR );
136
  }
137
  }
includes/class-wc-gateway-ppec-client-credential-signature.php CHANGED
@@ -32,7 +32,7 @@ class WC_Gateway_PPEC_Client_Credential_Signature extends WC_Gateway_PPEC_Client
32
  * {@inheritdoc}
33
  */
34
  public function get_request_params() {
35
- $params = parent::get_request_params();
36
  $params['SIGNATURE'] = $this->_signature;
37
 
38
  return $params;
32
  * {@inheritdoc}
33
  */
34
  public function get_request_params() {
35
+ $params = parent::get_request_params();
36
  $params['SIGNATURE'] = $this->_signature;
37
 
38
  return $params;
includes/class-wc-gateway-ppec-client.php CHANGED
@@ -61,7 +61,8 @@ class WC_Gateway_PPEC_Client {
61
  public function get_payer_id() {
62
  $option_key = 'woocommerce_ppec_payer_id_' . $this->_environment . '_' . md5( $this->_credential->get_username() . ':' . $this->_credential->get_password() );
63
 
64
- if ( $payer_id = get_option( $option_key ) ) {
 
65
  return $payer_id;
66
  } else {
67
  $result = $this->get_pal_details();
@@ -81,7 +82,7 @@ class WC_Gateway_PPEC_Client {
81
  * @param string $environment Environment. Either 'live' or 'sandbox'
82
  */
83
  public function set_environment( $environment ) {
84
- if ( ! in_array( $environment, array( 'live', 'sandbox' ) ) ) {
85
  $environment = 'live';
86
  }
87
 
@@ -128,7 +129,7 @@ class WC_Gateway_PPEC_Client {
128
  // For cURL transport.
129
  add_action( 'http_api_curl', array( $this->_credential, 'configure_curl' ), 10, 3 );
130
 
131
- wc_gateway_ppec_log( sprintf( '%s: remote request to %s with params: %s', __METHOD__, $this->get_endpoint(), print_r( $body, true ) ) );
132
 
133
  $resp = wp_safe_remote_post( $this->get_endpoint(), $args );
134
 
@@ -147,7 +148,7 @@ class WC_Gateway_PPEC_Client {
147
  'L_SEVERITYCODE0' => 'Error',
148
  );
149
 
150
- wc_gateway_ppec_log( sprintf( '%s: returns error: %s', __METHOD__, print_r( $error, true ) ) );
151
 
152
  return $error;
153
  }
@@ -170,7 +171,7 @@ class WC_Gateway_PPEC_Client {
170
  throw new Exception( __( 'Invalid credential object', 'woocommerce-gateway-paypal-express-checkout' ), self::INVALID_CREDENTIAL_ERROR );
171
  }
172
 
173
- if ( ! in_array( $this->_environment, array( 'live', 'sandbox' ) ) ) {
174
  throw new Exception( __( 'Invalid environment', 'woocommerce-gateway-paypal-express-checkout' ), self::INVALID_ENVIRONMENT_ERROR );
175
  }
176
  }
@@ -188,6 +189,7 @@ class WC_Gateway_PPEC_Client {
188
  */
189
  protected function _process_response( $response ) {
190
  if ( is_wp_error( $response ) ) {
 
191
  throw new Exception( sprintf( __( 'An error occurred while trying to connect to PayPal: %s', 'woocommerce-gateway-paypal-express-checkout' ), $response->get_error_message() ), self::REQUEST_ERROR );
192
  }
193
 
@@ -197,7 +199,7 @@ class WC_Gateway_PPEC_Client {
197
  throw new Exception( __( 'Malformed response received from PayPal', 'woocommerce-gateway-paypal-express-checkout' ), self::REQUEST_ERROR );
198
  }
199
 
200
- wc_gateway_ppec_log( sprintf( '%s: acknowleged response body: %s', __METHOD__, print_r( $result, true ) ) );
201
 
202
  remove_action( 'http_api_curl', array( $this->_credential, 'configure_curl' ), 10 );
203
 
@@ -250,7 +252,7 @@ class WC_Gateway_PPEC_Client {
250
  $params = array();
251
  $logo_url_or_id = $settings->logo_image_url;
252
  $header_url_or_id = $settings->header_image_url;
253
- $params['LOGOIMG'] = filter_var( $logo_url_or_id, FILTER_VALIDATE_URL ) ? $logo_url_or_id : wp_get_attachment_image_url( $logo_url_or_id, 'thumbnail' );
254
  $params['HDRIMG'] = filter_var( $header_url_or_id, FILTER_VALIDATE_URL ) ? $header_url_or_id : wp_get_attachment_image_url( $header_url_or_id, 'thumbnail' );
255
  $params['PAGESTYLE'] = $settings->page_style;
256
  $params['BRANDNAME'] = $settings->get_brand_name();
@@ -266,7 +268,7 @@ class WC_Gateway_PPEC_Client {
266
  $params['ADDROVERRIDE'] = '1';
267
  }
268
 
269
- if ( in_array( $settings->landing_page, array( 'Billing', 'Login' ) ) ) {
270
  $params['LANDINGPAGE'] = $settings->landing_page;
271
  }
272
 
@@ -298,12 +300,12 @@ class WC_Gateway_PPEC_Client {
298
  $params = array_merge(
299
  $params,
300
  array(
301
- 'PAYMENTREQUEST_0_AMT' => $details['order_total'],
302
- 'PAYMENTREQUEST_0_ITEMAMT' => $details['total_item_amount'],
303
- 'PAYMENTREQUEST_0_SHIPPINGAMT' => $details['shipping'],
304
- 'PAYMENTREQUEST_0_TAXAMT' => $details['order_tax'],
305
- 'PAYMENTREQUEST_0_SHIPDISCAMT' => $details['ship_discount_amount'],
306
- 'NOSHIPPING' => WC_Gateway_PPEC_Plugin::needs_shipping() ? 0 : 1,
307
  )
308
  );
309
 
@@ -329,7 +331,7 @@ class WC_Gateway_PPEC_Client {
329
  foreach ( $details['items'] as $line_item_key => $values ) {
330
  $line_item_params = array(
331
  'L_PAYMENTREQUEST_0_NAME' . $count => $values['name'],
332
- 'L_PAYMENTREQUEST_0_DESC' . $count => ! empty( $values['description'] ) ? substr( strip_tags( $values['description'] ), 0, 127 ) : '',
333
  'L_PAYMENTREQUEST_0_QTY' . $count => $values['quantity'],
334
  'L_PAYMENTREQUEST_0_AMT' . $count => $values['amount'],
335
  );
@@ -370,9 +372,9 @@ class WC_Gateway_PPEC_Client {
370
  $query_args['create-billing-agreement'] = 'true';
371
  }
372
 
373
- $url = add_query_arg( $query_args, wc_get_checkout_url() );
374
  $order_id = $context_args['order_id'];
375
- return apply_filters( 'woocommerce_paypal_express_checkout_set_express_checkout_params_get_return_url', $url, $order_id);
376
  }
377
 
378
  /**
@@ -385,7 +387,7 @@ class WC_Gateway_PPEC_Client {
385
  * @return string Cancel URL
386
  */
387
  protected function _get_cancel_url( $context_args ) {
388
- $url = add_query_arg( 'woo-paypal-cancel', 'true', wc_get_cart_url() );
389
  $order_id = $context_args['order_id'];
390
  return apply_filters( 'woocommerce_paypal_express_checkout_set_express_checkout_params_get_cancel_url', $url, $order_id );
391
  }
@@ -398,11 +400,11 @@ class WC_Gateway_PPEC_Client {
398
  * @return string Billing agreement description
399
  */
400
  protected function _get_billing_agreement_description() {
401
- /* translators: placeholder is blogname */
402
- $description = sprintf( _x( 'Orders with %s', 'data sent to PayPal', 'woocommerce-subscriptions' ), get_bloginfo( 'name' ) );
403
 
404
- if ( strlen( $description ) > 127 ) {
405
- $description = substr( $description, 0, 124 ) . '...';
406
  }
407
 
408
  return html_entity_decode( $description, ENT_NOQUOTES, 'UTF-8' );
@@ -442,10 +444,10 @@ class WC_Gateway_PPEC_Client {
442
  $settings = wc_gateway_ppec()->settings;
443
  $decimals = $settings->get_number_of_decimal_digits();
444
 
445
- return array(
446
- 'name' => 'Discount',
447
- 'quantity' => 1,
448
- 'amount' => '-' . round( $amount, $decimals ),
449
  );
450
  }
451
 
@@ -461,7 +463,7 @@ class WC_Gateway_PPEC_Client {
461
  */
462
  protected function _get_details_from_cart() {
463
  $settings = wc_gateway_ppec()->settings;
464
- $old_wc = version_compare( WC_VERSION, '3.0', '<' );
465
 
466
  WC()->cart->calculate_totals();
467
 
@@ -494,7 +496,7 @@ class WC_Gateway_PPEC_Client {
494
 
495
  $items = array();
496
  foreach ( WC()->cart->cart_contents as $cart_item_key => $values ) {
497
- $amount = round( $values['line_subtotal'] / $values['quantity'] , $decimals );
498
 
499
  if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
500
  $name = $values['data']->post->post_title;
@@ -517,7 +519,7 @@ class WC_Gateway_PPEC_Client {
517
  }
518
 
519
  foreach ( WC()->cart->get_fees() as $fee_key => $fee_values ) {
520
- $item = array(
521
  'name' => $fee_values->name,
522
  'description' => '',
523
  'quantity' => 1,
@@ -543,7 +545,7 @@ class WC_Gateway_PPEC_Client {
543
 
544
  $rounded_total = 0;
545
  foreach ( WC()->cart->cart_contents as $cart_item_key => $values ) {
546
- $amount = round( $values['line_subtotal'] / $values['quantity'] , $decimals );
547
  $rounded_total += round( $amount * $values['quantity'], $decimals );
548
  }
549
 
@@ -580,7 +582,7 @@ class WC_Gateway_PPEC_Client {
580
  // the difference.
581
  $diff = 0;
582
 
583
- if ( $details['total_item_amount'] + $discounts != $rounded_total ) {
584
  if ( 'add' === $settings->get_subtotal_mismatch_behavior() ) {
585
  // Add line item to make up different between WooCommerce
586
  // calculations and PayPal calculations.
@@ -600,35 +602,35 @@ class WC_Gateway_PPEC_Client {
600
 
601
  // Enter discount shenanigans. Item total cannot be 0 so make modifications
602
  // accordingly.
603
- if ( $details['total_item_amount'] == 0 ) {
604
  // Omit line items altogether.
605
  unset( $details['items'] );
606
- } else if ( $discounts > 0 && 0 < $details['total_item_amount'] && ! empty( $details['items'] ) ) {
607
  // Else if there is discount, add them to the line-items
608
- $details['items'][] = $this->_get_extra_discount_line_item($discounts);
609
  }
610
 
611
  $details['ship_discount_amount'] = 0;
612
 
613
  // AMT
614
- $details['order_total'] = round( $details['order_total'], $decimals );
615
 
616
  // ITEMAMT
617
  $details['total_item_amount'] = round( $details['total_item_amount'], $decimals );
618
 
619
  // If the totals don't line up, adjust the tax to make it work (it's
620
  // probably a tax mismatch).
621
- $wc_order_total = round( $total, $decimals );
622
  $discounted_total = $details['order_total'];
623
 
624
- if ( $wc_order_total != $discounted_total ) {
625
  // tax cannot be negative
626
  if ( $discounted_total < $wc_order_total ) {
627
  $details['order_tax'] += $wc_order_total - $discounted_total;
628
- $details['order_tax'] = round( $details['order_tax'], $decimals );
629
  } else {
630
  $details['ship_discount_amount'] += $wc_order_total - $discounted_total;
631
- $details['ship_discount_amount'] = round( $details['ship_discount_amount'], $decimals );
632
  }
633
 
634
  $details['order_total'] = $wc_order_total;
@@ -666,8 +668,8 @@ class WC_Gateway_PPEC_Client {
666
 
667
  protected function _get_total_order_fees( $order ) {
668
  $total = 0;
669
- $fees = $order->get_fees();
670
- foreach( $fees as $fee ) {
671
  $total = $total + $fee->get_amount();
672
  }
673
 
@@ -704,11 +706,12 @@ class WC_Gateway_PPEC_Client {
704
  $details = $this->get_details( $details, $order->get_total_discount(), $rounded_total, $order->get_total() );
705
 
706
  // PayPal shipping address from order.
707
- $shipping_address = new PayPal_Address;
708
 
709
  $old_wc = version_compare( WC_VERSION, '3.0', '<' );
710
 
711
  if ( ( $old_wc && ( $order->shipping_address_1 || $order->shipping_address_2 ) ) || ( ! $old_wc && $order->has_shipping_address() ) ) {
 
712
  $shipping_first_name = $old_wc ? $order->shipping_first_name : $order->get_shipping_first_name();
713
  $shipping_last_name = $old_wc ? $order->shipping_last_name : $order->get_shipping_last_name();
714
  $shipping_address_1 = $old_wc ? $order->shipping_address_1 : $order->get_shipping_address_1();
@@ -717,9 +720,11 @@ class WC_Gateway_PPEC_Client {
717
  $shipping_state = $old_wc ? $order->shipping_state : $order->get_shipping_state();
718
  $shipping_postcode = $old_wc ? $order->shipping_postcode : $order->get_shipping_postcode();
719
  $shipping_country = $old_wc ? $order->shipping_country : $order->get_shipping_country();
 
720
  } else {
721
  // Fallback to billing in case no shipping methods are set. The address returned from PayPal
722
  // will be stored in the order as billing.
 
723
  $shipping_first_name = $old_wc ? $order->billing_first_name : $order->get_billing_first_name();
724
  $shipping_last_name = $old_wc ? $order->billing_last_name : $order->get_billing_last_name();
725
  $shipping_address_1 = $old_wc ? $order->billing_address_1 : $order->get_billing_address_1();
@@ -728,6 +733,7 @@ class WC_Gateway_PPEC_Client {
728
  $shipping_state = $old_wc ? $order->billing_state : $order->get_billing_state();
729
  $shipping_postcode = $old_wc ? $order->billing_postcode : $order->get_billing_postcode();
730
  $shipping_country = $old_wc ? $order->billing_country : $order->get_billing_country();
 
731
  }
732
 
733
  $shipping_address->setName( $shipping_first_name . ' ' . $shipping_last_name );
@@ -763,13 +769,13 @@ class WC_Gateway_PPEC_Client {
763
  protected function _get_address_from_customer() {
764
  $customer = WC()->customer;
765
 
766
- $shipping_address = new PayPal_Address;
767
 
768
  $old_wc = version_compare( WC_VERSION, '3.0', '<' );
769
 
770
  if ( $customer->get_shipping_address() || $customer->get_shipping_address_2() ) {
771
  $shipping_first_name = $old_wc ? $customer->shipping_first_name : $customer->get_shipping_first_name();
772
- $shipping_last_name = $old_wc ? $customer->shipping_last_name : $customer->get_shipping_last_name();
773
  $shipping_address_1 = $customer->get_shipping_address();
774
  $shipping_address_2 = $customer->get_shipping_address_2();
775
  $shipping_city = $customer->get_shipping_city();
@@ -779,6 +785,7 @@ class WC_Gateway_PPEC_Client {
779
  } else {
780
  // Fallback to billing in case no shipping methods are set. The address returned from PayPal
781
  // will be stored in the order as billing.
 
782
  $shipping_first_name = $old_wc ? $customer->billing_first_name : $customer->get_billing_first_name();
783
  $shipping_last_name = $old_wc ? $customer->billing_last_name : $customer->get_billing_last_name();
784
  $shipping_address_1 = $old_wc ? $customer->get_address() : $customer->get_billing_address_1();
@@ -787,6 +794,7 @@ class WC_Gateway_PPEC_Client {
787
  $shipping_state = $old_wc ? $customer->get_state() : $customer->get_billing_state();
788
  $shipping_postcode = $old_wc ? $customer->get_postcode() : $customer->get_billing_postcode();
789
  $shipping_country = $old_wc ? $customer->get_country() : $customer->get_billing_country();
 
790
  }
791
 
792
  $shipping_address->setName( $shipping_first_name . ' ' . $shipping_last_name );
@@ -818,14 +826,14 @@ class WC_Gateway_PPEC_Client {
818
  $items = array();
819
  foreach ( $order->get_items( array( 'line_item', 'fee' ) ) as $cart_item_key => $order_item ) {
820
 
821
- if( 'fee' === $order_item['type']) {
822
- $item = array(
823
  'name' => $order_item['name'],
824
  'quantity' => 1,
825
  'amount' => round( $order_item['line_total'], $decimals ),
826
  );
827
  } else {
828
- $amount = round( $order_item['line_subtotal'] / $order_item['qty'] , $decimals );
829
  $product = version_compare( WC_VERSION, '3.0', '<' ) ? $order->get_product_from_item( $order_item ) : $order_item->get_product();
830
  $item = array(
831
  'name' => $order_item['name'],
@@ -857,15 +865,15 @@ class WC_Gateway_PPEC_Client {
857
 
858
  $rounded_total = 0;
859
  foreach ( $order->get_items( array( 'line_item', 'fee', 'coupon' ) ) as $cart_item_key => $values ) {
860
- if( 'coupon' === $values['type']) {
861
- $amount = round($values['line_total'], $decimals);
862
  $rounded_total -= $amount;
863
  continue;
864
  }
865
- if( 'fee' === $values['type']) {
866
- $amount = round( $values['line_total'], $decimals);
867
  } else {
868
- $amount = round( $values['line_subtotal'] / $values['qty'] , $decimals );
869
  $amount = round( $amount * $values['qty'], $decimals );
870
  }
871
  $rounded_total += $amount;
@@ -920,8 +928,8 @@ class WC_Gateway_PPEC_Client {
920
  * @return array Params for DoExpressCheckoutPayment call
921
  */
922
  public function get_do_express_checkout_params( array $args ) {
923
- $settings = wc_gateway_ppec()->settings;
924
- $order = wc_get_order( $args['order_id'] );
925
 
926
  $old_wc = version_compare( WC_VERSION, '3.0', '<' );
927
  $order_id = $old_wc ? $order->id : $order->get_id();
@@ -943,11 +951,13 @@ class WC_Gateway_PPEC_Client {
943
  'PAYMENTREQUEST_0_NOTIFYURL' => WC()->api_request_url( 'WC_Gateway_PPEC' ),
944
  'PAYMENTREQUEST_0_PAYMENTACTION' => $settings->get_paymentaction(),
945
  'PAYMENTREQUEST_0_INVNUM' => $settings->invoice_prefix . $order->get_order_number(),
946
- 'PAYMENTREQUEST_0_CUSTOM' => json_encode( array(
947
- 'order_id' => $order_id,
948
- 'order_number' => $order_number,
949
- 'order_key' => $order_key,
950
- ) ),
 
 
951
  'NOSHIPPING' => WC_Gateway_PPEC_Plugin::needs_shipping() ? 0 : 1,
952
  );
953
 
@@ -963,7 +973,7 @@ class WC_Gateway_PPEC_Client {
963
  foreach ( $details['items'] as $line_item_key => $values ) {
964
  $line_item_params = array(
965
  'L_PAYMENTREQUEST_0_NAME' . $count => $values['name'],
966
- 'L_PAYMENTREQUEST_0_DESC' . $count => ! empty( $values['description'] ) ? strip_tags( $values['description'] ) : '',
967
  'L_PAYMENTREQUEST_0_QTY' . $count => $values['quantity'],
968
  'L_PAYMENTREQUEST_0_AMT' . $count => $values['amount'],
969
  );
@@ -1031,7 +1041,7 @@ class WC_Gateway_PPEC_Client {
1031
  */
1032
  public function get_do_reference_transaction_params( array $args ) {
1033
  $settings = wc_gateway_ppec()->settings;
1034
- $order = wc_get_order( $args['order_id'] );
1035
 
1036
  $old_wc = version_compare( WC_VERSION, '3.0', '<' );
1037
  $order_id = $old_wc ? $order->id : $order->get_id();
@@ -1051,10 +1061,12 @@ class WC_Gateway_PPEC_Client {
1051
  'NOTIFYURL' => WC()->api_request_url( 'WC_Gateway_PPEC' ),
1052
  'PAYMENTACTION' => $settings->get_paymentaction(),
1053
  'INVNUM' => $settings->invoice_prefix . $order->get_order_number(),
1054
- 'CUSTOM' => json_encode( array(
1055
- 'order_id' => $order_id,
1056
- 'order_key' => $order_key,
1057
- ) ),
 
 
1058
  );
1059
 
1060
  // We want to add the shipping parameters only if we have all of the required
@@ -1079,7 +1091,7 @@ class WC_Gateway_PPEC_Client {
1079
  foreach ( $details['items'] as $line_item_key => $values ) {
1080
  $line_item_params = array(
1081
  'L_NAME' . $count => $values['name'],
1082
- 'L_DESC' . $count => ! empty( $values['description'] ) ? strip_tags( $values['description'] ) : '',
1083
  'L_QTY' . $count => $values['quantity'],
1084
  'L_AMT' . $count => $values['amount'],
1085
  'L_NUMBER' . $count => $values['sku'],
@@ -1150,12 +1162,12 @@ class WC_Gateway_PPEC_Client {
1150
 
1151
  $result = $this->get_pal_details();
1152
 
1153
- if ( 'Success' != $result['ACK'] && 'SuccessWithWarning' != $result['ACK'] ) {
1154
  // Look at the result a little more closely to make sure it's a credentialing issue.
1155
  $found_10002 = false;
1156
  foreach ( $result as $index => $value ) {
1157
  if ( preg_match( '/^L_ERRORCODE\d+$/', $index ) ) {
1158
- if ( '10002' == $value ) {
1159
  $found_10002 = true;
1160
  }
1161
  }
@@ -1182,7 +1194,7 @@ class WC_Gateway_PPEC_Client {
1182
  $this->set_credential( $credentials );
1183
  $this->set_environment( $environment );
1184
 
1185
- $req = array(
1186
  'RETURNURL' => home_url( '/' ),
1187
  'CANCELURL' => home_url( '/' ),
1188
  'REQBILLINGADDRESS' => '1',
@@ -1190,11 +1202,11 @@ class WC_Gateway_PPEC_Client {
1190
  );
1191
  $result = $this->set_express_checkout( $req );
1192
 
1193
- if ( 'Success' != $result['ACK'] && 'SuccessWithWarning' != $result['ACK'] ) {
1194
  $found_11601 = false;
1195
  foreach ( $result as $index => $value ) {
1196
  if ( preg_match( '/^L_ERRORCODE\d+$/', $index ) ) {
1197
- if ( '11601' == $value ) {
1198
  $found_11601 = true;
1199
  }
1200
  }
@@ -1223,7 +1235,7 @@ class WC_Gateway_PPEC_Client {
1223
  return (
1224
  isset( $response['ACK'] )
1225
  &&
1226
- in_array( $response['ACK'], array( 'Success', 'SuccessWithWarning' ) )
1227
  );
1228
  }
1229
 
61
  public function get_payer_id() {
62
  $option_key = 'woocommerce_ppec_payer_id_' . $this->_environment . '_' . md5( $this->_credential->get_username() . ':' . $this->_credential->get_password() );
63
 
64
+ $payer_id = get_option( $option_key );
65
+ if ( $payer_id ) {
66
  return $payer_id;
67
  } else {
68
  $result = $this->get_pal_details();
82
  * @param string $environment Environment. Either 'live' or 'sandbox'
83
  */
84
  public function set_environment( $environment ) {
85
+ if ( ! in_array( $environment, array( 'live', 'sandbox' ), true ) ) {
86
  $environment = 'live';
87
  }
88
 
129
  // For cURL transport.
130
  add_action( 'http_api_curl', array( $this->_credential, 'configure_curl' ), 10, 3 );
131
 
132
+ wc_gateway_ppec_log( sprintf( '%s: remote request to %s with params: %s', __METHOD__, $this->get_endpoint(), print_r( $body, true ) ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
133
 
134
  $resp = wp_safe_remote_post( $this->get_endpoint(), $args );
135
 
148
  'L_SEVERITYCODE0' => 'Error',
149
  );
150
 
151
+ wc_gateway_ppec_log( sprintf( '%s: returns error: %s', __METHOD__, print_r( $error, true ) ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
152
 
153
  return $error;
154
  }
171
  throw new Exception( __( 'Invalid credential object', 'woocommerce-gateway-paypal-express-checkout' ), self::INVALID_CREDENTIAL_ERROR );
172
  }
173
 
174
+ if ( ! in_array( $this->_environment, array( 'live', 'sandbox' ), true ) ) {
175
  throw new Exception( __( 'Invalid environment', 'woocommerce-gateway-paypal-express-checkout' ), self::INVALID_ENVIRONMENT_ERROR );
176
  }
177
  }
189
  */
190
  protected function _process_response( $response ) {
191
  if ( is_wp_error( $response ) ) {
192
+ // Translators: placeholder is an error message.
193
  throw new Exception( sprintf( __( 'An error occurred while trying to connect to PayPal: %s', 'woocommerce-gateway-paypal-express-checkout' ), $response->get_error_message() ), self::REQUEST_ERROR );
194
  }
195
 
199
  throw new Exception( __( 'Malformed response received from PayPal', 'woocommerce-gateway-paypal-express-checkout' ), self::REQUEST_ERROR );
200
  }
201
 
202
+ wc_gateway_ppec_log( sprintf( '%s: acknowleged response body: %s', __METHOD__, print_r( $result, true ) ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
203
 
204
  remove_action( 'http_api_curl', array( $this->_credential, 'configure_curl' ), 10 );
205
 
252
  $params = array();
253
  $logo_url_or_id = $settings->logo_image_url;
254
  $header_url_or_id = $settings->header_image_url;
255
+ $params['LOGOIMG'] = filter_var( $logo_url_or_id, FILTER_VALIDATE_URL ) ? $logo_url_or_id : wp_get_attachment_image_url( $logo_url_or_id, 'thumbnail' );
256
  $params['HDRIMG'] = filter_var( $header_url_or_id, FILTER_VALIDATE_URL ) ? $header_url_or_id : wp_get_attachment_image_url( $header_url_or_id, 'thumbnail' );
257
  $params['PAGESTYLE'] = $settings->page_style;
258
  $params['BRANDNAME'] = $settings->get_brand_name();
268
  $params['ADDROVERRIDE'] = '1';
269
  }
270
 
271
+ if ( in_array( $settings->landing_page, array( 'Billing', 'Login' ), true ) ) {
272
  $params['LANDINGPAGE'] = $settings->landing_page;
273
  }
274
 
300
  $params = array_merge(
301
  $params,
302
  array(
303
+ 'PAYMENTREQUEST_0_AMT' => $details['order_total'],
304
+ 'PAYMENTREQUEST_0_ITEMAMT' => $details['total_item_amount'],
305
+ 'PAYMENTREQUEST_0_SHIPPINGAMT' => $details['shipping'],
306
+ 'PAYMENTREQUEST_0_TAXAMT' => $details['order_tax'],
307
+ 'PAYMENTREQUEST_0_SHIPDISCAMT' => $details['ship_discount_amount'],
308
+ 'NOSHIPPING' => WC_Gateway_PPEC_Plugin::needs_shipping() ? 0 : 1,
309
  )
310
  );
311
 
331
  foreach ( $details['items'] as $line_item_key => $values ) {
332
  $line_item_params = array(
333
  'L_PAYMENTREQUEST_0_NAME' . $count => $values['name'],
334
+ 'L_PAYMENTREQUEST_0_DESC' . $count => ! empty( $values['description'] ) ? substr( strip_tags( $values['description'] ), 0, 127 ) : '', // phpcs:ignore WordPress.WP.AlternativeFunctions.strip_tags_strip_tags
335
  'L_PAYMENTREQUEST_0_QTY' . $count => $values['quantity'],
336
  'L_PAYMENTREQUEST_0_AMT' . $count => $values['amount'],
337
  );
372
  $query_args['create-billing-agreement'] = 'true';
373
  }
374
 
375
+ $url = add_query_arg( $query_args, wc_get_checkout_url() );
376
  $order_id = $context_args['order_id'];
377
+ return apply_filters( 'woocommerce_paypal_express_checkout_set_express_checkout_params_get_return_url', $url, $order_id );
378
  }
379
 
380
  /**
387
  * @return string Cancel URL
388
  */
389
  protected function _get_cancel_url( $context_args ) {
390
+ $url = add_query_arg( 'woo-paypal-cancel', 'true', wc_get_cart_url() );
391
  $order_id = $context_args['order_id'];
392
  return apply_filters( 'woocommerce_paypal_express_checkout_set_express_checkout_params_get_cancel_url', $url, $order_id );
393
  }
400
  * @return string Billing agreement description
401
  */
402
  protected function _get_billing_agreement_description() {
403
+ /* Translators: placeholder is blogname. */
404
+ $description = sprintf( _x( 'Orders with %s', 'data sent to PayPal', 'woocommerce-gateway-paypal-express-checkout' ), get_bloginfo( 'name' ) );
405
 
406
+ if ( strlen( $description ) > 127 ) {
407
+ $description = substr( $description, 0, 124 ) . '...';
408
  }
409
 
410
  return html_entity_decode( $description, ENT_NOQUOTES, 'UTF-8' );
444
  $settings = wc_gateway_ppec()->settings;
445
  $decimals = $settings->get_number_of_decimal_digits();
446
 
447
+ return array(
448
+ 'name' => 'Discount',
449
+ 'quantity' => 1,
450
+ 'amount' => '-' . round( $amount, $decimals ),
451
  );
452
  }
453
 
463
  */
464
  protected function _get_details_from_cart() {
465
  $settings = wc_gateway_ppec()->settings;
466
+ $old_wc = version_compare( WC_VERSION, '3.0', '<' );
467
 
468
  WC()->cart->calculate_totals();
469
 
496
 
497
  $items = array();
498
  foreach ( WC()->cart->cart_contents as $cart_item_key => $values ) {
499
+ $amount = round( $values['line_subtotal'] / $values['quantity'], $decimals );
500
 
501
  if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
502
  $name = $values['data']->post->post_title;
519
  }
520
 
521
  foreach ( WC()->cart->get_fees() as $fee_key => $fee_values ) {
522
+ $item = array(
523
  'name' => $fee_values->name,
524
  'description' => '',
525
  'quantity' => 1,
545
 
546
  $rounded_total = 0;
547
  foreach ( WC()->cart->cart_contents as $cart_item_key => $values ) {
548
+ $amount = round( $values['line_subtotal'] / $values['quantity'], $decimals );
549
  $rounded_total += round( $amount * $values['quantity'], $decimals );
550
  }
551
 
582
  // the difference.
583
  $diff = 0;
584
 
585
+ if ( $details['total_item_amount'] + $discounts != $rounded_total ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
586
  if ( 'add' === $settings->get_subtotal_mismatch_behavior() ) {
587
  // Add line item to make up different between WooCommerce
588
  // calculations and PayPal calculations.
602
 
603
  // Enter discount shenanigans. Item total cannot be 0 so make modifications
604
  // accordingly.
605
+ if ( 0 == $details['total_item_amount'] ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
606
  // Omit line items altogether.
607
  unset( $details['items'] );
608
+ } elseif ( $discounts > 0 && 0 < $details['total_item_amount'] && ! empty( $details['items'] ) ) {
609
  // Else if there is discount, add them to the line-items
610
+ $details['items'][] = $this->_get_extra_discount_line_item( $discounts );
611
  }
612
 
613
  $details['ship_discount_amount'] = 0;
614
 
615
  // AMT
616
+ $details['order_total'] = round( $details['order_total'], $decimals );
617
 
618
  // ITEMAMT
619
  $details['total_item_amount'] = round( $details['total_item_amount'], $decimals );
620
 
621
  // If the totals don't line up, adjust the tax to make it work (it's
622
  // probably a tax mismatch).
623
+ $wc_order_total = round( $total, $decimals );
624
  $discounted_total = $details['order_total'];
625
 
626
+ if ( $wc_order_total != $discounted_total ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
627
  // tax cannot be negative
628
  if ( $discounted_total < $wc_order_total ) {
629
  $details['order_tax'] += $wc_order_total - $discounted_total;
630
+ $details['order_tax'] = round( $details['order_tax'], $decimals );
631
  } else {
632
  $details['ship_discount_amount'] += $wc_order_total - $discounted_total;
633
+ $details['ship_discount_amount'] = round( $details['ship_discount_amount'], $decimals );
634
  }
635
 
636
  $details['order_total'] = $wc_order_total;
668
 
669
  protected function _get_total_order_fees( $order ) {
670
  $total = 0;
671
+ $fees = $order->get_fees();
672
+ foreach ( $fees as $fee ) {
673
  $total = $total + $fee->get_amount();
674
  }
675
 
706
  $details = $this->get_details( $details, $order->get_total_discount(), $rounded_total, $order->get_total() );
707
 
708
  // PayPal shipping address from order.
709
+ $shipping_address = new PayPal_Address();
710
 
711
  $old_wc = version_compare( WC_VERSION, '3.0', '<' );
712
 
713
  if ( ( $old_wc && ( $order->shipping_address_1 || $order->shipping_address_2 ) ) || ( ! $old_wc && $order->has_shipping_address() ) ) {
714
+ // phpcs:disable WordPress.WhiteSpace.OperatorSpacing.SpacingBefore
715
  $shipping_first_name = $old_wc ? $order->shipping_first_name : $order->get_shipping_first_name();
716
  $shipping_last_name = $old_wc ? $order->shipping_last_name : $order->get_shipping_last_name();
717
  $shipping_address_1 = $old_wc ? $order->shipping_address_1 : $order->get_shipping_address_1();
720
  $shipping_state = $old_wc ? $order->shipping_state : $order->get_shipping_state();
721
  $shipping_postcode = $old_wc ? $order->shipping_postcode : $order->get_shipping_postcode();
722
  $shipping_country = $old_wc ? $order->shipping_country : $order->get_shipping_country();
723
+ // phpcs:enable
724
  } else {
725
  // Fallback to billing in case no shipping methods are set. The address returned from PayPal
726
  // will be stored in the order as billing.
727
+ // phpcs:disable WordPress.WhiteSpace.OperatorSpacing.SpacingBefore
728
  $shipping_first_name = $old_wc ? $order->billing_first_name : $order->get_billing_first_name();
729
  $shipping_last_name = $old_wc ? $order->billing_last_name : $order->get_billing_last_name();
730
  $shipping_address_1 = $old_wc ? $order->billing_address_1 : $order->get_billing_address_1();
733
  $shipping_state = $old_wc ? $order->billing_state : $order->get_billing_state();
734
  $shipping_postcode = $old_wc ? $order->billing_postcode : $order->get_billing_postcode();
735
  $shipping_country = $old_wc ? $order->billing_country : $order->get_billing_country();
736
+ // phpcs:enable
737
  }
738
 
739
  $shipping_address->setName( $shipping_first_name . ' ' . $shipping_last_name );
769
  protected function _get_address_from_customer() {
770
  $customer = WC()->customer;
771
 
772
+ $shipping_address = new PayPal_Address();
773
 
774
  $old_wc = version_compare( WC_VERSION, '3.0', '<' );
775
 
776
  if ( $customer->get_shipping_address() || $customer->get_shipping_address_2() ) {
777
  $shipping_first_name = $old_wc ? $customer->shipping_first_name : $customer->get_shipping_first_name();
778
+ $shipping_last_name = $old_wc ? $customer->shipping_last_name : $customer->get_shipping_last_name();
779
  $shipping_address_1 = $customer->get_shipping_address();
780
  $shipping_address_2 = $customer->get_shipping_address_2();
781
  $shipping_city = $customer->get_shipping_city();
785
  } else {
786
  // Fallback to billing in case no shipping methods are set. The address returned from PayPal
787
  // will be stored in the order as billing.
788
+ // phpcs:disable WordPress.WhiteSpace.OperatorSpacing.SpacingBefore
789
  $shipping_first_name = $old_wc ? $customer->billing_first_name : $customer->get_billing_first_name();
790
  $shipping_last_name = $old_wc ? $customer->billing_last_name : $customer->get_billing_last_name();
791
  $shipping_address_1 = $old_wc ? $customer->get_address() : $customer->get_billing_address_1();
794
  $shipping_state = $old_wc ? $customer->get_state() : $customer->get_billing_state();
795
  $shipping_postcode = $old_wc ? $customer->get_postcode() : $customer->get_billing_postcode();
796
  $shipping_country = $old_wc ? $customer->get_country() : $customer->get_billing_country();
797
+ // phpcs:enable
798
  }
799
 
800
  $shipping_address->setName( $shipping_first_name . ' ' . $shipping_last_name );
826
  $items = array();
827
  foreach ( $order->get_items( array( 'line_item', 'fee' ) ) as $cart_item_key => $order_item ) {
828
 
829
+ if ( 'fee' === $order_item['type'] ) {
830
+ $item = array(
831
  'name' => $order_item['name'],
832
  'quantity' => 1,
833
  'amount' => round( $order_item['line_total'], $decimals ),
834
  );
835
  } else {
836
+ $amount = round( $order_item['line_subtotal'] / $order_item['qty'], $decimals );
837
  $product = version_compare( WC_VERSION, '3.0', '<' ) ? $order->get_product_from_item( $order_item ) : $order_item->get_product();
838
  $item = array(
839
  'name' => $order_item['name'],
865
 
866
  $rounded_total = 0;
867
  foreach ( $order->get_items( array( 'line_item', 'fee', 'coupon' ) ) as $cart_item_key => $values ) {
868
+ if ( 'coupon' === $values['type'] ) {
869
+ $amount = round( $values['line_total'], $decimals );
870
  $rounded_total -= $amount;
871
  continue;
872
  }
873
+ if ( 'fee' === $values['type'] ) {
874
+ $amount = round( $values['line_total'], $decimals );
875
  } else {
876
+ $amount = round( $values['line_subtotal'] / $values['qty'], $decimals );
877
  $amount = round( $amount * $values['qty'], $decimals );
878
  }
879
  $rounded_total += $amount;
928
  * @return array Params for DoExpressCheckoutPayment call
929
  */
930
  public function get_do_express_checkout_params( array $args ) {
931
+ $settings = wc_gateway_ppec()->settings;
932
+ $order = wc_get_order( $args['order_id'] );
933
 
934
  $old_wc = version_compare( WC_VERSION, '3.0', '<' );
935
  $order_id = $old_wc ? $order->id : $order->get_id();
951
  'PAYMENTREQUEST_0_NOTIFYURL' => WC()->api_request_url( 'WC_Gateway_PPEC' ),
952
  'PAYMENTREQUEST_0_PAYMENTACTION' => $settings->get_paymentaction(),
953
  'PAYMENTREQUEST_0_INVNUM' => $settings->invoice_prefix . $order->get_order_number(),
954
+ 'PAYMENTREQUEST_0_CUSTOM' => wp_json_encode(
955
+ array(
956
+ 'order_id' => $order_id,
957
+ 'order_number' => $order_number,
958
+ 'order_key' => $order_key,
959
+ )
960
+ ),
961
  'NOSHIPPING' => WC_Gateway_PPEC_Plugin::needs_shipping() ? 0 : 1,
962
  );
963
 
973
  foreach ( $details['items'] as $line_item_key => $values ) {
974
  $line_item_params = array(
975
  'L_PAYMENTREQUEST_0_NAME' . $count => $values['name'],
976
+ 'L_PAYMENTREQUEST_0_DESC' . $count => ! empty( $values['description'] ) ? strip_tags( $values['description'] ) : '', // phpcs:ignore WordPress.WP.AlternativeFunctions.strip_tags_strip_tags
977
  'L_PAYMENTREQUEST_0_QTY' . $count => $values['quantity'],
978
  'L_PAYMENTREQUEST_0_AMT' . $count => $values['amount'],
979
  );
1041
  */
1042
  public function get_do_reference_transaction_params( array $args ) {
1043
  $settings = wc_gateway_ppec()->settings;
1044
+ $order = wc_get_order( $args['order_id'] );
1045
 
1046
  $old_wc = version_compare( WC_VERSION, '3.0', '<' );
1047
  $order_id = $old_wc ? $order->id : $order->get_id();
1061
  'NOTIFYURL' => WC()->api_request_url( 'WC_Gateway_PPEC' ),
1062
  'PAYMENTACTION' => $settings->get_paymentaction(),
1063
  'INVNUM' => $settings->invoice_prefix . $order->get_order_number(),
1064
+ 'CUSTOM' => wp_json_encode(
1065
+ array(
1066
+ 'order_id' => $order_id,
1067
+ 'order_key' => $order_key,
1068
+ )
1069
+ ),
1070
  );
1071
 
1072
  // We want to add the shipping parameters only if we have all of the required
1091
  foreach ( $details['items'] as $line_item_key => $values ) {
1092
  $line_item_params = array(
1093
  'L_NAME' . $count => $values['name'],
1094
+ 'L_DESC' . $count => ! empty( $values['description'] ) ? strip_tags( $values['description'] ) : '', // phpcs:ignore WordPress.WP.AlternativeFunctions.strip_tags_strip_tags
1095
  'L_QTY' . $count => $values['quantity'],
1096
  'L_AMT' . $count => $values['amount'],
1097
  'L_NUMBER' . $count => $values['sku'],
1162
 
1163
  $result = $this->get_pal_details();
1164
 
1165
+ if ( 'Success' !== $result['ACK'] && 'SuccessWithWarning' !== $result['ACK'] ) {
1166
  // Look at the result a little more closely to make sure it's a credentialing issue.
1167
  $found_10002 = false;
1168
  foreach ( $result as $index => $value ) {
1169
  if ( preg_match( '/^L_ERRORCODE\d+$/', $index ) ) {
1170
+ if ( '10002' == $value ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
1171
  $found_10002 = true;
1172
  }
1173
  }
1194
  $this->set_credential( $credentials );
1195
  $this->set_environment( $environment );
1196
 
1197
+ $req = array(
1198
  'RETURNURL' => home_url( '/' ),
1199
  'CANCELURL' => home_url( '/' ),
1200
  'REQBILLINGADDRESS' => '1',
1202
  );
1203
  $result = $this->set_express_checkout( $req );
1204
 
1205
+ if ( 'Success' !== $result['ACK'] && 'SuccessWithWarning' !== $result['ACK'] ) {
1206
  $found_11601 = false;
1207
  foreach ( $result as $index => $value ) {
1208
  if ( preg_match( '/^L_ERRORCODE\d+$/', $index ) ) {
1209
+ if ( '11601' == $value ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
1210
  $found_11601 = true;
1211
  }
1212
  }
1235
  return (
1236
  isset( $response['ACK'] )
1237
  &&
1238
+ in_array( $response['ACK'], array( 'Success', 'SuccessWithWarning' ), true )
1239
  );
1240
  }
1241
 
includes/class-wc-gateway-ppec-gateway-loader.php CHANGED
@@ -15,14 +15,14 @@ class WC_Gateway_PPEC_Gateway_Loader {
15
  public function __construct() {
16
  $includes_path = wc_gateway_ppec()->includes_path;
17
 
18
- require_once( $includes_path . 'class-wc-gateway-ppec-refund.php' );
19
- require_once( $includes_path . 'abstracts/abstract-wc-gateway-ppec.php' );
20
 
21
- require_once( $includes_path . 'class-wc-gateway-ppec-with-paypal.php' );
22
- require_once( $includes_path . 'class-wc-gateway-ppec-with-paypal-credit.php' );
23
- require_once( $includes_path . 'class-wc-gateway-ppec-with-paypal-addons.php' );
24
- require_once( $includes_path . 'class-wc-gateway-ppec-with-spb.php' );
25
- require_once( $includes_path . 'class-wc-gateway-ppec-with-spb-addons.php' );
26
 
27
  add_filter( 'woocommerce_payment_gateways', array( $this, 'payment_gateways' ) );
28
  }
15
  public function __construct() {
16
  $includes_path = wc_gateway_ppec()->includes_path;
17
 
18
+ require_once $includes_path . 'class-wc-gateway-ppec-refund.php';
19
+ require_once $includes_path . 'abstracts/abstract-wc-gateway-ppec.php';
20
 
21
+ require_once $includes_path . 'class-wc-gateway-ppec-with-paypal.php';
22
+ require_once $includes_path . 'class-wc-gateway-ppec-with-paypal-credit.php';
23
+ require_once $includes_path . 'class-wc-gateway-ppec-with-paypal-addons.php';
24
+ require_once $includes_path . 'class-wc-gateway-ppec-with-spb.php';
25
+ require_once $includes_path . 'class-wc-gateway-ppec-with-spb-addons.php';
26
 
27
  add_filter( 'woocommerce_payment_gateways', array( $this, 'payment_gateways' ) );
28
  }
includes/class-wc-gateway-ppec-ipn-handler.php CHANGED
@@ -25,20 +25,20 @@ class WC_Gateway_PPEC_IPN_Handler extends WC_Gateway_PPEC_PayPal_Request_Handler
25
  */
26
  public function check_request() {
27
  try {
28
- if ( empty( $_POST ) ) {
29
  throw new Exception( esc_html__( 'Empty POST data.', 'woocommerce-gateway-paypal-express-checkout' ) );
30
  }
31
 
32
- if ( $this->is_valid_ipn_request( $_POST ) ) {
33
  wc_gateway_ppec_log( 'IPN request is valid according to PayPal.' );
34
- do_action( 'woocommerce_paypal_express_checkout_valid_ipn_request', wp_unslash( $_POST ) );
35
  exit;
36
  } else {
37
  wc_gateway_ppec_log( 'IPN request is NOT valid according to PayPal.' );
38
- throw new Exception( esc_html__( 'Invalid IPN request.' , 'woocommerce-gateway-paypal-express-checkout' ) );
39
  }
40
  } catch ( Exception $e ) {
41
- wp_die( $e->getMessage(), esc_html__( 'PayPal IPN Request Failure', 'woocommerce-gateway-paypal-express-checkout' ), array( 'response' => 500 ) );
42
  }
43
  }
44
 
@@ -53,7 +53,7 @@ class WC_Gateway_PPEC_IPN_Handler extends WC_Gateway_PPEC_PayPal_Request_Handler
53
  public function is_valid_ipn_request( array $posted_data ) {
54
  wc_gateway_ppec_log( sprintf( '%s: %s', __FUNCTION__, 'Checking IPN request validity' ) );
55
 
56
- $ipn_request = array(
57
  'cmd' => '_notify-validate',
58
  );
59
  $ipn_request += wp_unslash( $posted_data );
@@ -70,8 +70,8 @@ class WC_Gateway_PPEC_IPN_Handler extends WC_Gateway_PPEC_PayPal_Request_Handler
70
  // Post back to PayPal to check validity of IPN request.
71
  $response = wp_safe_remote_post( $this->get_validator_url(), $params );
72
 
73
- wc_gateway_ppec_log( sprintf( '%s: %s: %s', __FUNCTION__, 'Verify IPN request', print_r( $params, true ) ) );
74
- wc_gateway_ppec_log( sprintf( '%s: %s: %s', __FUNCTION__, 'Response for the IPN request', print_r( $response, true ) ) );
75
 
76
  if ( is_wp_error( $response ) ) {
77
  throw new Exception( $response->get_error_message() );
@@ -92,12 +92,12 @@ class WC_Gateway_PPEC_IPN_Handler extends WC_Gateway_PPEC_PayPal_Request_Handler
92
  * @param array $posted_data Posted data
93
  */
94
  public function handle_valid_ipn( $posted_data ) {
95
- if ( ! empty( $posted_data['custom'] ) && ( $order = $this->get_paypal_order( $posted_data['custom'] ) ) ) {
96
  // Lowercase returned variables.
97
  $posted_data['payment_status'] = strtolower( $posted_data['payment_status'] );
98
 
99
  // Sandbox fix.
100
- if ( ( empty( $posted_data['pending_reason'] ) || 'authorization' !== $posted_data['pending_reason'] ) && isset( $posted_data['test_ipn'] ) && 1 == $posted_data['test_ipn'] && 'pending' == $posted_data['payment_status'] ) {
101
  $posted_data['payment_status'] = 'completed';
102
  }
103
 
@@ -120,7 +120,7 @@ class WC_Gateway_PPEC_IPN_Handler extends WC_Gateway_PPEC_PayPal_Request_Handler
120
  */
121
  protected function validate_transaction_type( $txn_type ) {
122
  $accepted_types = array( 'cart', 'instant', 'express_checkout', 'web_accept', 'masspay', 'send_money' );
123
- if ( ! in_array( strtolower( $txn_type ), $accepted_types ) ) {
124
  wc_gateway_ppec_log( 'Aborting, Invalid type:' . $txn_type );
125
  exit;
126
  }
@@ -133,12 +133,13 @@ class WC_Gateway_PPEC_IPN_Handler extends WC_Gateway_PPEC_PayPal_Request_Handler
133
  * @param string $currency Currency
134
  */
135
  protected function validate_currency( $order, $currency ) {
136
- $old_wc = version_compare( WC_VERSION, '3.0', '<' );
137
  $order_currency = $old_wc ? $order->order_currency : $order->get_currency();
138
 
139
  if ( $order_currency !== $currency ) {
140
  wc_gateway_ppec_log( 'Payment error: Currencies do not match (sent "' . $order_currency . '" | returned "' . $currency . '")' );
141
  // Put this order on-hold for manual checking.
 
142
  $order->update_status( 'on-hold', sprintf( __( 'Validation error: PayPal currencies do not match (code %s).', 'woocommerce-gateway-paypal-express-checkout' ), $currency ) );
143
  exit;
144
  }
@@ -151,9 +152,10 @@ class WC_Gateway_PPEC_IPN_Handler extends WC_Gateway_PPEC_PayPal_Request_Handler
151
  * @param int $amount Amount
152
  */
153
  protected function validate_amount( $order, $amount ) {
154
- if ( number_format( $order->get_total(), 2, '.', '' ) != number_format( $amount, 2, '.', '' ) ) {
155
  wc_gateway_ppec_log( 'Payment error: Amounts do not match (gross ' . $amount . ')' );
156
  // Put this order on-hold for manual checking.
 
157
  $order->update_status( 'on-hold', sprintf( __( 'Validation error: PayPal amounts do not match (gross %s).', 'woocommerce-gateway-paypal-express-checkout' ), $amount ) );
158
  exit;
159
  }
@@ -189,6 +191,7 @@ class WC_Gateway_PPEC_IPN_Handler extends WC_Gateway_PPEC_PayPal_Request_Handler
189
  if ( 'authorization' === $posted_data['pending_reason'] ) {
190
  $this->payment_on_hold( $order, __( 'Payment authorized. Change payment status to processing or complete to capture funds.', 'woocommerce-gateway-paypal-express-checkout' ) );
191
  } else {
 
192
  $this->payment_on_hold( $order, sprintf( __( 'Payment pending (%s).', 'woocommerce-gateway-paypal-express-checkout' ), $posted_data['pending_reason'] ) );
193
  }
194
  }
@@ -211,6 +214,7 @@ class WC_Gateway_PPEC_IPN_Handler extends WC_Gateway_PPEC_PayPal_Request_Handler
211
  * @param array $posted_data Posted data
212
  */
213
  protected function payment_status_failed( $order, $posted_data ) {
 
214
  $order->update_status( 'failed', sprintf( __( 'Payment %s via IPN.', 'woocommerce-gateway-paypal-express-checkout' ), wc_clean( $posted_data['payment_status'] ) ) );
215
  }
216
 
@@ -253,11 +257,14 @@ class WC_Gateway_PPEC_IPN_Handler extends WC_Gateway_PPEC_PayPal_Request_Handler
253
  protected function payment_status_refunded( $order, $posted_data ) {
254
  // Only handle full refunds, not partial.
255
  $order_id = version_compare( WC_VERSION, '3.0', '<' ) ? $order->id : $order->get_id();
256
- if ( $order->get_total() == ( $posted_data['mc_gross'] * -1 ) ) {
257
  // Mark order as refunded.
 
258
  $order->update_status( 'refunded', sprintf( __( 'Payment %s via IPN.', 'woocommerce-gateway-paypal-express-checkout' ), strtolower( $posted_data['payment_status'] ) ) );
259
  $this->send_ipn_email_notification(
 
260
  sprintf( __( 'Payment for order %s refunded', 'woocommerce-gateway-paypal-express-checkout' ), '<a class="link" href="' . esc_url( admin_url( 'post.php?post=' . $order_id . '&action=edit' ) ) . '">' . $order->get_order_number() . '</a>' ),
 
261
  sprintf( __( 'Order #%1$s has been marked as refunded - PayPal reason code: %2$s', 'woocommerce-gateway-paypal-express-checkout' ), $order->get_order_number(), $posted_data['reason_code'] )
262
  );
263
  }
@@ -271,9 +278,12 @@ class WC_Gateway_PPEC_IPN_Handler extends WC_Gateway_PPEC_PayPal_Request_Handler
271
  */
272
  protected function payment_status_reversed( $order, $posted_data ) {
273
  $order_id = version_compare( WC_VERSION, '3.0', '<' ) ? $order->id : $order->get_id();
 
274
  $order->update_status( 'on-hold', sprintf( __( 'Payment %s via IPN.', 'woocommerce-gateway-paypal-express-checkout' ), wc_clean( $posted_data['payment_status'] ) ) );
275
  $this->send_ipn_email_notification(
 
276
  sprintf( __( 'Payment for order %s reversed', 'woocommerce-gateway-paypal-express-checkout' ), '<a class="link" href="' . esc_url( admin_url( 'post.php?post=' . $order_id . '&action=edit' ) ) . '">' . $order->get_order_number() . '</a>' ),
 
277
  sprintf( __( 'Order #%1$s has been marked on-hold due to a reversal - PayPal reason code: %2$s', 'woocommerce-gateway-paypal-express-checkout' ), $order->get_order_number(), wc_clean( $posted_data['reason_code'] ) )
278
  );
279
  }
@@ -287,7 +297,9 @@ class WC_Gateway_PPEC_IPN_Handler extends WC_Gateway_PPEC_PayPal_Request_Handler
287
  protected function payment_status_canceled_reversal( $order, $posted_data ) {
288
  $order_id = version_compare( WC_VERSION, '3.0', '<' ) ? $order->id : $order->get_id();
289
  $this->send_ipn_email_notification(
 
290
  sprintf( __( 'Reversal cancelled for order #%s', 'woocommerce-gateway-paypal-express-checkout' ), $order->get_order_number() ),
 
291
  sprintf( __( 'Order #%1$s has had a reversal cancelled. Please check the status of payment and update the order status accordingly here: %2$s', 'woocommerce-gateway-paypal-express-checkout' ), $order->get_order_number(), esc_url( admin_url( 'post.php?post=' . $order_id . '&action=edit' ) ) )
292
  );
293
  }
@@ -306,7 +318,7 @@ class WC_Gateway_PPEC_IPN_Handler extends WC_Gateway_PPEC_PayPal_Request_Handler
306
  'first_name' => 'Payer first name',
307
  'last_name' => 'Payer last name',
308
  'payment_type' => 'Payment type',
309
- 'payment_status' => '_paypal_status'
310
  );
311
 
312
  $old_wc = version_compare( WC_VERSION, '3.0', '<' );
@@ -340,7 +352,7 @@ class WC_Gateway_PPEC_IPN_Handler extends WC_Gateway_PPEC_PayPal_Request_Handler
340
  $new_order_settings = get_option( 'woocommerce_new_order_settings', array() );
341
  $mailer = WC()->mailer();
342
  $message = $mailer->wrap_message( $subject, $message );
343
- $mailer->send( ! empty( $new_order_settings['recipient'] ) ? $new_order_settings['recipient'] : get_option( 'admin_email' ), strip_tags( $subject ), $message );
344
  }
345
 
346
  /**
25
  */
26
  public function check_request() {
27
  try {
28
+ if ( empty( $_POST ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
29
  throw new Exception( esc_html__( 'Empty POST data.', 'woocommerce-gateway-paypal-express-checkout' ) );
30
  }
31
 
32
+ if ( $this->is_valid_ipn_request( $_POST ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
33
  wc_gateway_ppec_log( 'IPN request is valid according to PayPal.' );
34
+ do_action( 'woocommerce_paypal_express_checkout_valid_ipn_request', wp_unslash( $_POST ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
35
  exit;
36
  } else {
37
  wc_gateway_ppec_log( 'IPN request is NOT valid according to PayPal.' );
38
+ throw new Exception( esc_html__( 'Invalid IPN request.', 'woocommerce-gateway-paypal-express-checkout' ) );
39
  }
40
  } catch ( Exception $e ) {
41
+ wp_die( $e->getMessage(), esc_html__( 'PayPal IPN Request Failure', 'woocommerce-gateway-paypal-express-checkout' ), array( 'response' => 500 ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
42
  }
43
  }
44
 
53
  public function is_valid_ipn_request( array $posted_data ) {
54
  wc_gateway_ppec_log( sprintf( '%s: %s', __FUNCTION__, 'Checking IPN request validity' ) );
55
 
56
+ $ipn_request = array(
57
  'cmd' => '_notify-validate',
58
  );
59
  $ipn_request += wp_unslash( $posted_data );
70
  // Post back to PayPal to check validity of IPN request.
71
  $response = wp_safe_remote_post( $this->get_validator_url(), $params );
72
 
73
+ wc_gateway_ppec_log( sprintf( '%s: %s: %s', __FUNCTION__, 'Verify IPN request', print_r( $params, true ) ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
74
+ wc_gateway_ppec_log( sprintf( '%s: %s: %s', __FUNCTION__, 'Response for the IPN request', print_r( $response, true ) ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
75
 
76
  if ( is_wp_error( $response ) ) {
77
  throw new Exception( $response->get_error_message() );
92
  * @param array $posted_data Posted data
93
  */
94
  public function handle_valid_ipn( $posted_data ) {
95
+ if ( ! empty( $posted_data['custom'] ) && ( $order = $this->get_paypal_order( $posted_data['custom'] ) ) ) { // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure,WordPress.CodeAnalysis.AssignmentInCondition.Found
96
  // Lowercase returned variables.
97
  $posted_data['payment_status'] = strtolower( $posted_data['payment_status'] );
98
 
99
  // Sandbox fix.
100
+ if ( ( empty( $posted_data['pending_reason'] ) || 'authorization' !== $posted_data['pending_reason'] ) && isset( $posted_data['test_ipn'] ) && 1 == $posted_data['test_ipn'] && 'pending' == $posted_data['payment_status'] ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
101
  $posted_data['payment_status'] = 'completed';
102
  }
103
 
120
  */
121
  protected function validate_transaction_type( $txn_type ) {
122
  $accepted_types = array( 'cart', 'instant', 'express_checkout', 'web_accept', 'masspay', 'send_money' );
123
+ if ( ! in_array( strtolower( $txn_type ), $accepted_types, true ) ) {
124
  wc_gateway_ppec_log( 'Aborting, Invalid type:' . $txn_type );
125
  exit;
126
  }
133
  * @param string $currency Currency
134
  */
135
  protected function validate_currency( $order, $currency ) {
136
+ $old_wc = version_compare( WC_VERSION, '3.0', '<' );
137
  $order_currency = $old_wc ? $order->order_currency : $order->get_currency();
138
 
139
  if ( $order_currency !== $currency ) {
140
  wc_gateway_ppec_log( 'Payment error: Currencies do not match (sent "' . $order_currency . '" | returned "' . $currency . '")' );
141
  // Put this order on-hold for manual checking.
142
+ // Translators: placeholder is a currency code.
143
  $order->update_status( 'on-hold', sprintf( __( 'Validation error: PayPal currencies do not match (code %s).', 'woocommerce-gateway-paypal-express-checkout' ), $currency ) );
144
  exit;
145
  }
152
  * @param int $amount Amount
153
  */
154
  protected function validate_amount( $order, $amount ) {
155
+ if ( number_format( $order->get_total(), 2, '.', '' ) != number_format( $amount, 2, '.', '' ) ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
156
  wc_gateway_ppec_log( 'Payment error: Amounts do not match (gross ' . $amount . ')' );
157
  // Put this order on-hold for manual checking.
158
+ // Translators: placeholder is an amount.
159
  $order->update_status( 'on-hold', sprintf( __( 'Validation error: PayPal amounts do not match (gross %s).', 'woocommerce-gateway-paypal-express-checkout' ), $amount ) );
160
  exit;
161
  }
191
  if ( 'authorization' === $posted_data['pending_reason'] ) {
192
  $this->payment_on_hold( $order, __( 'Payment authorized. Change payment status to processing or complete to capture funds.', 'woocommerce-gateway-paypal-express-checkout' ) );
193
  } else {
194
+ // Translators: placeholder is the reason for the payment to be in pending status.
195
  $this->payment_on_hold( $order, sprintf( __( 'Payment pending (%s).', 'woocommerce-gateway-paypal-express-checkout' ), $posted_data['pending_reason'] ) );
196
  }
197
  }
214
  * @param array $posted_data Posted data
215
  */
216
  protected function payment_status_failed( $order, $posted_data ) {
217
+ // Translators: placeholder is a payment status.
218
  $order->update_status( 'failed', sprintf( __( 'Payment %s via IPN.', 'woocommerce-gateway-paypal-express-checkout' ), wc_clean( $posted_data['payment_status'] ) ) );
219
  }
220
 
257
  protected function payment_status_refunded( $order, $posted_data ) {
258
  // Only handle full refunds, not partial.
259
  $order_id = version_compare( WC_VERSION, '3.0', '<' ) ? $order->id : $order->get_id();
260
+ if ( $order->get_total() == ( $posted_data['mc_gross'] * -1 ) ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
261
  // Mark order as refunded.
262
+ // Translators: placeholder is a payment status.
263
  $order->update_status( 'refunded', sprintf( __( 'Payment %s via IPN.', 'woocommerce-gateway-paypal-express-checkout' ), strtolower( $posted_data['payment_status'] ) ) );
264
  $this->send_ipn_email_notification(
265
+ /* Translators: placeholder is an order number (linked to its details screen). */
266
  sprintf( __( 'Payment for order %s refunded', 'woocommerce-gateway-paypal-express-checkout' ), '<a class="link" href="' . esc_url( admin_url( 'post.php?post=' . $order_id . '&action=edit' ) ) . '">' . $order->get_order_number() . '</a>' ),
267
+ /* Translators: 1) is an order number, 2) is a PayPal reason code. */
268
  sprintf( __( 'Order #%1$s has been marked as refunded - PayPal reason code: %2$s', 'woocommerce-gateway-paypal-express-checkout' ), $order->get_order_number(), $posted_data['reason_code'] )
269
  );
270
  }
278
  */
279
  protected function payment_status_reversed( $order, $posted_data ) {
280
  $order_id = version_compare( WC_VERSION, '3.0', '<' ) ? $order->id : $order->get_id();
281
+ // Translators: placeholder is a payment status.
282
  $order->update_status( 'on-hold', sprintf( __( 'Payment %s via IPN.', 'woocommerce-gateway-paypal-express-checkout' ), wc_clean( $posted_data['payment_status'] ) ) );
283
  $this->send_ipn_email_notification(
284
+ /* Translators: placeholder is an order number (linked to its details screen). */
285
  sprintf( __( 'Payment for order %s reversed', 'woocommerce-gateway-paypal-express-checkout' ), '<a class="link" href="' . esc_url( admin_url( 'post.php?post=' . $order_id . '&action=edit' ) ) . '">' . $order->get_order_number() . '</a>' ),
286
+ /* Translators: 1) is an order number, 2) is a PayPal reason code. */
287
  sprintf( __( 'Order #%1$s has been marked on-hold due to a reversal - PayPal reason code: %2$s', 'woocommerce-gateway-paypal-express-checkout' ), $order->get_order_number(), wc_clean( $posted_data['reason_code'] ) )
288
  );
289
  }
297
  protected function payment_status_canceled_reversal( $order, $posted_data ) {
298
  $order_id = version_compare( WC_VERSION, '3.0', '<' ) ? $order->id : $order->get_id();
299
  $this->send_ipn_email_notification(
300
+ /* Translators: placeholder is an order number. */
301
  sprintf( __( 'Reversal cancelled for order #%s', 'woocommerce-gateway-paypal-express-checkout' ), $order->get_order_number() ),
302
+ /* Translators: 1) is an order number, 2) is the URL of the order's edit screen. */
303
  sprintf( __( 'Order #%1$s has had a reversal cancelled. Please check the status of payment and update the order status accordingly here: %2$s', 'woocommerce-gateway-paypal-express-checkout' ), $order->get_order_number(), esc_url( admin_url( 'post.php?post=' . $order_id . '&action=edit' ) ) )
304
  );
305
  }
318
  'first_name' => 'Payer first name',
319
  'last_name' => 'Payer last name',
320
  'payment_type' => 'Payment type',
321
+ 'payment_status' => '_paypal_status',
322
  );
323
 
324
  $old_wc = version_compare( WC_VERSION, '3.0', '<' );
352
  $new_order_settings = get_option( 'woocommerce_new_order_settings', array() );
353
  $mailer = WC()->mailer();
354
  $message = $mailer->wrap_message( $subject, $message );
355
+ $mailer->send( ! empty( $new_order_settings['recipient'] ) ? $new_order_settings['recipient'] : get_option( 'admin_email' ), wp_strip_all_tags( $subject ), $message );
356
  }
357
 
358
  /**
includes/class-wc-gateway-ppec-ips-handler.php CHANGED
@@ -47,7 +47,7 @@ class WC_Gateway_PPEC_IPS_Handler {
47
  * @return string Redirect URL
48
  */
49
  public function get_redirect_url( $env ) {
50
- if ( ! in_array( $env, array( 'live', 'sandbox' ) ) ) {
51
  $env = 'live';
52
  }
53
 
@@ -85,7 +85,7 @@ class WC_Gateway_PPEC_IPS_Handler {
85
  */
86
  public function get_signup_url( $env ) {
87
  $query_args = array(
88
- 'redirect' => urlencode( $this->get_redirect_url( $env ) ),
89
  'countryCode' => WC()->countries->get_base_country(),
90
  'merchantId' => md5( site_url( '/' ) . time() ),
91
  );
@@ -99,7 +99,7 @@ class WC_Gateway_PPEC_IPS_Handler {
99
  * @return bool Returns true of base country in supported countries
100
  */
101
  public function is_supported() {
102
- return in_array( WC()->countries->get_base_country(), $this->_supported_countries );
103
  }
104
 
105
  /**
@@ -133,18 +133,18 @@ class WC_Gateway_PPEC_IPS_Handler {
133
  if ( empty( $_GET['wc_ppec_ips_admin_nonce'] ) || empty( $_GET['env'] ) ) {
134
  return false;
135
  }
136
- $env = in_array( $_GET['env'], array( 'live', 'sandbox' ) ) ? $_GET['env'] : 'live';
137
 
138
  // Verify the nonce.
139
- if ( ! wp_verify_nonce( $_GET['wc_ppec_ips_admin_nonce'], 'wc_ppec_ips' ) ) {
140
- wp_die( __( 'Invalid connection request', 'woocommerce-gateway-paypal-express-checkout' ) );
141
  }
142
 
143
- wc_gateway_ppec_log( sprintf( '%s: returned back from IPS flow with parameters: %s', __METHOD__, print_r( $_GET, true ) ) );
144
 
145
  // Check if error.
146
  if ( ! empty( $_GET['error'] ) ) {
147
- $error_message = ! empty( $_GET['error_message'] ) ? $_GET['error_message'] : '';
148
  wc_gateway_ppec_log( sprintf( '%s: returned back from IPS flow with error: %s', __METHOD__, $error_message ) );
149
 
150
  $this->_redirect_with_messages( __( 'Sorry, Easy Setup encountered an error. Please try again.', 'woocommerce-gateway-paypal-express-checkout' ) );
@@ -159,11 +159,7 @@ class WC_Gateway_PPEC_IPS_Handler {
159
  }
160
  }
161
 
162
- $creds = new WC_Gateway_PPEC_Client_Credential_Signature(
163
- $_GET['api_username'],
164
- $_GET['api_password'],
165
- $_GET['signature']
166
- );
167
 
168
  $error_msgs = array();
169
  try {
@@ -183,7 +179,7 @@ class WC_Gateway_PPEC_IPS_Handler {
183
  );
184
 
185
  if ( ! empty( $error_msgs ) ) {
186
- wc_gateway_ppec_log( sprintf( '%s: returned back from IPS flow: %s', __METHOD__, print_r( $error_msgs, true ) ) );
187
  }
188
 
189
  // Save credentials to settings API
47
  * @return string Redirect URL
48
  */
49
  public function get_redirect_url( $env ) {
50
+ if ( ! in_array( $env, array( 'live', 'sandbox' ), true ) ) {
51
  $env = 'live';
52
  }
53
 
85
  */
86
  public function get_signup_url( $env ) {
87
  $query_args = array(
88
+ 'redirect' => urlencode( $this->get_redirect_url( $env ) ), /* phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.urlencode_urlencode */
89
  'countryCode' => WC()->countries->get_base_country(),
90
  'merchantId' => md5( site_url( '/' ) . time() ),
91
  );
99
  * @return bool Returns true of base country in supported countries
100
  */
101
  public function is_supported() {
102
+ return in_array( WC()->countries->get_base_country(), $this->_supported_countries, true );
103
  }
104
 
105
  /**
133
  if ( empty( $_GET['wc_ppec_ips_admin_nonce'] ) || empty( $_GET['env'] ) ) {
134
  return false;
135
  }
136
+ $env = in_array( $_GET['env'], array( 'live', 'sandbox' ), true ) ? $_GET['env'] : 'live'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
137
 
138
  // Verify the nonce.
139
+ if ( ! wp_verify_nonce( $_GET['wc_ppec_ips_admin_nonce'], 'wc_ppec_ips' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
140
+ wp_die( __( 'Invalid connection request', 'woocommerce-gateway-paypal-express-checkout' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
141
  }
142
 
143
+ wc_gateway_ppec_log( sprintf( '%s: returned back from IPS flow with parameters: %s', __METHOD__, print_r( $_GET, true ) ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
144
 
145
  // Check if error.
146
  if ( ! empty( $_GET['error'] ) ) {
147
+ $error_message = ! empty( $_GET['error_message'] ) ? $_GET['error_message'] : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
148
  wc_gateway_ppec_log( sprintf( '%s: returned back from IPS flow with error: %s', __METHOD__, $error_message ) );
149
 
150
  $this->_redirect_with_messages( __( 'Sorry, Easy Setup encountered an error. Please try again.', 'woocommerce-gateway-paypal-express-checkout' ) );
159
  }
160
  }
161
 
162
+ $creds = new WC_Gateway_PPEC_Client_Credential_Signature( $_GET['api_username'], $_GET['api_password'], $_GET['signature'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
 
 
 
 
163
 
164
  $error_msgs = array();
165
  try {
179
  );
180
 
181
  if ( ! empty( $error_msgs ) ) {
182
+ wc_gateway_ppec_log( sprintf( '%s: returned back from IPS flow: %s', __METHOD__, print_r( $error_msgs, true ) ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
183
  }
184
 
185
  // Save credentials to settings API
includes/class-wc-gateway-ppec-payment-details.php CHANGED
@@ -9,13 +9,13 @@ if ( ! defined( 'ABSPATH' ) ) {
9
  }
10
 
11
  class PayPal_Payment_Details {
12
- public $token = false;
13
- public $billing_agreement_id = false;
14
- public $redirect_required = false;
15
- public $redirect_requested = false;
16
- public $note = false;
17
 
18
- public $payments = false;
19
 
20
  public $shipping_option_details = false;
21
 
@@ -25,19 +25,19 @@ class PayPal_Payment_Details {
25
  'BILLINGAGREEMENTID' => 'billing_agreement_id',
26
  'REDIRECTREQUIRED' => 'redirect_required',
27
  'SUCCESSPAGEREDIRECTREQUESTED' => 'redirect_requested',
28
- 'NOTE' => 'note'
29
  );
30
 
31
  $max_payment_num = -1;
32
 
33
  foreach ( $doECResponse as $index => $value ) {
34
  if ( array_key_exists( $index, $map ) ) {
35
- $key = $map[ $index ];
36
  $this->$key = $value;
37
  }
38
  // Figure out the highest payment number
39
  if ( preg_match( '/^PAYMENTINFO_(\d)_(TRANSACTIONID|EBAYITEMAUCTIONTXNID|PARENTTRANSACTIONID|RECEIPTID|TRANSACTIONTYPE|PAYMENTTYPE|EXPECTEDECHECKCLEARDATE|ORDERTIME|AMT|CURRENCYCODE|FEEAMT|SETTLEAMT|TAXAMT|EXCHANGERATE|PAYMENTSTATUS|PENDINGREASON|REASONCODE|HOLDDECISION|SHIPPINGMETHOD|PROTECTIONELIGIBILITY|PROTECTIONELIGIBILITYTYPE|RECEIPTREFERENCENUMBER|SHIPPINGAMT|HANDLINGAMT|PAYMENTREQUESTID|INSTRUMENTCATEGORY|INSTRUMENTID|OFFERCODE|OFFERTRACKINGID|SHORTMESSAGE|LONGMESSAGE|ERRORCODE|SEVERITYCODE|ACK|SELLERPAYPALACCOUNTID|SECUREMERCHANTACCOUNTID|SELLERID|SELLERUSERNAME|SELLERREGISTRATIONDATE)$/', $index, $matches ) ) {
40
- if ( $matches[1] > $max_payment_num ) {
41
  $max_payment_num = $matches[1];
42
  }
43
  }
@@ -62,12 +62,12 @@ class PayPal_Payment_Details {
62
  class PayPal_Payment_Payment_FMF_Details {
63
  public $filters = false;
64
 
65
- function loadFromDoECResponse( $doECResponse, $bucketNum ) {
66
  $max_filter_num = array(
67
  'PENDING' => -1,
68
  'REPORT' => -1,
69
  'DENY' => -1,
70
- 'ACCEPT' => -1
71
  );
72
 
73
  $found_any = false;
@@ -117,11 +117,11 @@ class PayPal_Payment_Fraud_Management_Filter {
117
  }
118
 
119
  class PayPal_Payment_Shipping_Option_Details {
120
- public $calculation_mode = false;
121
- public $insurance_option_selected = false;
122
  public $shipping_option_is_default = false;
123
- public $shipping_option_amount = false;
124
- public $shipping_option_name = false;
125
 
126
  public function loadFromDoECResponse( $doECResponse ) {
127
  $map = array(
@@ -129,14 +129,14 @@ class PayPal_Payment_Shipping_Option_Details {
129
  'INSURANCEOPTIONSELECTED' => 'insurance_option_selected',
130
  'SHIPPINGOPTIONISDEFAULT' => 'shipping_option_is_default',
131
  'SHIPPINGOPTIONAMOUNT' => 'shipping_option_amount',
132
- 'SHIPPINGOPTIONNAME' => 'shipping_option_name'
133
  );
134
 
135
  $found_any = false;
136
  foreach ( $map as $index => $value ) {
137
  if ( array_key_exists( $index, $doECResponse ) ) {
138
  $this->$value = $doECResponse[ $index ];
139
- $found_any = true;
140
  }
141
  }
142
 
@@ -151,84 +151,84 @@ class PayPal_Payment_Payment_Details {
151
  public $receipt_id = false;
152
  public $transaction_type = false;
153
 
154
- const TransactionTypeCart = 'cart';
155
- const TransactionTypeExpressCheckout = 'express-checkout';
156
-
157
- public $payment_type = false;
158
-
159
- const PaymentTypeNone = 'none';
160
- const PaymentTypeEcheck = 'echeck';
161
- const PaymentTypeInstant = 'instant';
162
-
163
- public $expected_echeck_clear_date = false;
164
- public $order_time = false;
165
- public $amount = false;
166
- public $currency_code = false;
167
- public $fee_amount = false;
168
- public $settlement_amount = false;
169
- public $tax_amount = false;
170
- public $exchange_rate = false;
171
- public $payment_status = false;
172
-
173
- const PaymentStatusNone = 'None';
174
- const PaymentStatusCanceledReversal = 'Canceled-Reversal';
175
- const PaymentStatusCompleted = 'Completed';
176
- const PaymentStatusDenied = 'Denied';
177
- const PaymentStatusExpired = 'Expired';
178
- const PaymentStatusFailed = 'Failed';
179
- const PaymentStatusInProgress = 'In-Progress';
180
- const PaymentStatusPartiallyRefunded = 'Partially-Refunded';
181
- const PaymentStatusPending = 'Pending';
182
- const PaymentStatusRefunded = 'Refunded';
183
- const PaymentStatusReversed = 'Reversed';
184
- const PaymentStatusProcessed = 'Processed';
185
- const PaymentStatusVoided = 'Voided';
186
- const PaymentStatusCompletedFundsHeld = 'Completed-Funds-Held';
187
-
188
- public $pending_reason = false;
189
-
190
- const PendingReasonNone = 'none';
191
- const PendingReasonAddress = 'address';
192
- const PendingReasonAuthorization = 'authorization';
193
- const PendingReasonEcheck = 'echeck';
194
- const PendingReasonInternational = 'intl';
195
- const PendingReasonMultiCurrency = 'multi-currency';
196
- const PendingReasonOrder = 'order';
197
- const PendingReasonPaymentReview = 'payment-review';
198
- const PendingReasonRegulatoryReview = 'regulatory-review';
199
- const PendingReasonUnilateral = 'unilateral';
200
- const PendingReasonVerify = 'verify';
201
- const PendingReasonOther = 'other';
202
-
203
- public $reason_code = false;
204
-
205
- const ReasonCodeNone = 'none';
206
- const ReasonCodeChargeback = 'chargeback';
207
- const ReasonCodeGuarantee = 'guarantee';
208
- const ReasonCodeBuyerComplaint = 'buyer-complaint';
209
- const ReasonCodeRefund = 'refund';
210
- const ReasonCodeOther = 'other';
211
 
212
  public $hold_decision = false;
213
 
214
- const HoldDecisionNewSellerPaymentHold = 'newsellerpaymenthold';
215
- const HoldDecisionPaymentHold = 'paymenthold';
216
 
217
- public $shipping_method = false;
218
 
219
- public $protection_eligibility_details = false;
220
- public $receipt_reference_number = false;
221
- public $shipping_amount = false;
222
 
223
- public $handling_amount = false;
224
 
225
- public $payment_request_id = false;
226
- public $instrument_details = false;
227
 
228
- public $offer_details = false;
229
- public $error_details = false;
230
- public $seller_details = false;
231
- public $fmf_details = false;
232
 
233
  public function loadFromDoECResponse( $doECResponse, $bucketNum ) {
234
  $map = array(
@@ -254,7 +254,7 @@ class PayPal_Payment_Payment_Details {
254
  'RECEIPTREFERENCENUMBER' => 'receipt_reference_number',
255
  'SHIPPINGAMT' => 'shipping_amount',
256
  'HANDLINGAMT' => 'handling_amount',
257
- 'PAYMENTREQUESTID' => 'payment_request_id'
258
  );
259
 
260
  $found_any = false;
@@ -262,7 +262,7 @@ class PayPal_Payment_Payment_Details {
262
  $var_name = 'PAYMENTINFO_' . $bucketNum . '_' . $index;
263
  if ( array_key_exists( $var_name, $doECResponse ) ) {
264
  $this->$value = $doECResponse[ $var_name ];
265
- $found_any = true;
266
  }
267
  }
268
 
@@ -300,13 +300,13 @@ class PayPal_Payment_Payment_Details {
300
  }
301
 
302
  class PayPal_Payment_Payment_Protection_Eligibility_Details {
303
- public $protection_eligibility = false;
304
 
305
- const ProtectionEligibilityEligible = 'Eligible';
306
- const ProtectionEligibilityPartiallyEligible = 'PartiallyEligible';
307
- const ProtectionEligibilityIneligible = 'Ineligible';
308
 
309
- public $protection_eligibility_type = false;
310
 
311
  const ProtectionEligibilityTypeItemNotReceivedEligible = 'ItemNotReceivedEligible';
312
  const ProtectionEligibilityTypeUnauthorizedPaymentEligible = 'UnauthorizedPaymentEligible';
@@ -315,7 +315,7 @@ class PayPal_Payment_Payment_Protection_Eligibility_Details {
315
  public function isItemNotReceivedEligible() {
316
  $types = explode( ',', $this->protection_eligibility_type );
317
  foreach ( $types as $value ) {
318
- if ( self::ProtectionEligibilityTypeItemNotReceivedEligible == $value ) {
319
  return true;
320
  }
321
  }
@@ -325,7 +325,7 @@ class PayPal_Payment_Payment_Protection_Eligibility_Details {
325
  public function isUnauthorizedPaymentEligible() {
326
  $types = explode( ',', $this->protection_eligibility_type );
327
  foreach ( $types as $value ) {
328
- if ( self::ProtectionEligibilityTypeUnauthorizedPaymentEligible == $value ) {
329
  return true;
330
  }
331
  }
@@ -335,7 +335,7 @@ class PayPal_Payment_Payment_Protection_Eligibility_Details {
335
  public function loadFromDoECResponse( $doECResponse, $bucketNum ) {
336
  $map = array(
337
  'PROTECTIONELIGIBILITY' => 'protection_eligibility',
338
- 'PROTECTIONELIGIBILITYTYPE' => 'protection_eligibility_type'
339
  );
340
 
341
  $found_any = false;
@@ -344,7 +344,7 @@ class PayPal_Payment_Payment_Protection_Eligibility_Details {
344
  $var_name = 'PAYMENTINFO_' . $bucketNum . '_' . $index;
345
  if ( array_key_exists( $var_name, $doECResponse ) ) {
346
  $this->$value = $doECResponse[ $var_name ];
347
- $found_any = true;
348
  }
349
  }
350
 
@@ -353,19 +353,19 @@ class PayPal_Payment_Payment_Protection_Eligibility_Details {
353
  }
354
 
355
  class PayPal_Payment_Payment_Instrument_Details {
356
- public $instrument_category = false;
357
 
358
  const InstrumentCategoryPayPalCredit = '1';
359
  const InstrumentCategoryPrivateCard = '2';
360
 
361
- public $instrument_id = false;
362
 
363
  // Returns true to indicate that the getECResponse array contained variables that were pertinent to this object.
364
  // If not, it returns false to indicate that the caller can destroy this object.
365
  public function loadFromDoECResponse( $doECResponse, $bucketNum ) {
366
- $map = array(
367
  'INSTRUMENTCATEGORY' => 'instrument_category',
368
- 'INSTRUMENTID' => 'instrument_id'
369
  );
370
  $found_any = false;
371
 
@@ -373,7 +373,7 @@ class PayPal_Payment_Payment_Instrument_Details {
373
  $var_name = 'PAYMENTINFO_' . $bucketNum . '_' . $index;
374
  if ( array_key_exists( $var_name, $doECResponse ) ) {
375
  $this->$value = $doECResponse[ $var_name ];
376
- $found_any = true;
377
  }
378
  }
379
 
@@ -388,7 +388,7 @@ class PayPal_Payment_Payment_Offer_Details {
388
  public function loadFromDoECResponse( $doECResponse, $bucketNum ) {
389
  $map = array(
390
  'OFFERCODE' => 'offer_code',
391
- 'OFFERTRACKINGID' => 'offer_tracking_id'
392
  );
393
  }
394
  }
@@ -406,7 +406,7 @@ class PayPal_Payment_Payment_Error_Details {
406
  'LONGMESSAGE' => 'long_message',
407
  'ERRORCODE' => 'error_code',
408
  'SEVERITYCODE' => 'severity_code',
409
- 'ACK' => 'ack'
410
  );
411
 
412
  $found_any = false;
@@ -414,7 +414,7 @@ class PayPal_Payment_Payment_Error_Details {
414
  $var_name = 'PAYMENTINFO_' . $bucketNum . '_' . $index;
415
  if ( array_key_exists( $var_name, $doECResponse ) ) {
416
  $this->$value = $doECResponse[ $var_name ];
417
- $found_any = true;
418
  }
419
  }
420
 
@@ -435,7 +435,7 @@ class PayPal_Payment_Payment_Seller_Details {
435
  'SECUREMERCHANTACCOUNTID' => 'secure_merchant_account_id',
436
  'SELLERID' => 'seller_id',
437
  'SELLERUSERNAME' => 'user_name',
438
- 'SELLERREGISTRATIONDATE' => 'registration_date'
439
  );
440
 
441
  $found_any = false;
@@ -443,7 +443,7 @@ class PayPal_Payment_Payment_Seller_Details {
443
  $var_name = 'PAYMENTINFO_' . $bucketNum . '_' . $index;
444
  if ( array_key_exists( $var_name, $doECResponse ) ) {
445
  $this->$value = $doECResponse[ $var_name ];
446
- $found_any = true;
447
  }
448
  }
449
 
9
  }
10
 
11
  class PayPal_Payment_Details {
12
+ public $token = false;
13
+ public $billing_agreement_id = false;
14
+ public $redirect_required = false;
15
+ public $redirect_requested = false;
16
+ public $note = false;
17
 
18
+ public $payments = false;
19
 
20
  public $shipping_option_details = false;
21
 
25
  'BILLINGAGREEMENTID' => 'billing_agreement_id',
26
  'REDIRECTREQUIRED' => 'redirect_required',
27
  'SUCCESSPAGEREDIRECTREQUESTED' => 'redirect_requested',
28
+ 'NOTE' => 'note',
29
  );
30
 
31
  $max_payment_num = -1;
32
 
33
  foreach ( $doECResponse as $index => $value ) {
34
  if ( array_key_exists( $index, $map ) ) {
35
+ $key = $map[ $index ];
36
  $this->$key = $value;
37
  }
38
  // Figure out the highest payment number
39
  if ( preg_match( '/^PAYMENTINFO_(\d)_(TRANSACTIONID|EBAYITEMAUCTIONTXNID|PARENTTRANSACTIONID|RECEIPTID|TRANSACTIONTYPE|PAYMENTTYPE|EXPECTEDECHECKCLEARDATE|ORDERTIME|AMT|CURRENCYCODE|FEEAMT|SETTLEAMT|TAXAMT|EXCHANGERATE|PAYMENTSTATUS|PENDINGREASON|REASONCODE|HOLDDECISION|SHIPPINGMETHOD|PROTECTIONELIGIBILITY|PROTECTIONELIGIBILITYTYPE|RECEIPTREFERENCENUMBER|SHIPPINGAMT|HANDLINGAMT|PAYMENTREQUESTID|INSTRUMENTCATEGORY|INSTRUMENTID|OFFERCODE|OFFERTRACKINGID|SHORTMESSAGE|LONGMESSAGE|ERRORCODE|SEVERITYCODE|ACK|SELLERPAYPALACCOUNTID|SECUREMERCHANTACCOUNTID|SELLERID|SELLERUSERNAME|SELLERREGISTRATIONDATE)$/', $index, $matches ) ) {
40
+ if ( $matches[1] > $max_payment_num ) {
41
  $max_payment_num = $matches[1];
42
  }
43
  }
62
  class PayPal_Payment_Payment_FMF_Details {
63
  public $filters = false;
64
 
65
+ public function loadFromDoECResponse( $doECResponse, $bucketNum ) {
66
  $max_filter_num = array(
67
  'PENDING' => -1,
68
  'REPORT' => -1,
69
  'DENY' => -1,
70
+ 'ACCEPT' => -1,
71
  );
72
 
73
  $found_any = false;
117
  }
118
 
119
  class PayPal_Payment_Shipping_Option_Details {
120
+ public $calculation_mode = false;
121
+ public $insurance_option_selected = false;
122
  public $shipping_option_is_default = false;
123
+ public $shipping_option_amount = false;
124
+ public $shipping_option_name = false;
125
 
126
  public function loadFromDoECResponse( $doECResponse ) {
127
  $map = array(
129
  'INSURANCEOPTIONSELECTED' => 'insurance_option_selected',
130
  'SHIPPINGOPTIONISDEFAULT' => 'shipping_option_is_default',
131
  'SHIPPINGOPTIONAMOUNT' => 'shipping_option_amount',
132
+ 'SHIPPINGOPTIONNAME' => 'shipping_option_name',
133
  );
134
 
135
  $found_any = false;
136
  foreach ( $map as $index => $value ) {
137
  if ( array_key_exists( $index, $doECResponse ) ) {
138
  $this->$value = $doECResponse[ $index ];
139
+ $found_any = true;
140
  }
141
  }
142
 
151
  public $receipt_id = false;
152
  public $transaction_type = false;
153
 
154
+ const TransactionTypeCart = 'cart';
155
+ const TransactionTypeExpressCheckout = 'express-checkout';
156
+
157
+ public $payment_type = false;
158
+
159
+ const PaymentTypeNone = 'none';
160
+ const PaymentTypeEcheck = 'echeck';
161
+ const PaymentTypeInstant = 'instant';
162
+
163
+ public $expected_echeck_clear_date = false;
164
+ public $order_time = false;
165
+ public $amount = false;
166
+ public $currency_code = false;
167
+ public $fee_amount = false;
168
+ public $settlement_amount = false;
169
+ public $tax_amount = false;
170
+ public $exchange_rate = false;
171
+ public $payment_status = false;
172
+
173
+ const PaymentStatusNone = 'None';
174
+ const PaymentStatusCanceledReversal = 'Canceled-Reversal';
175
+ const PaymentStatusCompleted = 'Completed';
176
+ const PaymentStatusDenied = 'Denied';
177
+ const PaymentStatusExpired = 'Expired';
178
+ const PaymentStatusFailed = 'Failed';
179
+ const PaymentStatusInProgress = 'In-Progress';
180
+ const PaymentStatusPartiallyRefunded = 'Partially-Refunded';
181
+ const PaymentStatusPending = 'Pending';
182
+ const PaymentStatusRefunded = 'Refunded';
183
+ const PaymentStatusReversed = 'Reversed';
184
+ const PaymentStatusProcessed = 'Processed';
185
+ const PaymentStatusVoided = 'Voided';
186
+ const PaymentStatusCompletedFundsHeld = 'Completed-Funds-Held';
187
+
188
+ public $pending_reason = false;
189
+
190
+ const PendingReasonNone = 'none';
191
+ const PendingReasonAddress = 'address';
192
+ const PendingReasonAuthorization = 'authorization';
193
+ const PendingReasonEcheck = 'echeck';
194
+ const PendingReasonInternational = 'intl';
195
+ const PendingReasonMultiCurrency = 'multi-currency';
196
+ const PendingReasonOrder = 'order';
197
+ const PendingReasonPaymentReview = 'payment-review';
198
+ const PendingReasonRegulatoryReview = 'regulatory-review';
199
+ const PendingReasonUnilateral = 'unilateral';
200
+ const PendingReasonVerify = 'verify';
201
+ const PendingReasonOther = 'other';
202
+
203
+ public $reason_code = false;
204
+
205
+ const ReasonCodeNone = 'none';
206
+ const ReasonCodeChargeback = 'chargeback';
207
+ const ReasonCodeGuarantee = 'guarantee';
208
+ const ReasonCodeBuyerComplaint = 'buyer-complaint';
209
+ const ReasonCodeRefund = 'refund';
210
+ const ReasonCodeOther = 'other';
211
 
212
  public $hold_decision = false;
213
 
214
+ const HoldDecisionNewSellerPaymentHold = 'newsellerpaymenthold';
215
+ const HoldDecisionPaymentHold = 'paymenthold';
216
 
217
+ public $shipping_method = false;
218
 
219
+ public $protection_eligibility_details = false;
220
+ public $receipt_reference_number = false;
221
+ public $shipping_amount = false;
222
 
223
+ public $handling_amount = false;
224
 
225
+ public $payment_request_id = false;
226
+ public $instrument_details = false;
227
 
228
+ public $offer_details = false;
229
+ public $error_details = false;
230
+ public $seller_details = false;
231
+ public $fmf_details = false;
232
 
233
  public function loadFromDoECResponse( $doECResponse, $bucketNum ) {
234
  $map = array(
254
  'RECEIPTREFERENCENUMBER' => 'receipt_reference_number',
255
  'SHIPPINGAMT' => 'shipping_amount',
256
  'HANDLINGAMT' => 'handling_amount',
257
+ 'PAYMENTREQUESTID' => 'payment_request_id',
258
  );
259
 
260
  $found_any = false;
262
  $var_name = 'PAYMENTINFO_' . $bucketNum . '_' . $index;
263
  if ( array_key_exists( $var_name, $doECResponse ) ) {
264
  $this->$value = $doECResponse[ $var_name ];
265
+ $found_any = true;
266
  }
267
  }
268
 
300
  }
301
 
302
  class PayPal_Payment_Payment_Protection_Eligibility_Details {
303
+ public $protection_eligibility = false;
304
 
305
+ const ProtectionEligibilityEligible = 'Eligible';
306
+ const ProtectionEligibilityPartiallyEligible = 'PartiallyEligible';
307
+ const ProtectionEligibilityIneligible = 'Ineligible';
308
 
309
+ public $protection_eligibility_type = false;
310
 
311
  const ProtectionEligibilityTypeItemNotReceivedEligible = 'ItemNotReceivedEligible';
312
  const ProtectionEligibilityTypeUnauthorizedPaymentEligible = 'UnauthorizedPaymentEligible';
315
  public function isItemNotReceivedEligible() {
316
  $types = explode( ',', $this->protection_eligibility_type );
317
  foreach ( $types as $value ) {
318
+ if ( self::ProtectionEligibilityTypeItemNotReceivedEligible == $value ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
319
  return true;
320
  }
321
  }
325
  public function isUnauthorizedPaymentEligible() {
326
  $types = explode( ',', $this->protection_eligibility_type );
327
  foreach ( $types as $value ) {
328
+ if ( self::ProtectionEligibilityTypeUnauthorizedPaymentEligible == $value ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
329
  return true;
330
  }
331
  }
335
  public function loadFromDoECResponse( $doECResponse, $bucketNum ) {
336
  $map = array(
337
  'PROTECTIONELIGIBILITY' => 'protection_eligibility',
338
+ 'PROTECTIONELIGIBILITYTYPE' => 'protection_eligibility_type',
339
  );
340
 
341
  $found_any = false;
344
  $var_name = 'PAYMENTINFO_' . $bucketNum . '_' . $index;
345
  if ( array_key_exists( $var_name, $doECResponse ) ) {
346
  $this->$value = $doECResponse[ $var_name ];
347
+ $found_any = true;
348
  }
349
  }
350
 
353
  }
354
 
355
  class PayPal_Payment_Payment_Instrument_Details {
356
+ public $instrument_category = false;
357
 
358
  const InstrumentCategoryPayPalCredit = '1';
359
  const InstrumentCategoryPrivateCard = '2';
360
 
361
+ public $instrument_id = false;
362
 
363
  // Returns true to indicate that the getECResponse array contained variables that were pertinent to this object.
364
  // If not, it returns false to indicate that the caller can destroy this object.
365
  public function loadFromDoECResponse( $doECResponse, $bucketNum ) {
366
+ $map = array(
367
  'INSTRUMENTCATEGORY' => 'instrument_category',
368
+ 'INSTRUMENTID' => 'instrument_id',
369
  );
370
  $found_any = false;
371
 
373
  $var_name = 'PAYMENTINFO_' . $bucketNum . '_' . $index;
374
  if ( array_key_exists( $var_name, $doECResponse ) ) {
375
  $this->$value = $doECResponse[ $var_name ];
376
+ $found_any = true;
377
  }
378
  }
379
 
388
  public function loadFromDoECResponse( $doECResponse, $bucketNum ) {
389
  $map = array(
390
  'OFFERCODE' => 'offer_code',
391
+ 'OFFERTRACKINGID' => 'offer_tracking_id',
392
  );
393
  }
394
  }
406
  'LONGMESSAGE' => 'long_message',
407
  'ERRORCODE' => 'error_code',
408
  'SEVERITYCODE' => 'severity_code',
409
+ 'ACK' => 'ack',
410
  );
411
 
412
  $found_any = false;
414
  $var_name = 'PAYMENTINFO_' . $bucketNum . '_' . $index;
415
  if ( array_key_exists( $var_name, $doECResponse ) ) {
416
  $this->$value = $doECResponse[ $var_name ];
417
+ $found_any = true;
418
  }
419
  }
420
 
435
  'SECUREMERCHANTACCOUNTID' => 'secure_merchant_account_id',
436
  'SELLERID' => 'seller_id',
437
  'SELLERUSERNAME' => 'user_name',
438
+ 'SELLERREGISTRATIONDATE' => 'registration_date',
439
  );
440
 
441
  $found_any = false;
443
  $var_name = 'PAYMENTINFO_' . $bucketNum . '_' . $index;
444
  if ( array_key_exists( $var_name, $doECResponse ) ) {
445
  $this->$value = $doECResponse[ $var_name ];
446
+ $found_any = true;
447
  }
448
  }
449
 
includes/class-wc-gateway-ppec-plugin.php CHANGED
@@ -9,9 +9,9 @@ if ( ! defined( 'ABSPATH' ) ) {
9
 
10
  class WC_Gateway_PPEC_Plugin {
11
 
12
- const ALREADY_BOOTSTRAPED = 1;
13
  const DEPENDENCIES_UNSATISFIED = 2;
14
- const NOT_CONNECTED = 3;
15
 
16
  /**
17
  * Filepath of main plugin file.
@@ -98,7 +98,7 @@ class WC_Gateway_PPEC_Plugin {
98
  $settings_array['debug'] = get_option( 'pp_woo_logging_enabled' ) ? 'yes' : 'no';
99
 
100
  // Make sure button size is correct.
101
- if ( ! in_array( $settings_array['button_size'], array( 'small', 'medium', 'large' ) ) ) {
102
  $settings_array['button_size'] = 'medium';
103
  }
104
 
@@ -144,7 +144,7 @@ class WC_Gateway_PPEC_Plugin {
144
  register_activation_hook( $this->file, array( $this, 'activate' ) );
145
 
146
  add_action( 'plugins_loaded', array( $this, 'bootstrap' ) );
147
- add_filter( 'allowed_redirect_hosts' , array( $this, 'whitelist_paypal_domains_for_redirect' ) );
148
  add_action( 'init', array( $this, 'load_plugin_textdomain' ) );
149
 
150
  add_filter( 'plugin_action_links_' . plugin_basename( $this->file ), array( $this, 'plugin_action_links' ) );
@@ -155,7 +155,7 @@ class WC_Gateway_PPEC_Plugin {
155
  public function bootstrap() {
156
  try {
157
  if ( $this->_bootstrapped ) {
158
- throw new Exception( __( '%s in WooCommerce Gateway PayPal Checkout plugin can only be called once', 'woocommerce-gateway-paypal-express-checkout' ), self::ALREADY_BOOTSTRAPED );
159
  }
160
 
161
  $this->_check_dependencies();
@@ -169,7 +169,7 @@ class WC_Gateway_PPEC_Plugin {
169
 
170
  $this->_bootstrapped = true;
171
  } catch ( Exception $e ) {
172
- if ( in_array( $e->getCode(), array( self::ALREADY_BOOTSTRAPED, self::DEPENDENCIES_UNSATISFIED ) ) ) {
173
  $this->bootstrap_warning_message = $e->getMessage();
174
  }
175
 
@@ -295,6 +295,7 @@ class WC_Gateway_PPEC_Plugin {
295
  $credential = $this->settings->get_active_api_credentials();
296
  if ( ! is_a( $credential, 'WC_Gateway_PPEC_Client_Credential' ) || '' === $credential->get_username() ) {
297
  $setting_link = $this->get_admin_setting_link();
 
298
  throw new Exception( sprintf( __( 'PayPal Checkout is almost ready. To get started, <a href="%s">connect your PayPal account</a>.', 'woocommerce-gateway-paypal-express-checkout' ), esc_url( $setting_link ) ), self::NOT_CONNECTED );
299
  }
300
  }
@@ -303,7 +304,7 @@ class WC_Gateway_PPEC_Plugin {
303
  * Run the plugin.
304
  */
305
  protected function _run() {
306
- require_once( $this->includes_path . 'functions.php' );
307
  $this->_load_handlers();
308
  }
309
 
@@ -312,7 +313,7 @@ class WC_Gateway_PPEC_Plugin {
312
  */
313
  public function activate() {
314
  if ( ! isset( $this->settings ) ) {
315
- require_once( $this->includes_path . 'class-wc-gateway-ppec-settings.php' );
316
  $settings = new WC_Gateway_PPEC_Settings();
317
  } else {
318
  $settings = $this->settings;
@@ -333,15 +334,15 @@ class WC_Gateway_PPEC_Plugin {
333
  $this->_load_client();
334
 
335
  // Load handlers.
336
- require_once( $this->includes_path . 'class-wc-gateway-ppec-privacy.php' );
337
- require_once( $this->includes_path . 'class-wc-gateway-ppec-settings.php' );
338
- require_once( $this->includes_path . 'class-wc-gateway-ppec-gateway-loader.php' );
339
- require_once( $this->includes_path . 'class-wc-gateway-ppec-admin-handler.php' );
340
- require_once( $this->includes_path . 'class-wc-gateway-ppec-checkout-handler.php' );
341
- require_once( $this->includes_path . 'class-wc-gateway-ppec-cart-handler.php' );
342
- require_once( $this->includes_path . 'class-wc-gateway-ppec-ips-handler.php' );
343
- require_once( $this->includes_path . 'abstracts/abstract-wc-gateway-ppec-paypal-request-handler.php' );
344
- require_once( $this->includes_path . 'class-wc-gateway-ppec-ipn-handler.php' );
345
 
346
  $this->settings = new WC_Gateway_PPEC_Settings();
347
  $this->gateway_loader = new WC_Gateway_PPEC_Gateway_Loader();
@@ -358,10 +359,10 @@ class WC_Gateway_PPEC_Plugin {
358
  * @since 1.1.0
359
  */
360
  protected function _load_client() {
361
- require_once( $this->includes_path . 'abstracts/abstract-wc-gateway-ppec-client-credential.php' );
362
- require_once( $this->includes_path . 'class-wc-gateway-ppec-client-credential-certificate.php' );
363
- require_once( $this->includes_path . 'class-wc-gateway-ppec-client-credential-signature.php' );
364
- require_once( $this->includes_path . 'class-wc-gateway-ppec-client.php' );
365
  }
366
 
367
  /**
@@ -424,7 +425,7 @@ class WC_Gateway_PPEC_Plugin {
424
  $plugin_links = array();
425
 
426
  if ( function_exists( 'WC' ) ) {
427
- $setting_url = $this->get_admin_setting_link();
428
  $plugin_links[] = '<a href="' . esc_url( $setting_url ) . '">' . esc_html__( 'Settings', 'woocommerce-gateway-paypal-express-checkout' ) . '</a>';
429
  }
430
 
@@ -500,10 +501,11 @@ class WC_Gateway_PPEC_Plugin {
500
  }
501
 
502
  $setting_link = $this->get_admin_setting_link();
 
503
  $message = sprintf( __( '<p>PayPal Checkout with new <strong>Smart Payment Buttons™</strong> gives your customers the power to pay the way they want without leaving your site.</p><p>The <strong>existing buttons will be removed</strong> in the <strong>next release</strong>. Please upgrade to Smart Payment Buttons on the <a href="%s">PayPal Checkout settings page</a>.</p>', 'woocommerce-gateway-paypal-express-checkout' ), esc_url( $setting_link ) );
504
  ?>
505
  <div class="notice notice-error">
506
- <?php echo wp_kses( $message, array( 'a' => array( 'href' => array() ), 'strong' => array(), 'p' => array() ) ); ?>
507
  </div>
508
  <?php
509
  }
9
 
10
  class WC_Gateway_PPEC_Plugin {
11
 
12
+ const ALREADY_BOOTSTRAPED = 1;
13
  const DEPENDENCIES_UNSATISFIED = 2;
14
+ const NOT_CONNECTED = 3;
15
 
16
  /**
17
  * Filepath of main plugin file.
98
  $settings_array['debug'] = get_option( 'pp_woo_logging_enabled' ) ? 'yes' : 'no';
99
 
100
  // Make sure button size is correct.
101
+ if ( ! in_array( $settings_array['button_size'], array( 'small', 'medium', 'large' ), true ) ) {
102
  $settings_array['button_size'] = 'medium';
103
  }
104
 
144
  register_activation_hook( $this->file, array( $this, 'activate' ) );
145
 
146
  add_action( 'plugins_loaded', array( $this, 'bootstrap' ) );
147
+ add_filter( 'allowed_redirect_hosts', array( $this, 'whitelist_paypal_domains_for_redirect' ) );
148
  add_action( 'init', array( $this, 'load_plugin_textdomain' ) );
149
 
150
  add_filter( 'plugin_action_links_' . plugin_basename( $this->file ), array( $this, 'plugin_action_links' ) );
155
  public function bootstrap() {
156
  try {
157
  if ( $this->_bootstrapped ) {
158
+ throw new Exception( __( 'bootstrap() in WooCommerce Gateway PayPal Checkout plugin can only be called once', 'woocommerce-gateway-paypal-express-checkout' ), self::ALREADY_BOOTSTRAPED );
159
  }
160
 
161
  $this->_check_dependencies();
169
 
170
  $this->_bootstrapped = true;
171
  } catch ( Exception $e ) {
172
+ if ( in_array( $e->getCode(), array( self::ALREADY_BOOTSTRAPED, self::DEPENDENCIES_UNSATISFIED ) ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
173
  $this->bootstrap_warning_message = $e->getMessage();
174
  }
175
 
295
  $credential = $this->settings->get_active_api_credentials();
296
  if ( ! is_a( $credential, 'WC_Gateway_PPEC_Client_Credential' ) || '' === $credential->get_username() ) {
297
  $setting_link = $this->get_admin_setting_link();
298
+ // Translators: placeholder is the URL of the gateway settings page.
299
  throw new Exception( sprintf( __( 'PayPal Checkout is almost ready. To get started, <a href="%s">connect your PayPal account</a>.', 'woocommerce-gateway-paypal-express-checkout' ), esc_url( $setting_link ) ), self::NOT_CONNECTED );
300
  }
301
  }
304
  * Run the plugin.
305
  */
306
  protected function _run() {
307
+ require_once $this->includes_path . 'functions.php';
308
  $this->_load_handlers();
309
  }
310
 
313
  */
314
  public function activate() {
315
  if ( ! isset( $this->settings ) ) {
316
+ require_once $this->includes_path . 'class-wc-gateway-ppec-settings.php';
317
  $settings = new WC_Gateway_PPEC_Settings();
318
  } else {
319
  $settings = $this->settings;
334
  $this->_load_client();
335
 
336
  // Load handlers.
337
+ require_once $this->includes_path . 'class-wc-gateway-ppec-settings.php';
338
+ require_once $this->includes_path . 'class-wc-gateway-ppec-privacy.php';
339
+ require_once $this->includes_path . 'class-wc-gateway-ppec-gateway-loader.php';
340
+ require_once $this->includes_path . 'class-wc-gateway-ppec-admin-handler.php';
341
+ require_once $this->includes_path . 'class-wc-gateway-ppec-checkout-handler.php';
342
+ require_once $this->includes_path . 'class-wc-gateway-ppec-cart-handler.php';
343
+ require_once $this->includes_path . 'class-wc-gateway-ppec-ips-handler.php';
344
+ require_once $this->includes_path . 'abstracts/abstract-wc-gateway-ppec-paypal-request-handler.php';
345
+ require_once $this->includes_path . 'class-wc-gateway-ppec-ipn-handler.php';
346
 
347
  $this->settings = new WC_Gateway_PPEC_Settings();
348
  $this->gateway_loader = new WC_Gateway_PPEC_Gateway_Loader();
359
  * @since 1.1.0
360
  */
361
  protected function _load_client() {
362
+ require_once $this->includes_path . 'abstracts/abstract-wc-gateway-ppec-client-credential.php';
363
+ require_once $this->includes_path . 'class-wc-gateway-ppec-client-credential-certificate.php';
364
+ require_once $this->includes_path . 'class-wc-gateway-ppec-client-credential-signature.php';
365
+ require_once $this->includes_path . 'class-wc-gateway-ppec-client.php';
366
  }
367
 
368
  /**
425
  $plugin_links = array();
426
 
427
  if ( function_exists( 'WC' ) ) {
428
+ $setting_url = $this->get_admin_setting_link();
429
  $plugin_links[] = '<a href="' . esc_url( $setting_url ) . '">' . esc_html__( 'Settings', 'woocommerce-gateway-paypal-express-checkout' ) . '</a>';
430
  }
431
 
501
  }
502
 
503
  $setting_link = $this->get_admin_setting_link();
504
+ // Translators: placeholder is the URL of the gateway settings page.
505
  $message = sprintf( __( '<p>PayPal Checkout with new <strong>Smart Payment Buttons™</strong> gives your customers the power to pay the way they want without leaving your site.</p><p>The <strong>existing buttons will be removed</strong> in the <strong>next release</strong>. Please upgrade to Smart Payment Buttons on the <a href="%s">PayPal Checkout settings page</a>.</p>', 'woocommerce-gateway-paypal-express-checkout' ), esc_url( $setting_link ) );
506
  ?>
507
  <div class="notice notice-error">
508
+ <?php echo wp_kses( $message, array( 'a' => array( 'href' => array() ), 'strong' => array(), 'p' => array() ) ); // phpcs:ignore WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound ?>
509
  </div>
510
  <?php
511
  }
includes/class-wc-gateway-ppec-privacy.php CHANGED
@@ -30,7 +30,7 @@ class WC_Gateway_PPEC_Privacy extends WC_Abstract_Privacy {
30
  protected function get_ppec_orders( $email_address, $page ) {
31
  $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
32
 
33
- $order_query = array(
34
  'payment_method' => array( 'ppec_paypal' ),
35
  'limit' => 10,
36
  'page' => $page,
@@ -50,6 +50,7 @@ class WC_Gateway_PPEC_Privacy extends WC_Abstract_Privacy {
50
  *
51
  */
52
  public function get_privacy_message() {
 
53
  return wpautop( sprintf( __( 'By using this extension, you may be storing personal data or sharing data with an external service. <a href="%s" target="_blank">Learn more about how this works, including what you may want to include in your privacy policy.</a>', 'woocommerce-gateway-paypal-express-checkout' ), 'https://docs.woocommerce.com/document/privacy-payments/#woocommerce-gateway-paypal-express-checkout' ) );
54
  }
55
 
@@ -78,7 +79,7 @@ class WC_Gateway_PPEC_Privacy extends WC_Abstract_Privacy {
78
  'data' => array(
79
  array(
80
  'name' => __( 'PPEC Refundable transaction data', 'woocommerce-gateway-paypal-express-checkout' ),
81
- 'value' => json_encode( get_post_meta( $order->get_id(), '_woo_pp_txnData', true ) ),
82
  ),
83
  array(
84
  'name' => __( 'PPEC Billing agreement id', 'woocommerce-gateway-paypal-express-checkout' ),
@@ -111,7 +112,7 @@ class WC_Gateway_PPEC_Privacy extends WC_Abstract_Privacy {
111
  $data_to_export = array();
112
 
113
  $meta_query = array(
114
- 'relation' => 'AND',
115
  array(
116
  'key' => '_payment_method',
117
  'value' => array( 'ppec_paypal' ),
@@ -124,10 +125,10 @@ class WC_Gateway_PPEC_Privacy extends WC_Abstract_Privacy {
124
  ),
125
  );
126
 
127
- $subscription_query = array(
128
- 'posts_per_page' => 10,
129
- 'page' => $page,
130
- 'meta_query' => $meta_query,
131
  );
132
 
133
  $subscriptions = wcs_get_subscriptions( $subscription_query );
@@ -143,7 +144,7 @@ class WC_Gateway_PPEC_Privacy extends WC_Abstract_Privacy {
143
  'data' => array(
144
  array(
145
  'name' => __( 'PPEC Refundable transaction data', 'woocommerce-gateway-paypal-express-checkout' ),
146
- 'value' => json_encode( get_post_meta( $subscription->get_id(), '_woo_pp_txnData', true ) ),
147
  ),
148
  array(
149
  'name' => __( 'PPEC Billing agreement id', 'woocommerce-gateway-paypal-express-checkout' ),
@@ -181,11 +182,13 @@ class WC_Gateway_PPEC_Privacy extends WC_Abstract_Privacy {
181
  $order = wc_get_order( $order->get_id() );
182
 
183
  list( $removed, $retained, $msgs ) = $this->maybe_handle_order( $order );
 
184
  $items_removed |= $removed;
185
  $items_retained |= $retained;
186
  $messages = array_merge( $messages, $msgs );
187
 
188
  list( $removed, $retained, $msgs ) = $this->maybe_handle_subscription( $order );
 
189
  $items_removed |= $removed;
190
  $items_retained |= $retained;
191
  $messages = array_merge( $messages, $msgs );
@@ -220,14 +223,15 @@ class WC_Gateway_PPEC_Privacy extends WC_Abstract_Privacy {
220
  $subscription = current( wcs_get_subscriptions_for_order( $order->get_id() ) );
221
  $subscription_id = $subscription->get_id();
222
 
223
- $ppec_billing = get_post_meta( $subscription_id, '_ppec_billing_agreement_id', true );
224
 
225
  if ( empty( $ppec_billing ) ) {
226
  return array( false, false, array() );
227
  }
228
 
229
  if ( $subscription->has_status( apply_filters( 'woocommerce_paypal_express_checkout_privacy_eraser_subs_statuses', array( 'on-hold', 'active' ) ) ) ) {
230
- return array( false, true, array( sprintf( __( 'Order ID %d contains an active Subscription' ), $order->get_id() ) ) );
 
231
  }
232
 
233
  $renewal_orders = WC_Subscriptions_Renewal_Order::get_renewal_orders( $order->get_id() );
30
  protected function get_ppec_orders( $email_address, $page ) {
31
  $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data.
32
 
33
+ $order_query = array(
34
  'payment_method' => array( 'ppec_paypal' ),
35
  'limit' => 10,
36
  'page' => $page,
50
  *
51
  */
52
  public function get_privacy_message() {
53
+ // Translators: placeholder is the URL of WC's privacy statement (PPEC section).
54
  return wpautop( sprintf( __( 'By using this extension, you may be storing personal data or sharing data with an external service. <a href="%s" target="_blank">Learn more about how this works, including what you may want to include in your privacy policy.</a>', 'woocommerce-gateway-paypal-express-checkout' ), 'https://docs.woocommerce.com/document/privacy-payments/#woocommerce-gateway-paypal-express-checkout' ) );
55
  }
56
 
79
  'data' => array(
80
  array(
81
  'name' => __( 'PPEC Refundable transaction data', 'woocommerce-gateway-paypal-express-checkout' ),
82
+ 'value' => wp_json_encode( get_post_meta( $order->get_id(), '_woo_pp_txnData', true ) ),
83
  ),
84
  array(
85
  'name' => __( 'PPEC Billing agreement id', 'woocommerce-gateway-paypal-express-checkout' ),
112
  $data_to_export = array();
113
 
114
  $meta_query = array(
115
+ 'relation' => 'AND',
116
  array(
117
  'key' => '_payment_method',
118
  'value' => array( 'ppec_paypal' ),
125
  ),
126
  );
127
 
128
+ $subscription_query = array(
129
+ 'posts_per_page' => 10,
130
+ 'page' => $page,
131
+ 'meta_query' => $meta_query, /* phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query */
132
  );
133
 
134
  $subscriptions = wcs_get_subscriptions( $subscription_query );
144
  'data' => array(
145
  array(
146
  'name' => __( 'PPEC Refundable transaction data', 'woocommerce-gateway-paypal-express-checkout' ),
147
+ 'value' => wp_json_encode( get_post_meta( $subscription->get_id(), '_woo_pp_txnData', true ) ),
148
  ),
149
  array(
150
  'name' => __( 'PPEC Billing agreement id', 'woocommerce-gateway-paypal-express-checkout' ),
182
  $order = wc_get_order( $order->get_id() );
183
 
184
  list( $removed, $retained, $msgs ) = $this->maybe_handle_order( $order );
185
+
186
  $items_removed |= $removed;
187
  $items_retained |= $retained;
188
  $messages = array_merge( $messages, $msgs );
189
 
190
  list( $removed, $retained, $msgs ) = $this->maybe_handle_subscription( $order );
191
+
192
  $items_removed |= $removed;
193
  $items_retained |= $retained;
194
  $messages = array_merge( $messages, $msgs );
223
  $subscription = current( wcs_get_subscriptions_for_order( $order->get_id() ) );
224
  $subscription_id = $subscription->get_id();
225
 
226
+ $ppec_billing = get_post_meta( $subscription_id, '_ppec_billing_agreement_id', true );
227
 
228
  if ( empty( $ppec_billing ) ) {
229
  return array( false, false, array() );
230
  }
231
 
232
  if ( $subscription->has_status( apply_filters( 'woocommerce_paypal_express_checkout_privacy_eraser_subs_statuses', array( 'on-hold', 'active' ) ) ) ) {
233
+ // Translators: placeholder is an order number.
234
+ return array( false, true, array( sprintf( __( 'Order ID %d contains an active Subscription', 'woocommerce-gateway-paypal-express-checkout' ), $order->get_id() ) ) );
235
  }
236
 
237
  $renewal_orders = WC_Subscriptions_Renewal_Order::get_renewal_orders( $order->get_id() );
includes/class-wc-gateway-ppec-refund.php CHANGED
@@ -36,7 +36,7 @@ class WC_Gateway_PPEC_Refund {
36
  // if success return the transaction ID of the refund
37
  // if failure then do 'throw new PayPal_API_Exception( $response );'
38
 
39
- if ( 'Success' == $response['ACK'] || 'SuccessWithWarning' == $response['ACK'] ) {
40
  return $response['REFUNDTRANSACTIONID'];
41
  } else {
42
  throw new PayPal_API_Exception( $response );
36
  // if success return the transaction ID of the refund
37
  // if failure then do 'throw new PayPal_API_Exception( $response );'
38
 
39
+ if ( 'Success' === $response['ACK'] || 'SuccessWithWarning' === $response['ACK'] ) {
40
  return $response['REFUNDTRANSACTIONID'];
41
  } else {
42
  throw new PayPal_API_Exception( $response );
includes/class-wc-gateway-ppec-session-data.php CHANGED
@@ -78,14 +78,17 @@ class WC_Gateway_PPEC_Session_Data {
78
  * @param array $args Arguments for session data
79
  */
80
  public function __construct( $args = array() ) {
81
- $args = wp_parse_args( $args, array(
82
- 'token' => '',
83
- 'source' => 'cart',
84
- 'order_id' => false,
85
- 'expires_in' => 10800,
86
- 'use_paypal_credit' => false,
87
- 'cancel_url' => '',
88
- ) );
 
 
 
89
 
90
  $this->token = $args['token'];
91
  $this->source = $args['source'];
78
  * @param array $args Arguments for session data
79
  */
80
  public function __construct( $args = array() ) {
81
+ $args = wp_parse_args(
82
+ $args,
83
+ array(
84
+ 'token' => '',
85
+ 'source' => 'cart',
86
+ 'order_id' => false,
87
+ 'expires_in' => 10800,
88
+ 'use_paypal_credit' => false,
89
+ 'cancel_url' => '',
90
+ )
91
+ );
92
 
93
  $this->token = $args['token'];
94
  $this->source = $args['source'];
includes/class-wc-gateway-ppec-settings.php CHANGED
@@ -173,7 +173,7 @@ class WC_Gateway_PPEC_Settings {
173
  */
174
  public function get_live_api_credentials() {
175
  if ( $this->api_certificate ) {
176
- return new WC_Gateway_PPEC_Client_Credential_Certificate( $this->api_username, $this->api_password, base64_decode( $this->api_certificate ), $this->api_subject );
177
  }
178
 
179
  return new WC_Gateway_PPEC_Client_Credential_Signature( $this->api_username, $this->api_password, $this->api_signature, $this->api_subject );
@@ -186,7 +186,7 @@ class WC_Gateway_PPEC_Settings {
186
  */
187
  public function get_sandbox_api_credentials() {
188
  if ( $this->sandbox_api_certificate ) {
189
- return new WC_Gateway_PPEC_Client_Credential_Certificate( $this->sandbox_api_username, $this->sandbox_api_password, base64_decode( $this->sandbox_api_certificate ), $this->sandbox_api_subject );
190
  }
191
 
192
  return new WC_Gateway_PPEC_Client_Credential_Signature( $this->sandbox_api_username, $this->sandbox_api_password, $this->sandbox_api_signature, $this->sandbox_api_subject );
@@ -240,7 +240,7 @@ class WC_Gateway_PPEC_Settings {
240
  $url .= 'sandbox.';
241
  }
242
 
243
- $url .= 'paypal.com/checkoutnow?token=' . urlencode( $token );
244
 
245
  if ( $commit ) {
246
  $url .= '&useraction=commit';
@@ -263,9 +263,11 @@ class WC_Gateway_PPEC_Settings {
263
  _deprecated_function( __METHOD__, '1.2.0', 'WC_Gateway_PPEC_Client::get_set_express_checkout_params' );
264
 
265
  // Still missing order_id in args.
266
- return wc_gateway_ppec()->client->get_set_express_checkout_params( array(
267
- 'skip_checkout' => false,
268
- ) );
 
 
269
  }
270
 
271
  /**
@@ -282,7 +284,7 @@ class WC_Gateway_PPEC_Settings {
282
  $params = array();
283
  if ( ! is_array( $buckets ) ) {
284
  $num_buckets = $buckets;
285
- $buckets = array();
286
  for ( $i = 0; $i < $num_buckets; $i++ ) {
287
  $buckets[] = $i;
288
  }
@@ -292,7 +294,12 @@ class WC_Gateway_PPEC_Settings {
292
  $params[ 'PAYMENTREQUEST_' . $bucket_num . '_NOTIFYURL' ] = WC()->api_request_url( 'WC_Gateway_PPEC' );
293
  $params[ 'PAYMENTREQUEST_' . $bucket_num . '_PAYMENTACTION' ] = $this->get_paymentaction();
294
  $params[ 'PAYMENTREQUEST_' . $bucket_num . '_INVNUM' ] = $this->invoice_prefix . $order->get_order_number();
295
- $params[ 'PAYMENTREQUEST_' . $bucket_num . '_CUSTOM' ] = json_encode( array( 'order_id' => $order->id, 'order_key' => $order->order_key ) );
 
 
 
 
 
296
  }
297
 
298
  return $params;
@@ -363,7 +370,7 @@ class WC_Gateway_PPEC_Settings {
363
  return (
364
  'yes' === $this->enabled
365
  &&
366
- in_array( get_woocommerce_currency(), array( 'HUF', 'TWD', 'JPY' ) )
367
  &&
368
  0 !== absint( get_option( 'woocommerce_price_num_decimals', 2 ) )
369
  );
@@ -380,15 +387,15 @@ class WC_Gateway_PPEC_Settings {
380
  // For stores based in the US, we need to do some special mapping so PayPal Credit is allowed.
381
  if ( wc_gateway_ppec_is_US_based_store() ) {
382
  // PayPal has support for French, Spanish and Chinese languages based in the US. See https://developer.paypal.com/docs/archive/checkout/reference/supported-locales/
383
- preg_match('/^(fr|es|zh)_/', $locale, $language_code );
384
 
385
  if ( ! empty( $language_code ) ) {
386
  $locale = $language_code[0] . 'US';
387
  } else {
388
  $locale = 'en_US';
389
  }
390
- } elseif ( ! in_array( $locale, $this->_supported_locales ) ) {
391
- // Mapping some WP locales to PayPal locales
392
  if ( isset( $this->_locales_mapping[ $locale ] ) ) {
393
  $locale = $this->_locales_mapping[ $locale ];
394
  } else {
@@ -450,7 +457,7 @@ class WC_Gateway_PPEC_Settings {
450
  * @return bool Returns true if currency supports 0 decimal places
451
  */
452
  public function is_currency_supports_zero_decimal() {
453
- return in_array( get_woocommerce_currency(), array( 'HUF', 'JPY', 'TWD' ) );
454
  }
455
 
456
  /**
173
  */
174
  public function get_live_api_credentials() {
175
  if ( $this->api_certificate ) {
176
+ return new WC_Gateway_PPEC_Client_Credential_Certificate( $this->api_username, $this->api_password, base64_decode( $this->api_certificate ), $this->api_subject ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
177
  }
178
 
179
  return new WC_Gateway_PPEC_Client_Credential_Signature( $this->api_username, $this->api_password, $this->api_signature, $this->api_subject );
186
  */
187
  public function get_sandbox_api_credentials() {
188
  if ( $this->sandbox_api_certificate ) {
189
+ return new WC_Gateway_PPEC_Client_Credential_Certificate( $this->sandbox_api_username, $this->sandbox_api_password, base64_decode( $this->sandbox_api_certificate ), $this->sandbox_api_subject ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
190
  }
191
 
192
  return new WC_Gateway_PPEC_Client_Credential_Signature( $this->sandbox_api_username, $this->sandbox_api_password, $this->sandbox_api_signature, $this->sandbox_api_subject );
240
  $url .= 'sandbox.';
241
  }
242
 
243
+ $url .= 'paypal.com/checkoutnow?token=' . urlencode( $token ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.urlencode_urlencode
244
 
245
  if ( $commit ) {
246
  $url .= '&useraction=commit';
263
  _deprecated_function( __METHOD__, '1.2.0', 'WC_Gateway_PPEC_Client::get_set_express_checkout_params' );
264
 
265
  // Still missing order_id in args.
266
+ return wc_gateway_ppec()->client->get_set_express_checkout_params(
267
+ array(
268
+ 'skip_checkout' => false,
269
+ )
270
+ );
271
  }
272
 
273
  /**
284
  $params = array();
285
  if ( ! is_array( $buckets ) ) {
286
  $num_buckets = $buckets;
287
+ $buckets = array();
288
  for ( $i = 0; $i < $num_buckets; $i++ ) {
289
  $buckets[] = $i;
290
  }
294
  $params[ 'PAYMENTREQUEST_' . $bucket_num . '_NOTIFYURL' ] = WC()->api_request_url( 'WC_Gateway_PPEC' );
295
  $params[ 'PAYMENTREQUEST_' . $bucket_num . '_PAYMENTACTION' ] = $this->get_paymentaction();
296
  $params[ 'PAYMENTREQUEST_' . $bucket_num . '_INVNUM' ] = $this->invoice_prefix . $order->get_order_number();
297
+ $params[ 'PAYMENTREQUEST_' . $bucket_num . '_CUSTOM' ] = wp_json_encode(
298
+ array(
299
+ 'order_id' => $order->id,
300
+ 'order_key' => $order->order_key,
301
+ )
302
+ );
303
  }
304
 
305
  return $params;
370
  return (
371
  'yes' === $this->enabled
372
  &&
373
+ in_array( get_woocommerce_currency(), array( 'HUF', 'TWD', 'JPY' ), true )
374
  &&
375
  0 !== absint( get_option( 'woocommerce_price_num_decimals', 2 ) )
376
  );
387
  // For stores based in the US, we need to do some special mapping so PayPal Credit is allowed.
388
  if ( wc_gateway_ppec_is_US_based_store() ) {
389
  // PayPal has support for French, Spanish and Chinese languages based in the US. See https://developer.paypal.com/docs/archive/checkout/reference/supported-locales/
390
+ preg_match( '/^(fr|es|zh)_/', $locale, $language_code );
391
 
392
  if ( ! empty( $language_code ) ) {
393
  $locale = $language_code[0] . 'US';
394
  } else {
395
  $locale = 'en_US';
396
  }
397
+ } elseif ( ! in_array( $locale, $this->_supported_locales, true ) ) {
398
+ // Mapping some WP locales to PayPal locales.
399
  if ( isset( $this->_locales_mapping[ $locale ] ) ) {
400
  $locale = $this->_locales_mapping[ $locale ];
401
  } else {
457
  * @return bool Returns true if currency supports 0 decimal places
458
  */
459
  public function is_currency_supports_zero_decimal() {
460
+ return in_array( get_woocommerce_currency(), array( 'HUF', 'JPY', 'TWD' ), true );
461
  }
462
 
463
  /**
includes/class-wc-gateway-ppec-with-paypal-addons.php CHANGED
@@ -162,17 +162,19 @@ class WC_Gateway_PPEC_With_PayPal_Addons extends WC_Gateway_PPEC_With_PayPal {
162
  return;
163
  }
164
 
165
- if ( 0 == $amount ) {
166
  $order->payment_complete();
167
  return;
168
  }
169
 
170
  $client = wc_gateway_ppec()->client;
171
- $params = $client->get_do_reference_transaction_params( array(
172
- 'reference_id' => $billing_agreement_id,
173
- 'amount' => $amount,
174
- 'order_id' => $order_id,
175
- ) );
 
 
176
 
177
  $resp = $client->do_reference_transaction( $params );
178
 
@@ -214,13 +216,13 @@ class WC_Gateway_PPEC_With_PayPal_Addons extends WC_Gateway_PPEC_With_PayPal {
214
  case 'Processed':
215
  case 'In-Progress':
216
  $transaction_id = $response['TRANSACTIONID'];
 
217
  $order->add_order_note( sprintf( __( 'PayPal payment approved (ID: %s)', 'woocommerce-gateway-paypal-express-checkout' ), $transaction_id ) );
218
  $order->payment_complete( $transaction_id );
219
  break;
220
  default:
221
  throw new Exception( __( 'PayPal payment declined', 'woocommerce-gateway-paypal-express-checkout' ) );
222
  }
223
-
224
  } catch ( Exception $e ) {
225
  $order->update_status( 'failed', $e->getMessage() );
226
  }
162
  return;
163
  }
164
 
165
+ if ( 0.0 === (float) $amount ) {
166
  $order->payment_complete();
167
  return;
168
  }
169
 
170
  $client = wc_gateway_ppec()->client;
171
+ $params = $client->get_do_reference_transaction_params(
172
+ array(
173
+ 'reference_id' => $billing_agreement_id,
174
+ 'amount' => $amount,
175
+ 'order_id' => $order_id,
176
+ )
177
+ );
178
 
179
  $resp = $client->do_reference_transaction( $params );
180
 
216
  case 'Processed':
217
  case 'In-Progress':
218
  $transaction_id = $response['TRANSACTIONID'];
219
+ // Translators: %s is a transaction ID.
220
  $order->add_order_note( sprintf( __( 'PayPal payment approved (ID: %s)', 'woocommerce-gateway-paypal-express-checkout' ), $transaction_id ) );
221
  $order->payment_complete( $transaction_id );
222
  break;
223
  default:
224
  throw new Exception( __( 'PayPal payment declined', 'woocommerce-gateway-paypal-express-checkout' ) );
225
  }
 
226
  } catch ( Exception $e ) {
227
  $order->update_status( 'failed', $e->getMessage() );
228
  }
includes/class-wc-gateway-ppec-with-paypal-credit.php CHANGED
@@ -6,13 +6,13 @@ if ( ! defined( 'ABSPATH' ) ) {
6
 
7
  class WC_Gateway_PPEC_With_PayPal_Credit extends WC_Gateway_PPEC_With_PayPal {
8
  public function __construct() {
9
- $this->icon = 'https://www.paypalobjects.com/webstatic/en_US/i/buttons/ppc-acceptance-small.png';
10
 
11
  parent::__construct();
12
 
13
  if ( ! is_admin() ) {
14
  if ( wc_gateway_ppec()->checkout->is_started_from_checkout_page() ) {
15
- $this->title = __( 'PayPal Credit', 'woocommerce-gateway-paypal-express-checkout' );;
16
  }
17
  }
18
 
6
 
7
  class WC_Gateway_PPEC_With_PayPal_Credit extends WC_Gateway_PPEC_With_PayPal {
8
  public function __construct() {
9
+ $this->icon = 'https://www.paypalobjects.com/webstatic/en_US/i/buttons/ppc-acceptance-small.png';
10
 
11
  parent::__construct();
12
 
13
  if ( ! is_admin() ) {
14
  if ( wc_gateway_ppec()->checkout->is_started_from_checkout_page() ) {
15
+ $this->title = __( 'PayPal Credit', 'woocommerce-gateway-paypal-express-checkout' );
16
  }
17
  }
18
 
includes/class-wc-gateway-ppec-with-spb-addons.php CHANGED
@@ -45,12 +45,12 @@ class WC_Gateway_PPEC_With_SPB_Addons extends WC_Gateway_PPEC_With_PayPal_Addons
45
  * @return array
46
  */
47
  public function process_payment( $order_id ) {
48
- if ( isset( $_POST['payerID'] ) && isset( $_POST['paymentToken'] ) ) {
49
  $session = WC()->session->get( 'paypal', new stdClass() );
50
 
51
  $session->checkout_completed = true;
52
- $session->payer_id = $_POST['payerID'];
53
- $session->token = $_POST['paymentToken'];
54
 
55
  WC()->session->set( 'paypal', $session );
56
  }
45
  * @return array
46
  */
47
  public function process_payment( $order_id ) {
48
+ if ( isset( $_POST['payerID'] ) && isset( $_POST['paymentToken'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
49
  $session = WC()->session->get( 'paypal', new stdClass() );
50
 
51
  $session->checkout_completed = true;
52
+ $session->payer_id = $_POST['payerID']; // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
53
+ $session->token = $_POST['paymentToken']; // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
54
 
55
  WC()->session->set( 'paypal', $session );
56
  }
includes/class-wc-gateway-ppec-with-spb.php CHANGED
@@ -45,12 +45,12 @@ class WC_Gateway_PPEC_With_SPB extends WC_Gateway_PPEC_With_PayPal {
45
  * @return array
46
  */
47
  public function process_payment( $order_id ) {
48
- if ( isset( $_POST['payerID'] ) && isset( $_POST['paymentToken'] ) ) {
49
  $session = WC()->session->get( 'paypal', new stdClass() );
50
 
51
  $session->checkout_completed = true;
52
- $session->payer_id = $_POST['payerID'];
53
- $session->token = $_POST['paymentToken'];
54
 
55
  WC()->session->set( 'paypal', $session );
56
  }
45
  * @return array
46
  */
47
  public function process_payment( $order_id ) {
48
+ if ( isset( $_POST['payerID'] ) && isset( $_POST['paymentToken'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
49
  $session = WC()->session->get( 'paypal', new stdClass() );
50
 
51
  $session->checkout_completed = true;
52
+ $session->payer_id = $_POST['payerID']; // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
53
+ $session->token = $_POST['paymentToken']; // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
54
 
55
  WC()->session->set( 'paypal', $session );
56
  }
includes/exceptions/class-wc-gateway-ppec-api-exception.php CHANGED
@@ -49,7 +49,7 @@ class PayPal_API_Exception extends Exception {
49
  $errors[ $matches[1] ]['long'] = $value;
50
  } elseif ( preg_match( '/^L_SEVERITYCODE(\d+)$/', $index, $matches ) ) {
51
  $errors[ $matches[1] ]['severity'] = $value;
52
- } elseif ( 'CORRELATIONID' == $index ) {
53
  $this->correlation_id = $value;
54
  }
55
  }
@@ -57,7 +57,7 @@ class PayPal_API_Exception extends Exception {
57
  $this->errors = array();
58
  $error_messages = array();
59
  foreach ( $errors as $value ) {
60
- $error = new PayPal_API_Error( $value['code'], $value['message'], $value['long'], $value['severity'] );
61
  $this->errors[] = $error;
62
 
63
  /* translators: placeholders are error code and message from PayPal */
49
  $errors[ $matches[1] ]['long'] = $value;
50
  } elseif ( preg_match( '/^L_SEVERITYCODE(\d+)$/', $index, $matches ) ) {
51
  $errors[ $matches[1] ]['severity'] = $value;
52
+ } elseif ( 'CORRELATIONID' === $index ) {
53
  $this->correlation_id = $value;
54
  }
55
  }
57
  $this->errors = array();
58
  $error_messages = array();
59
  foreach ( $errors as $value ) {
60
+ $error = new PayPal_API_Error( $value['code'], $value['message'], $value['long'], $value['severity'] );
61
  $this->errors[] = $error;
62
 
63
  /* translators: placeholders are error code and message from PayPal */
includes/functions.php CHANGED
@@ -7,7 +7,7 @@ function woo_pp_start_checkout() {
7
  $redirect_url = $checkout->start_checkout_from_cart();
8
  wp_safe_redirect( $redirect_url );
9
  exit;
10
- } catch( PayPal_API_Exception $e ) {
11
  wc_add_notice( $e->getMessage(), 'error' );
12
 
13
  $redirect_url = wc_get_cart_url();
@@ -21,10 +21,10 @@ function woo_pp_start_checkout() {
21
  if( ( window.opener != null ) && ( window.opener !== window ) &&
22
  ( typeof window.opener.paypal != "undefined" ) &&
23
  ( typeof window.opener.paypal.checkout != "undefined" ) ) {
24
- window.opener.location.assign( "<?php echo $redirect_url; ?>" );
25
  window.close();
26
  } else {
27
- window.location.assign( "<?php echo $redirect_url; ?>" );
28
  }
29
  </script>
30
  <?php
@@ -33,7 +33,6 @@ function woo_pp_start_checkout() {
33
  wp_safe_redirect( $redirect_url );
34
  exit;
35
  }
36
-
37
  }
38
  }
39
 
@@ -64,7 +63,7 @@ function wc_gateway_ppec_log( $message ) {
64
  $wc_ppec_logger->add( 'wc_gateway_ppec', $message );
65
 
66
  if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
67
- error_log( $message );
68
  }
69
  }
70
 
@@ -87,7 +86,7 @@ function wc_gateway_ppec_is_credit_supported() {
87
  * @return bool Returns true if buyer is checking out with PayPal Credit
88
  */
89
  function wc_gateway_ppec_is_using_credit() {
90
- return ! empty( $_GET['use-ppc'] ) && 'true' === $_GET['use-ppc'];
91
  }
92
 
93
  const PPEC_FEE_META_NAME_OLD = 'PayPal Transaction Fee';
@@ -190,23 +189,23 @@ function wc_gateway_ppec_save_transaction_data( $order, $transaction_response, $
190
  }
191
 
192
  $txn = array(
193
- 'txnID' => $transaction_response[$prefix . 'TRANSACTIONID'],
194
- 'amount' => $transaction_response[$prefix . 'AMT'],
195
- 'refunded_amount' => 0
196
  );
197
 
198
- $status = ! empty( $transaction_response[$prefix . 'PAYMENTSTATUS'] ) ? $transaction_response[$prefix . 'PAYMENTSTATUS'] : '';
199
 
200
- if ( 'Completed' == $status ) {
201
  $txn['status'] = 'Completed';
202
  } else {
203
- $txn['status'] = $status . '_' . $transaction_response[$prefix . 'REASONCODE'];
204
  }
205
  $txnData['refundable_txns'][] = $txn;
206
 
207
  $paymentAction = $settings->get_paymentaction();
208
 
209
- if ( 'authorization' == $paymentAction ) {
210
  $txnData['auth_status'] = 'NotCompleted';
211
  }
212
 
@@ -216,5 +215,6 @@ function wc_gateway_ppec_save_transaction_data( $order, $transaction_response, $
216
  update_post_meta( $order_id, '_woo_pp_txnData', $txnData );
217
  } else {
218
  $order->update_meta_data( '_woo_pp_txnData', $txnData );
 
219
  }
220
  }
7
  $redirect_url = $checkout->start_checkout_from_cart();
8
  wp_safe_redirect( $redirect_url );
9
  exit;
10
+ } catch ( PayPal_API_Exception $e ) {
11
  wc_add_notice( $e->getMessage(), 'error' );
12
 
13
  $redirect_url = wc_get_cart_url();
21
  if( ( window.opener != null ) && ( window.opener !== window ) &&
22
  ( typeof window.opener.paypal != "undefined" ) &&
23
  ( typeof window.opener.paypal.checkout != "undefined" ) ) {
24
+ window.opener.location.assign( "<?php echo $redirect_url; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>" );
25
  window.close();
26
  } else {
27
+ window.location.assign( "<?php echo $redirect_url; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>" );
28
  }
29
  </script>
30
  <?php
33
  wp_safe_redirect( $redirect_url );
34
  exit;
35
  }
 
36
  }
37
  }
38
 
63
  $wc_ppec_logger->add( 'wc_gateway_ppec', $message );
64
 
65
  if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
66
+ error_log( $message ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
67
  }
68
  }
69
 
86
  * @return bool Returns true if buyer is checking out with PayPal Credit
87
  */
88
  function wc_gateway_ppec_is_using_credit() {
89
+ return ! empty( $_GET['use-ppc'] ) && 'true' === $_GET['use-ppc']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
90
  }
91
 
92
  const PPEC_FEE_META_NAME_OLD = 'PayPal Transaction Fee';
189
  }
190
 
191
  $txn = array(
192
+ 'txnID' => $transaction_response[ $prefix . 'TRANSACTIONID' ],
193
+ 'amount' => $transaction_response[ $prefix . 'AMT' ],
194
+ 'refunded_amount' => 0,
195
  );
196
 
197
+ $status = ! empty( $transaction_response[ $prefix . 'PAYMENTSTATUS' ] ) ? $transaction_response[ $prefix . 'PAYMENTSTATUS' ] : '';
198
 
199
+ if ( 'Completed' === $status ) {
200
  $txn['status'] = 'Completed';
201
  } else {
202
+ $txn['status'] = $status . '_' . $transaction_response[ $prefix . 'REASONCODE' ];
203
  }
204
  $txnData['refundable_txns'][] = $txn;
205
 
206
  $paymentAction = $settings->get_paymentaction();
207
 
208
+ if ( 'authorization' === $paymentAction ) {
209
  $txnData['auth_status'] = 'NotCompleted';
210
  }
211
 
215
  update_post_meta( $order_id, '_woo_pp_txnData', $txnData );
216
  } else {
217
  $order->update_meta_data( '_woo_pp_txnData', $txnData );
218
+ $order->save();
219
  }
220
  }
includes/settings/settings-ppec.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
 
3
  if ( ! defined( 'ABSPATH' ) ) {
4
  exit;
@@ -14,7 +15,8 @@ $needs_sandbox_creds = ! $has_sandbox_credential && ! (bool) $sandbox_credential
14
  $enable_ips = wc_gateway_ppec()->ips->is_supported();
15
 
16
  if ( $enable_ips && $needs_creds ) {
17
- $ips_button = '<a href="' . esc_url( wc_gateway_ppec()->ips->get_signup_url( 'live' ) ) . '" class="button button-primary">' . __( 'Setup or link an existing PayPal account', 'woocommerce-gateway-paypal-express-checkout' ) . '</a>';
 
18
  $api_creds_text = sprintf( __( '%s or <a href="#" class="ppec-toggle-settings">click here to toggle manual API credential input</a>.', 'woocommerce-gateway-paypal-express-checkout' ), $ips_button );
19
  } else {
20
  $reset_link = add_query_arg(
@@ -37,6 +39,7 @@ if ( $enable_ips && $needs_creds ) {
37
 
38
  if ( $enable_ips && $needs_sandbox_creds ) {
39
  $sandbox_ips_button = '<a href="' . esc_url( wc_gateway_ppec()->ips->get_signup_url( 'sandbox' ) ) . '" class="button button-primary">' . __( 'Setup or link an existing PayPal Sandbox account', 'woocommerce-gateway-paypal-express-checkout' ) . '</a>';
 
40
  $sandbox_api_creds_text = sprintf( __( '%s or <a href="#" class="ppec-toggle-sandbox-settings">click here to toggle manual API credential input</a>.', 'woocommerce-gateway-paypal-express-checkout' ), $sandbox_ips_button );
41
  } else {
42
  $reset_link = add_query_arg(
@@ -62,7 +65,7 @@ if ( ! wc_gateway_ppec_is_credit_supported() ) {
62
  $credit_enabled_label .= '<p><em>' . __( 'This option is disabled. Currently PayPal Credit only available for U.S. merchants using USD currency.', 'woocommerce-gateway-paypal-express-checkout' ) . '</em></p>';
63
  }
64
 
65
- $credit_enabled_description = __( 'This enables PayPal Credit, which displays a PayPal Credit button next to the primary PayPal Checkout button. PayPal Checkout lets you give customers access to financing through PayPal Credit® - at no additional cost to you. You get paid up front, even though customers have more time to pay. A pre-integrated payment button shows up next to the PayPal Button, and lets customers pay quickly with PayPal Credit®. (Should be unchecked for stores involved in Real Money Gaming.)', 'woocommerce-gateway-paypal-express-checkout' );
66
 
67
  /**
68
  * Settings for PayPal Gateway.
@@ -266,14 +269,19 @@ $settings = array(
266
  'type' => 'checkbox',
267
  'label' => __( 'Require Billing Address', 'woocommerce-gateway-paypal-express-checkout' ),
268
  'default' => 'no',
269
- 'description' => sprintf( __( 'PayPal only returns a shipping address back to the website. To make sure billing address is returned as well, please enable this functionality on your PayPal account by calling %1$sPayPal Technical Support%2$s.', 'woocommerce-gateway-paypal-express-checkout' ), '<a href="https://www.paypal.com/us/selfhelp/contact/call">', '</a>' ),
 
 
 
 
 
270
  ),
271
  'require_phone_number' => array(
272
  'title' => __( 'Require Phone Number', 'woocommerce-gateway-paypal-express-checkout' ),
273
  'type' => 'checkbox',
274
  'label' => __( 'Require Phone Number', 'woocommerce-gateway-paypal-express-checkout' ),
275
  'default' => 'no',
276
- 'description' => __( 'Require buyer to enter their telephone number during checkout if none is provided by PayPal', 'woocommerce-gateway-paypal-express-checkout' ),
277
  ),
278
  'paymentaction' => array(
279
  'title' => __( 'Payment Action', 'woocommerce-gateway-paypal-express-checkout' ),
@@ -318,7 +326,11 @@ $settings = array(
318
  'type' => 'checkbox',
319
  'default' => $this->get_option( 'button_size' ) ? 'no' : 'yes', // A 'button_size' value having been set indicates that settings have been initialized before, requiring merchant opt-in to SPB.
320
  'label' => __( 'Use Smart Payment Buttons', 'woocommerce-gateway-paypal-express-checkout' ),
321
- 'description' => sprintf( __( 'PayPal Checkout\'s Smart Payment Buttons provide a variety of button customization options, such as color, language, shape, and multiple button layout. <a href="%s">Learn more about Smart Payment Buttons</a>.', 'woocommerce-gateway-paypal-express-checkout' ), 'https://developer.paypal.com/docs/integration/direct/express-checkout/integration-jsv4/#smart-payment-buttons' ),
 
 
 
 
322
  ),
323
  'button_color' => array(
324
  'title' => __( 'Button Color', 'woocommerce-gateway-paypal-express-checkout' ),
@@ -414,18 +426,18 @@ $per_context_settings = array(
414
  'desc_tip' => true,
415
  'description' => __( 'Hides the specified funding methods.', 'woocommerce-gateway-paypal-express-checkout' ),
416
  'options' => array(
417
- 'CREDIT' => __( 'PayPal Credit', 'woocommerce-gateway-paypal-express-checkout' ),
418
- 'ELV' => __( 'ELV', 'woocommerce-gateway-paypal-express-checkout' ),
419
- 'CARD' => __( 'Credit or debit cards', 'woocommerce-gateway-paypal-express-checkout' ),
420
- 'VENMO' => __( 'Venmo', 'woocommerce-gateway-paypal-express-checkout' ),
421
- 'SEPA' => __( 'SEPA-Lastschrift', 'woocommerce-gateway-paypal-express-checkout' ),
422
- 'BANCONTACT' => __( 'Bancontact', 'woocommerce-gateway-paypal-express-checkout' ),
423
- 'EPS' => __( 'eps', 'woocommerce-gateway-paypal-express-checkout' ),
424
- 'GIROPAY' => __( 'giropay', 'woocommerce-gateway-paypal-express-checkout' ),
425
- 'IDEAL' => __( 'iDEAL', 'woocommerce-gateway-paypal-express-checkout' ),
426
- 'MYBANK' => __( 'MyBank', 'woocommerce-gateway-paypal-express-checkout' ),
427
- 'P24' => __( 'Przelewy24', 'woocommerce-gateway-paypal-express-checkout' ),
428
- 'SOFORT' => __( 'Sofort', 'woocommerce-gateway-paypal-express-checkout' ),
429
  ),
430
  ),
431
  'credit_enabled' => array(
@@ -444,7 +456,8 @@ $per_context_settings = array(
444
  * Cart / global button settings.
445
  */
446
  $settings = array_merge( $settings, $per_context_settings );
447
- $per_context_settings['button_size']['class'] .= ' woocommerce_ppec_paypal_spb';
 
448
  $per_context_settings['credit_enabled']['class'] .= ' woocommerce_ppec_paypal_spb';
449
 
450
  $settings['cart_checkout_enabled'] = array(
@@ -461,10 +474,11 @@ $settings['cart_checkout_enabled'] = array(
461
  * Mini-cart button settings.
462
  */
463
  $settings['mini_cart_settings'] = array(
464
- 'title' => __( 'Mini-cart Button Settings', 'woocommerce-gateway-paypal-express-checkout' ),
465
- 'type' => 'title',
466
- 'class' => 'woocommerce_ppec_paypal_spb',
467
  );
 
468
  $settings['mini_cart_settings_toggle'] = array(
469
  'title' => __( 'Configure Settings', 'woocommerce-gateway-paypal-express-checkout' ),
470
  'label' => __( 'Configure settings specific to mini-cart', 'woocommerce-gateway-paypal-express-checkout' ),
@@ -474,8 +488,8 @@ $settings['mini_cart_settings_toggle'] = array(
474
  'desc_tip' => true,
475
  'description' => __( 'Optionally override global button settings above and configure buttons for this context.', 'woocommerce-gateway-paypal-express-checkout' ),
476
  );
477
- foreach( $per_context_settings as $key => $value ) {
478
- $value['class'] .= ' woocommerce_ppec_paypal_mini_cart';
479
  $settings[ 'mini_cart_' . $key ] = $value;
480
  }
481
 
@@ -483,10 +497,11 @@ foreach( $per_context_settings as $key => $value ) {
483
  * Single product button settings.
484
  */
485
  $settings['single_product_settings'] = array(
486
- 'title' => __( 'Single Product Button Settings', 'woocommerce-gateway-paypal-express-checkout' ),
487
- 'type' => 'title',
488
- 'class' => 'woocommerce_ppec_paypal_spb',
489
  );
 
490
  $settings['checkout_on_single_product_enabled'] = array(
491
  'title' => __( 'Checkout on Single Product', 'woocommerce-gateway-paypal-express-checkout' ),
492
  'type' => 'checkbox',
@@ -496,6 +511,7 @@ $settings['checkout_on_single_product_enabled'] = array(
496
  'desc_tip' => true,
497
  'description' => __( 'Enable PayPal Checkout on Single Product view.', 'woocommerce-gateway-paypal-express-checkout' ),
498
  );
 
499
  $settings['single_product_settings_toggle'] = array(
500
  'title' => __( 'Configure Settings', 'woocommerce-gateway-paypal-express-checkout' ),
501
  'label' => __( 'Configure settings specific to Single Product view', 'woocommerce-gateway-paypal-express-checkout' ),
@@ -505,8 +521,8 @@ $settings['single_product_settings_toggle'] = array(
505
  'desc_tip' => true,
506
  'description' => __( 'Optionally override global button settings above and configure buttons for this context.', 'woocommerce-gateway-paypal-express-checkout' ),
507
  );
508
- foreach( $per_context_settings as $key => $value ) {
509
- $value['class'] .= ' woocommerce_ppec_paypal_single_product';
510
  $settings[ 'single_product_' . $key ] = $value;
511
  }
512
  $settings['single_product_button_layout']['default'] = 'horizontal';
@@ -515,10 +531,11 @@ $settings['single_product_button_layout']['default'] = 'horizontal';
515
  * Regular checkout button settings.
516
  */
517
  $settings['mark_settings'] = array(
518
- 'title' => __( 'Regular Checkout Button Settings', 'woocommerce-gateway-paypal-express-checkout' ),
519
- 'type' => 'title',
520
- 'class' => 'woocommerce_ppec_paypal_spb',
521
  );
 
522
  $settings['mark_enabled'] = array(
523
  'title' => __( 'PayPal Mark', 'woocommerce-gateway-paypal-express-checkout' ),
524
  'type' => 'checkbox',
@@ -528,6 +545,7 @@ $settings['mark_enabled'] = array(
528
  'desc_tip' => true,
529
  'default' => 'yes',
530
  );
 
531
  $settings['mark_settings_toggle'] = array(
532
  'title' => __( 'Configure Settings', 'woocommerce-gateway-paypal-express-checkout' ),
533
  'label' => __( 'Configure settings specific to regular checkout', 'woocommerce-gateway-paypal-express-checkout' ),
@@ -537,9 +555,11 @@ $settings['mark_settings_toggle'] = array(
537
  'desc_tip' => true,
538
  'description' => __( 'Optionally override global button settings above and configure buttons for this context.', 'woocommerce-gateway-paypal-express-checkout' ),
539
  );
540
- foreach( $per_context_settings as $key => $value ) {
541
- $value['class'] .= ' woocommerce_ppec_paypal_mark';
542
  $settings[ 'mark_' . $key ] = $value;
543
  }
544
 
545
  return apply_filters( 'woocommerce_paypal_express_checkout_settings', $settings );
 
 
1
  <?php
2
+ // phpcs:disable WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned
3
 
4
  if ( ! defined( 'ABSPATH' ) ) {
5
  exit;
15
  $enable_ips = wc_gateway_ppec()->ips->is_supported();
16
 
17
  if ( $enable_ips && $needs_creds ) {
18
+ $ips_button = '<a href="' . esc_url( wc_gateway_ppec()->ips->get_signup_url( 'live' ) ) . '" class="button button-primary">' . __( 'Setup or link an existing PayPal account', 'woocommerce-gateway-paypal-express-checkout' ) . '</a>';
19
+ // Translators: placeholder is the button "Setup or link an existing PayPal account".
20
  $api_creds_text = sprintf( __( '%s or <a href="#" class="ppec-toggle-settings">click here to toggle manual API credential input</a>.', 'woocommerce-gateway-paypal-express-checkout' ), $ips_button );
21
  } else {
22
  $reset_link = add_query_arg(
39
 
40
  if ( $enable_ips && $needs_sandbox_creds ) {
41
  $sandbox_ips_button = '<a href="' . esc_url( wc_gateway_ppec()->ips->get_signup_url( 'sandbox' ) ) . '" class="button button-primary">' . __( 'Setup or link an existing PayPal Sandbox account', 'woocommerce-gateway-paypal-express-checkout' ) . '</a>';
42
+ // Translators: placeholder is the button "Setup or link an existing PayPal sandbox account".
43
  $sandbox_api_creds_text = sprintf( __( '%s or <a href="#" class="ppec-toggle-sandbox-settings">click here to toggle manual API credential input</a>.', 'woocommerce-gateway-paypal-express-checkout' ), $sandbox_ips_button );
44
  } else {
45
  $reset_link = add_query_arg(
65
  $credit_enabled_label .= '<p><em>' . __( 'This option is disabled. Currently PayPal Credit only available for U.S. merchants using USD currency.', 'woocommerce-gateway-paypal-express-checkout' ) . '</em></p>';
66
  }
67
 
68
+ $credit_enabled_description = __( 'This enables PayPal Credit, which displays a PayPal Credit button next to the primary PayPal Checkout button. PayPal Checkout lets you give customers access to financing through PayPal Credit® - at no additional cost to you. You get paid up front, even though customers have more time to pay. A pre-integrated payment button shows up next to the PayPal Button, and lets customers pay quickly with PayPal Credit®. (Should be unchecked for stores involved in Real Money Gaming.)', 'woocommerce-gateway-paypal-express-checkout' );
69
 
70
  /**
71
  * Settings for PayPal Gateway.
269
  'type' => 'checkbox',
270
  'label' => __( 'Require Billing Address', 'woocommerce-gateway-paypal-express-checkout' ),
271
  'default' => 'no',
272
+ 'description' => sprintf(
273
+ /* Translators: 1) is an <a> tag linking to PayPal's contact info, 2) is the closing </a> tag. */
274
+ __( 'PayPal only returns a shipping address back to the website. To make sure billing address is returned as well, please enable this functionality on your PayPal account by calling %1$sPayPal Technical Support%2$s.', 'woocommerce-gateway-paypal-express-checkout' ),
275
+ '<a href="https://www.paypal.com/us/selfhelp/contact/call">',
276
+ '</a>'
277
+ ),
278
  ),
279
  'require_phone_number' => array(
280
  'title' => __( 'Require Phone Number', 'woocommerce-gateway-paypal-express-checkout' ),
281
  'type' => 'checkbox',
282
  'label' => __( 'Require Phone Number', 'woocommerce-gateway-paypal-express-checkout' ),
283
  'default' => 'no',
284
+ 'description' => __( 'Require buyer to enter their telephone number during checkout if none is provided by PayPal. Disabling this option doesn\'t affect direct Debit or Credit Card payments offered by PayPal.', 'woocommerce-gateway-paypal-express-checkout' ),
285
  ),
286
  'paymentaction' => array(
287
  'title' => __( 'Payment Action', 'woocommerce-gateway-paypal-express-checkout' ),
326
  'type' => 'checkbox',
327
  'default' => $this->get_option( 'button_size' ) ? 'no' : 'yes', // A 'button_size' value having been set indicates that settings have been initialized before, requiring merchant opt-in to SPB.
328
  'label' => __( 'Use Smart Payment Buttons', 'woocommerce-gateway-paypal-express-checkout' ),
329
+ 'description' => sprintf(
330
+ /* Translators: %s is the URL of the Smart Payment Buttons integration docs. */
331
+ __( 'PayPal Checkout\'s Smart Payment Buttons provide a variety of button customization options, such as color, language, shape, and multiple button layout. <a href="%s">Learn more about Smart Payment Buttons</a>.', 'woocommerce-gateway-paypal-express-checkout' ),
332
+ 'https://developer.paypal.com/docs/integration/direct/express-checkout/integration-jsv4/#smart-payment-buttons'
333
+ ),
334
  ),
335
  'button_color' => array(
336
  'title' => __( 'Button Color', 'woocommerce-gateway-paypal-express-checkout' ),
426
  'desc_tip' => true,
427
  'description' => __( 'Hides the specified funding methods.', 'woocommerce-gateway-paypal-express-checkout' ),
428
  'options' => array(
429
+ 'CREDIT' => __( 'PayPal Credit', 'woocommerce-gateway-paypal-express-checkout' ),
430
+ 'ELV' => __( 'ELV', 'woocommerce-gateway-paypal-express-checkout' ),
431
+ 'CARD' => __( 'Credit or debit cards', 'woocommerce-gateway-paypal-express-checkout' ),
432
+ 'VENMO' => __( 'Venmo', 'woocommerce-gateway-paypal-express-checkout' ),
433
+ 'SEPA' => __( 'SEPA-Lastschrift', 'woocommerce-gateway-paypal-express-checkout' ),
434
+ 'BANCONTACT' => __( 'Bancontact', 'woocommerce-gateway-paypal-express-checkout' ),
435
+ 'EPS' => __( 'eps', 'woocommerce-gateway-paypal-express-checkout' ),
436
+ 'GIROPAY' => __( 'giropay', 'woocommerce-gateway-paypal-express-checkout' ),
437
+ 'IDEAL' => __( 'iDEAL', 'woocommerce-gateway-paypal-express-checkout' ),
438
+ 'MYBANK' => __( 'MyBank', 'woocommerce-gateway-paypal-express-checkout' ),
439
+ 'P24' => __( 'Przelewy24', 'woocommerce-gateway-paypal-express-checkout' ),
440
+ 'SOFORT' => __( 'Sofort', 'woocommerce-gateway-paypal-express-checkout' ),
441
  ),
442
  ),
443
  'credit_enabled' => array(
456
  * Cart / global button settings.
457
  */
458
  $settings = array_merge( $settings, $per_context_settings );
459
+
460
+ $per_context_settings['button_size']['class'] .= ' woocommerce_ppec_paypal_spb';
461
  $per_context_settings['credit_enabled']['class'] .= ' woocommerce_ppec_paypal_spb';
462
 
463
  $settings['cart_checkout_enabled'] = array(
474
  * Mini-cart button settings.
475
  */
476
  $settings['mini_cart_settings'] = array(
477
+ 'title' => __( 'Mini-cart Button Settings', 'woocommerce-gateway-paypal-express-checkout' ),
478
+ 'type' => 'title',
479
+ 'class' => 'woocommerce_ppec_paypal_spb',
480
  );
481
+
482
  $settings['mini_cart_settings_toggle'] = array(
483
  'title' => __( 'Configure Settings', 'woocommerce-gateway-paypal-express-checkout' ),
484
  'label' => __( 'Configure settings specific to mini-cart', 'woocommerce-gateway-paypal-express-checkout' ),
488
  'desc_tip' => true,
489
  'description' => __( 'Optionally override global button settings above and configure buttons for this context.', 'woocommerce-gateway-paypal-express-checkout' ),
490
  );
491
+ foreach ( $per_context_settings as $key => $value ) {
492
+ $value['class'] .= ' woocommerce_ppec_paypal_mini_cart';
493
  $settings[ 'mini_cart_' . $key ] = $value;
494
  }
495
 
497
  * Single product button settings.
498
  */
499
  $settings['single_product_settings'] = array(
500
+ 'title' => __( 'Single Product Button Settings', 'woocommerce-gateway-paypal-express-checkout' ),
501
+ 'type' => 'title',
502
+ 'class' => 'woocommerce_ppec_paypal_spb',
503
  );
504
+
505
  $settings['checkout_on_single_product_enabled'] = array(
506
  'title' => __( 'Checkout on Single Product', 'woocommerce-gateway-paypal-express-checkout' ),
507
  'type' => 'checkbox',
511
  'desc_tip' => true,
512
  'description' => __( 'Enable PayPal Checkout on Single Product view.', 'woocommerce-gateway-paypal-express-checkout' ),
513
  );
514
+
515
  $settings['single_product_settings_toggle'] = array(
516
  'title' => __( 'Configure Settings', 'woocommerce-gateway-paypal-express-checkout' ),
517
  'label' => __( 'Configure settings specific to Single Product view', 'woocommerce-gateway-paypal-express-checkout' ),
521
  'desc_tip' => true,
522
  'description' => __( 'Optionally override global button settings above and configure buttons for this context.', 'woocommerce-gateway-paypal-express-checkout' ),
523
  );
524
+ foreach ( $per_context_settings as $key => $value ) {
525
+ $value['class'] .= ' woocommerce_ppec_paypal_single_product';
526
  $settings[ 'single_product_' . $key ] = $value;
527
  }
528
  $settings['single_product_button_layout']['default'] = 'horizontal';
531
  * Regular checkout button settings.
532
  */
533
  $settings['mark_settings'] = array(
534
+ 'title' => __( 'Regular Checkout Button Settings', 'woocommerce-gateway-paypal-express-checkout' ),
535
+ 'type' => 'title',
536
+ 'class' => 'woocommerce_ppec_paypal_spb',
537
  );
538
+
539
  $settings['mark_enabled'] = array(
540
  'title' => __( 'PayPal Mark', 'woocommerce-gateway-paypal-express-checkout' ),
541
  'type' => 'checkbox',
545
  'desc_tip' => true,
546
  'default' => 'yes',
547
  );
548
+
549
  $settings['mark_settings_toggle'] = array(
550
  'title' => __( 'Configure Settings', 'woocommerce-gateway-paypal-express-checkout' ),
551
  'label' => __( 'Configure settings specific to regular checkout', 'woocommerce-gateway-paypal-express-checkout' ),
555
  'desc_tip' => true,
556
  'description' => __( 'Optionally override global button settings above and configure buttons for this context.', 'woocommerce-gateway-paypal-express-checkout' ),
557
  );
558
+ foreach ( $per_context_settings as $key => $value ) {
559
+ $value['class'] .= ' woocommerce_ppec_paypal_mark';
560
  $settings[ 'mark_' . $key ] = $value;
561
  }
562
 
563
  return apply_filters( 'woocommerce_paypal_express_checkout_settings', $settings );
564
+
565
+ // phpcs:enable
languages/woocommerce-gateway-paypal-express-checkout.pot CHANGED
@@ -9,7 +9,7 @@ msgstr ""
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "POT-Creation-Date: 2020-05-28T16:20:25+10:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
15
  "X-Domain: woocommerce-gateway-paypal-express-checkout\n"
@@ -36,8 +36,8 @@ msgstr ""
36
 
37
  #: includes/abstracts/abstract-wc-gateway-ppec.php:18
38
  #: includes/class-wc-gateway-ppec-privacy.php:12
39
- #: includes/settings/settings-ppec.php:358
40
- #: includes/settings/settings-ppec.php:404
41
  msgid "PayPal Checkout"
42
  msgstr ""
43
 
@@ -57,107 +57,113 @@ msgstr ""
57
  msgid "No API certificate on file."
58
  msgstr ""
59
 
60
- #: includes/abstracts/abstract-wc-gateway-ppec.php:211
61
- msgid "expires on %s (%s)"
 
62
  msgstr ""
63
 
64
- #: includes/abstracts/abstract-wc-gateway-ppec.php:215
65
- msgid "expired on %s (%s)"
 
66
  msgstr ""
67
 
68
- #: includes/abstracts/abstract-wc-gateway-ppec.php:225
 
69
  msgid "Certificate belongs to API username %1$s; %2$s."
70
  msgstr ""
71
 
72
- #: includes/abstracts/abstract-wc-gateway-ppec.php:227
73
  msgid "The certificate on file is not valid."
74
  msgstr ""
75
 
76
- #: includes/abstracts/abstract-wc-gateway-ppec.php:292
77
  msgid "Error: You must enter API username."
78
  msgstr ""
79
 
80
- #: includes/abstracts/abstract-wc-gateway-ppec.php:296
81
  msgid "Error: You must enter API password."
82
  msgstr ""
83
 
84
- #: includes/abstracts/abstract-wc-gateway-ppec.php:300
85
  msgid "Error: You must provide API signature or certificate."
86
  msgstr ""
87
 
88
- #: includes/abstracts/abstract-wc-gateway-ppec.php:310
89
- #: includes/abstracts/abstract-wc-gateway-ppec.php:337
90
  msgid "Error: The API credentials you provided are not valid. Please double-check that you entered them correctly and try again."
91
  msgstr ""
92
 
93
- #: includes/abstracts/abstract-wc-gateway-ppec.php:314
94
  msgid "An error occurred while trying to validate your API credentials. Unable to verify that your API credentials are correct."
95
  msgstr ""
96
 
97
- #: includes/abstracts/abstract-wc-gateway-ppec.php:321
98
  msgid "Error: The API certificate is not valid."
99
  msgstr ""
100
 
101
- #: includes/abstracts/abstract-wc-gateway-ppec.php:328
102
  msgid "Error: The API certificate has expired."
103
  msgstr ""
104
 
105
- #: includes/abstracts/abstract-wc-gateway-ppec.php:330
106
  msgid "Error: The API username does not match the name in the API certificate. Make sure that you have the correct API certificate."
107
  msgstr ""
108
 
109
- #: includes/abstracts/abstract-wc-gateway-ppec.php:340
110
  msgid "An error occurred while trying to validate your API credentials. Unable to verify that your API credentials are correct."
111
  msgstr ""
112
 
113
- #: includes/abstracts/abstract-wc-gateway-ppec.php:359
114
  msgid "The \"require billing address\" option is not enabled by your account and has been disabled."
115
  msgstr ""
116
 
117
- #: includes/abstracts/abstract-wc-gateway-ppec.php:384
118
  msgid "Refund Error: You need to specify a refund amount."
119
  msgstr ""
120
 
121
- #: includes/abstracts/abstract-wc-gateway-ppec.php:396
122
  msgid "Refund Error: Sorry! This is not a refundable transaction."
123
  msgstr ""
124
 
125
- #: includes/abstracts/abstract-wc-gateway-ppec.php:408
126
- #: includes/abstracts/abstract-wc-gateway-ppec.php:431
127
- #: includes/abstracts/abstract-wc-gateway-ppec.php:481
 
128
  msgid "PayPal refund completed; transaction ID = %s"
129
  msgstr ""
130
 
131
- #: includes/abstracts/abstract-wc-gateway-ppec.php:455
132
  msgid "Refund Error: All transactions have been fully refunded. There is no amount left to refund"
133
  msgstr ""
134
 
135
- #: includes/abstracts/abstract-wc-gateway-ppec.php:457
 
136
  msgid "Refund Error: The requested refund amount is too large. The refund amount must be less than or equal to %s."
137
  msgstr ""
138
 
139
- #: includes/abstracts/abstract-wc-gateway-ppec.php:572
 
140
  msgid "Already using URL as image: %s"
141
  msgstr ""
142
 
143
- #: includes/abstracts/abstract-wc-gateway-ppec.php:580
144
  msgid "Select a image to upload"
145
  msgstr ""
146
 
147
- #: includes/abstracts/abstract-wc-gateway-ppec.php:581
148
  msgid "Use this image"
149
  msgstr ""
150
 
151
- #: includes/abstracts/abstract-wc-gateway-ppec.php:582
152
- #: includes/abstracts/abstract-wc-gateway-ppec.php:585
153
  msgid "Add image"
154
  msgstr ""
155
 
156
- #: includes/abstracts/abstract-wc-gateway-ppec.php:593
157
  msgid "Remove image"
158
  msgstr ""
159
 
160
- #: includes/abstracts/abstract-wc-gateway-ppec.php:632
161
  msgid "Remove"
162
  msgstr ""
163
 
@@ -173,128 +179,132 @@ msgstr ""
173
  msgid "Unable to capture charge!"
174
  msgstr ""
175
 
176
- #: includes/class-wc-gateway-ppec-admin-handler.php:189
 
177
  msgid "PayPal Checkout charge complete (Charge ID: %s)"
178
  msgstr ""
179
 
180
- #: includes/class-wc-gateway-ppec-admin-handler.php:231
181
  msgid "Unable to void charge!"
182
  msgstr ""
183
 
184
- #: includes/class-wc-gateway-ppec-admin-handler.php:233
 
185
  msgid "PayPal Checkout charge voided (Charge ID: %s)"
186
  msgstr ""
187
 
188
- #: includes/class-wc-gateway-ppec-admin-handler.php:340
189
  msgid "This represents the fee PayPal collects for the transaction."
190
  msgstr ""
191
 
192
- #: includes/class-wc-gateway-ppec-admin-handler.php:341
193
  msgid "PayPal Fee:"
194
  msgstr ""
195
 
196
- #: includes/class-wc-gateway-ppec-admin-handler.php:350
197
  msgid "This represents the net total that will be credited to your PayPal account. This may be in a different currency than is set in your PayPal account."
198
  msgstr ""
199
 
200
- #: includes/class-wc-gateway-ppec-admin-handler.php:351
201
  msgid "PayPal Payout:"
202
  msgstr ""
203
 
204
- #: includes/class-wc-gateway-ppec-admin-handler.php:386
 
205
  msgid "%1$sWarning!%2$s PayPal Checkout will drop support for WooCommerce %3$s in a soon to be released update. To continue using PayPal Checkout please %4$supdate to %1$sWooCommerce 3.0%2$s or greater%5$s."
206
  msgstr ""
207
 
208
- #: includes/class-wc-gateway-ppec-api-error.php:22
209
  msgid "Unable to communicate with PayPal. Please try your payment again."
210
  msgstr ""
211
 
212
- #: includes/class-wc-gateway-ppec-api-error.php:23
213
  msgid "PayPal rejected your email address because it is not valid. Please double-check your email address and try again."
214
  msgstr ""
215
 
216
- #: includes/class-wc-gateway-ppec-api-error.php:26
217
  msgid "Your PayPal checkout session is invalid. Please check out again."
218
  msgstr ""
219
 
220
- #: includes/class-wc-gateway-ppec-api-error.php:27
221
  msgid "Your PayPal checkout session has expired. Please check out again."
222
  msgstr ""
223
 
224
- #: includes/class-wc-gateway-ppec-api-error.php:29
225
  msgid "Your PayPal payment has already been completed. Please contact the store owner for more information."
226
  msgstr ""
227
 
228
- #: includes/class-wc-gateway-ppec-api-error.php:30
229
  msgid "Your PayPal payment could not be processed. Please check out again or contact PayPal for assistance."
230
  msgstr ""
231
 
232
- #: includes/class-wc-gateway-ppec-api-error.php:31
233
  msgid "Your PayPal payment could not be processed. Please select an alternative method of payment or contact PayPal for assistance."
234
  msgstr ""
235
 
236
- #: includes/class-wc-gateway-ppec-api-error.php:33
237
  msgid "Your PayPal payment could not be processed. Please return to PayPal and select a new method of payment."
238
  msgstr ""
239
 
240
- #: includes/class-wc-gateway-ppec-api-error.php:35
241
  msgid "You have not approved this transaction on the PayPal website. Please check out again and be sure to complete all steps of the PayPal checkout process."
242
  msgstr ""
243
 
244
- #: includes/class-wc-gateway-ppec-api-error.php:36
245
  msgid "Your shipping address may not be in a different country than your country of residence. Please double-check your shipping address and try again."
246
  msgstr ""
247
 
248
- #: includes/class-wc-gateway-ppec-api-error.php:37
249
  msgid "This store does not accept transactions from buyers in your country. Please contact the store owner for assistance."
250
  msgstr ""
251
 
252
- #: includes/class-wc-gateway-ppec-api-error.php:38
253
  msgid "The transaction is over the threshold allowed by this store. Please contact the store owner for assistance."
254
  msgstr ""
255
 
256
- #: includes/class-wc-gateway-ppec-api-error.php:40
257
  msgid "Your transaction was declined. Please contact the store owner for assistance."
258
  msgstr ""
259
 
260
- #: includes/class-wc-gateway-ppec-api-error.php:41
261
- #: includes/class-wc-gateway-ppec-api-error.php:46
262
  msgid "The country in your shipping address is not valid. Please double-check your shipping address and try again."
263
  msgstr ""
264
 
265
- #: includes/class-wc-gateway-ppec-api-error.php:42
266
  msgid "The street address in your shipping address is not valid. Please double-check your shipping address and try again."
267
  msgstr ""
268
 
269
- #: includes/class-wc-gateway-ppec-api-error.php:43
270
  msgid "The city in your shipping address is not valid. Please double-check your shipping address and try again."
271
  msgstr ""
272
 
273
- #: includes/class-wc-gateway-ppec-api-error.php:44
274
  msgid "The state in your shipping address is not valid. Please double-check your shipping address and try again."
275
  msgstr ""
276
 
277
- #: includes/class-wc-gateway-ppec-api-error.php:45
278
  msgid "The ZIP code or postal code in your shipping address is not valid. Please double-check your shipping address and try again."
279
  msgstr ""
280
 
281
- #: includes/class-wc-gateway-ppec-api-error.php:47
282
  msgid "PayPal rejected your shipping address because the city, state, and/or ZIP code are incorrect. Please double-check that they are all spelled correctly and try again."
283
  msgstr ""
284
 
285
- #: includes/class-wc-gateway-ppec-api-error.php:49
286
  msgid "Your PayPal payment could not be processed. Please contact PayPal for assistance."
287
  msgstr ""
288
 
289
- #: includes/class-wc-gateway-ppec-api-error.php:51
290
  msgid "The redemption code(s) you entered on PayPal cannot be used at this time. Please return to PayPal and remove them."
291
  msgstr ""
292
 
293
- #: includes/class-wc-gateway-ppec-api-error.php:54
294
  msgid "Your funding instrument is invalid. Please check out again and select a new funding source."
295
  msgstr ""
296
 
297
- #: includes/class-wc-gateway-ppec-api-error.php:55
 
298
  msgid "An error (%s) occurred while processing your PayPal payment. Please contact the store owner for assistance."
299
  msgstr ""
300
 
@@ -304,21 +314,21 @@ msgstr ""
304
  msgid "Cheatin&#8217; huh?"
305
  msgstr ""
306
 
307
- #: includes/class-wc-gateway-ppec-cart-handler.php:320
308
- #: includes/class-wc-gateway-ppec-cart-handler.php:363
309
- #: includes/class-wc-gateway-ppec-cart-handler.php:398
310
  msgid "Check out with PayPal"
311
  msgstr ""
312
 
313
- #: includes/class-wc-gateway-ppec-cart-handler.php:354
314
  msgid "OR"
315
  msgstr ""
316
 
317
- #: includes/class-wc-gateway-ppec-cart-handler.php:368
318
  msgid "Pay with PayPal Credit"
319
  msgstr ""
320
 
321
- #: includes/class-wc-gateway-ppec-cart-handler.php:508
322
  msgid "An error occurred while processing your PayPal payment. Please contact the store owner for assistance."
323
  msgstr ""
324
 
@@ -354,17 +364,17 @@ msgstr ""
354
  msgid "Create an account by entering the information below. If you are a returning customer please login at the top of the page."
355
  msgstr ""
356
 
357
- #: includes/class-wc-gateway-ppec-checkout-handler.php:346
358
  msgid "Shipping details"
359
  msgstr ""
360
 
361
  #: includes/class-wc-gateway-ppec-checkout-handler.php:444
362
- #: includes/class-wc-gateway-ppec-checkout-handler.php:498
363
- #: includes/class-wc-gateway-ppec-checkout-handler.php:1124
364
  msgid "Your PayPal checkout session has expired. Please check out again."
365
  msgstr ""
366
 
367
- #: includes/class-wc-gateway-ppec-checkout-handler.php:493
368
  msgid "Sorry, an error occurred while trying to retrieve your information from PayPal. Please try again."
369
  msgstr ""
370
 
@@ -372,33 +382,35 @@ msgstr ""
372
  msgid "Cancel"
373
  msgstr ""
374
 
375
- #: includes/class-wc-gateway-ppec-checkout-handler.php:624
376
  msgid "You have cancelled Checkout with PayPal. Please try to process your order again."
377
  msgstr ""
378
 
379
- #: includes/class-wc-gateway-ppec-checkout-handler.php:951
380
- #: includes/class-wc-gateway-ppec-ipn-handler.php:190
381
  msgid "Payment authorized. Change payment status to processing or complete to capture funds."
382
  msgstr ""
383
 
384
- #: includes/class-wc-gateway-ppec-checkout-handler.php:953
385
- #: includes/class-wc-gateway-ppec-ipn-handler.php:192
 
 
386
  msgid "Payment pending (%s)."
387
  msgstr ""
388
 
389
- #: includes/class-wc-gateway-ppec-checkout-handler.php:1135
390
  msgid "The payment method was updated for this subscription."
391
  msgstr ""
392
 
393
- #: includes/class-wc-gateway-ppec-checkout-handler.php:1140
394
  msgid "The payment method was updated for all your current subscriptions."
395
  msgstr ""
396
 
397
- #: includes/class-wc-gateway-ppec-checkout-handler.php:1149
398
  msgid "There was a problem updating your payment method. Please try again later or use a different payment method."
399
  msgstr ""
400
 
401
- #: includes/class-wc-gateway-ppec-checkout-handler.php:1172
402
  msgid "You have cancelled Checkout with PayPal. The payment method was not updated."
403
  msgstr ""
404
 
@@ -410,39 +422,47 @@ msgstr ""
410
  msgid "Unable to accept certificate password during cURL configuration"
411
  msgstr ""
412
 
413
- #: includes/class-wc-gateway-ppec-client-credential-certificate.php:87
414
- #: includes/class-wc-gateway-ppec-client-credential-certificate.php:133
 
415
  msgid "Unable to write certificate file %s during cURL configuration"
416
  msgstr ""
417
 
418
- #: includes/class-wc-gateway-ppec-client-credential-certificate.php:113
419
  msgid "Failed to retrieve private key during cURL configuration"
420
  msgstr ""
421
 
422
- #: includes/class-wc-gateway-ppec-client-credential-certificate.php:117
423
  msgid "Failed to export PKCS12 file during cURL configuration"
424
  msgstr ""
425
 
426
- #: includes/class-wc-gateway-ppec-client.php:166
427
  msgid "Missing credential"
428
  msgstr ""
429
 
430
- #: includes/class-wc-gateway-ppec-client.php:170
431
  msgid "Invalid credential object"
432
  msgstr ""
433
 
434
- #: includes/class-wc-gateway-ppec-client.php:174
435
  msgid "Invalid environment"
436
  msgstr ""
437
 
438
- #: includes/class-wc-gateway-ppec-client.php:191
 
439
  msgid "An error occurred while trying to connect to PayPal: %s"
440
  msgstr ""
441
 
442
- #: includes/class-wc-gateway-ppec-client.php:197
443
  msgid "Malformed response received from PayPal"
444
  msgstr ""
445
 
 
 
 
 
 
 
446
  #: includes/class-wc-gateway-ppec-ipn-handler.php:29
447
  msgid "Empty POST data."
448
  msgstr ""
@@ -455,45 +475,54 @@ msgstr ""
455
  msgid "PayPal IPN Request Failure"
456
  msgstr ""
457
 
458
- #: includes/class-wc-gateway-ppec-ipn-handler.php:142
 
459
  msgid "Validation error: PayPal currencies do not match (code %s)."
460
  msgstr ""
461
 
462
- #: includes/class-wc-gateway-ppec-ipn-handler.php:157
 
463
  msgid "Validation error: PayPal amounts do not match (gross %s)."
464
  msgstr ""
465
 
466
- #: includes/class-wc-gateway-ppec-ipn-handler.php:183
467
  msgid "IPN payment completed"
468
  msgstr ""
469
 
470
- #: includes/class-wc-gateway-ppec-ipn-handler.php:214
471
- #: includes/class-wc-gateway-ppec-ipn-handler.php:258
472
- #: includes/class-wc-gateway-ppec-ipn-handler.php:274
 
473
  msgid "Payment %s via IPN."
474
  msgstr ""
475
 
476
- #: includes/class-wc-gateway-ppec-ipn-handler.php:260
 
477
  msgid "Payment for order %s refunded"
478
  msgstr ""
479
 
480
- #: includes/class-wc-gateway-ppec-ipn-handler.php:261
 
481
  msgid "Order #%1$s has been marked as refunded - PayPal reason code: %2$s"
482
  msgstr ""
483
 
484
- #: includes/class-wc-gateway-ppec-ipn-handler.php:276
 
485
  msgid "Payment for order %s reversed"
486
  msgstr ""
487
 
488
- #: includes/class-wc-gateway-ppec-ipn-handler.php:277
 
489
  msgid "Order #%1$s has been marked on-hold due to a reversal - PayPal reason code: %2$s"
490
  msgstr ""
491
 
492
- #: includes/class-wc-gateway-ppec-ipn-handler.php:290
 
493
  msgid "Reversal cancelled for order #%s"
494
  msgstr ""
495
 
496
- #: includes/class-wc-gateway-ppec-ipn-handler.php:291
 
497
  msgid "Order #%1$s has had a reversal cancelled. Please check the status of payment and update the order status accordingly here: %2$s"
498
  msgstr ""
499
 
@@ -506,20 +535,20 @@ msgstr ""
506
  msgid "Sorry, Easy Setup encountered an error. Please try again."
507
  msgstr ""
508
 
509
- #: includes/class-wc-gateway-ppec-ips-handler.php:173
510
  msgid "Easy Setup was able to obtain your API credentials, but was unable to verify that they work correctly. Please make sure your PayPal account is set up properly and try Easy Setup again."
511
  msgstr ""
512
 
513
- #: includes/class-wc-gateway-ppec-ips-handler.php:177
514
  msgid "Easy Setup was able to obtain your API credentials, but an error occurred while trying to verify that they work correctly. Please try Easy Setup again."
515
  msgstr ""
516
 
517
- #: includes/class-wc-gateway-ppec-ips-handler.php:182
518
  msgid "Success! Your PayPal account has been set up successfully."
519
  msgstr ""
520
 
521
  #: includes/class-wc-gateway-ppec-plugin.php:158
522
- msgid "%s in WooCommerce Gateway PayPal Checkout plugin can only be called once"
523
  msgstr ""
524
 
525
  #: includes/class-wc-gateway-ppec-plugin.php:260
@@ -538,31 +567,33 @@ msgstr ""
538
  msgid "WooCommerce Gateway PayPal Checkout requires OpenSSL >= 1.0.1 to be installed on your server"
539
  msgstr ""
540
 
541
- #: includes/class-wc-gateway-ppec-plugin.php:298
 
542
  msgid "PayPal Checkout is almost ready. To get started, <a href=\"%s\">connect your PayPal account</a>."
543
  msgstr ""
544
 
545
- #: includes/class-wc-gateway-ppec-plugin.php:428
546
  msgid "Settings"
547
  msgstr ""
548
 
549
- #: includes/class-wc-gateway-ppec-plugin.php:447
550
  msgid "View Documentation"
551
  msgstr ""
552
 
553
- #: includes/class-wc-gateway-ppec-plugin.php:447
554
  msgid "Docs"
555
  msgstr ""
556
 
557
- #: includes/class-wc-gateway-ppec-plugin.php:448
558
  msgid "Open a support request at WooCommerce.com"
559
  msgstr ""
560
 
561
- #: includes/class-wc-gateway-ppec-plugin.php:448
562
  msgid "Support"
563
  msgstr ""
564
 
565
- #: includes/class-wc-gateway-ppec-plugin.php:503
 
566
  msgid "<p>PayPal Checkout with new <strong>Smart Payment Buttons™</strong> gives your customers the power to pay the way they want without leaving your site.</p><p>The <strong>existing buttons will be removed</strong> in the <strong>next release</strong>. Please upgrade to Smart Payment Buttons on the <a href=\"%s\">PayPal Checkout settings page</a>.</p>"
567
  msgstr ""
568
 
@@ -578,55 +609,62 @@ msgstr ""
578
  msgid "WooCommerce PPEC Data"
579
  msgstr ""
580
 
581
- #: includes/class-wc-gateway-ppec-privacy.php:53
 
582
  msgid "By using this extension, you may be storing personal data or sharing data with an external service. <a href=\"%s\" target=\"_blank\">Learn more about how this works, including what you may want to include in your privacy policy.</a>"
583
  msgstr ""
584
 
585
- #: includes/class-wc-gateway-ppec-privacy.php:76
586
  msgid "Orders"
587
  msgstr ""
588
 
589
- #: includes/class-wc-gateway-ppec-privacy.php:80
590
- #: includes/class-wc-gateway-ppec-privacy.php:145
591
  msgid "PPEC Refundable transaction data"
592
  msgstr ""
593
 
594
- #: includes/class-wc-gateway-ppec-privacy.php:84
595
- #: includes/class-wc-gateway-ppec-privacy.php:149
596
  msgid "PPEC Billing agreement id"
597
  msgstr ""
598
 
599
- #: includes/class-wc-gateway-ppec-privacy.php:141
600
  msgid "Subscriptions"
601
  msgstr ""
602
 
603
- #: includes/class-wc-gateway-ppec-privacy.php:245
 
 
 
 
 
604
  msgid "PayPal Checkout Subscriptions Data Erased."
605
  msgstr ""
606
 
607
- #: includes/class-wc-gateway-ppec-privacy.php:268
608
  msgid "PayPal Checkout Order Data Erased."
609
  msgstr ""
610
 
611
- #: includes/class-wc-gateway-ppec-with-paypal-addons.php:196
612
  msgid "PayPal API error"
613
  msgstr ""
614
 
615
  #. translators: placeholder is pending reason from PayPal API.
616
- #: includes/class-wc-gateway-ppec-with-paypal-addons.php:206
617
  msgid "PayPal transaction held: %s"
618
  msgstr ""
619
 
620
- #: includes/class-wc-gateway-ppec-with-paypal-addons.php:217
 
621
  msgid "PayPal payment approved (ID: %s)"
622
  msgstr ""
623
 
624
- #: includes/class-wc-gateway-ppec-with-paypal-addons.php:221
625
  msgid "PayPal payment declined"
626
  msgstr ""
627
 
628
  #: includes/class-wc-gateway-ppec-with-paypal-credit.php:15
629
- #: includes/settings/settings-ppec.php:417
630
  msgid "PayPal Credit"
631
  msgstr ""
632
 
@@ -644,573 +682,577 @@ msgstr ""
644
  msgid "The buyer's session information could not be found."
645
  msgstr ""
646
 
647
- #: includes/settings/settings-ppec.php:17
648
  msgid "Setup or link an existing PayPal account"
649
  msgstr ""
650
 
651
- #: includes/settings/settings-ppec.php:18
 
652
  msgid "%s or <a href=\"#\" class=\"ppec-toggle-settings\">click here to toggle manual API credential input</a>."
653
  msgstr ""
654
 
655
  #. Translators: Placeholders are opening an closing link HTML tags.
656
- #: includes/settings/settings-ppec.php:31
657
  msgid "To reset current credentials and use another account %1$sclick here%2$s. %3$sLearn more about your API Credentials%2$s."
658
  msgstr ""
659
 
660
  #. Translators: Placeholders are opening an closing link HTML tags.
661
  #. Translators: Placeholders are opening and closing link HTML tags.
662
- #: includes/settings/settings-ppec.php:32
663
- #: includes/settings/settings-ppec.php:54
664
  msgid "Reset current credentials"
665
  msgstr ""
666
 
667
- #: includes/settings/settings-ppec.php:34
668
- #: includes/settings/settings-ppec.php:56
669
  msgid "Learn more"
670
  msgstr ""
671
 
672
- #: includes/settings/settings-ppec.php:39
673
  msgid "Setup or link an existing PayPal Sandbox account"
674
  msgstr ""
675
 
676
- #: includes/settings/settings-ppec.php:40
 
677
  msgid "%s or <a href=\"#\" class=\"ppec-toggle-sandbox-settings\">click here to toggle manual API credential input</a>."
678
  msgstr ""
679
 
680
  #. Translators: Placeholders are opening and closing link HTML tags.
681
- #: includes/settings/settings-ppec.php:53
682
  msgid "Your account setting is set to sandbox, no real charging takes place. To accept live payments, switch your environment to live and connect your PayPal account. To reset current credentials and use other sandbox account %1$sclick here%2$s. %3$sLearn more about your API Credentials%2$s."
683
  msgstr ""
684
 
685
- #: includes/settings/settings-ppec.php:60
686
- #: includes/settings/settings-ppec.php:432
687
  msgid "Enable PayPal Credit to eligible customers"
688
  msgstr ""
689
 
690
- #: includes/settings/settings-ppec.php:62
691
  msgid "This option is disabled. Currently PayPal Credit only available for U.S. merchants using USD currency."
692
  msgstr ""
693
 
694
- #: includes/settings/settings-ppec.php:65
695
  msgid "This enables PayPal Credit, which displays a PayPal Credit button next to the primary PayPal Checkout button. PayPal Checkout lets you give customers access to financing through PayPal Credit® - at no additional cost to you. You get paid up front, even though customers have more time to pay. A pre-integrated payment button shows up next to the PayPal Button, and lets customers pay quickly with PayPal Credit®. (Should be unchecked for stores involved in Real Money Gaming.)"
696
  msgstr ""
697
 
698
- #: includes/settings/settings-ppec.php:72
699
  msgid "Enable/Disable"
700
  msgstr ""
701
 
702
- #: includes/settings/settings-ppec.php:74
703
  msgid "Enable PayPal Checkout"
704
  msgstr ""
705
 
706
- #: includes/settings/settings-ppec.php:75
707
  msgid "This enables PayPal Checkout which allows customers to checkout directly via PayPal from your cart page."
708
  msgstr ""
709
 
710
- #: includes/settings/settings-ppec.php:81
711
  msgid "Title"
712
  msgstr ""
713
 
714
- #: includes/settings/settings-ppec.php:83
715
  msgid "This controls the title which the user sees during checkout."
716
  msgstr ""
717
 
718
- #: includes/settings/settings-ppec.php:84
719
- #: includes/settings/settings-ppec.php:357
720
- #: includes/settings/settings-ppec.php:403
721
  msgid "PayPal"
722
  msgstr ""
723
 
724
- #: includes/settings/settings-ppec.php:88
725
  msgid "Description"
726
  msgstr ""
727
 
728
- #: includes/settings/settings-ppec.php:91
729
  msgid "This controls the description which the user sees during checkout."
730
  msgstr ""
731
 
732
- #: includes/settings/settings-ppec.php:92
733
  msgid "Pay via PayPal; you can pay with your credit card if you don't have a PayPal account."
734
  msgstr ""
735
 
736
- #: includes/settings/settings-ppec.php:96
737
  msgid "Account Settings"
738
  msgstr ""
739
 
740
- #: includes/settings/settings-ppec.php:101
741
  msgid "Environment"
742
  msgstr ""
743
 
744
- #: includes/settings/settings-ppec.php:104
745
  msgid "This setting specifies whether you will process live transactions, or whether you will process simulated transactions using the PayPal Sandbox."
746
  msgstr ""
747
 
748
- #: includes/settings/settings-ppec.php:108
749
  msgid "Live"
750
  msgstr ""
751
 
752
- #: includes/settings/settings-ppec.php:109
753
  msgid "Sandbox"
754
  msgstr ""
755
 
756
- #: includes/settings/settings-ppec.php:114
757
  msgid "API Credentials"
758
  msgstr ""
759
 
760
- #: includes/settings/settings-ppec.php:119
761
  msgid "Live API Username"
762
  msgstr ""
763
 
764
- #: includes/settings/settings-ppec.php:121
765
- #: includes/settings/settings-ppec.php:128
766
- #: includes/settings/settings-ppec.php:135
767
- #: includes/settings/settings-ppec.php:162
768
- #: includes/settings/settings-ppec.php:169
769
- #: includes/settings/settings-ppec.php:176
770
  msgid "Get your API credentials from PayPal."
771
  msgstr ""
772
 
773
- #: includes/settings/settings-ppec.php:126
774
  msgid "Live API Password"
775
  msgstr ""
776
 
777
- #: includes/settings/settings-ppec.php:133
778
  msgid "Live API Signature"
779
  msgstr ""
780
 
781
- #: includes/settings/settings-ppec.php:138
782
- #: includes/settings/settings-ppec.php:179
783
  msgid "Optional if you provide a certificate below"
784
  msgstr ""
785
 
786
- #: includes/settings/settings-ppec.php:141
787
  msgid "Live API Certificate"
788
  msgstr ""
789
 
790
- #: includes/settings/settings-ppec.php:147
791
  msgid "Live API Subject"
792
  msgstr ""
793
 
794
- #: includes/settings/settings-ppec.php:149
795
- #: includes/settings/settings-ppec.php:190
796
  msgid "If you're processing transactions on behalf of someone else's PayPal account, enter their email address or Secure Merchant Account ID (also known as a Payer ID) here. Generally, you must have API permissions in place with the other account in order to process anything other than \"sale\" transactions for them."
797
  msgstr ""
798
 
799
- #: includes/settings/settings-ppec.php:152
800
- #: includes/settings/settings-ppec.php:193
801
- #: includes/settings/settings-ppec.php:213
802
- #: includes/settings/settings-ppec.php:221
803
- #: includes/settings/settings-ppec.php:229
804
  msgid "Optional"
805
  msgstr ""
806
 
807
- #: includes/settings/settings-ppec.php:155
808
  msgid "Sandbox API Credentials"
809
  msgstr ""
810
 
811
- #: includes/settings/settings-ppec.php:160
812
  msgid "Sandbox API Username"
813
  msgstr ""
814
 
815
- #: includes/settings/settings-ppec.php:167
816
  msgid "Sandbox API Password"
817
  msgstr ""
818
 
819
- #: includes/settings/settings-ppec.php:174
820
  msgid "Sandbox API Signature"
821
  msgstr ""
822
 
823
- #: includes/settings/settings-ppec.php:182
824
  msgid "Sandbox API Certificate"
825
  msgstr ""
826
 
827
- #: includes/settings/settings-ppec.php:188
828
  msgid "Sandbox API Subject"
829
  msgstr ""
830
 
831
- #: includes/settings/settings-ppec.php:196
832
  msgid "PayPal-hosted Checkout Settings"
833
  msgstr ""
834
 
835
- #: includes/settings/settings-ppec.php:198
836
  msgid "Customize the appearance of PayPal Checkout on the PayPal side."
837
  msgstr ""
838
 
839
- #: includes/settings/settings-ppec.php:201
840
  msgid "Brand Name"
841
  msgstr ""
842
 
843
- #: includes/settings/settings-ppec.php:203
844
  msgid "A label that overrides the business name in the PayPal account on the PayPal hosted checkout pages."
845
  msgstr ""
846
 
847
- #: includes/settings/settings-ppec.php:208
848
  msgid "Logo Image (190×60)"
849
  msgstr ""
850
 
851
- #: includes/settings/settings-ppec.php:210
852
  msgid "If you want PayPal to co-brand the checkout page with your logo, enter the URL of your logo image here.<br/>The image must be no larger than 190x60, GIF, PNG, or JPG format, and should be served over HTTPS."
853
  msgstr ""
854
 
855
- #: includes/settings/settings-ppec.php:216
856
  msgid "Header Image (750×90)"
857
  msgstr ""
858
 
859
- #: includes/settings/settings-ppec.php:218
860
  msgid "If you want PayPal to co-brand the checkout page with your header, enter the URL of your header image here.<br/>The image must be no larger than 750x90, GIF, PNG, or JPG format, and should be served over HTTPS."
861
  msgstr ""
862
 
863
- #: includes/settings/settings-ppec.php:224
864
  msgid "Page Style"
865
  msgstr ""
866
 
867
- #: includes/settings/settings-ppec.php:226
868
  msgid "Optionally enter the name of the page style you wish to use. These are defined within your PayPal account."
869
  msgstr ""
870
 
871
- #: includes/settings/settings-ppec.php:232
872
  msgid "Landing Page"
873
  msgstr ""
874
 
875
- #: includes/settings/settings-ppec.php:235
876
  msgid "Type of PayPal page to display."
877
  msgstr ""
878
 
879
- #: includes/settings/settings-ppec.php:239
880
  msgctxt "Type of PayPal page"
881
  msgid "Billing (Non-PayPal account)"
882
  msgstr ""
883
 
884
- #: includes/settings/settings-ppec.php:240
885
  msgctxt "Type of PayPal page"
886
  msgid "Login (PayPal account login)"
887
  msgstr ""
888
 
889
- #: includes/settings/settings-ppec.php:245
890
  msgid "Advanced Settings"
891
  msgstr ""
892
 
893
- #: includes/settings/settings-ppec.php:250
894
  msgid "Debug Log"
895
  msgstr ""
896
 
897
- #: includes/settings/settings-ppec.php:252
898
  msgid "Enable Logging"
899
  msgstr ""
900
 
901
- #: includes/settings/settings-ppec.php:255
902
  msgid "Log PayPal events, such as IPN requests."
903
  msgstr ""
904
 
905
- #: includes/settings/settings-ppec.php:258
906
  msgid "Invoice Prefix"
907
  msgstr ""
908
 
909
- #: includes/settings/settings-ppec.php:260
910
  msgid "Please enter a prefix for your invoice numbers. If you use your PayPal account for multiple stores ensure this prefix is unique as PayPal will not allow orders with the same invoice number."
911
  msgstr ""
912
 
913
- #: includes/settings/settings-ppec.php:265
914
  msgid "Billing Addresses"
915
  msgstr ""
916
 
917
- #: includes/settings/settings-ppec.php:267
918
  msgid "Require Billing Address"
919
  msgstr ""
920
 
921
- #: includes/settings/settings-ppec.php:269
 
922
  msgid "PayPal only returns a shipping address back to the website. To make sure billing address is returned as well, please enable this functionality on your PayPal account by calling %1$sPayPal Technical Support%2$s."
923
  msgstr ""
924
 
925
- #: includes/settings/settings-ppec.php:272
926
- #: includes/settings/settings-ppec.php:274
927
  msgid "Require Phone Number"
928
  msgstr ""
929
 
930
- #: includes/settings/settings-ppec.php:276
931
- msgid "Require buyer to enter their telephone number during checkout if none is provided by PayPal"
932
  msgstr ""
933
 
934
- #: includes/settings/settings-ppec.php:279
935
  msgid "Payment Action"
936
  msgstr ""
937
 
938
- #: includes/settings/settings-ppec.php:282
939
  msgid "Choose whether you wish to capture funds immediately or authorize payment only."
940
  msgstr ""
941
 
942
- #: includes/settings/settings-ppec.php:286
943
  msgid "Sale"
944
  msgstr ""
945
 
946
- #: includes/settings/settings-ppec.php:287
947
  msgid "Authorize"
948
  msgstr ""
949
 
950
- #: includes/settings/settings-ppec.php:291
951
  msgid "Instant Payments"
952
  msgstr ""
953
 
954
- #: includes/settings/settings-ppec.php:293
955
  msgid "Require Instant Payment"
956
  msgstr ""
957
 
958
- #: includes/settings/settings-ppec.php:296
959
  msgid "If you enable this setting, PayPal will be instructed not to allow the buyer to use funding sources that take additional time to complete (for example, eChecks). Instead, the buyer will be required to use an instant funding source, such as an instant transfer, a credit/debit card, or PayPal Credit."
960
  msgstr ""
961
 
962
- #: includes/settings/settings-ppec.php:299
963
  msgid "Subtotal Mismatch Behavior"
964
  msgstr ""
965
 
966
- #: includes/settings/settings-ppec.php:302
967
  msgid "Internally, WC calculates line item prices and taxes out to four decimal places; however, PayPal can only handle amounts out to two decimal places (or, depending on the currency, no decimal places at all). Occasionally, this can cause discrepancies between the way WooCommerce calculates prices versus the way PayPal calculates them. If a mismatch occurs, this option controls how the order is dealt with so payment can still be taken."
968
  msgstr ""
969
 
970
- #: includes/settings/settings-ppec.php:306
971
  msgid "Add another line item"
972
  msgstr ""
973
 
974
- #: includes/settings/settings-ppec.php:307
975
  msgid "Do not send line items to PayPal"
976
  msgstr ""
977
 
978
- #: includes/settings/settings-ppec.php:312
979
  msgid "Button Settings"
980
  msgstr ""
981
 
982
- #: includes/settings/settings-ppec.php:314
983
  msgid "Customize the appearance of PayPal Checkout on your site."
984
  msgstr ""
985
 
986
- #: includes/settings/settings-ppec.php:317
987
  msgid "Smart Payment Buttons"
988
  msgstr ""
989
 
990
- #: includes/settings/settings-ppec.php:320
991
  msgid "Use Smart Payment Buttons"
992
  msgstr ""
993
 
994
- #: includes/settings/settings-ppec.php:321
 
995
  msgid "PayPal Checkout's Smart Payment Buttons provide a variety of button customization options, such as color, language, shape, and multiple button layout. <a href=\"%s\">Learn more about Smart Payment Buttons</a>."
996
  msgstr ""
997
 
998
- #: includes/settings/settings-ppec.php:324
999
  msgid "Button Color"
1000
  msgstr ""
1001
 
1002
- #: includes/settings/settings-ppec.php:329
1003
  msgid "Controls the background color of the primary button. Use \"Gold\" to leverage PayPal's recognition and preference, or change it to match your site design or aesthetic."
1004
  msgstr ""
1005
 
1006
- #: includes/settings/settings-ppec.php:331
1007
  msgid "Gold (Recommended)"
1008
  msgstr ""
1009
 
1010
- #: includes/settings/settings-ppec.php:332
1011
  msgid "Blue"
1012
  msgstr ""
1013
 
1014
- #: includes/settings/settings-ppec.php:333
1015
  msgid "Silver"
1016
  msgstr ""
1017
 
1018
- #: includes/settings/settings-ppec.php:334
1019
  msgid "Black"
1020
  msgstr ""
1021
 
1022
- #: includes/settings/settings-ppec.php:338
1023
  msgid "Button Shape"
1024
  msgstr ""
1025
 
1026
- #: includes/settings/settings-ppec.php:343
1027
  msgid "The pill-shaped button's unique and powerful shape signifies PayPal in people's minds. Use the rectangular button as an alternative when pill-shaped buttons might pose design challenges."
1028
  msgstr ""
1029
 
1030
- #: includes/settings/settings-ppec.php:345
1031
  msgid "Pill"
1032
  msgstr ""
1033
 
1034
- #: includes/settings/settings-ppec.php:346
1035
  msgid "Rectangle"
1036
  msgstr ""
1037
 
1038
- #: includes/settings/settings-ppec.php:350
1039
- #: includes/settings/settings-ppec.php:396
1040
  msgid "Button Label"
1041
  msgstr ""
1042
 
1043
- #: includes/settings/settings-ppec.php:355
1044
  msgid "This controls the label on the primary button."
1045
  msgstr ""
1046
 
1047
- #: includes/settings/settings-ppec.php:359
1048
- #: includes/settings/settings-ppec.php:405
1049
  msgid "PayPal Buy Now"
1050
  msgstr ""
1051
 
1052
- #: includes/settings/settings-ppec.php:360
1053
- #: includes/settings/settings-ppec.php:406
1054
  msgid "Pay with PayPal"
1055
  msgstr ""
1056
 
1057
- #: includes/settings/settings-ppec.php:370
1058
  msgid "Button Layout"
1059
  msgstr ""
1060
 
1061
- #: includes/settings/settings-ppec.php:375
1062
  msgid "If additional funding sources are available to the buyer through PayPal, such as Venmo, then multiple buttons are displayed in the space provided. Choose \"vertical\" for a dynamic list of alternative and local payment options, or \"horizontal\" when space is limited."
1063
  msgstr ""
1064
 
1065
- #: includes/settings/settings-ppec.php:377
1066
  msgid "Vertical"
1067
  msgstr ""
1068
 
1069
- #: includes/settings/settings-ppec.php:378
1070
  msgid "Horizontal"
1071
  msgstr ""
1072
 
1073
- #: includes/settings/settings-ppec.php:382
1074
  msgid "Button Size"
1075
  msgstr ""
1076
 
1077
- #: includes/settings/settings-ppec.php:387
1078
  msgid "PayPal offers different sizes of the \"PayPal Checkout\" buttons, allowing you to select a size that best fits your site's theme. This setting will allow you to choose which size button(s) appear on your cart page. (The \"Responsive\" option adjusts to container size, and is available and recommended for Smart Payment Buttons.)"
1079
  msgstr ""
1080
 
1081
- #: includes/settings/settings-ppec.php:389
1082
  msgid "Responsive"
1083
  msgstr ""
1084
 
1085
- #: includes/settings/settings-ppec.php:390
1086
  msgid "Small"
1087
  msgstr ""
1088
 
1089
- #: includes/settings/settings-ppec.php:391
1090
  msgid "Medium"
1091
  msgstr ""
1092
 
1093
- #: includes/settings/settings-ppec.php:392
1094
  msgid "Large"
1095
  msgstr ""
1096
 
1097
- #: includes/settings/settings-ppec.php:401
1098
  msgid "PayPal offers different labels on the \"PayPal Checkout\" buttons, allowing you to select a suitable label.)"
1099
  msgstr ""
1100
 
1101
- #: includes/settings/settings-ppec.php:415
1102
  msgid "Hides the specified funding methods."
1103
  msgstr ""
1104
 
1105
- #: includes/settings/settings-ppec.php:418
1106
  msgid "ELV"
1107
  msgstr ""
1108
 
1109
- #: includes/settings/settings-ppec.php:419
1110
  msgid "Credit or debit cards"
1111
  msgstr ""
1112
 
1113
- #: includes/settings/settings-ppec.php:420
1114
  msgid "Venmo"
1115
  msgstr ""
1116
 
1117
- #: includes/settings/settings-ppec.php:421
1118
  msgid "SEPA-Lastschrift"
1119
  msgstr ""
1120
 
1121
- #: includes/settings/settings-ppec.php:422
1122
  msgid "Bancontact"
1123
  msgstr ""
1124
 
1125
- #: includes/settings/settings-ppec.php:423
1126
  msgid "eps"
1127
  msgstr ""
1128
 
1129
- #: includes/settings/settings-ppec.php:424
1130
  msgid "giropay"
1131
  msgstr ""
1132
 
1133
- #: includes/settings/settings-ppec.php:425
1134
  msgid "iDEAL"
1135
  msgstr ""
1136
 
1137
- #: includes/settings/settings-ppec.php:426
1138
  msgid "MyBank"
1139
  msgstr ""
1140
 
1141
- #: includes/settings/settings-ppec.php:427
1142
  msgid "Przelewy24"
1143
  msgstr ""
1144
 
1145
- #: includes/settings/settings-ppec.php:428
1146
  msgid "Sofort"
1147
  msgstr ""
1148
 
1149
- #: includes/settings/settings-ppec.php:451
1150
  msgid "Checkout on cart page"
1151
  msgstr ""
1152
 
1153
- #: includes/settings/settings-ppec.php:454
1154
  msgid "Enable PayPal Checkout on the cart page"
1155
  msgstr ""
1156
 
1157
- #: includes/settings/settings-ppec.php:455
1158
  msgid "This shows or hides the PayPal Checkout button on the cart page."
1159
  msgstr ""
1160
 
1161
- #: includes/settings/settings-ppec.php:464
1162
  msgid "Mini-cart Button Settings"
1163
  msgstr ""
1164
 
1165
- #: includes/settings/settings-ppec.php:469
1166
- #: includes/settings/settings-ppec.php:500
1167
- #: includes/settings/settings-ppec.php:532
1168
  msgid "Configure Settings"
1169
  msgstr ""
1170
 
1171
- #: includes/settings/settings-ppec.php:470
1172
  msgid "Configure settings specific to mini-cart"
1173
  msgstr ""
1174
 
1175
- #: includes/settings/settings-ppec.php:475
1176
- #: includes/settings/settings-ppec.php:506
1177
- #: includes/settings/settings-ppec.php:538
1178
  msgid "Optionally override global button settings above and configure buttons for this context."
1179
  msgstr ""
1180
 
1181
- #: includes/settings/settings-ppec.php:486
1182
  msgid "Single Product Button Settings"
1183
  msgstr ""
1184
 
1185
- #: includes/settings/settings-ppec.php:491
1186
- #: includes/settings/settings-ppec.php:494
1187
  msgid "Checkout on Single Product"
1188
  msgstr ""
1189
 
1190
- #: includes/settings/settings-ppec.php:497
1191
  msgid "Enable PayPal Checkout on Single Product view."
1192
  msgstr ""
1193
 
1194
- #: includes/settings/settings-ppec.php:501
1195
  msgid "Configure settings specific to Single Product view"
1196
  msgstr ""
1197
 
1198
- #: includes/settings/settings-ppec.php:518
1199
  msgid "Regular Checkout Button Settings"
1200
  msgstr ""
1201
 
1202
- #: includes/settings/settings-ppec.php:523
1203
  msgid "PayPal Mark"
1204
  msgstr ""
1205
 
1206
- #: includes/settings/settings-ppec.php:526
1207
  msgid "Enable the PayPal Mark on regular checkout"
1208
  msgstr ""
1209
 
1210
- #: includes/settings/settings-ppec.php:527
1211
  msgid "This enables the PayPal mark, which can be shown on regular WooCommerce checkout to use PayPal Checkout like a regular WooCommerce gateway."
1212
  msgstr ""
1213
 
1214
- #: includes/settings/settings-ppec.php:533
1215
  msgid "Configure settings specific to regular checkout"
1216
  msgstr ""
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "POT-Creation-Date: 2020-07-01T13:39:01+10:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
15
  "X-Domain: woocommerce-gateway-paypal-express-checkout\n"
36
 
37
  #: includes/abstracts/abstract-wc-gateway-ppec.php:18
38
  #: includes/class-wc-gateway-ppec-privacy.php:12
39
+ #: includes/settings/settings-ppec.php:370
40
+ #: includes/settings/settings-ppec.php:416
41
  msgid "PayPal Checkout"
42
  msgstr ""
43
 
57
  msgid "No API certificate on file."
58
  msgstr ""
59
 
60
+ #. Translators: placeholders are a date in local format and its timezone.
61
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:212
62
+ msgid "expires on %1$s (%2$s)"
63
  msgstr ""
64
 
65
+ #. Translators: placeholders are a date in local format and its timezone.
66
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:217
67
+ msgid "expired on %1$s (%2$s)"
68
  msgstr ""
69
 
70
+ #. Translators: 1) is a certificate's CN, 2) is the expiration date.
71
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:228
72
  msgid "Certificate belongs to API username %1$s; %2$s."
73
  msgstr ""
74
 
75
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:230
76
  msgid "The certificate on file is not valid."
77
  msgstr ""
78
 
79
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:295
80
  msgid "Error: You must enter API username."
81
  msgstr ""
82
 
83
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:299
84
  msgid "Error: You must enter API password."
85
  msgstr ""
86
 
87
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:303
88
  msgid "Error: You must provide API signature or certificate."
89
  msgstr ""
90
 
91
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:313
92
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:340
93
  msgid "Error: The API credentials you provided are not valid. Please double-check that you entered them correctly and try again."
94
  msgstr ""
95
 
96
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:317
97
  msgid "An error occurred while trying to validate your API credentials. Unable to verify that your API credentials are correct."
98
  msgstr ""
99
 
100
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:324
101
  msgid "Error: The API certificate is not valid."
102
  msgstr ""
103
 
104
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:331
105
  msgid "Error: The API certificate has expired."
106
  msgstr ""
107
 
108
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:333
109
  msgid "Error: The API username does not match the name in the API certificate. Make sure that you have the correct API certificate."
110
  msgstr ""
111
 
112
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:343
113
  msgid "An error occurred while trying to validate your API credentials. Unable to verify that your API credentials are correct."
114
  msgstr ""
115
 
116
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:362
117
  msgid "The \"require billing address\" option is not enabled by your account and has been disabled."
118
  msgstr ""
119
 
120
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:387
121
  msgid "Refund Error: You need to specify a refund amount."
122
  msgstr ""
123
 
124
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:399
125
  msgid "Refund Error: Sorry! This is not a refundable transaction."
126
  msgstr ""
127
 
128
+ #. Translators: placeholder is a transaction ID.
129
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:412
130
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:437
131
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:489
132
  msgid "PayPal refund completed; transaction ID = %s"
133
  msgstr ""
134
 
135
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:461
136
  msgid "Refund Error: All transactions have been fully refunded. There is no amount left to refund"
137
  msgstr ""
138
 
139
+ #. Translators: placeholder is an amount (with currency symbol).
140
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:464
141
  msgid "Refund Error: The requested refund amount is too large. The refund amount must be less than or equal to %s."
142
  msgstr ""
143
 
144
+ #. Translators: placeholder is an image's URL.
145
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:582
146
  msgid "Already using URL as image: %s"
147
  msgstr ""
148
 
149
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:590
150
  msgid "Select a image to upload"
151
  msgstr ""
152
 
153
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:591
154
  msgid "Use this image"
155
  msgstr ""
156
 
157
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:592
158
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:595
159
  msgid "Add image"
160
  msgstr ""
161
 
162
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:603
163
  msgid "Remove image"
164
  msgstr ""
165
 
166
+ #: includes/abstracts/abstract-wc-gateway-ppec.php:642
167
  msgid "Remove"
168
  msgstr ""
169
 
179
  msgid "Unable to capture charge!"
180
  msgstr ""
181
 
182
+ #. Translators: %s is a transaction ID.
183
+ #: includes/class-wc-gateway-ppec-admin-handler.php:190
184
  msgid "PayPal Checkout charge complete (Charge ID: %s)"
185
  msgstr ""
186
 
187
+ #: includes/class-wc-gateway-ppec-admin-handler.php:232
188
  msgid "Unable to void charge!"
189
  msgstr ""
190
 
191
+ #. Translators: %s is a transaction ID.
192
+ #: includes/class-wc-gateway-ppec-admin-handler.php:235
193
  msgid "PayPal Checkout charge voided (Charge ID: %s)"
194
  msgstr ""
195
 
196
+ #: includes/class-wc-gateway-ppec-admin-handler.php:342
197
  msgid "This represents the fee PayPal collects for the transaction."
198
  msgstr ""
199
 
200
+ #: includes/class-wc-gateway-ppec-admin-handler.php:343
201
  msgid "PayPal Fee:"
202
  msgstr ""
203
 
204
+ #: includes/class-wc-gateway-ppec-admin-handler.php:352
205
  msgid "This represents the net total that will be credited to your PayPal account. This may be in a different currency than is set in your PayPal account."
206
  msgstr ""
207
 
208
+ #: includes/class-wc-gateway-ppec-admin-handler.php:353
209
  msgid "PayPal Payout:"
210
  msgstr ""
211
 
212
+ #. Translators: %1$ <strong> tag, %2$ </strong> closing tag, %3$ WooCommerce version, %4$ <a> tag linking to Plugins screen, %5$ </a> closing tag.
213
+ #: includes/class-wc-gateway-ppec-admin-handler.php:392
214
  msgid "%1$sWarning!%2$s PayPal Checkout will drop support for WooCommerce %3$s in a soon to be released update. To continue using PayPal Checkout please %4$supdate to %1$sWooCommerce 3.0%2$s or greater%5$s."
215
  msgstr ""
216
 
217
+ #: includes/class-wc-gateway-ppec-api-error.php:23
218
  msgid "Unable to communicate with PayPal. Please try your payment again."
219
  msgstr ""
220
 
221
+ #: includes/class-wc-gateway-ppec-api-error.php:24
222
  msgid "PayPal rejected your email address because it is not valid. Please double-check your email address and try again."
223
  msgstr ""
224
 
225
+ #: includes/class-wc-gateway-ppec-api-error.php:27
226
  msgid "Your PayPal checkout session is invalid. Please check out again."
227
  msgstr ""
228
 
229
+ #: includes/class-wc-gateway-ppec-api-error.php:28
230
  msgid "Your PayPal checkout session has expired. Please check out again."
231
  msgstr ""
232
 
233
+ #: includes/class-wc-gateway-ppec-api-error.php:30
234
  msgid "Your PayPal payment has already been completed. Please contact the store owner for more information."
235
  msgstr ""
236
 
237
+ #: includes/class-wc-gateway-ppec-api-error.php:31
238
  msgid "Your PayPal payment could not be processed. Please check out again or contact PayPal for assistance."
239
  msgstr ""
240
 
241
+ #: includes/class-wc-gateway-ppec-api-error.php:32
242
  msgid "Your PayPal payment could not be processed. Please select an alternative method of payment or contact PayPal for assistance."
243
  msgstr ""
244
 
245
+ #: includes/class-wc-gateway-ppec-api-error.php:34
246
  msgid "Your PayPal payment could not be processed. Please return to PayPal and select a new method of payment."
247
  msgstr ""
248
 
249
+ #: includes/class-wc-gateway-ppec-api-error.php:36
250
  msgid "You have not approved this transaction on the PayPal website. Please check out again and be sure to complete all steps of the PayPal checkout process."
251
  msgstr ""
252
 
253
+ #: includes/class-wc-gateway-ppec-api-error.php:37
254
  msgid "Your shipping address may not be in a different country than your country of residence. Please double-check your shipping address and try again."
255
  msgstr ""
256
 
257
+ #: includes/class-wc-gateway-ppec-api-error.php:38
258
  msgid "This store does not accept transactions from buyers in your country. Please contact the store owner for assistance."
259
  msgstr ""
260
 
261
+ #: includes/class-wc-gateway-ppec-api-error.php:39
262
  msgid "The transaction is over the threshold allowed by this store. Please contact the store owner for assistance."
263
  msgstr ""
264
 
265
+ #: includes/class-wc-gateway-ppec-api-error.php:41
266
  msgid "Your transaction was declined. Please contact the store owner for assistance."
267
  msgstr ""
268
 
269
+ #: includes/class-wc-gateway-ppec-api-error.php:42
270
+ #: includes/class-wc-gateway-ppec-api-error.php:47
271
  msgid "The country in your shipping address is not valid. Please double-check your shipping address and try again."
272
  msgstr ""
273
 
274
+ #: includes/class-wc-gateway-ppec-api-error.php:43
275
  msgid "The street address in your shipping address is not valid. Please double-check your shipping address and try again."
276
  msgstr ""
277
 
278
+ #: includes/class-wc-gateway-ppec-api-error.php:44
279
  msgid "The city in your shipping address is not valid. Please double-check your shipping address and try again."
280
  msgstr ""
281
 
282
+ #: includes/class-wc-gateway-ppec-api-error.php:45
283
  msgid "The state in your shipping address is not valid. Please double-check your shipping address and try again."
284
  msgstr ""
285
 
286
+ #: includes/class-wc-gateway-ppec-api-error.php:46
287
  msgid "The ZIP code or postal code in your shipping address is not valid. Please double-check your shipping address and try again."
288
  msgstr ""
289
 
290
+ #: includes/class-wc-gateway-ppec-api-error.php:48
291
  msgid "PayPal rejected your shipping address because the city, state, and/or ZIP code are incorrect. Please double-check that they are all spelled correctly and try again."
292
  msgstr ""
293
 
294
+ #: includes/class-wc-gateway-ppec-api-error.php:50
295
  msgid "Your PayPal payment could not be processed. Please contact PayPal for assistance."
296
  msgstr ""
297
 
298
+ #: includes/class-wc-gateway-ppec-api-error.php:52
299
  msgid "The redemption code(s) you entered on PayPal cannot be used at this time. Please return to PayPal and remove them."
300
  msgstr ""
301
 
302
+ #: includes/class-wc-gateway-ppec-api-error.php:55
303
  msgid "Your funding instrument is invalid. Please check out again and select a new funding source."
304
  msgstr ""
305
 
306
+ #. Translators: placeholder is an error code.
307
+ #: includes/class-wc-gateway-ppec-api-error.php:58
308
  msgid "An error (%s) occurred while processing your PayPal payment. Please contact the store owner for assistance."
309
  msgstr ""
310
 
314
  msgid "Cheatin&#8217; huh?"
315
  msgstr ""
316
 
317
+ #: includes/class-wc-gateway-ppec-cart-handler.php:326
318
+ #: includes/class-wc-gateway-ppec-cart-handler.php:373
319
+ #: includes/class-wc-gateway-ppec-cart-handler.php:408
320
  msgid "Check out with PayPal"
321
  msgstr ""
322
 
323
+ #: includes/class-wc-gateway-ppec-cart-handler.php:362
324
  msgid "OR"
325
  msgstr ""
326
 
327
+ #: includes/class-wc-gateway-ppec-cart-handler.php:378
328
  msgid "Pay with PayPal Credit"
329
  msgstr ""
330
 
331
+ #: includes/class-wc-gateway-ppec-cart-handler.php:520
332
  msgid "An error occurred while processing your PayPal payment. Please contact the store owner for assistance."
333
  msgstr ""
334
 
364
  msgid "Create an account by entering the information below. If you are a returning customer please login at the top of the page."
365
  msgstr ""
366
 
367
+ #: includes/class-wc-gateway-ppec-checkout-handler.php:345
368
  msgid "Shipping details"
369
  msgstr ""
370
 
371
  #: includes/class-wc-gateway-ppec-checkout-handler.php:444
372
+ #: includes/class-wc-gateway-ppec-checkout-handler.php:499
373
+ #: includes/class-wc-gateway-ppec-checkout-handler.php:1130
374
  msgid "Your PayPal checkout session has expired. Please check out again."
375
  msgstr ""
376
 
377
+ #: includes/class-wc-gateway-ppec-checkout-handler.php:494
378
  msgid "Sorry, an error occurred while trying to retrieve your information from PayPal. Please try again."
379
  msgstr ""
380
 
382
  msgid "Cancel"
383
  msgstr ""
384
 
385
+ #: includes/class-wc-gateway-ppec-checkout-handler.php:626
386
  msgid "You have cancelled Checkout with PayPal. Please try to process your order again."
387
  msgstr ""
388
 
389
+ #: includes/class-wc-gateway-ppec-checkout-handler.php:956
390
+ #: includes/class-wc-gateway-ppec-ipn-handler.php:192
391
  msgid "Payment authorized. Change payment status to processing or complete to capture funds."
392
  msgstr ""
393
 
394
+ #. Translators: placeholder is a reason (from PayPal) for the payment to be pending.
395
+ #. Translators: placeholder is the reason for the payment to be in pending status.
396
+ #: includes/class-wc-gateway-ppec-checkout-handler.php:959
397
+ #: includes/class-wc-gateway-ppec-ipn-handler.php:195
398
  msgid "Payment pending (%s)."
399
  msgstr ""
400
 
401
+ #: includes/class-wc-gateway-ppec-checkout-handler.php:1141
402
  msgid "The payment method was updated for this subscription."
403
  msgstr ""
404
 
405
+ #: includes/class-wc-gateway-ppec-checkout-handler.php:1146
406
  msgid "The payment method was updated for all your current subscriptions."
407
  msgstr ""
408
 
409
+ #: includes/class-wc-gateway-ppec-checkout-handler.php:1155
410
  msgid "There was a problem updating your payment method. Please try again later or use a different payment method."
411
  msgstr ""
412
 
413
+ #: includes/class-wc-gateway-ppec-checkout-handler.php:1178
414
  msgid "You have cancelled Checkout with PayPal. The payment method was not updated."
415
  msgstr ""
416
 
422
  msgid "Unable to accept certificate password during cURL configuration"
423
  msgstr ""
424
 
425
+ #. Translators: %s is a filepath.
426
+ #: includes/class-wc-gateway-ppec-client-credential-certificate.php:88
427
+ #: includes/class-wc-gateway-ppec-client-credential-certificate.php:135
428
  msgid "Unable to write certificate file %s during cURL configuration"
429
  msgstr ""
430
 
431
+ #: includes/class-wc-gateway-ppec-client-credential-certificate.php:114
432
  msgid "Failed to retrieve private key during cURL configuration"
433
  msgstr ""
434
 
435
+ #: includes/class-wc-gateway-ppec-client-credential-certificate.php:118
436
  msgid "Failed to export PKCS12 file during cURL configuration"
437
  msgstr ""
438
 
439
+ #: includes/class-wc-gateway-ppec-client.php:167
440
  msgid "Missing credential"
441
  msgstr ""
442
 
443
+ #: includes/class-wc-gateway-ppec-client.php:171
444
  msgid "Invalid credential object"
445
  msgstr ""
446
 
447
+ #: includes/class-wc-gateway-ppec-client.php:175
448
  msgid "Invalid environment"
449
  msgstr ""
450
 
451
+ #. Translators: placeholder is an error message.
452
+ #: includes/class-wc-gateway-ppec-client.php:193
453
  msgid "An error occurred while trying to connect to PayPal: %s"
454
  msgstr ""
455
 
456
+ #: includes/class-wc-gateway-ppec-client.php:199
457
  msgid "Malformed response received from PayPal"
458
  msgstr ""
459
 
460
+ #. Translators: placeholder is blogname.
461
+ #: includes/class-wc-gateway-ppec-client.php:404
462
+ msgctxt "data sent to PayPal"
463
+ msgid "Orders with %s"
464
+ msgstr ""
465
+
466
  #: includes/class-wc-gateway-ppec-ipn-handler.php:29
467
  msgid "Empty POST data."
468
  msgstr ""
475
  msgid "PayPal IPN Request Failure"
476
  msgstr ""
477
 
478
+ #. Translators: placeholder is a currency code.
479
+ #: includes/class-wc-gateway-ppec-ipn-handler.php:143
480
  msgid "Validation error: PayPal currencies do not match (code %s)."
481
  msgstr ""
482
 
483
+ #. Translators: placeholder is an amount.
484
+ #: includes/class-wc-gateway-ppec-ipn-handler.php:159
485
  msgid "Validation error: PayPal amounts do not match (gross %s)."
486
  msgstr ""
487
 
488
+ #: includes/class-wc-gateway-ppec-ipn-handler.php:185
489
  msgid "IPN payment completed"
490
  msgstr ""
491
 
492
+ #. Translators: placeholder is a payment status.
493
+ #: includes/class-wc-gateway-ppec-ipn-handler.php:218
494
+ #: includes/class-wc-gateway-ppec-ipn-handler.php:263
495
+ #: includes/class-wc-gateway-ppec-ipn-handler.php:282
496
  msgid "Payment %s via IPN."
497
  msgstr ""
498
 
499
+ #. Translators: placeholder is an order number (linked to its details screen).
500
+ #: includes/class-wc-gateway-ppec-ipn-handler.php:266
501
  msgid "Payment for order %s refunded"
502
  msgstr ""
503
 
504
+ #. Translators: 1) is an order number, 2) is a PayPal reason code.
505
+ #: includes/class-wc-gateway-ppec-ipn-handler.php:268
506
  msgid "Order #%1$s has been marked as refunded - PayPal reason code: %2$s"
507
  msgstr ""
508
 
509
+ #. Translators: placeholder is an order number (linked to its details screen).
510
+ #: includes/class-wc-gateway-ppec-ipn-handler.php:285
511
  msgid "Payment for order %s reversed"
512
  msgstr ""
513
 
514
+ #. Translators: 1) is an order number, 2) is a PayPal reason code.
515
+ #: includes/class-wc-gateway-ppec-ipn-handler.php:287
516
  msgid "Order #%1$s has been marked on-hold due to a reversal - PayPal reason code: %2$s"
517
  msgstr ""
518
 
519
+ #. Translators: placeholder is an order number.
520
+ #: includes/class-wc-gateway-ppec-ipn-handler.php:301
521
  msgid "Reversal cancelled for order #%s"
522
  msgstr ""
523
 
524
+ #. Translators: 1) is an order number, 2) is the URL of the order's edit screen.
525
+ #: includes/class-wc-gateway-ppec-ipn-handler.php:303
526
  msgid "Order #%1$s has had a reversal cancelled. Please check the status of payment and update the order status accordingly here: %2$s"
527
  msgstr ""
528
 
535
  msgid "Sorry, Easy Setup encountered an error. Please try again."
536
  msgstr ""
537
 
538
+ #: includes/class-wc-gateway-ppec-ips-handler.php:169
539
  msgid "Easy Setup was able to obtain your API credentials, but was unable to verify that they work correctly. Please make sure your PayPal account is set up properly and try Easy Setup again."
540
  msgstr ""
541
 
542
+ #: includes/class-wc-gateway-ppec-ips-handler.php:173
543
  msgid "Easy Setup was able to obtain your API credentials, but an error occurred while trying to verify that they work correctly. Please try Easy Setup again."
544
  msgstr ""
545
 
546
+ #: includes/class-wc-gateway-ppec-ips-handler.php:178
547
  msgid "Success! Your PayPal account has been set up successfully."
548
  msgstr ""
549
 
550
  #: includes/class-wc-gateway-ppec-plugin.php:158
551
+ msgid "bootstrap() in WooCommerce Gateway PayPal Checkout plugin can only be called once"
552
  msgstr ""
553
 
554
  #: includes/class-wc-gateway-ppec-plugin.php:260
567
  msgid "WooCommerce Gateway PayPal Checkout requires OpenSSL >= 1.0.1 to be installed on your server"
568
  msgstr ""
569
 
570
+ #. Translators: placeholder is the URL of the gateway settings page.
571
+ #: includes/class-wc-gateway-ppec-plugin.php:299
572
  msgid "PayPal Checkout is almost ready. To get started, <a href=\"%s\">connect your PayPal account</a>."
573
  msgstr ""
574
 
575
+ #: includes/class-wc-gateway-ppec-plugin.php:429
576
  msgid "Settings"
577
  msgstr ""
578
 
579
+ #: includes/class-wc-gateway-ppec-plugin.php:448
580
  msgid "View Documentation"
581
  msgstr ""
582
 
583
+ #: includes/class-wc-gateway-ppec-plugin.php:448
584
  msgid "Docs"
585
  msgstr ""
586
 
587
+ #: includes/class-wc-gateway-ppec-plugin.php:449
588
  msgid "Open a support request at WooCommerce.com"
589
  msgstr ""
590
 
591
+ #: includes/class-wc-gateway-ppec-plugin.php:449
592
  msgid "Support"
593
  msgstr ""
594
 
595
+ #. Translators: placeholder is the URL of the gateway settings page.
596
+ #: includes/class-wc-gateway-ppec-plugin.php:505
597
  msgid "<p>PayPal Checkout with new <strong>Smart Payment Buttons™</strong> gives your customers the power to pay the way they want without leaving your site.</p><p>The <strong>existing buttons will be removed</strong> in the <strong>next release</strong>. Please upgrade to Smart Payment Buttons on the <a href=\"%s\">PayPal Checkout settings page</a>.</p>"
598
  msgstr ""
599
 
609
  msgid "WooCommerce PPEC Data"
610
  msgstr ""
611
 
612
+ #. Translators: placeholder is the URL of WC's privacy statement (PPEC section).
613
+ #: includes/class-wc-gateway-ppec-privacy.php:54
614
  msgid "By using this extension, you may be storing personal data or sharing data with an external service. <a href=\"%s\" target=\"_blank\">Learn more about how this works, including what you may want to include in your privacy policy.</a>"
615
  msgstr ""
616
 
617
+ #: includes/class-wc-gateway-ppec-privacy.php:77
618
  msgid "Orders"
619
  msgstr ""
620
 
621
+ #: includes/class-wc-gateway-ppec-privacy.php:81
622
+ #: includes/class-wc-gateway-ppec-privacy.php:146
623
  msgid "PPEC Refundable transaction data"
624
  msgstr ""
625
 
626
+ #: includes/class-wc-gateway-ppec-privacy.php:85
627
+ #: includes/class-wc-gateway-ppec-privacy.php:150
628
  msgid "PPEC Billing agreement id"
629
  msgstr ""
630
 
631
+ #: includes/class-wc-gateway-ppec-privacy.php:142
632
  msgid "Subscriptions"
633
  msgstr ""
634
 
635
+ #. Translators: placeholder is an order number.
636
+ #: includes/class-wc-gateway-ppec-privacy.php:234
637
+ msgid "Order ID %d contains an active Subscription"
638
+ msgstr ""
639
+
640
+ #: includes/class-wc-gateway-ppec-privacy.php:249
641
  msgid "PayPal Checkout Subscriptions Data Erased."
642
  msgstr ""
643
 
644
+ #: includes/class-wc-gateway-ppec-privacy.php:272
645
  msgid "PayPal Checkout Order Data Erased."
646
  msgstr ""
647
 
648
+ #: includes/class-wc-gateway-ppec-with-paypal-addons.php:198
649
  msgid "PayPal API error"
650
  msgstr ""
651
 
652
  #. translators: placeholder is pending reason from PayPal API.
653
+ #: includes/class-wc-gateway-ppec-with-paypal-addons.php:208
654
  msgid "PayPal transaction held: %s"
655
  msgstr ""
656
 
657
+ #. Translators: %s is a transaction ID.
658
+ #: includes/class-wc-gateway-ppec-with-paypal-addons.php:220
659
  msgid "PayPal payment approved (ID: %s)"
660
  msgstr ""
661
 
662
+ #: includes/class-wc-gateway-ppec-with-paypal-addons.php:224
663
  msgid "PayPal payment declined"
664
  msgstr ""
665
 
666
  #: includes/class-wc-gateway-ppec-with-paypal-credit.php:15
667
+ #: includes/settings/settings-ppec.php:429
668
  msgid "PayPal Credit"
669
  msgstr ""
670
 
682
  msgid "The buyer's session information could not be found."
683
  msgstr ""
684
 
685
+ #: includes/settings/settings-ppec.php:18
686
  msgid "Setup or link an existing PayPal account"
687
  msgstr ""
688
 
689
+ #. Translators: placeholder is the button "Setup or link an existing PayPal account".
690
+ #: includes/settings/settings-ppec.php:20
691
  msgid "%s or <a href=\"#\" class=\"ppec-toggle-settings\">click here to toggle manual API credential input</a>."
692
  msgstr ""
693
 
694
  #. Translators: Placeholders are opening an closing link HTML tags.
695
+ #: includes/settings/settings-ppec.php:33
696
  msgid "To reset current credentials and use another account %1$sclick here%2$s. %3$sLearn more about your API Credentials%2$s."
697
  msgstr ""
698
 
699
  #. Translators: Placeholders are opening an closing link HTML tags.
700
  #. Translators: Placeholders are opening and closing link HTML tags.
701
+ #: includes/settings/settings-ppec.php:34
702
+ #: includes/settings/settings-ppec.php:57
703
  msgid "Reset current credentials"
704
  msgstr ""
705
 
706
+ #: includes/settings/settings-ppec.php:36
707
+ #: includes/settings/settings-ppec.php:59
708
  msgid "Learn more"
709
  msgstr ""
710
 
711
+ #: includes/settings/settings-ppec.php:41
712
  msgid "Setup or link an existing PayPal Sandbox account"
713
  msgstr ""
714
 
715
+ #. Translators: placeholder is the button "Setup or link an existing PayPal sandbox account".
716
+ #: includes/settings/settings-ppec.php:43
717
  msgid "%s or <a href=\"#\" class=\"ppec-toggle-sandbox-settings\">click here to toggle manual API credential input</a>."
718
  msgstr ""
719
 
720
  #. Translators: Placeholders are opening and closing link HTML tags.
721
+ #: includes/settings/settings-ppec.php:56
722
  msgid "Your account setting is set to sandbox, no real charging takes place. To accept live payments, switch your environment to live and connect your PayPal account. To reset current credentials and use other sandbox account %1$sclick here%2$s. %3$sLearn more about your API Credentials%2$s."
723
  msgstr ""
724
 
725
+ #: includes/settings/settings-ppec.php:63
726
+ #: includes/settings/settings-ppec.php:444
727
  msgid "Enable PayPal Credit to eligible customers"
728
  msgstr ""
729
 
730
+ #: includes/settings/settings-ppec.php:65
731
  msgid "This option is disabled. Currently PayPal Credit only available for U.S. merchants using USD currency."
732
  msgstr ""
733
 
734
+ #: includes/settings/settings-ppec.php:68
735
  msgid "This enables PayPal Credit, which displays a PayPal Credit button next to the primary PayPal Checkout button. PayPal Checkout lets you give customers access to financing through PayPal Credit® - at no additional cost to you. You get paid up front, even though customers have more time to pay. A pre-integrated payment button shows up next to the PayPal Button, and lets customers pay quickly with PayPal Credit®. (Should be unchecked for stores involved in Real Money Gaming.)"
736
  msgstr ""
737
 
738
+ #: includes/settings/settings-ppec.php:75
739
  msgid "Enable/Disable"
740
  msgstr ""
741
 
742
+ #: includes/settings/settings-ppec.php:77
743
  msgid "Enable PayPal Checkout"
744
  msgstr ""
745
 
746
+ #: includes/settings/settings-ppec.php:78
747
  msgid "This enables PayPal Checkout which allows customers to checkout directly via PayPal from your cart page."
748
  msgstr ""
749
 
750
+ #: includes/settings/settings-ppec.php:84
751
  msgid "Title"
752
  msgstr ""
753
 
754
+ #: includes/settings/settings-ppec.php:86
755
  msgid "This controls the title which the user sees during checkout."
756
  msgstr ""
757
 
758
+ #: includes/settings/settings-ppec.php:87
759
+ #: includes/settings/settings-ppec.php:369
760
+ #: includes/settings/settings-ppec.php:415
761
  msgid "PayPal"
762
  msgstr ""
763
 
764
+ #: includes/settings/settings-ppec.php:91
765
  msgid "Description"
766
  msgstr ""
767
 
768
+ #: includes/settings/settings-ppec.php:94
769
  msgid "This controls the description which the user sees during checkout."
770
  msgstr ""
771
 
772
+ #: includes/settings/settings-ppec.php:95
773
  msgid "Pay via PayPal; you can pay with your credit card if you don't have a PayPal account."
774
  msgstr ""
775
 
776
+ #: includes/settings/settings-ppec.php:99
777
  msgid "Account Settings"
778
  msgstr ""
779
 
780
+ #: includes/settings/settings-ppec.php:104
781
  msgid "Environment"
782
  msgstr ""
783
 
784
+ #: includes/settings/settings-ppec.php:107
785
  msgid "This setting specifies whether you will process live transactions, or whether you will process simulated transactions using the PayPal Sandbox."
786
  msgstr ""
787
 
788
+ #: includes/settings/settings-ppec.php:111
789
  msgid "Live"
790
  msgstr ""
791
 
792
+ #: includes/settings/settings-ppec.php:112
793
  msgid "Sandbox"
794
  msgstr ""
795
 
796
+ #: includes/settings/settings-ppec.php:117
797
  msgid "API Credentials"
798
  msgstr ""
799
 
800
+ #: includes/settings/settings-ppec.php:122
801
  msgid "Live API Username"
802
  msgstr ""
803
 
804
+ #: includes/settings/settings-ppec.php:124
805
+ #: includes/settings/settings-ppec.php:131
806
+ #: includes/settings/settings-ppec.php:138
807
+ #: includes/settings/settings-ppec.php:165
808
+ #: includes/settings/settings-ppec.php:172
809
+ #: includes/settings/settings-ppec.php:179
810
  msgid "Get your API credentials from PayPal."
811
  msgstr ""
812
 
813
+ #: includes/settings/settings-ppec.php:129
814
  msgid "Live API Password"
815
  msgstr ""
816
 
817
+ #: includes/settings/settings-ppec.php:136
818
  msgid "Live API Signature"
819
  msgstr ""
820
 
821
+ #: includes/settings/settings-ppec.php:141
822
+ #: includes/settings/settings-ppec.php:182
823
  msgid "Optional if you provide a certificate below"
824
  msgstr ""
825
 
826
+ #: includes/settings/settings-ppec.php:144
827
  msgid "Live API Certificate"
828
  msgstr ""
829
 
830
+ #: includes/settings/settings-ppec.php:150
831
  msgid "Live API Subject"
832
  msgstr ""
833
 
834
+ #: includes/settings/settings-ppec.php:152
835
+ #: includes/settings/settings-ppec.php:193
836
  msgid "If you're processing transactions on behalf of someone else's PayPal account, enter their email address or Secure Merchant Account ID (also known as a Payer ID) here. Generally, you must have API permissions in place with the other account in order to process anything other than \"sale\" transactions for them."
837
  msgstr ""
838
 
839
+ #: includes/settings/settings-ppec.php:155
840
+ #: includes/settings/settings-ppec.php:196
841
+ #: includes/settings/settings-ppec.php:216
842
+ #: includes/settings/settings-ppec.php:224
843
+ #: includes/settings/settings-ppec.php:232
844
  msgid "Optional"
845
  msgstr ""
846
 
847
+ #: includes/settings/settings-ppec.php:158
848
  msgid "Sandbox API Credentials"
849
  msgstr ""
850
 
851
+ #: includes/settings/settings-ppec.php:163
852
  msgid "Sandbox API Username"
853
  msgstr ""
854
 
855
+ #: includes/settings/settings-ppec.php:170
856
  msgid "Sandbox API Password"
857
  msgstr ""
858
 
859
+ #: includes/settings/settings-ppec.php:177
860
  msgid "Sandbox API Signature"
861
  msgstr ""
862
 
863
+ #: includes/settings/settings-ppec.php:185
864
  msgid "Sandbox API Certificate"
865
  msgstr ""
866
 
867
+ #: includes/settings/settings-ppec.php:191
868
  msgid "Sandbox API Subject"
869
  msgstr ""
870
 
871
+ #: includes/settings/settings-ppec.php:199
872
  msgid "PayPal-hosted Checkout Settings"
873
  msgstr ""
874
 
875
+ #: includes/settings/settings-ppec.php:201
876
  msgid "Customize the appearance of PayPal Checkout on the PayPal side."
877
  msgstr ""
878
 
879
+ #: includes/settings/settings-ppec.php:204
880
  msgid "Brand Name"
881
  msgstr ""
882
 
883
+ #: includes/settings/settings-ppec.php:206
884
  msgid "A label that overrides the business name in the PayPal account on the PayPal hosted checkout pages."
885
  msgstr ""
886
 
887
+ #: includes/settings/settings-ppec.php:211
888
  msgid "Logo Image (190×60)"
889
  msgstr ""
890
 
891
+ #: includes/settings/settings-ppec.php:213
892
  msgid "If you want PayPal to co-brand the checkout page with your logo, enter the URL of your logo image here.<br/>The image must be no larger than 190x60, GIF, PNG, or JPG format, and should be served over HTTPS."
893
  msgstr ""
894
 
895
+ #: includes/settings/settings-ppec.php:219
896
  msgid "Header Image (750×90)"
897
  msgstr ""
898
 
899
+ #: includes/settings/settings-ppec.php:221
900
  msgid "If you want PayPal to co-brand the checkout page with your header, enter the URL of your header image here.<br/>The image must be no larger than 750x90, GIF, PNG, or JPG format, and should be served over HTTPS."
901
  msgstr ""
902
 
903
+ #: includes/settings/settings-ppec.php:227
904
  msgid "Page Style"
905
  msgstr ""
906
 
907
+ #: includes/settings/settings-ppec.php:229
908
  msgid "Optionally enter the name of the page style you wish to use. These are defined within your PayPal account."
909
  msgstr ""
910
 
911
+ #: includes/settings/settings-ppec.php:235
912
  msgid "Landing Page"
913
  msgstr ""
914
 
915
+ #: includes/settings/settings-ppec.php:238
916
  msgid "Type of PayPal page to display."
917
  msgstr ""
918
 
919
+ #: includes/settings/settings-ppec.php:242
920
  msgctxt "Type of PayPal page"
921
  msgid "Billing (Non-PayPal account)"
922
  msgstr ""
923
 
924
+ #: includes/settings/settings-ppec.php:243
925
  msgctxt "Type of PayPal page"
926
  msgid "Login (PayPal account login)"
927
  msgstr ""
928
 
929
+ #: includes/settings/settings-ppec.php:248
930
  msgid "Advanced Settings"
931
  msgstr ""
932
 
933
+ #: includes/settings/settings-ppec.php:253
934
  msgid "Debug Log"
935
  msgstr ""
936
 
937
+ #: includes/settings/settings-ppec.php:255
938
  msgid "Enable Logging"
939
  msgstr ""
940
 
941
+ #: includes/settings/settings-ppec.php:258
942
  msgid "Log PayPal events, such as IPN requests."
943
  msgstr ""
944
 
945
+ #: includes/settings/settings-ppec.php:261
946
  msgid "Invoice Prefix"
947
  msgstr ""
948
 
949
+ #: includes/settings/settings-ppec.php:263
950
  msgid "Please enter a prefix for your invoice numbers. If you use your PayPal account for multiple stores ensure this prefix is unique as PayPal will not allow orders with the same invoice number."
951
  msgstr ""
952
 
953
+ #: includes/settings/settings-ppec.php:268
954
  msgid "Billing Addresses"
955
  msgstr ""
956
 
957
+ #: includes/settings/settings-ppec.php:270
958
  msgid "Require Billing Address"
959
  msgstr ""
960
 
961
+ #. Translators: 1) is an <a> tag linking to PayPal's contact info, 2) is the closing </a> tag.
962
+ #: includes/settings/settings-ppec.php:274
963
  msgid "PayPal only returns a shipping address back to the website. To make sure billing address is returned as well, please enable this functionality on your PayPal account by calling %1$sPayPal Technical Support%2$s."
964
  msgstr ""
965
 
966
+ #: includes/settings/settings-ppec.php:280
967
+ #: includes/settings/settings-ppec.php:282
968
  msgid "Require Phone Number"
969
  msgstr ""
970
 
971
+ #: includes/settings/settings-ppec.php:284
972
+ msgid "Require buyer to enter their telephone number during checkout if none is provided by PayPal. Disabling this option doesn't affect direct Debit or Credit Card payments offered by PayPal."
973
  msgstr ""
974
 
975
+ #: includes/settings/settings-ppec.php:287
976
  msgid "Payment Action"
977
  msgstr ""
978
 
979
+ #: includes/settings/settings-ppec.php:290
980
  msgid "Choose whether you wish to capture funds immediately or authorize payment only."
981
  msgstr ""
982
 
983
+ #: includes/settings/settings-ppec.php:294
984
  msgid "Sale"
985
  msgstr ""
986
 
987
+ #: includes/settings/settings-ppec.php:295
988
  msgid "Authorize"
989
  msgstr ""
990
 
991
+ #: includes/settings/settings-ppec.php:299
992
  msgid "Instant Payments"
993
  msgstr ""
994
 
995
+ #: includes/settings/settings-ppec.php:301
996
  msgid "Require Instant Payment"
997
  msgstr ""
998
 
999
+ #: includes/settings/settings-ppec.php:304
1000
  msgid "If you enable this setting, PayPal will be instructed not to allow the buyer to use funding sources that take additional time to complete (for example, eChecks). Instead, the buyer will be required to use an instant funding source, such as an instant transfer, a credit/debit card, or PayPal Credit."
1001
  msgstr ""
1002
 
1003
+ #: includes/settings/settings-ppec.php:307
1004
  msgid "Subtotal Mismatch Behavior"
1005
  msgstr ""
1006
 
1007
+ #: includes/settings/settings-ppec.php:310
1008
  msgid "Internally, WC calculates line item prices and taxes out to four decimal places; however, PayPal can only handle amounts out to two decimal places (or, depending on the currency, no decimal places at all). Occasionally, this can cause discrepancies between the way WooCommerce calculates prices versus the way PayPal calculates them. If a mismatch occurs, this option controls how the order is dealt with so payment can still be taken."
1009
  msgstr ""
1010
 
1011
+ #: includes/settings/settings-ppec.php:314
1012
  msgid "Add another line item"
1013
  msgstr ""
1014
 
1015
+ #: includes/settings/settings-ppec.php:315
1016
  msgid "Do not send line items to PayPal"
1017
  msgstr ""
1018
 
1019
+ #: includes/settings/settings-ppec.php:320
1020
  msgid "Button Settings"
1021
  msgstr ""
1022
 
1023
+ #: includes/settings/settings-ppec.php:322
1024
  msgid "Customize the appearance of PayPal Checkout on your site."
1025
  msgstr ""
1026
 
1027
+ #: includes/settings/settings-ppec.php:325
1028
  msgid "Smart Payment Buttons"
1029
  msgstr ""
1030
 
1031
+ #: includes/settings/settings-ppec.php:328
1032
  msgid "Use Smart Payment Buttons"
1033
  msgstr ""
1034
 
1035
+ #. Translators: %s is the URL of the Smart Payment Buttons integration docs.
1036
+ #: includes/settings/settings-ppec.php:331
1037
  msgid "PayPal Checkout's Smart Payment Buttons provide a variety of button customization options, such as color, language, shape, and multiple button layout. <a href=\"%s\">Learn more about Smart Payment Buttons</a>."
1038
  msgstr ""
1039
 
1040
+ #: includes/settings/settings-ppec.php:336
1041
  msgid "Button Color"
1042
  msgstr ""
1043
 
1044
+ #: includes/settings/settings-ppec.php:341
1045
  msgid "Controls the background color of the primary button. Use \"Gold\" to leverage PayPal's recognition and preference, or change it to match your site design or aesthetic."
1046
  msgstr ""
1047
 
1048
+ #: includes/settings/settings-ppec.php:343
1049
  msgid "Gold (Recommended)"
1050
  msgstr ""
1051
 
1052
+ #: includes/settings/settings-ppec.php:344
1053
  msgid "Blue"
1054
  msgstr ""
1055
 
1056
+ #: includes/settings/settings-ppec.php:345
1057
  msgid "Silver"
1058
  msgstr ""
1059
 
1060
+ #: includes/settings/settings-ppec.php:346
1061
  msgid "Black"
1062
  msgstr ""
1063
 
1064
+ #: includes/settings/settings-ppec.php:350
1065
  msgid "Button Shape"
1066
  msgstr ""
1067
 
1068
+ #: includes/settings/settings-ppec.php:355
1069
  msgid "The pill-shaped button's unique and powerful shape signifies PayPal in people's minds. Use the rectangular button as an alternative when pill-shaped buttons might pose design challenges."
1070
  msgstr ""
1071
 
1072
+ #: includes/settings/settings-ppec.php:357
1073
  msgid "Pill"
1074
  msgstr ""
1075
 
1076
+ #: includes/settings/settings-ppec.php:358
1077
  msgid "Rectangle"
1078
  msgstr ""
1079
 
1080
+ #: includes/settings/settings-ppec.php:362
1081
+ #: includes/settings/settings-ppec.php:408
1082
  msgid "Button Label"
1083
  msgstr ""
1084
 
1085
+ #: includes/settings/settings-ppec.php:367
1086
  msgid "This controls the label on the primary button."
1087
  msgstr ""
1088
 
1089
+ #: includes/settings/settings-ppec.php:371
1090
+ #: includes/settings/settings-ppec.php:417
1091
  msgid "PayPal Buy Now"
1092
  msgstr ""
1093
 
1094
+ #: includes/settings/settings-ppec.php:372
1095
+ #: includes/settings/settings-ppec.php:418
1096
  msgid "Pay with PayPal"
1097
  msgstr ""
1098
 
1099
+ #: includes/settings/settings-ppec.php:382
1100
  msgid "Button Layout"
1101
  msgstr ""
1102
 
1103
+ #: includes/settings/settings-ppec.php:387
1104
  msgid "If additional funding sources are available to the buyer through PayPal, such as Venmo, then multiple buttons are displayed in the space provided. Choose \"vertical\" for a dynamic list of alternative and local payment options, or \"horizontal\" when space is limited."
1105
  msgstr ""
1106
 
1107
+ #: includes/settings/settings-ppec.php:389
1108
  msgid "Vertical"
1109
  msgstr ""
1110
 
1111
+ #: includes/settings/settings-ppec.php:390
1112
  msgid "Horizontal"
1113
  msgstr ""
1114
 
1115
+ #: includes/settings/settings-ppec.php:394
1116
  msgid "Button Size"
1117
  msgstr ""
1118
 
1119
+ #: includes/settings/settings-ppec.php:399
1120
  msgid "PayPal offers different sizes of the \"PayPal Checkout\" buttons, allowing you to select a size that best fits your site's theme. This setting will allow you to choose which size button(s) appear on your cart page. (The \"Responsive\" option adjusts to container size, and is available and recommended for Smart Payment Buttons.)"
1121
  msgstr ""
1122
 
1123
+ #: includes/settings/settings-ppec.php:401
1124
  msgid "Responsive"
1125
  msgstr ""
1126
 
1127
+ #: includes/settings/settings-ppec.php:402
1128
  msgid "Small"
1129
  msgstr ""
1130
 
1131
+ #: includes/settings/settings-ppec.php:403
1132
  msgid "Medium"
1133
  msgstr ""
1134
 
1135
+ #: includes/settings/settings-ppec.php:404
1136
  msgid "Large"
1137
  msgstr ""
1138
 
1139
+ #: includes/settings/settings-ppec.php:413
1140
  msgid "PayPal offers different labels on the \"PayPal Checkout\" buttons, allowing you to select a suitable label.)"
1141
  msgstr ""
1142
 
1143
+ #: includes/settings/settings-ppec.php:427
1144
  msgid "Hides the specified funding methods."
1145
  msgstr ""
1146
 
1147
+ #: includes/settings/settings-ppec.php:430
1148
  msgid "ELV"
1149
  msgstr ""
1150
 
1151
+ #: includes/settings/settings-ppec.php:431
1152
  msgid "Credit or debit cards"
1153
  msgstr ""
1154
 
1155
+ #: includes/settings/settings-ppec.php:432
1156
  msgid "Venmo"
1157
  msgstr ""
1158
 
1159
+ #: includes/settings/settings-ppec.php:433
1160
  msgid "SEPA-Lastschrift"
1161
  msgstr ""
1162
 
1163
+ #: includes/settings/settings-ppec.php:434
1164
  msgid "Bancontact"
1165
  msgstr ""
1166
 
1167
+ #: includes/settings/settings-ppec.php:435
1168
  msgid "eps"
1169
  msgstr ""
1170
 
1171
+ #: includes/settings/settings-ppec.php:436
1172
  msgid "giropay"
1173
  msgstr ""
1174
 
1175
+ #: includes/settings/settings-ppec.php:437
1176
  msgid "iDEAL"
1177
  msgstr ""
1178
 
1179
+ #: includes/settings/settings-ppec.php:438
1180
  msgid "MyBank"
1181
  msgstr ""
1182
 
1183
+ #: includes/settings/settings-ppec.php:439
1184
  msgid "Przelewy24"
1185
  msgstr ""
1186
 
1187
+ #: includes/settings/settings-ppec.php:440
1188
  msgid "Sofort"
1189
  msgstr ""
1190
 
1191
+ #: includes/settings/settings-ppec.php:464
1192
  msgid "Checkout on cart page"
1193
  msgstr ""
1194
 
1195
+ #: includes/settings/settings-ppec.php:467
1196
  msgid "Enable PayPal Checkout on the cart page"
1197
  msgstr ""
1198
 
1199
+ #: includes/settings/settings-ppec.php:468
1200
  msgid "This shows or hides the PayPal Checkout button on the cart page."
1201
  msgstr ""
1202
 
1203
+ #: includes/settings/settings-ppec.php:477
1204
  msgid "Mini-cart Button Settings"
1205
  msgstr ""
1206
 
1207
+ #: includes/settings/settings-ppec.php:483
1208
+ #: includes/settings/settings-ppec.php:516
1209
+ #: includes/settings/settings-ppec.php:550
1210
  msgid "Configure Settings"
1211
  msgstr ""
1212
 
1213
+ #: includes/settings/settings-ppec.php:484
1214
  msgid "Configure settings specific to mini-cart"
1215
  msgstr ""
1216
 
1217
+ #: includes/settings/settings-ppec.php:489
1218
+ #: includes/settings/settings-ppec.php:522
1219
+ #: includes/settings/settings-ppec.php:556
1220
  msgid "Optionally override global button settings above and configure buttons for this context."
1221
  msgstr ""
1222
 
1223
+ #: includes/settings/settings-ppec.php:500
1224
  msgid "Single Product Button Settings"
1225
  msgstr ""
1226
 
1227
+ #: includes/settings/settings-ppec.php:506
1228
+ #: includes/settings/settings-ppec.php:509
1229
  msgid "Checkout on Single Product"
1230
  msgstr ""
1231
 
1232
+ #: includes/settings/settings-ppec.php:512
1233
  msgid "Enable PayPal Checkout on Single Product view."
1234
  msgstr ""
1235
 
1236
+ #: includes/settings/settings-ppec.php:517
1237
  msgid "Configure settings specific to Single Product view"
1238
  msgstr ""
1239
 
1240
+ #: includes/settings/settings-ppec.php:534
1241
  msgid "Regular Checkout Button Settings"
1242
  msgstr ""
1243
 
1244
+ #: includes/settings/settings-ppec.php:540
1245
  msgid "PayPal Mark"
1246
  msgstr ""
1247
 
1248
+ #: includes/settings/settings-ppec.php:543
1249
  msgid "Enable the PayPal Mark on regular checkout"
1250
  msgstr ""
1251
 
1252
+ #: includes/settings/settings-ppec.php:544
1253
  msgid "This enables the PayPal mark, which can be shown on regular WooCommerce checkout to use PayPal Checkout like a regular WooCommerce gateway."
1254
  msgstr ""
1255
 
1256
+ #: includes/settings/settings-ppec.php:551
1257
  msgid "Configure settings specific to regular checkout"
1258
  msgstr ""
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === WooCommerce PayPal Checkout Payment Gateway ===
2
- Contributors: automattic, woothemes, akeda, dwainm, royho, allendav, slash1andy, woosteve, spraveenitpro, mikedmoore, fernashes, shellbeezy, danieldudzic, mikaey, fullysupportedphil, dsmithweb, corsonr, bor0, zandyring, pauldechov, robobot3000
3
  Tags: ecommerce, e-commerce, commerce, woothemes, wordpress ecommerce, store, sales, sell, shop, shopping, cart, checkout, configurable, paypal
4
  Requires at least: 4.4
5
  Tested up to: 5.4
6
  Requires PHP: 5.5
7
- Stable tag: 2.0.2
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
@@ -102,6 +102,14 @@ Please use this to inform us about bugs, or make contributions via PRs.
102
 
103
  == Changelog ==
104
 
 
 
 
 
 
 
 
 
105
  = 2.0.2 - 2020-05-28 =
106
  * Fix - Javascript errors during checkout when the Payment Action is set to Authorize. PR#754
107
  * Fix - Style the Smart Payment Buttons according to the chosen button size setting. PR#753
@@ -274,4 +282,4 @@ Please use this to inform us about bugs, or make contributions via PRs.
274
  * Fix - Compatibility with Subscriptions and Checkout from Single Product page.
275
  * Fix - Make sure session object exists before use to prevent fatal error.
276
 
277
- [See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce-gateway-paypal-express-checkout/master/changelog.txt).
1
  === WooCommerce PayPal Checkout Payment Gateway ===
2
+ Contributors: woocommerce, automattic, woothemes, akeda, dwainm, royho, allendav, slash1andy, woosteve, spraveenitpro, mikedmoore, fernashes, shellbeezy, danieldudzic, mikaey, fullysupportedphil, dsmithweb, corsonr, bor0, zandyring, pauldechov, robobot3000
3
  Tags: ecommerce, e-commerce, commerce, woothemes, wordpress ecommerce, store, sales, sell, shop, shopping, cart, checkout, configurable, paypal
4
  Requires at least: 4.4
5
  Tested up to: 5.4
6
  Requires PHP: 5.5
7
+ Stable tag: 2.0.3
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
102
 
103
  == Changelog ==
104
 
105
+ = 2.0.3 - 2020-07-01 =
106
+ * Fix - Records the proper refunded_amount to _woo_pp_txnData in the database PR#764
107
+ * Fix - Redirect customers back to the original page they left on after closing PayPal modal PR#765
108
+ * Fix - Preserve horizontal layout style setting when using standalone buttons PR#774
109
+ * Fix - Smart payment buttons compatibility with older browsers PR#778
110
+ * Tweak - Update the Require Phone Number field description PR#772
111
+ * Dev - Make the SDK script args filterable PR#763
112
+
113
  = 2.0.2 - 2020-05-28 =
114
  * Fix - Javascript errors during checkout when the Payment Action is set to Authorize. PR#754
115
  * Fix - Style the Smart Payment Buttons according to the chosen button size setting. PR#753
282
  * Fix - Compatibility with Subscriptions and Checkout from Single Product page.
283
  * Fix - Make sure session object exists before use to prevent fatal error.
284
 
285
+ [See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce-gateway-paypal-express-checkout/main/changelog.txt).
woocommerce-gateway-paypal-express-checkout.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: WooCommerce PayPal Checkout Gateway
4
  * Plugin URI: https://woocommerce.com/products/woocommerce-gateway-paypal-express-checkout/
5
  * Description: Accept all major credit and debit cards, plus Venmo and PayPal Credit in the US, presenting options in a customizable stack of payment buttons. Fast, seamless, and flexible.
6
- * Version: 2.0.2
7
  * Author: WooCommerce
8
  * Author URI: https://woocommerce.com
9
  * Copyright: © 2019 WooCommerce / PayPal.
@@ -11,7 +11,7 @@
11
  * License URI: http://www.gnu.org/licenses/gpl-3.0.html
12
  * Text Domain: woocommerce-gateway-paypal-express-checkout
13
  * Domain Path: /languages
14
- * WC tested up to: 4.1
15
  * WC requires at least: 2.6
16
  */
17
  /**
@@ -27,7 +27,7 @@ if ( ! defined( 'ABSPATH' ) ) {
27
  exit; // Exit if accessed directly
28
  }
29
 
30
- define( 'WC_GATEWAY_PPEC_VERSION', '2.0.2' );
31
 
32
  /**
33
  * Return instance of WC_Gateway_PPEC_Plugin.
@@ -38,7 +38,7 @@ function wc_gateway_ppec() {
38
  static $plugin;
39
 
40
  if ( ! isset( $plugin ) ) {
41
- require_once( 'includes/class-wc-gateway-ppec-plugin.php' );
42
 
43
  $plugin = new WC_Gateway_PPEC_Plugin( __FILE__, WC_GATEWAY_PPEC_VERSION );
44
  }
3
  * Plugin Name: WooCommerce PayPal Checkout Gateway
4
  * Plugin URI: https://woocommerce.com/products/woocommerce-gateway-paypal-express-checkout/
5
  * Description: Accept all major credit and debit cards, plus Venmo and PayPal Credit in the US, presenting options in a customizable stack of payment buttons. Fast, seamless, and flexible.
6
+ * Version: 2.0.3
7
  * Author: WooCommerce
8
  * Author URI: https://woocommerce.com
9
  * Copyright: © 2019 WooCommerce / PayPal.
11
  * License URI: http://www.gnu.org/licenses/gpl-3.0.html
12
  * Text Domain: woocommerce-gateway-paypal-express-checkout
13
  * Domain Path: /languages
14
+ * WC tested up to: 4.3
15
  * WC requires at least: 2.6
16
  */
17
  /**
27
  exit; // Exit if accessed directly
28
  }
29
 
30
+ define( 'WC_GATEWAY_PPEC_VERSION', '2.0.3' );
31
 
32
  /**
33
  * Return instance of WC_Gateway_PPEC_Plugin.
38
  static $plugin;
39
 
40
  if ( ! isset( $plugin ) ) {
41
+ require_once 'includes/class-wc-gateway-ppec-plugin.php';
42
 
43
  $plugin = new WC_Gateway_PPEC_Plugin( __FILE__, WC_GATEWAY_PPEC_VERSION );
44
  }