Event Tickets - Version 5.4.0.2

Version Description

Download this release

Release Info

Developer moraleida.me
Plugin Icon 128x128 Event Tickets
Version 5.4.0.2
Comparing to
See all releases

Code changes from version 5.4.0.1 to 5.4.0.2

common/vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit78b01256e32a6fb33d625f6d51c85105::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit22b0b9d3bd6cb9696e315abdde5ea87b::getLoader();
common/vendor/autoload_52.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
- return ComposerAutoloaderInit62cc26a3eb7f6ed4034448d86b0f07f3::getLoader();
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
+ return ComposerAutoloaderInit930bf84dc8bcd3bb2c164a905ad4003a::getLoader();
common/vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit78b01256e32a6fb33d625f6d51c85105
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit78b01256e32a6fb33d625f6d51c85105
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit78b01256e32a6fb33d625f6d51c85105', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit78b01256e32a6fb33d625f6d51c85105', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
- call_user_func(\Composer\Autoload\ComposerStaticInit78b01256e32a6fb33d625f6d51c85105::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit22b0b9d3bd6cb9696e315abdde5ea87b
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit22b0b9d3bd6cb9696e315abdde5ea87b', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit22b0b9d3bd6cb9696e315abdde5ea87b', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
+ call_user_func(\Composer\Autoload\ComposerStaticInit22b0b9d3bd6cb9696e315abdde5ea87b::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
common/vendor/composer/autoload_real_52.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real_52.php generated by xrstf/composer-php52
4
 
5
- class ComposerAutoloaderInit62cc26a3eb7f6ed4034448d86b0f07f3 {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit62cc26a3eb7f6ed4034448d86b0f07f3 {
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit62cc26a3eb7f6ed4034448d86b0f07f3', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit62cc26a3eb7f6ed4034448d86b0f07f3', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);
2
 
3
  // autoload_real_52.php generated by xrstf/composer-php52
4
 
5
+ class ComposerAutoloaderInit930bf84dc8bcd3bb2c164a905ad4003a {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit930bf84dc8bcd3bb2c164a905ad4003a', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit930bf84dc8bcd3bb2c164a905ad4003a', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);
common/vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit78b01256e32a6fb33d625f6d51c85105
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'T' =>
@@ -269,10 +269,10 @@ class ComposerStaticInit78b01256e32a6fb33d625f6d51c85105
269
  public static function getInitializer(ClassLoader $loader)
270
  {
271
  return \Closure::bind(function () use ($loader) {
272
- $loader->prefixLengthsPsr4 = ComposerStaticInit78b01256e32a6fb33d625f6d51c85105::$prefixLengthsPsr4;
273
- $loader->prefixDirsPsr4 = ComposerStaticInit78b01256e32a6fb33d625f6d51c85105::$prefixDirsPsr4;
274
- $loader->prefixesPsr0 = ComposerStaticInit78b01256e32a6fb33d625f6d51c85105::$prefixesPsr0;
275
- $loader->classMap = ComposerStaticInit78b01256e32a6fb33d625f6d51c85105::$classMap;
276
 
277
  }, null, ClassLoader::class);
278
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit22b0b9d3bd6cb9696e315abdde5ea87b
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'T' =>
269
  public static function getInitializer(ClassLoader $loader)
270
  {
271
  return \Closure::bind(function () use ($loader) {
272
+ $loader->prefixLengthsPsr4 = ComposerStaticInit22b0b9d3bd6cb9696e315abdde5ea87b::$prefixLengthsPsr4;
273
+ $loader->prefixDirsPsr4 = ComposerStaticInit22b0b9d3bd6cb9696e315abdde5ea87b::$prefixDirsPsr4;
274
+ $loader->prefixesPsr0 = ComposerStaticInit22b0b9d3bd6cb9696e315abdde5ea87b::$prefixesPsr0;
275
+ $loader->classMap = ComposerStaticInit22b0b9d3bd6cb9696e315abdde5ea87b::$classMap;
276
 
277
  }, null, ClassLoader::class);
278
  }
event-tickets.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Event Tickets
4
  Plugin URI: https://evnt.is/1acb
5
  Description: Event Tickets allows you to sell basic tickets and collect RSVPs from any post, page, or event.
6
- Version: 5.4.0.1
7
  Author: The Events Calendar
8
  Author URI: https://evnt.is/1aor
9
  License: GPLv2 or later
3
  Plugin Name: Event Tickets
4
  Plugin URI: https://evnt.is/1acb
5
  Description: Event Tickets allows you to sell basic tickets and collect RSVPs from any post, page, or event.
6
+ Version: 5.4.0.2
7
  Author: The Events Calendar
8
  Author URI: https://evnt.is/1aor
9
  License: GPLv2 or later
lang/event-tickets.pot CHANGED
@@ -2,17 +2,17 @@
2
  # This file is distributed under the same license as the Event Tickets package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Event Tickets 5.4.0.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/event-tickets\n"
7
- "POT-Creation-Date: 2022-05-23 14:31:33+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2022-05-23 14:31\n"
12
  "Last-Translator: \n"
13
  "Language-Team: \n"
14
 
15
- #. #-#-#-#-# event-tickets.pot (Event Tickets 5.4.0.1) #-#-#-#-#
16
  #. Plugin Name of the plugin/theme
17
  #: event-tickets.php:61 src/Tribe/Admin/Notices.php:92 src/Tribe/Main.php:701
18
  #: src/Tribe/Privacy.php:59 src/admin-views/admin-welcome-message.php:60
@@ -402,25 +402,25 @@ msgstr ""
402
  msgid "E.g.: 01020"
403
  msgstr ""
404
 
405
- #: src/Tickets/Commerce/Gateways/PayPal/Client.php:742
406
  msgid "The PayPal webhook does not exist"
407
  msgstr ""
408
 
409
- #: src/Tickets/Commerce/Gateways/PayPal/Client.php:745
410
  msgid "Unexpected PayPal response when getting webhook"
411
  msgstr ""
412
 
413
- #: src/Tickets/Commerce/Gateways/PayPal/Client.php:792
414
  msgid "Unexpected PayPal response when creating webhook"
415
  msgstr ""
416
 
417
- #: src/Tickets/Commerce/Gateways/PayPal/Client.php:803
418
  msgid ""
419
  "PayPal webhook limit has been reached, you need to go into your developer."
420
  "paypal.com account and remove webhooks from the associated account"
421
  msgstr ""
422
 
423
- #: src/Tickets/Commerce/Gateways/PayPal/Client.php:862
424
  msgid "Unexpected PayPal response when updating webhook"
425
  msgstr ""
426
 
@@ -4490,42 +4490,46 @@ msgstr ""
4490
  msgid "Unexpected response from PayPal when on boarding"
4491
  msgstr ""
4492
 
4493
- #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:311
4494
- #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:349
4495
  msgid "Order ID in PayPal"
4496
  msgstr ""
4497
 
4498
- #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:324
4499
  msgid "Payer ID token from PayPal"
4500
  msgstr ""
4501
 
4502
- #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:362
4503
  #: src/Tickets/Commerce/Gateways/Stripe/REST/Order_Endpoint.php:282
4504
  msgid "To which status the failing should change this order to"
4505
  msgstr ""
4506
 
4507
- #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:375
4508
  #: src/Tickets/Commerce/Gateways/Stripe/REST/Order_Endpoint.php:295
4509
  msgid "Why this particular order has failed."
4510
  msgstr ""
4511
 
4512
- #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:416
4513
  msgid "Creating new PayPal order failed. Please try again."
4514
  msgstr ""
4515
 
4516
- #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:417
4517
  msgid "Your PayPal order was cancelled."
4518
  msgstr ""
4519
 
4520
- #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:418
4521
  msgid "Provided Order id is not valid."
4522
  msgstr ""
4523
 
4524
- #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:419
4525
  msgid "There was a problem while processing your payment, please try again."
4526
  msgstr ""
4527
 
4528
- #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:420
 
 
 
 
4529
  msgid "There was a problem with the Order status change, please try again."
4530
  msgstr ""
4531
 
2
  # This file is distributed under the same license as the Event Tickets package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Event Tickets 5.4.0.2\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/event-tickets\n"
7
+ "POT-Creation-Date: 2022-06-02 15:33:28+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2022-06-02 15:33\n"
12
  "Last-Translator: \n"
13
  "Language-Team: \n"
14
 
15
+ #. #-#-#-#-# event-tickets.pot (Event Tickets 5.4.0.2) #-#-#-#-#
16
  #. Plugin Name of the plugin/theme
17
  #: event-tickets.php:61 src/Tribe/Admin/Notices.php:92 src/Tribe/Main.php:701
18
  #: src/Tribe/Privacy.php:59 src/admin-views/admin-welcome-message.php:60
402
  msgid "E.g.: 01020"
403
  msgstr ""
404
 
405
+ #: src/Tickets/Commerce/Gateways/PayPal/Client.php:775
406
  msgid "The PayPal webhook does not exist"
407
  msgstr ""
408
 
409
+ #: src/Tickets/Commerce/Gateways/PayPal/Client.php:778
410
  msgid "Unexpected PayPal response when getting webhook"
411
  msgstr ""
412
 
413
+ #: src/Tickets/Commerce/Gateways/PayPal/Client.php:825
414
  msgid "Unexpected PayPal response when creating webhook"
415
  msgstr ""
416
 
417
+ #: src/Tickets/Commerce/Gateways/PayPal/Client.php:836
418
  msgid ""
419
  "PayPal webhook limit has been reached, you need to go into your developer."
420
  "paypal.com account and remove webhooks from the associated account"
421
  msgstr ""
422
 
423
+ #: src/Tickets/Commerce/Gateways/PayPal/Client.php:895
424
  msgid "Unexpected PayPal response when updating webhook"
425
  msgstr ""
426
 
4490
  msgid "Unexpected response from PayPal when on boarding"
4491
  msgstr ""
4492
 
4493
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:369
4494
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:407
4495
  msgid "Order ID in PayPal"
4496
  msgstr ""
4497
 
4498
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:382
4499
  msgid "Payer ID token from PayPal"
4500
  msgstr ""
4501
 
4502
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:420
4503
  #: src/Tickets/Commerce/Gateways/Stripe/REST/Order_Endpoint.php:282
4504
  msgid "To which status the failing should change this order to"
4505
  msgstr ""
4506
 
4507
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:433
4508
  #: src/Tickets/Commerce/Gateways/Stripe/REST/Order_Endpoint.php:295
4509
  msgid "Why this particular order has failed."
4510
  msgstr ""
4511
 
4512
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:474
4513
  msgid "Creating new PayPal order failed. Please try again."
4514
  msgstr ""
4515
 
4516
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:475
4517
  msgid "Your PayPal order was cancelled."
4518
  msgstr ""
4519
 
4520
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:476
4521
  msgid "Provided Order id is not valid."
4522
  msgstr ""
4523
 
4524
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:477
4525
  msgid "There was a problem while processing your payment, please try again."
4526
  msgstr ""
4527
 
4528
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:478
4529
+ msgid "Your payment was declined."
4530
+ msgstr ""
4531
+
4532
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:479
4533
  msgid "There was a problem with the Order status change, please try again."
4534
  msgstr ""
4535
 
readme.txt CHANGED
@@ -3,8 +3,8 @@
3
  Contributors: theeventscalendar, brianjessee, camwynsp, aguseo, bordoni, borkweb, GeoffBel, jentheo, leahkoerper, lucatume, neillmcshea, vicskf, zbtirrell, juanfra, moraleida.me
4
  Tags: tickets, registration, event registration, RSVP, ticket sales, attendee management
5
  Requires at least: 5.6
6
- Tested up to: 5.9.3
7
- Stable tag: 5.4.0.1
8
  Requires PHP: 7.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -119,7 +119,7 @@ Event Tickets is translated into multiple languages, including German, Danish, a
119
  3. When the popup appears select the event-tickets.x.x.zip file from your desktop. (The 'x.x' will change depending on the current version number).
120
  4. Follow the on-screen instructions and wait as the upload completes.
121
  5. When it's finished, activate the plugin via the prompt. A message will show confirming activation was successful.
122
- 6. For access to new updates, make sure you have added your valid License Key under Events --> Settings --> Licenses.
123
 
124
  == Screenshots ==
125
 
@@ -188,6 +188,12 @@ Check out our extensive [knowledgebase](https://evnt.is/18wm) for articles on us
188
 
189
  == Changelog ==
190
 
 
 
 
 
 
 
191
  = [5.4.0.1] 2022-05-23 =
192
 
193
  * Fix - Check if function exists for `get_current_screen` to avoid a fatal if not.
3
  Contributors: theeventscalendar, brianjessee, camwynsp, aguseo, bordoni, borkweb, GeoffBel, jentheo, leahkoerper, lucatume, neillmcshea, vicskf, zbtirrell, juanfra, moraleida.me
4
  Tags: tickets, registration, event registration, RSVP, ticket sales, attendee management
5
  Requires at least: 5.6
6
+ Tested up to: 6.0
7
+ Stable tag: 5.4.0.2
8
  Requires PHP: 7.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
119
  3. When the popup appears select the event-tickets.x.x.zip file from your desktop. (The 'x.x' will change depending on the current version number).
120
  4. Follow the on-screen instructions and wait as the upload completes.
121
  5. When it's finished, activate the plugin via the prompt. A message will show confirming activation was successful.
122
+ 6. For access to new updates, make sure you have added your valid License Key under Tickets --> Settings --> Licenses.
123
 
124
  == Screenshots ==
125
 
188
 
189
  == Changelog ==
190
 
191
+ = [5.4.0.2] 2022-06-06 =
192
+
193
+ * Fix - Adds a safety check to avoid issuing tickets for late-declined purchases in PayPal, when the Order status returned is valid. [ET-1533]
194
+ * Tweak - Added filters: `tec_tickets_commerce_cart_order_hash`
195
+ * Language - 1 new strings added, 15 updated, 0 fuzzied, and 0 obsoleted.
196
+
197
  = [5.4.0.1] 2022-05-23 =
198
 
199
  * Fix - Check if function exists for `get_current_screen` to avoid a fatal if not.
src/Tickets/Commerce/Cart.php CHANGED
@@ -193,6 +193,31 @@ class Cart {
193
  return (string) apply_filters( 'tec_tickets_commerce_cart_url', $url );
194
  }
195
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  /**
197
  * Reads the cart hash from the cookies.
198
  *
193
  return (string) apply_filters( 'tec_tickets_commerce_cart_url', $url );
194
  }
195
 
196
+ /**
197
+ * Generates a unique version of the cart hash, used to enforce idempotency in REST API requests.
198
+ *
199
+ * @since 5.4.0.2
200
+ *
201
+ * @param string $salt An optional value to make sure the generated hash is not directly translatable to the cart
202
+ * hash.
203
+ *
204
+ * @return string
205
+ */
206
+ public function generate_cart_order_hash( $salt = '' ): string {
207
+ $cart_hash = $this->get_cart_hash();
208
+
209
+ /**
210
+ * Allows modifications to the cart/order hash for Tickets Commerce.
211
+ *
212
+ * @since 5.4.0.2
213
+ *
214
+ * @param string $cart_order_hash The md5-hashed cart hash.
215
+ * @param string $cart_hash The current cart hash.
216
+ * @param string $salt The salt value.
217
+ */
218
+ return (string) apply_filters( 'tec_tickets_commerce_cart_order_hash', md5( $cart_hash . $salt ), $cart_hash, $salt );
219
+ }
220
+
221
  /**
222
  * Reads the cart hash from the cookies.
223
  *
src/Tickets/Commerce/Gateways/PayPal/Client.php CHANGED
@@ -2,6 +2,7 @@
2
 
3
  namespace TEC\Tickets\Commerce\Gateways\PayPal;
4
 
 
5
  use TEC\Tickets\Commerce\Gateways\PayPal\REST\Webhook_Endpoint;
6
  use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Events;
7
  use Tribe__Utils__Array as Arr;
@@ -517,6 +518,7 @@ class Client {
517
  $args = [
518
  'headers' => [
519
  'PayPal-Partner-Attribution-Id' => Gateway::ATTRIBUTION_ID,
 
520
  'Prefer' => 'return=representation',
521
  ],
522
  'body' => $body,
@@ -527,6 +529,36 @@ class Client {
527
  return $response;
528
  }
529
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
530
  /**
531
  * Captures an order for a given ID in PayPal.
532
  *
@@ -556,6 +588,7 @@ class Client {
556
  $args = [
557
  'headers' => [
558
  'PayPal-Partner-Attribution-Id' => Gateway::ATTRIBUTION_ID,
 
559
  'Prefer' => 'return=representation',
560
  ],
561
  'body' => $body,
2
 
3
  namespace TEC\Tickets\Commerce\Gateways\PayPal;
4
 
5
+ use TEC\Tickets\Commerce\Cart;
6
  use TEC\Tickets\Commerce\Gateways\PayPal\REST\Webhook_Endpoint;
7
  use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks\Events;
8
  use Tribe__Utils__Array as Arr;
518
  $args = [
519
  'headers' => [
520
  'PayPal-Partner-Attribution-Id' => Gateway::ATTRIBUTION_ID,
521
+ 'PayPal-Request-Id' => tribe( Cart::class )->generate_cart_order_hash(),
522
  'Prefer' => 'return=representation',
523
  ],
524
  'body' => $body,
529
  return $response;
530
  }
531
 
532
+ /**
533
+ * Retrieves an order object for a given ID in PayPal.
534
+ *
535
+ * @since 5.4.0.2
536
+ *
537
+ * @param string $order_id Order ID to retrieve.
538
+ *
539
+ * @return array|null
540
+ */
541
+ public function get_order( $order_id ) {
542
+ $query_args = [];
543
+ $body = [];
544
+
545
+ $args = [
546
+ 'headers' => [
547
+ 'PayPal-Partner-Attribution-Id' => Gateway::ATTRIBUTION_ID,
548
+ 'PayPal-Request-Id' => tribe( Cart::class )->generate_cart_order_hash(),
549
+ 'Prefer' => 'return=representation',
550
+ ],
551
+ 'body' => $body,
552
+ ];
553
+
554
+ $order_id = urlencode( $order_id );
555
+ $url = '/v2/checkout/orders/{order_id}';
556
+ $url = str_replace( '{order_id}', $order_id, $url );
557
+ $response = $this->get( $url, $query_args, $args );
558
+
559
+ return $response;
560
+ }
561
+
562
  /**
563
  * Captures an order for a given ID in PayPal.
564
  *
588
  $args = [
589
  'headers' => [
590
  'PayPal-Partner-Attribution-Id' => Gateway::ATTRIBUTION_ID,
591
+ 'PayPal-Request-Id' => tribe( Cart::class )->generate_cart_order_hash(),
592
  'Prefer' => 'return=representation',
593
  ],
594
  'body' => $body,
src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php CHANGED
@@ -182,6 +182,12 @@ class Order_Endpoint extends Abstract_REST_Endpoint {
182
  return new WP_Error( 'tec-tc-gateway-paypal-nonexistent-order-id', $messages['nonexistent-order-id'], $order );
183
  }
184
 
 
 
 
 
 
 
185
  $payer_id = $request->get_param( 'payer_id' );
186
 
187
  $paypal_capture_response = tribe( Client::class )->capture_order( $paypal_order_id, $payer_id );
@@ -202,21 +208,73 @@ class Order_Endpoint extends Abstract_REST_Endpoint {
202
  return new WP_Error( 'tec-tc-gateway-paypal-failed-capture', $messages['failed-capture'], $paypal_capture_response );
203
  }
204
 
205
- $paypal_capture_status = Arr::get( $paypal_capture_response, [ 'status' ] );
206
- $status = tribe( Status::class )->convert_to_commerce_status( $paypal_capture_status );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
 
208
  if ( ! $status ) {
209
- return new WP_Error( 'tec-tc-gateway-paypal-invalid-capture-status', $messages['invalid-capture-status'], $paypal_capture_response );
210
  }
211
 
212
  $updated = tribe( Order::class )->modify_status( $order->ID, $status->get_slug(), [
213
- 'gateway_payload' => $paypal_capture_response,
214
  ] );
215
 
216
  if ( is_wp_error( $updated ) ) {
217
  return $updated;
218
  }
219
 
 
 
 
 
220
  $response['success'] = true;
221
  $response['status'] = $status->get_slug();
222
  $response['order_id'] = $order->ID;
@@ -224,7 +282,7 @@ class Order_Endpoint extends Abstract_REST_Endpoint {
224
  // When we have success we clear the cart.
225
  tribe( Cart::class )->clear_cart();
226
 
227
- $response['redirect_url'] = add_query_arg( [ 'tc-order-id' => $paypal_order_id ], tribe( Success::class )->get_url() );
228
 
229
  return new WP_REST_Response( $response );
230
  }
@@ -417,6 +475,7 @@ class Order_Endpoint extends Abstract_REST_Endpoint {
417
  'canceled-creating-order' => __( 'Your PayPal order was cancelled.', 'event-tickets' ),
418
  'nonexistent-order-id' => __( 'Provided Order id is not valid.', 'event-tickets' ),
419
  'failed-capture' => __( 'There was a problem while processing your payment, please try again.', 'event-tickets' ),
 
420
  'invalid-capture-status' => __( 'There was a problem with the Order status change, please try again.', 'event-tickets' ),
421
  ];
422
 
182
  return new WP_Error( 'tec-tc-gateway-paypal-nonexistent-order-id', $messages['nonexistent-order-id'], $order );
183
  }
184
 
185
+ $recheck = $request->get_param( 'recheck' );
186
+
187
+ if ( $recheck ) {
188
+ return $this->handle_recheck_order( $paypal_order_id, $order );
189
+ }
190
+
191
  $payer_id = $request->get_param( 'payer_id' );
192
 
193
  $paypal_capture_response = tribe( Client::class )->capture_order( $paypal_order_id, $payer_id );
208
  return new WP_Error( 'tec-tc-gateway-paypal-failed-capture', $messages['failed-capture'], $paypal_capture_response );
209
  }
210
 
211
+ $response['success'] = true;
212
+ $response['order_id'] = $paypal_order_id;
213
+
214
+ return new WP_REST_Response( $response );
215
+ }
216
+
217
+ /**
218
+ * Gets the Order object again, in another request, to check for purchases possibly denied after creation.
219
+ *
220
+ * @since 5.4.0.2
221
+ *
222
+ * @param string $order_id The PayPal order ID.
223
+ * @param \WP_Post $order The TC Order object.
224
+ *
225
+ * @return bool|WP_Error|WP_REST_Response
226
+ */
227
+ public function handle_recheck_order( $order_id, $order ) {
228
+
229
+ $paypal_order_response = tribe( Client::class )->get_order( $order_id );
230
+ $paypal_order_status = Arr::get( $paypal_order_response, [ 'status' ] );
231
+ $paypal_order_purchase_units = Arr::get( $paypal_order_response, [ 'purchase_units' ], [] );
232
+ $paypal_order_captures = [];
233
+ $messages = $this->get_error_messages();
234
+
235
+ foreach( $paypal_order_purchase_units as $unit ) {
236
+ if ( ! empty( $unit['payments']['captures'] ) ) {
237
+ $paypal_order_captures[] = $unit['payments']['captures'];
238
+ }
239
+ }
240
+
241
+ if ( Status::CREATED === $paypal_order_status && ! empty( $paypal_order_captures ) ) {
242
+ $paypal_order_captures = array_shift( $paypal_order_captures );
243
+ if ( count( $paypal_order_captures ) > 1 ) {
244
+ // Sort the captures array by the update timestamp
245
+ usort( $paypal_order_captures, function( $a, $b ) {
246
+ return strtotime( $a['update_time'] ) <=> strtotime( $b['update_time'] );
247
+ } );
248
+ }
249
+
250
+ foreach( $paypal_order_captures as $capture ) {
251
+ $paypal_order_status = $capture['status'];
252
+ $final = $capture['final_capture'] ?? false;
253
+
254
+ if ( $final ) {
255
+ break;
256
+ }
257
+ }
258
+ }
259
+
260
+ $status = tribe( Status::class )->convert_to_commerce_status( $paypal_order_status );
261
 
262
  if ( ! $status ) {
263
+ return new WP_Error( 'tec-tc-gateway-paypal-invalid-capture-status', $messages['invalid-capture-status'], $paypal_order_response );
264
  }
265
 
266
  $updated = tribe( Order::class )->modify_status( $order->ID, $status->get_slug(), [
267
+ 'gateway_payload' => $paypal_order_response,
268
  ] );
269
 
270
  if ( is_wp_error( $updated ) ) {
271
  return $updated;
272
  }
273
 
274
+ if ( in_array( $paypal_order_status, [ Status::FAILED, Status::DECLINED ], true ) ) {
275
+ return new WP_Error( 'tec-tc-gateway-paypal-capture-declined', $messages['capture-declined'], $paypal_order_response );
276
+ }
277
+
278
  $response['success'] = true;
279
  $response['status'] = $status->get_slug();
280
  $response['order_id'] = $order->ID;
282
  // When we have success we clear the cart.
283
  tribe( Cart::class )->clear_cart();
284
 
285
+ $response['redirect_url'] = add_query_arg( [ 'tc-order-id' => $order_id ], tribe( Success::class )->get_url() );
286
 
287
  return new WP_REST_Response( $response );
288
  }
475
  'canceled-creating-order' => __( 'Your PayPal order was cancelled.', 'event-tickets' ),
476
  'nonexistent-order-id' => __( 'Provided Order id is not valid.', 'event-tickets' ),
477
  'failed-capture' => __( 'There was a problem while processing your payment, please try again.', 'event-tickets' ),
478
+ 'capture-declined' => __( 'Your payment was declined.', 'event-tickets' ),
479
  'invalid-capture-status' => __( 'There was a problem with the Order status change, please try again.', 'event-tickets' ),
480
  ];
481
 
src/Tickets/Commerce/Gateways/PayPal/Status.php CHANGED
@@ -67,6 +67,24 @@ class Status {
67
  */
68
  CONST PAYER_ACTION_REQUIRED = 'PAYER_ACTION_REQUIRED';
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  /**
71
  * Default mapping from PayPal Status to Tickets Commerce
72
  *
@@ -81,6 +99,8 @@ class Status {
81
  self::VOIDED => Commerce_Status\Voided::SLUG,
82
  self::COMPLETED => Commerce_Status\Completed::SLUG,
83
  self::PAYER_ACTION_REQUIRED => Commerce_Status\Action_Required::SLUG,
 
 
84
  ];
85
 
86
  /**
67
  */
68
  CONST PAYER_ACTION_REQUIRED = 'PAYER_ACTION_REQUIRED';
69
 
70
+ /**
71
+ * Order Capture Status in PayPal for failed captures.
72
+ *
73
+ * @since 5.4.0.2
74
+ *
75
+ * @var string
76
+ */
77
+ CONST FAILED = 'FAILED';
78
+
79
+ /**
80
+ * Order Capture Status in PayPal for declined captures.
81
+ *
82
+ * @since 5.4.0.2
83
+ *
84
+ * @var string
85
+ */
86
+ CONST DECLINED = 'DECLINED';
87
+
88
  /**
89
  * Default mapping from PayPal Status to Tickets Commerce
90
  *
99
  self::VOIDED => Commerce_Status\Voided::SLUG,
100
  self::COMPLETED => Commerce_Status\Completed::SLUG,
101
  self::PAYER_ACTION_REQUIRED => Commerce_Status\Action_Required::SLUG,
102
+ self::FAILED => Commerce_Status\Denied::SLUG,
103
+ self::DECLINED => Commerce_Status\Denied::SLUG,
104
  ];
105
 
106
  /**
src/Tribe/Main.php CHANGED
@@ -8,7 +8,7 @@ class Tribe__Tickets__Main {
8
  /**
9
  * Current version of this plugin
10
  */
11
- const VERSION = '5.4.0.1';
12
 
13
  /**
14
  * Used to store the version history.
8
  /**
9
  * Current version of this plugin
10
  */
11
+ const VERSION = '5.4.0.2';
12
 
13
  /**
14
  * Used to store the version history.
src/resources/js/commerce/gateway/paypal/checkout.js CHANGED
@@ -241,6 +241,46 @@ tribe.tickets.commerce.gateway.paypal.checkout = {};
241
  tribe.tickets.debug.log( 'handleCreateOrderError', arguments );
242
  };
243
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  /**
245
  * Handles the Approval of the orders via PayPal.
246
  *
@@ -277,7 +317,7 @@ tribe.tickets.commerce.gateway.paypal.checkout = {};
277
  .then( response => response.json() )
278
  .then( data => {
279
  if ( data.success ) {
280
- return obj.handleApproveSuccess( data, actions, $container );
281
  } else {
282
  return obj.handleApproveFail( data, actions, $container );
283
  }
@@ -321,6 +361,8 @@ tribe.tickets.commerce.gateway.paypal.checkout = {};
321
  } else {
322
  obj.showNotice( $container, '', data.message );
323
  }
 
 
324
  }
325
 
326
  tribe.tickets.loader.hide( $container );
@@ -780,7 +822,7 @@ tribe.tickets.commerce.gateway.paypal.checkout = {};
780
  .then( data => {
781
  tribe.tickets.debug.log( data );
782
  if ( data.success ) {
783
- return obj.handleHostedApproveSuccess( data, actions, $container );
784
  } else {
785
  return obj.handleHostedApproveFail( data, actions, $container );
786
  }
241
  tribe.tickets.debug.log( 'handleCreateOrderError', arguments );
242
  };
243
 
244
+ /**
245
+ * Handles checking if a purchase was really successful or was late-declined.
246
+ *
247
+ * @since 5.4.0.2
248
+ *
249
+ * @param {Object} data PayPal data passed to this method.
250
+ * @param {Object} actions PayPal actions available on approve.
251
+ * @param {jQuery} $container jQuery object of the tickets container.
252
+ *
253
+ * @return {void}
254
+ */
255
+ obj.handleCheckSuccess = function ( data, actions, $container ) {
256
+ tribe.tickets.debug.log( 'handleCheckSuccess', arguments );
257
+
258
+ const body = {
259
+ 'recheck': true
260
+ };
261
+
262
+ return fetch(
263
+ obj.orderEndpointUrl + '/' + data.order_id,
264
+ {
265
+ method: 'POST',
266
+ headers: {
267
+ 'X-WP-Nonce': $container.find( tribe.tickets.commerce.selectors.nonce ).val(),
268
+ 'Content-Type': 'application/json',
269
+ },
270
+ body: JSON.stringify( body ),
271
+ }
272
+ )
273
+ .then( response => response.json() )
274
+ .then( data => {
275
+ if ( data.success ) {
276
+ return obj.handleApproveSuccess( data, actions, $container );
277
+ } else {
278
+ return obj.handleApproveFail( data, actions, $container );
279
+ }
280
+ } )
281
+ .catch( obj.handleApproveError );
282
+ };
283
+
284
  /**
285
  * Handles the Approval of the orders via PayPal.
286
  *
317
  .then( response => response.json() )
318
  .then( data => {
319
  if ( data.success ) {
320
+ return obj.handleCheckSuccess( data, actions, $container );
321
  } else {
322
  return obj.handleApproveFail( data, actions, $container );
323
  }
361
  } else {
362
  obj.showNotice( $container, '', data.message );
363
  }
364
+ } else {
365
+ obj.showNotice( $container, '', data.message );
366
  }
367
 
368
  tribe.tickets.loader.hide( $container );
822
  .then( data => {
823
  tribe.tickets.debug.log( data );
824
  if ( data.success ) {
825
+ return obj.handleCheckSuccess( data, actions, $container );
826
  } else {
827
  return obj.handleHostedApproveFail( data, actions, $container );
828
  }
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit655b524cc9aabb8f5d78d26911fcaedd::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit977385d9bfad842f5454b04705bbf797::getLoader();
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit655b524cc9aabb8f5d78d26911fcaedd
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit655b524cc9aabb8f5d78d26911fcaedd
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit655b524cc9aabb8f5d78d26911fcaedd', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit655b524cc9aabb8f5d78d26911fcaedd', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
- call_user_func(\Composer\Autoload\ComposerStaticInit655b524cc9aabb8f5d78d26911fcaedd::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit977385d9bfad842f5454b04705bbf797
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit977385d9bfad842f5454b04705bbf797', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit977385d9bfad842f5454b04705bbf797', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
+ call_user_func(\Composer\Autoload\ComposerStaticInit977385d9bfad842f5454b04705bbf797::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit655b524cc9aabb8f5d78d26911fcaedd
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'T' =>
@@ -206,9 +206,9 @@ class ComposerStaticInit655b524cc9aabb8f5d78d26911fcaedd
206
  public static function getInitializer(ClassLoader $loader)
207
  {
208
  return \Closure::bind(function () use ($loader) {
209
- $loader->prefixLengthsPsr4 = ComposerStaticInit655b524cc9aabb8f5d78d26911fcaedd::$prefixLengthsPsr4;
210
- $loader->prefixDirsPsr4 = ComposerStaticInit655b524cc9aabb8f5d78d26911fcaedd::$prefixDirsPsr4;
211
- $loader->classMap = ComposerStaticInit655b524cc9aabb8f5d78d26911fcaedd::$classMap;
212
 
213
  }, null, ClassLoader::class);
214
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit977385d9bfad842f5454b04705bbf797
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'T' =>
206
  public static function getInitializer(ClassLoader $loader)
207
  {
208
  return \Closure::bind(function () use ($loader) {
209
+ $loader->prefixLengthsPsr4 = ComposerStaticInit977385d9bfad842f5454b04705bbf797::$prefixLengthsPsr4;
210
+ $loader->prefixDirsPsr4 = ComposerStaticInit977385d9bfad842f5454b04705bbf797::$prefixDirsPsr4;
211
+ $loader->classMap = ComposerStaticInit977385d9bfad842f5454b04705bbf797::$classMap;
212
 
213
  }, null, ClassLoader::class);
214
  }