Skip to content

Feat/sync with square #3759

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 53 commits into from
Apr 29, 2025
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
cee2dd7
Add caching layer around requests
dpanta94 Apr 16, 2025
194e899
switch to constants
dpanta94 Apr 16, 2025
e3821ee
[wip] syncing of tickets
dpanta94 Apr 17, 2025
e39bcb3
Sync tickets and events with Square
dpanta94 Apr 21, 2025
220b916
version bump
dpanta94 Apr 21, 2025
63c8240
Ticket data moved in ET
dpanta94 Apr 21, 2025
a884dd7
Going into stock syncing discovery
dpanta94 Apr 21, 2025
8a7a33d
Progress with Syncing
dpanta94 Apr 22, 2025
4f22b0e
Lots of progress but need to re-organize my code
dpanta94 Apr 22, 2025
62fce59
Initial sync fully functional!
dpanta94 Apr 22, 2025
b704001
Docs and better code organization
dpanta94 Apr 22, 2025
911872b
clean up of not needed location option
dpanta94 Apr 22, 2025
462b8e9
More docs
dpanta94 Apr 22, 2025
591bbae
Avoid code duplication
dpanta94 Apr 22, 2025
4c29ad0
Docs updates
dpanta94 Apr 22, 2025
7c1ce32
minor fixes - cleanup
dpanta94 Apr 22, 2025
72cd3e9
phpcs issues
dpanta94 Apr 22, 2025
0a17e04
more phpcs! -_-
dpanta94 Apr 22, 2025
0055f94
Ensures we validate release-engineer tasks during final zip generation
dpanta94 Apr 23, 2025
f0281bd
Introduce get_provider_currency_code method
dpanta94 Apr 23, 2025
18bd100
Update into using dynamic currency code during sync
dpanta94 Apr 23, 2025
61ca31d
remove commented out code
dpanta94 Apr 24, 2025
9d1552a
Syncing completed except for series !
dpanta94 Apr 24, 2025
22d30e9
save post listener
dpanta94 Apr 24, 2025
727a9d5
Adding TEC and ECP integrations
dpanta94 Apr 24, 2025
acd9acb
Fixing some phpcs
dpanta94 Apr 24, 2025
a62cc77
phpcs
dpanta94 Apr 24, 2025
d9132ab
Fix some issues
dpanta94 Apr 25, 2025
b9c667d
:fast_forward: https://github.com/the-events-calendar/tribe-common/co…
tec-bot Apr 25, 2025
c858bdf
:fast_forward: https://github.com/the-events-calendar/tribe-common/co…
tec-bot Apr 25, 2025
ec6b7ac
Listen for ticket-able post type or sync status changes
dpanta94 Apr 25, 2025
49bc149
Ensure we are only syncing TC tickets
dpanta94 Apr 25, 2025
41cf9a4
fix remote ticket object id deletion during event deletion
dpanta94 Apr 25, 2025
3244ada
remove forgotten part of code
dpanta94 Apr 25, 2025
106eea9
After lots of trial and error...syncing process is perfect!
dpanta94 Apr 25, 2025
c99f2f5
Keep local snapshot of the last synced payload to avoid not required …
dpanta94 Apr 25, 2025
8251fbb
:fast_forward: https://github.com/the-events-calendar/tribe-common/co…
tec-bot Apr 25, 2025
fda7c02
Merge remote-tracking branch 'origin/bucket/square-payments' into fea…
dpanta94 Apr 25, 2025
ddb78f0
Fix fatal with wrong usage of static keyword
dpanta94 Apr 28, 2025
72e7696
fix phpcs
dpanta94 Apr 28, 2025
1d9412d
Introduced a rate limited retry system
dpanta94 Apr 28, 2025
6b65e4c
Fix copy pasted doc block
dpanta94 Apr 28, 2025
aea6af8
Merge remote-tracking branch 'origin/bucket/square-payments' into fea…
dpanta94 Apr 28, 2025
307639c
:fast_forward: https://github.com/the-events-calendar/tribe-common/co…
tec-bot Apr 28, 2025
1b7e196
:fast_forward: https://github.com/the-events-calendar/tribe-common/co…
tec-bot Apr 28, 2025
c09f9f1
:fast_forward: https://github.com/the-events-calendar/tribe-common/co…
tec-bot Apr 28, 2025
9baf457
Update common hash
dpanta94 Apr 28, 2025
26448f6
fix phpcs
dpanta94 Apr 28, 2025
6a091a7
Merge remote-tracking branch 'origin/bucket/square-payments' into fea…
dpanta94 Apr 29, 2025
58d2156
Fix infinite loops :argh:
dpanta94 Apr 29, 2025
ee8113e
Restore instances to regulator -_-
dpanta94 Apr 29, 2025
8c268b3
Fix various issues after manual testing
dpanta94 Apr 29, 2025
3e1fb3d
Schedule sync for only ticket-able ptypes with tickets
dpanta94 Apr 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/zip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,21 @@ jobs:
if: ${{ env.PRODUCTION_ZIP == 'true' }}
run: composer -- pup i18n

# ------------------------------------------------------------------------------
# Check `@release-engineer` tasks
# ------------------------------------------------------------------------------
- name: Check `@release-engineer` tasks
if: ${{ env.PRODUCTION_ZIP == 'true' }}
run: |
OUTPUT=$(find ./src/ -type f -exec grep -l "@release-engineer" {} \;)
if [ -n "$OUTPUT" ]; then
echo "Found @release-engineer tasks:"
echo "$OUTPUT"
exit 1
else
echo "No @release-engineer tasks found."
fi
# ------------------------------------------------------------------------------
# Run Pup Package - creates the zip file for new OR production builds
# ------------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion common
2 changes: 1 addition & 1 deletion event-tickets.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Plugin Name: Event Tickets
* Plugin URI: https://evnt.is/1acb
* Description: Event Tickets allows you to sell basic tickets and collect RSVPs from any post, page, or event.
* Version: 5.21.1
* Version: 5.24.0
* Requires at least: 6.5
* Requires PHP: 7.4
* Author: The Events Calendar
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "event-tickets",
"version": "5.21.1",
"version": "5.24.0",
"repository": "[email protected]:the-events-calendar/event-tickets.git",
"_zipname": "event-tickets",
"_zipfoldername": "event-tickets",
Expand Down
2 changes: 1 addition & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Contributors: theeventscalendar, brianjessee, camwynsp, redscar, tribalmike, rafsuntaskin, aguseo, bordoni, borkweb, jentheo, leahkoerper, lucatume, neillmcshea, vicskf, zbtirrell
Tags: tickets, event registration, RSVP, ticket sales, attendee management
Stable tag: 5.21.1
Stable tag: 5.24.0
Requires at least: 6.5
Tested up to: 6.7.2
Requires PHP: 7.4
Expand Down
20 changes: 17 additions & 3 deletions src/Tickets/Commerce/Gateways/Contracts/Abstract_Requests.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@
*/
abstract class Abstract_Requests implements Requests_Interface {

/**
* Get the headers.
*
* @since TBD
*
* @return array The headers.
*/
public static function get_headers(): array {
return [];
}

/**
* @inheritDoc
*/
Expand Down Expand Up @@ -53,9 +64,12 @@ public static function request( $method, $url, array $query_args = [], array $re
: add_query_arg( $query_args, $url );

$default_arguments = [
'headers' => [
'Authorization' => 'Bearer ' . tribe( static::$merchant )->get_client_secret(),
],
'headers' => array_merge(
[
'Authorization' => 'Bearer ' . tribe( static::$merchant )->get_client_secret(),
],
static::get_headers()
),
];

// By default, it's important that we have a body set for any method that is not the GET method.
Expand Down
2 changes: 1 addition & 1 deletion src/Tickets/Commerce/Gateways/Square/Assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ public function unregister(): void {
'tec-tickets-commerce-gateway-square-checkout',
'tec-tickets-commerce-square-style',
'tec-tickets-commerce-gateway-square-admin-webhooks',
'tec-tickets-commerce-gateway-square-admin-webhooks-styles',
'tec-tickets-commerce-admin-styles',
] as $asset ) {
$stellar_assets->remove( $asset );
}
Expand Down
15 changes: 14 additions & 1 deletion src/Tickets/Commerce/Gateways/Square/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use TEC\Common\Contracts\Provider\Controller as Controller_Contract;
use TEC\Tickets\Commerce\Gateways\Square\REST\On_Boarding_Endpoint;
use TEC\Tickets\Commerce\Gateways\Square\REST\Order_Endpoint;
use TEC\Tickets\Commerce\Gateways\Square\Syncs\Controller as Syncs_Controller;
use TEC\Tickets\Commerce\Gateways\Square\Webhooks;

/**
Expand Down Expand Up @@ -43,6 +44,12 @@ public function do_register(): void {
$this->container->register( Hooks::class );
$this->container->register( Notices\Controller::class );
$this->container->register( Webhooks::class );

if ( ! $this->container->get( Gateway::class )->is_enabled() ) {
return;
}

$this->container->register( Syncs_Controller::class );
}

/**
Expand All @@ -57,7 +64,13 @@ public function unregister(): void {
$this->container->get( Assets::class )->unregister();
$this->container->get( Ajax::class )->unregister();
$this->container->get( Hooks::class )->unregister();
$this->container->get( Webhooks::class )->unregister();
$this->container->get( Notices\Controller::class )->unregister();
$this->container->get( Webhooks::class )->unregister();

if ( ! $this->container->get( Gateway::class )->is_enabled() ) {
return;
}

$this->container->get( Syncs_Controller::class )->unregister();
}
}
4 changes: 2 additions & 2 deletions src/Tickets/Commerce/Gateways/Square/Gateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -355,9 +355,9 @@ public static function is_test_mode(): bool {
*/
public function get_location_id(): string {
if ( static::is_test_mode() ) {
return (string) tribe_get_option( Settings::$option_sandbox_location_id, '' );
return (string) tribe_get_option( Settings::OPTION_SANDBOX_LOCATION_ID, '' );
}

return (string) tribe_get_option( Settings::$option_location_id, '' );
return (string) tribe_get_option( Settings::OPTION_LOCATION_ID, '' );
}
}
9 changes: 4 additions & 5 deletions src/Tickets/Commerce/Gateways/Square/Merchant.php
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,7 @@ public function fetch_merchant_data( bool $force_refresh = false ): array {
return [];
}

// Make request using the Requests class.
$response = tribe( Requests::class )->get( "merchants/{$merchant_id}" );
$response = Requests::get_with_cache( "merchants/{$merchant_id}" );

// Handle error responses.
if ( is_wp_error( $response ) || isset( $response['errors'] ) ) {
Expand Down Expand Up @@ -623,10 +622,10 @@ public function get_client_secret(): string {
* @return string
*/
public function get_client_id(): string {
$client_id = tribe_get_option( Settings::$option_client_id );
$client_id = tribe_get_option( Settings::OPTION_CLIENT_ID );

if ( empty( $client_id ) && tribe( Gateway::class )->is_test_mode() ) {
$client_id = tribe_get_option( Settings::$option_sandbox_client_id );
$client_id = tribe_get_option( Settings::OPTION_SANDBOX_CLIENT_ID );
}

return $client_id;
Expand Down Expand Up @@ -658,7 +657,7 @@ public function get_locations(): array {

$url = 'locations';
$args = [];
$response = tribe( Requests::class )->get( $url, [], $args );
$response = Requests::get_with_cache( $url, [], $args );

if ( empty( $response['locations'] ) || ! is_array( $response['locations'] ) ) {
return [];
Expand Down
20 changes: 16 additions & 4 deletions src/Tickets/Commerce/Gateways/Square/Payment.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,26 @@ public static function create( string $source_id, Value $value, ?WP_Post $order
$body['reference_id'] = $order->ID;
}

/**
* Filters the payment body.
*
* @since TBD
*
* @param array $body The payment body.
* @param string $source_id The source ID.
* @param Value $value The value object.
* @param ?WP_Post $order The order post object.
*/
$body = apply_filters( 'tec_tickets_commerce_square_payment_body', $body, $source_id, $value, $order );

$args = [
'body' => $body,
'headers' => [
'Content-Type' => 'application/json',
],
];

return tribe( Requests::class )->post( 'payments', $query_args, $args );
return Requests::post( 'payments', $query_args, $args );
}

/**
Expand Down Expand Up @@ -152,7 +164,7 @@ public static function get( string $payment_id ): ?array {
'body' => $body,
];

return tribe( Requests::class )->get( "payments/{$payment_id}", $query_args, $args );
return Requests::get_with_cache( "payments/{$payment_id}", $query_args, $args );
}

/**
Expand All @@ -178,7 +190,7 @@ public static function update( string $payment_id, array $data ): ?array {
'body' => $body,
];

return tribe( Requests::class )->put( "payments/{$payment_id}", $query_args, $args );
return Requests::put( "payments/{$payment_id}", $query_args, $args );
}

/**
Expand All @@ -205,7 +217,7 @@ public static function cancel( string $payment_id ): ?array {
'body' => $body,
];

return tribe( Requests::class )->post( "payments/{$payment_id}/cancel", $query_args, $args );
return Requests::post( "payments/{$payment_id}/cancel", $query_args, $args );
}

/**
Expand Down
41 changes: 41 additions & 0 deletions src/Tickets/Commerce/Gateways/Square/Requests.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,34 @@ class Requests extends Abstract_Requests {
'sandbox' => 'https://connect.squareupsandbox.com/v2',
];

/**
* Get a response from the Square API with caching.
*
* @since TBD
*
* @param string $endpoint The endpoint path.
* @param array $query_args Query args appended to the URL.
* @param array $request_arguments Request arguments.
* @param bool $raw Whether to return the raw response.
*
* @return array|null
*/
public static function get_with_cache( $endpoint, array $query_args = [], array $request_arguments = [], $raw = false ): ?array {
$cache_key = md5( wp_json_encode( [ $endpoint, $query_args, $request_arguments, $raw ] ) );
$cache = tribe_cache();

$cached_response = $cache->get_transient( $cache_key );
if ( false !== $cached_response ) {
return $cached_response;
}

$response = self::get( $endpoint, $query_args, $request_arguments, $raw );

$cache->set_transient( $cache_key, $response, MINUTE_IN_SECONDS * 10 );

return $response;
}

/**
* Get REST API endpoint URL for requests.
*
Expand Down Expand Up @@ -80,4 +108,17 @@ public static function get_environment_url() {

return static::API_BASE_URLS[ $mode ] ?? static::API_BASE_URLS['sandbox'];
}

/**
* Get the headers.
*
* @since TBD
*
* @return array The headers.
*/
public static function get_headers(): array {
return [
'Square-Version' => '2025-04-16',
];
}
}
47 changes: 37 additions & 10 deletions src/Tickets/Commerce/Gateways/Square/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Settings extends Abstract_Settings {
*
* @var string
*/
public static string $option_client_id = 'tickets-commerce-square-client-id';
const OPTION_CLIENT_ID = 'tickets-commerce-square-client-id';

/**
* Sandbox Client ID option key.
Expand All @@ -31,7 +31,7 @@ class Settings extends Abstract_Settings {
*
* @var string
*/
public static string $option_sandbox_client_id = 'tickets-commerce-square-sandbox-client-id';
const OPTION_SANDBOX_CLIENT_ID = 'tickets-commerce-square-sandbox-client-id';

/**
* Location ID option key.
Expand All @@ -40,7 +40,7 @@ class Settings extends Abstract_Settings {
*
* @var string
*/
public static string $option_location_id = 'tickets-commerce-square-location-id';
const OPTION_LOCATION_ID = 'tickets-commerce-square-location-id';

/**
* Sandbox Location ID option key.
Expand All @@ -49,7 +49,16 @@ class Settings extends Abstract_Settings {
*
* @var string
*/
public static string $option_sandbox_location_id = 'tickets-commerce-square-sandbox-location-id';
const OPTION_SANDBOX_LOCATION_ID = 'tickets-commerce-square-sandbox-location-id';

/**
* Inventory sync option key.
*
* @since TBD
*
* @var string
*/
const OPTION_INVENTORY_SYNC = 'tickets-commerce-square-inventory-sync';

/**
* Get all the settings for the Square gateway.
Expand Down Expand Up @@ -95,24 +104,31 @@ public function get_settings(): array {
'type' => 'html',
'html' => '<h3>' . esc_html__( 'Square Settings', 'event-tickets' ) . '</h3>',
],
static::OPTION_INVENTORY_SYNC => [
'type' => 'checkbox_bool',
'label' => esc_html__( 'Enable Inventory Sync', 'event-tickets' ),
'tooltip' => esc_html__( 'If this option is selected, your Posts with Tickets on sale will be kept in sync with your Square inventory.', 'event-tickets' ),
'default' => false,
'validation_type' => 'boolean',
],
];

// If in sandbox mode, only show the sandbox location settings.
if ( $is_sandbox_mode ) {
$connected_settings[ static::$option_sandbox_location_id ] = [
$connected_settings[ static::OPTION_SANDBOX_LOCATION_ID ] = [
'type' => 'dropdown',
'label' => esc_html__( 'Square Test Location', 'event-tickets' ),
'tooltip' => esc_html__( 'Select the Square test location to process test payments through.', 'event-tickets' ),
'label' => esc_html__( 'Square Test Web Location', 'event-tickets' ),
'tooltip' => esc_html__( 'Select the Square test location to process test payments.', 'event-tickets' ),
'validation_type' => 'options',
'options' => $this->get_location_options( true ),
'can_be_empty' => false,
];
} else {
// In live mode, only show the live location settings.
$connected_settings[ static::$option_location_id ] = [
$connected_settings[ static::OPTION_LOCATION_ID ] = [
'type' => 'dropdown',
'label' => esc_html__( 'Square Location', 'event-tickets' ),
'tooltip' => esc_html__( 'Select the Square location to process payments through.', 'event-tickets' ),
'label' => esc_html__( 'Square Web Location', 'event-tickets' ),
'tooltip' => esc_html__( 'Select the Square location to process payments.', 'event-tickets' ),
'validation_type' => 'options',
'options' => $this->get_location_options( false ),
'can_be_empty' => false,
Expand Down Expand Up @@ -162,6 +178,17 @@ public function get_settings(): array {
return apply_filters( 'tec_tickets_commerce_square_settings', array_merge( $main_settings, $connected_settings ), $is_connected );
}

/**
* Check if inventory sync is enabled.
*
* @since TBD
*
* @return bool Whether inventory sync is enabled.
*/
public function is_inventory_sync_enabled(): bool {
return tribe_is_truthy( tribe_get_option( static::OPTION_INVENTORY_SYNC ) );
}

/**
* Get all available Square locations as an array of options for a dropdown field.
*
Expand Down
Loading
Loading