Skip to content

Commit 65acd01

Browse files
authored
Fix: ensure Stripe subscriptions respect multi-Stripe accounts (#8200)
1 parent ab5c12f commit 65acd01

File tree

3 files changed

+52
-7
lines changed

3 files changed

+52
-7
lines changed

src/PaymentGateways/Gateways/Stripe/StripePaymentElementGateway/Webhooks/Listeners/InvoicePaymentSucceeded.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public function __invoke(Event $event)
4343
}
4444

4545
/**
46+
* @unreleased Added $formId parameter and stripe_account option for Stripe Connect support
4647
* @since 4.8.0 Add support for Stripe API version 2025-03-31.basil and later versions
4748
* @since 4.3.0 Update Stripe Invoice metadata
4849
* @since 3.0.4 Return a bool value.
@@ -71,7 +72,7 @@ public function processEvent(Event $event): bool
7172
* the payment_intent which is required for processing this webhook.
7273
*/
7374
if (is_null($invoice->payment_intent)) {
74-
$invoice = $this->getCompleteInvoiceFromStripe($event->data->object->id);
75+
$invoice = $this->getCompleteInvoiceFromStripe($event->data->object->id, $subscription->donationFormId);
7576
}
7677

7778
$gatewayTransactionId = $invoice->payment_intent;

src/PaymentGateways/Gateways/Stripe/StripePaymentElementGateway/Webhooks/Listeners/StripeWebhookListenerRepository.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,28 @@ protected function getGatewaySubscriptionId(Invoice $invoice): ?string
8484
/**
8585
* Retrieve a complete invoice from the Stripe API.
8686
*
87-
* @since 4.8.0
87+
* For Stripe Connect accounts, we need to pass the connected account ID to retrieve the invoice from the correct account, not the platform account.
88+
*
89+
* @unreleased Added $formId parameter and stripe_account option for Stripe Connect support
8890
*
8991
* @param string $invoiceId The Stripe invoice ID
92+
* @param int|null $formId Form ID to determine the connected account
9093
* @return Invoice The complete Stripe invoice object with all properties
9194
* @throws Exception If the API call fails
9295
*/
93-
protected function getCompleteInvoiceFromStripe(string $invoiceId): Invoice
96+
protected function getCompleteInvoiceFromStripe(string $invoiceId, ?int $formId = null): Invoice
9497
{
9598
try {
96-
return \Stripe\Invoice::retrieve($invoiceId);
99+
$options = [];
100+
101+
if ($formId) {
102+
$connectedAccountId = give_stripe_get_connected_account_id($formId);
103+
if (!empty($connectedAccountId)) {
104+
$options = ['stripe_account' => $connectedAccountId];
105+
}
106+
}
107+
108+
return \Stripe\Invoice::retrieve($invoiceId, $options);
97109
} catch (ApiErrorException $exception) {
98110
throw new Exception(
99111
sprintf(

src/PaymentGateways/Gateways/Stripe/Webhooks/StripeEventListener.php

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ abstract class StripeEventListener implements EventListener
1717
use CanSetupStripeApp;
1818

1919
/**
20+
* @unreleased Pass connected account ID to Event::retrieve for Stripe Connect support
2021
* @since 2.21.0
2122
* @throws Exception
2223
*/
@@ -26,27 +27,58 @@ public function __invoke(Event $event)
2627
$this->setupStripeApp($formId);
2728
$this->logEventReceiveTime();
2829

29-
$this->processEvent($this->getEventFromStripe($event->id));
30+
$this->processEvent($this->getEventFromStripe($event->id, $formId));
3031
}
3132
}
3233

3334
/**
35+
* Retrieves the full event from Stripe.
36+
*
37+
* For Stripe Connect accounts, we need to pass the connected account ID to retrieve the event from the correct account, not the platform account.
38+
*
39+
* @unreleased Added $formId parameter and stripe_account option for Stripe Connect support
3440
* @since 2.21.0
3541
*
3642
* @param string $eventId
43+
* @param int|null $formId Form ID to determine the connected account
3744
*
3845
* @return Event
3946
* @throws Exception
4047
*/
41-
protected function getEventFromStripe($eventId)
48+
protected function getEventFromStripe($eventId, $formId = null)
4249
{
4350
try {
44-
return Event::retrieve($eventId);
51+
$options = $this->getStripeConnectOptions($formId);
52+
53+
return Event::retrieve($eventId, $options);
4554
} catch (\Exception $e) {
4655
throw new Exception($e->getMessage());
4756
}
4857
}
4958

59+
/**
60+
* Get Stripe Connect options for API calls.
61+
*
62+
* Returns an array with the stripe_account option if a connected account is configured for the given form. This is required for Stripe Connect to make API calls to the correct connected account instead of the platform account.
63+
*
64+
* @unreleased
65+
*
66+
* @param int|null $formId Form ID to determine the connected account
67+
*
68+
* @return array Options array for Stripe API calls
69+
*/
70+
protected function getStripeConnectOptions($formId = null): array
71+
{
72+
if ($formId) {
73+
$connectedAccountId = give_stripe_get_connected_account_id($formId);
74+
if (!empty($connectedAccountId)) {
75+
return ['stripe_account' => $connectedAccountId];
76+
}
77+
}
78+
79+
return [];
80+
}
81+
5082
/**
5183
* @since 2.21.0
5284
* @return void

0 commit comments

Comments
 (0)