From 91d06280cb393c5fc4b5528c10c2148258caca72 Mon Sep 17 00:00:00 2001 From: James Allan Date: Tue, 12 Sep 2023 19:54:06 +1000 Subject: [PATCH 1/8] WIP changes --- .../class-wc-payments-invoice-service.php | 14 ++++++++++++++ .../class-wc-payments-subscription-service.php | 2 ++ ...-wc-payments-subscriptions-event-handler.php | 6 ++++++ .../class-wc-payments-api-client.php | 17 +++++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/includes/subscriptions/class-wc-payments-invoice-service.php b/includes/subscriptions/class-wc-payments-invoice-service.php index 5e86e1c9e45..bcfd28840f6 100644 --- a/includes/subscriptions/class-wc-payments-invoice-service.php +++ b/includes/subscriptions/class-wc-payments-invoice-service.php @@ -309,6 +309,20 @@ public function get_and_attach_intent_info_to_order( $order, $intent_id ) { ); } + /** + * Sends a request to server to record the store's context for an invoice payment. + * + * @param string $invoice_id The subscription invoice ID. + */ + public function record_invoice_payment_context( string $invoice_id ) { + $this->payments_api_client->update_invoice( + $invoice_id, + [ + 'subscription_context' => class_exists( 'WC_Subscriptions' ) && WC_Payments_Features::is_stripe_billing_enabled() ? 'stripe_billing' : 'legacy_wcpay_subscription', + ] + ); + } + /** * Sets the subscription last invoice ID meta for WC subscription. * diff --git a/includes/subscriptions/class-wc-payments-subscription-service.php b/includes/subscriptions/class-wc-payments-subscription-service.php index c4b91bac644..9f52765061a 100644 --- a/includes/subscriptions/class-wc-payments-subscription-service.php +++ b/includes/subscriptions/class-wc-payments-subscription-service.php @@ -388,6 +388,8 @@ public function create_subscription( WC_Subscription $subscription ) { $subscription_data = $this->prepare_wcpay_subscription_data( $wcpay_customer_id, $subscription ); $this->validate_subscription_data( $subscription_data ); + $subscription_data['metadata']['source'] = $this->is_subscriptions_plugin_active() ? 'woo_subscriptions' : 'wcpay_subscriptions'; + $response = $this->payments_api_client->create_subscription( $subscription_data ); $this->set_wcpay_subscription_id( $subscription, $response['id'] ); diff --git a/includes/subscriptions/class-wc-payments-subscriptions-event-handler.php b/includes/subscriptions/class-wc-payments-subscriptions-event-handler.php index a728aa63f02..31f9d9525a1 100644 --- a/includes/subscriptions/class-wc-payments-subscriptions-event-handler.php +++ b/includes/subscriptions/class-wc-payments-subscriptions-event-handler.php @@ -186,6 +186,9 @@ public function handle_invoice_paid( array $body ) { $this->invoice_service->get_and_attach_intent_info_to_order( $order, $event_object['payment_intent'] ); } + // Record the store's Stripe Billing environment context on the payment intent. + $this->invoice_service->record_invoice_payment_context( $wcpay_invoice_id ); + // Remove pending invoice ID in case one was recorded for previous failed renewal attempts. $this->invoice_service->mark_pending_invoice_paid_for_subscription( $subscription ); } @@ -248,6 +251,9 @@ public function handle_invoice_payment_failed( array $body ) { // Record invoice ID so we can trigger repayment on payment method update. $this->invoice_service->mark_pending_invoice_for_subscription( $subscription, $wcpay_invoice_id ); + + // Record the store's Stripe Billing environment context on the payment intent. + $this->invoice_service->record_invoice_payment_context( $wcpay_invoice_id ); } /** diff --git a/includes/wc-payment-api/class-wc-payments-api-client.php b/includes/wc-payment-api/class-wc-payments-api-client.php index eeeddad0111..0d03fbd7e9e 100644 --- a/includes/wc-payment-api/class-wc-payments-api-client.php +++ b/includes/wc-payment-api/class-wc-payments-api-client.php @@ -1118,6 +1118,23 @@ public function charge_invoice( string $invoice_id, array $data = [] ) { ); } + /** + * Updates an invoice. + * + * @param string $invoice_id ID of the invoice to update. + * @param array $data Parameters to send to the invoice endpoint. Optional. Default is an empty array. + * @return array + * + * @throws API_Exception Error updating the invoice. + */ + public function update_invoice( string $invoice_id, array $data = [] ) { + return $this->request( + $data, + self::INVOICES_API . '/' . $invoice_id, + self::POST + ); + } + /** * Fetch a WCPay subscription. * From f40659ddb438f39e2b15087d920a1033e5a43eb1 Mon Sep 17 00:00:00 2001 From: James Allan Date: Wed, 13 Sep 2023 11:14:28 +1000 Subject: [PATCH 2/8] Add changelog entries --- changelog/fix-6529-add-stripe-billing-context | 4 ++++ changelog/fix-6529-add-stripe-billing-context-2 | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 changelog/fix-6529-add-stripe-billing-context create mode 100644 changelog/fix-6529-add-stripe-billing-context-2 diff --git a/changelog/fix-6529-add-stripe-billing-context b/changelog/fix-6529-add-stripe-billing-context new file mode 100644 index 00000000000..010248eefe7 --- /dev/null +++ b/changelog/fix-6529-add-stripe-billing-context @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Record the subscriptions environment context in transaction meta when Stripe Billing payments are handled. diff --git a/changelog/fix-6529-add-stripe-billing-context-2 b/changelog/fix-6529-add-stripe-billing-context-2 new file mode 100644 index 00000000000..fe9672a589a --- /dev/null +++ b/changelog/fix-6529-add-stripe-billing-context-2 @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Record the source (Woo Subscriptions or WCPay Subscriptions) when a Stripe Billing subscription is created. From 0c6dec6c9cad67afdeacb5c04deeb4e3f4e66d7e Mon Sep 17 00:00:00 2001 From: James Allan Date: Wed, 13 Sep 2023 11:15:52 +1000 Subject: [PATCH 3/8] Update function name to more align with its purpose --- .../subscriptions/class-wc-payments-invoice-service.php | 2 +- .../class-wc-payments-subscriptions-event-handler.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/includes/subscriptions/class-wc-payments-invoice-service.php b/includes/subscriptions/class-wc-payments-invoice-service.php index bcfd28840f6..66fd2dcc4f4 100644 --- a/includes/subscriptions/class-wc-payments-invoice-service.php +++ b/includes/subscriptions/class-wc-payments-invoice-service.php @@ -314,7 +314,7 @@ public function get_and_attach_intent_info_to_order( $order, $intent_id ) { * * @param string $invoice_id The subscription invoice ID. */ - public function record_invoice_payment_context( string $invoice_id ) { + public function record_subscription_payment_context( string $invoice_id ) { $this->payments_api_client->update_invoice( $invoice_id, [ diff --git a/includes/subscriptions/class-wc-payments-subscriptions-event-handler.php b/includes/subscriptions/class-wc-payments-subscriptions-event-handler.php index 31f9d9525a1..d91fa30405e 100644 --- a/includes/subscriptions/class-wc-payments-subscriptions-event-handler.php +++ b/includes/subscriptions/class-wc-payments-subscriptions-event-handler.php @@ -186,11 +186,11 @@ public function handle_invoice_paid( array $body ) { $this->invoice_service->get_and_attach_intent_info_to_order( $order, $event_object['payment_intent'] ); } - // Record the store's Stripe Billing environment context on the payment intent. - $this->invoice_service->record_invoice_payment_context( $wcpay_invoice_id ); - // Remove pending invoice ID in case one was recorded for previous failed renewal attempts. $this->invoice_service->mark_pending_invoice_paid_for_subscription( $subscription ); + + // Record the store's Stripe Billing environment context on the payment intent. + $this->invoice_service->record_subscription_payment_context( $wcpay_invoice_id ); } /** @@ -253,7 +253,7 @@ public function handle_invoice_payment_failed( array $body ) { $this->invoice_service->mark_pending_invoice_for_subscription( $subscription, $wcpay_invoice_id ); // Record the store's Stripe Billing environment context on the payment intent. - $this->invoice_service->record_invoice_payment_context( $wcpay_invoice_id ); + $this->invoice_service->record_subscription_payment_context( $wcpay_invoice_id ); } /** From 9d2c6aa0675c5c71e4c96c3e36ee401fe4133059 Mon Sep 17 00:00:00 2001 From: James Allan Date: Wed, 13 Sep 2023 11:55:29 +1000 Subject: [PATCH 4/8] Fix unit tests --- .../test-class-wc-payments-subscription-service.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/unit/subscriptions/test-class-wc-payments-subscription-service.php b/tests/unit/subscriptions/test-class-wc-payments-subscription-service.php index 550ce8da03d..9a8646fab3c 100644 --- a/tests/unit/subscriptions/test-class-wc-payments-subscription-service.php +++ b/tests/unit/subscriptions/test-class-wc-payments-subscription-service.php @@ -171,6 +171,9 @@ public function test_create_subscription() { ], ], ], + 'metadata' => [ + 'source' => 'woo_subscriptions', + ], ]; $this->assertNotEquals( $mock_subscription->get_meta( self::SUBSCRIPTION_ID_META_KEY ), $mock_wcpay_subscription_id ); From 8452459e7a1bbee5b2cc1c03d468f9cd9ad85849 Mon Sep 17 00:00:00 2001 From: James Allan Date: Wed, 13 Sep 2023 14:41:05 +1000 Subject: [PATCH 5/8] Update subscription source meta to be more specific --- .../subscriptions/class-wc-payments-subscription-service.php | 2 +- .../test-class-wc-payments-subscription-service.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/subscriptions/class-wc-payments-subscription-service.php b/includes/subscriptions/class-wc-payments-subscription-service.php index 9f52765061a..d552e31e0cb 100644 --- a/includes/subscriptions/class-wc-payments-subscription-service.php +++ b/includes/subscriptions/class-wc-payments-subscription-service.php @@ -388,7 +388,7 @@ public function create_subscription( WC_Subscription $subscription ) { $subscription_data = $this->prepare_wcpay_subscription_data( $wcpay_customer_id, $subscription ); $this->validate_subscription_data( $subscription_data ); - $subscription_data['metadata']['source'] = $this->is_subscriptions_plugin_active() ? 'woo_subscriptions' : 'wcpay_subscriptions'; + $subscription_data['metadata']['subscription_source'] = $this->is_subscriptions_plugin_active() ? 'woo_subscriptions' : 'wcpay_subscriptions'; $response = $this->payments_api_client->create_subscription( $subscription_data ); diff --git a/tests/unit/subscriptions/test-class-wc-payments-subscription-service.php b/tests/unit/subscriptions/test-class-wc-payments-subscription-service.php index 9a8646fab3c..61bf20df055 100644 --- a/tests/unit/subscriptions/test-class-wc-payments-subscription-service.php +++ b/tests/unit/subscriptions/test-class-wc-payments-subscription-service.php @@ -172,7 +172,7 @@ public function test_create_subscription() { ], ], 'metadata' => [ - 'source' => 'woo_subscriptions', + 'subscription_source' => 'woo_subscriptions', ], ]; From 98ded360c22777df9c87ebfa558d86e8717163af Mon Sep 17 00:00:00 2001 From: James Allan Date: Wed, 13 Sep 2023 15:25:15 +1000 Subject: [PATCH 6/8] Fix bug in payment intent meta data from order --- includes/class-wc-payment-gateway-wcpay.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/class-wc-payment-gateway-wcpay.php b/includes/class-wc-payment-gateway-wcpay.php index ccee24b21ad..f06f66c6fd9 100644 --- a/includes/class-wc-payment-gateway-wcpay.php +++ b/includes/class-wc-payment-gateway-wcpay.php @@ -1612,9 +1612,9 @@ protected function get_metadata_from_order( $order, $payment_type ) { 'subscription_payment' => 'no', ]; - if ( 'recurring' === (string) $payment_type && function_exists( 'wcs_order_contains_subscription' ) && wcs_order_contains_subscription( $order ) ) { + if ( 'recurring' === (string) $payment_type && function_exists( 'wcs_order_contains_subscription' ) && wcs_order_contains_subscription( $order, 'any' ) ) { $metadata['subscription_payment'] = wcs_order_contains_renewal( $order ) ? 'renewal' : 'initial'; - $metadata['payment_context'] = $this->is_subscriptions_plugin_active() ? 'regular_subscription' : 'wcpay_subscription'; + $metadata['payment_context'] = WC_Payments_Features::should_use_stripe_billing() ? 'wcpay_subscription' : 'regular_subscription'; } return apply_filters( 'wcpay_metadata_from_order', $metadata, $order, $payment_type ); } From e8748bf41fad1b1cbe4d33af46f8ec9275751237 Mon Sep 17 00:00:00 2001 From: James Allan Date: Wed, 13 Sep 2023 15:31:54 +1000 Subject: [PATCH 7/8] Add changelog entry for bug in recurring payment payment intent meta --- changelog/fix-payment-intent-meta-for-recurring-transactions | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelog/fix-payment-intent-meta-for-recurring-transactions diff --git a/changelog/fix-payment-intent-meta-for-recurring-transactions b/changelog/fix-payment-intent-meta-for-recurring-transactions new file mode 100644 index 00000000000..534b1a20f24 --- /dev/null +++ b/changelog/fix-payment-intent-meta-for-recurring-transactions @@ -0,0 +1,4 @@ +Significance: minor +Type: dev + +Fix payment context and subscription payment metadata stored on subscription recurring transactions From 68648cc4abda0886f5d33da29f68494b1c77ab63 Mon Sep 17 00:00:00 2001 From: James Allan Date: Wed, 13 Sep 2023 15:32:36 +1000 Subject: [PATCH 8/8] Add missing full stop in changelog entry --- changelog/fix-payment-intent-meta-for-recurring-transactions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog/fix-payment-intent-meta-for-recurring-transactions b/changelog/fix-payment-intent-meta-for-recurring-transactions index 534b1a20f24..b5e9efeeab0 100644 --- a/changelog/fix-payment-intent-meta-for-recurring-transactions +++ b/changelog/fix-payment-intent-meta-for-recurring-transactions @@ -1,4 +1,4 @@ Significance: minor Type: dev -Fix payment context and subscription payment metadata stored on subscription recurring transactions +Fix payment context and subscription payment metadata stored on subscription recurring transactions.