From 2c7763a53894e5c350d6ce76e0f4ab3b1e768bc5 Mon Sep 17 00:00:00 2001 From: Derrick Koo Date: Mon, 13 May 2024 10:19:24 -0600 Subject: [PATCH] fix(ras): sync purchase data only for most recent order/subscription (#3086) * fix(ras): sync purchase data only for most recent order/subscription * fix: payment page field --- .../plugins/class-newspack-newsletters.php | 80 ++++++++++++------- .../class-woocommerce-connection.php | 61 +++++++++----- .../class-woocommerce-order-utm.php | 3 +- 3 files changed, 96 insertions(+), 48 deletions(-) diff --git a/includes/plugins/class-newspack-newsletters.php b/includes/plugins/class-newspack-newsletters.php index 14ef831393..4bd8605a86 100644 --- a/includes/plugins/class-newspack-newsletters.php +++ b/includes/plugins/class-newspack-newsletters.php @@ -29,32 +29,7 @@ class Newspack_Newsletters { * * @var array */ - public static $metadata_keys = [ - 'account' => 'Account', - 'registration_date' => 'Registration Date', - 'connected_account' => 'Connected Account', - 'signup_page' => 'Signup Page', - 'signup_page_utm' => 'Signup UTM: ', - 'newsletter_selection' => 'Newsletter Selection', - 'referer' => 'Referrer Path', - 'registration_page' => 'Registration Page', - 'current_page_url' => 'Registration Page', - 'registration_method' => 'Registration Method', - - // Payment-related. - 'membership_status' => 'Membership Status', - 'payment_page' => 'Payment Page', - 'payment_page_utm' => 'Payment UTM: ', - 'sub_start_date' => 'Current Subscription Start Date', - 'sub_end_date' => 'Current Subscription End Date', - 'billing_cycle' => 'Billing Cycle', - 'recurring_payment' => 'Recurring Payment', - 'last_payment_date' => 'Last Payment Date', - 'last_payment_amount' => 'Last Payment Amount', - 'product_name' => 'Product Name', - 'next_payment_date' => 'Next Payment Date', - 'total_paid' => 'Total Paid', - ]; + public static $metadata_keys = []; /** * Initialize hooks and filters. @@ -65,7 +40,7 @@ public static function init() { * * @param array $metadata_keys The list of key/value pairs for metadata fields to be synced to the connected ESP. */ - self::$metadata_keys = \apply_filters( 'newspack_ras_metadata_keys', self::$metadata_keys ); + self::$metadata_keys = \apply_filters( 'newspack_ras_metadata_keys', self::get_all_metadata_fields() ); \add_filter( 'newspack_newsletters_contact_data', [ __CLASS__, 'normalize_contact_data' ] ); @@ -74,6 +49,57 @@ public static function init() { } } + /** + * Get basic contact metadata fields. + * + * @return array List of fields. + */ + public static function get_basic_metadata_fields() { + return [ + 'account' => 'Account', + 'registration_date' => 'Registration Date', + 'connected_account' => 'Connected Account', + 'signup_page' => 'Signup Page', + 'signup_page_utm' => 'Signup UTM: ', + 'newsletter_selection' => 'Newsletter Selection', + 'referer' => 'Referrer Path', + 'registration_page' => 'Registration Page', + 'current_page_url' => 'Registration Page', + 'registration_method' => 'Registration Method', + ]; + } + + /** + * Get payment-related metadata fields. + * + * @return array List of fields. + */ + public static function get_payment_metadata_fields() { + return [ + 'membership_status' => 'Membership Status', + 'payment_page' => 'Payment Page', + 'payment_page_utm' => 'Payment UTM: ', + 'sub_start_date' => 'Current Subscription Start Date', + 'sub_end_date' => 'Current Subscription End Date', + 'billing_cycle' => 'Billing Cycle', + 'recurring_payment' => 'Recurring Payment', + 'last_payment_date' => 'Last Payment Date', + 'last_payment_amount' => 'Last Payment Amount', + 'product_name' => 'Product Name', + 'next_payment_date' => 'Next Payment Date', + 'total_paid' => 'Total Paid', + ]; + } + + /** + * Get all metdata fields. + * + * @return array List of fields. + */ + public static function get_all_metadata_fields() { + return array_merge( self::get_basic_metadata_fields(), self::get_payment_metadata_fields() ); + } + /** * Whether or not we should use the special metadata keys for RAS sites. * diff --git a/includes/reader-revenue/woocommerce/class-woocommerce-connection.php b/includes/reader-revenue/woocommerce/class-woocommerce-connection.php index d7520696d9..be1f6d8caf 100644 --- a/includes/reader-revenue/woocommerce/class-woocommerce-connection.php +++ b/includes/reader-revenue/woocommerce/class-woocommerce-connection.php @@ -203,13 +203,15 @@ public static function get_contact_order_metadata( $order, $payment_page_url = f $metadata = []; - $referer_from_order = $order->get_meta( '_newspack_referer' ); - if ( empty( $referer_from_order ) ) { - $payment_page_url = \wc_get_checkout_url(); - } else { - $payment_page_url = $referer_from_order; + if ( empty( $payment_page_url ) ) { + $referer_from_order = $order->get_meta( '_newspack_referer' ); + if ( empty( $referer_from_order ) ) { + $payment_page_url = \wc_get_checkout_url(); + } else { + $payment_page_url = $referer_from_order; + } } - $metadata['payment_page'] = $payment_page_url; + $metadata[ Newspack_Newsletters::get_metadata_key( 'payment_page' ) ] = $payment_page_url; $utm = $order->get_meta( 'utm' ); if ( ! empty( $utm ) ) { @@ -297,6 +299,21 @@ public static function get_contact_order_metadata( $order, $payment_page_url = f } } + // Clear out any payment-related fields that don't relate to the current order. + $payment_fields = array_keys( Newspack_Newsletters::get_payment_metadata_fields() ); + foreach ( $payment_fields as $meta_key ) { + $meta_field = Newspack_Newsletters::get_metadata_key( $meta_key ); + if ( ! isset( $metadata[ $meta_field ] ) ) { + if ( 'payment_page_utm' === $meta_key ) { + foreach ( WooCommerce_Order_UTM::$params as $param ) { + $metadata[ $meta_field . $param ] = ''; + } + } else { + $metadata[ $meta_field ] = ''; + } + } + } + return $metadata; } @@ -317,43 +334,49 @@ public static function get_contact_from_customer( $customer, $order = false, $pa $metadata = []; $order_metadata = []; + $last_order = self::get_last_successful_order( $customer ); $metadata[ Newspack_Newsletters::get_metadata_key( 'account' ) ] = $customer->get_id(); $metadata[ Newspack_Newsletters::get_metadata_key( 'registration_date' ) ] = $customer->get_date_created()->date( Newspack_Newsletters::METADATA_DATE_FORMAT ); $metadata[ Newspack_Newsletters::get_metadata_key( 'total_paid' ) ] = \wc_format_localized_price( $customer->get_total_spent() ); - if ( ! $order ) { - $order = self::get_last_successful_order( $customer ); + // If a more recent order exists, use it to sync. + if ( ! $order || ( $last_order && $order->get_id() !== $last_order->get_id() ) ) { + $order = $last_order; + } - // If customer has no order, they might still have a Subscription. - if ( ! $order ) { - $user_subscriptions = wcs_get_users_subscriptions( $customer->get_id() ); - if ( $user_subscriptions ) { - $order = reset( $user_subscriptions ); - } + // If customer has no order, they might still have a Subscription. + if ( ! $order ) { + $user_subscriptions = \wcs_get_users_subscriptions( $customer->get_id() ); + if ( $user_subscriptions ) { + $order = reset( $user_subscriptions ); } } + // Get the order metadata. if ( $order ) { $order_metadata = self::get_contact_order_metadata( $order, $payment_page_url, $is_new ); } else { - // If the customer has no successful orders, ensure their spend totals are correct. - $order_metadata[ Newspack_Newsletters::get_metadata_key( 'last_payment_amount' ) ] = \wc_format_localized_price( '0.00' ); + // If the customer has no successful orders, clear out subscription-related fields. + $payment_fields = array_keys( Newspack_Newsletters::get_payment_metadata_fields() ); + foreach ( $payment_fields as $meta_key ) { + $metadata[ Newspack_Newsletters::get_metadata_key( $meta_key ) ] = ''; + } } - $metadata = array_merge( $metadata, $order_metadata ); + $metadata = array_merge( $order_metadata, $metadata ); $first_name = $customer->get_billing_first_name(); $last_name = $customer->get_billing_last_name(); $full_name = trim( "$first_name $last_name" ); $contact = [ 'email' => $customer->get_billing_email(), - 'metadata' => array_filter( $metadata ), + 'metadata' => $metadata, ]; if ( ! empty( $full_name ) ) { $contact['name'] = $full_name; } - return array_filter( $contact ); + return $contact; } /** diff --git a/includes/reader-revenue/woocommerce/class-woocommerce-order-utm.php b/includes/reader-revenue/woocommerce/class-woocommerce-order-utm.php index 9fdd544ba8..0bebe9d2aa 100644 --- a/includes/reader-revenue/woocommerce/class-woocommerce-order-utm.php +++ b/includes/reader-revenue/woocommerce/class-woocommerce-order-utm.php @@ -13,13 +13,12 @@ * WooCommerce Order UTM class. */ class WooCommerce_Order_UTM { - /** * UTM parameters. * * @var string[] */ - private static $params = [ + public static $params = [ 'source', 'medium', 'campaign',