mirror of
https://github.com/bitwarden/server
synced 2025-12-06 00:03:34 +00:00
[PM-21938] Fix: Invoice Payment Issues After Payment Method Updates (#6306)
* Resolve the unpaid issue after valid payment method is added * Removed the draft status * Remove draft from the logger msg
This commit is contained in:
@@ -580,11 +580,6 @@ public class SubscriberService(
|
||||
PaymentMethod = token
|
||||
});
|
||||
|
||||
var getExistingSetupIntentsForCustomer = stripeAdapter.SetupIntentList(new SetupIntentListOptions
|
||||
{
|
||||
Customer = subscriber.GatewayCustomerId
|
||||
});
|
||||
|
||||
// Find the setup intent for the incoming payment method token.
|
||||
var setupIntentsForUpdatedPaymentMethod = await getSetupIntentsForUpdatedPaymentMethod;
|
||||
|
||||
@@ -597,24 +592,15 @@ public class SubscriberService(
|
||||
|
||||
var matchingSetupIntent = setupIntentsForUpdatedPaymentMethod.First();
|
||||
|
||||
// Find the customer's existing setup intents that should be canceled.
|
||||
var existingSetupIntentsForCustomer = (await getExistingSetupIntentsForCustomer)
|
||||
.Where(si =>
|
||||
si.Status is "requires_payment_method" or "requires_confirmation" or "requires_action");
|
||||
|
||||
// Store the incoming payment method's setup intent ID in the cache for the subscriber so it can be verified later.
|
||||
await setupIntentCache.Set(subscriber.Id, matchingSetupIntent.Id);
|
||||
|
||||
// Cancel the customer's other open setup intents.
|
||||
var postProcessing = existingSetupIntentsForCustomer.Select(si =>
|
||||
stripeAdapter.SetupIntentCancel(si.Id,
|
||||
new SetupIntentCancelOptions { CancellationReason = "abandoned" })).ToList();
|
||||
|
||||
// Remove the customer's other attached Stripe payment methods.
|
||||
postProcessing.Add(RemoveStripePaymentMethodsAsync(customer));
|
||||
|
||||
// Remove the customer's Braintree customer ID.
|
||||
postProcessing.Add(RemoveBraintreeCustomerIdAsync(customer));
|
||||
var postProcessing = new List<Task>
|
||||
{
|
||||
RemoveStripePaymentMethodsAsync(customer),
|
||||
RemoveBraintreeCustomerIdAsync(customer)
|
||||
};
|
||||
|
||||
await Task.WhenAll(postProcessing);
|
||||
|
||||
@@ -622,11 +608,6 @@ public class SubscriberService(
|
||||
}
|
||||
case PaymentMethodType.Card:
|
||||
{
|
||||
var getExistingSetupIntentsForCustomer = stripeAdapter.SetupIntentList(new SetupIntentListOptions
|
||||
{
|
||||
Customer = subscriber.GatewayCustomerId
|
||||
});
|
||||
|
||||
// Remove the customer's other attached Stripe payment methods.
|
||||
await RemoveStripePaymentMethodsAsync(customer);
|
||||
|
||||
@@ -634,16 +615,6 @@ public class SubscriberService(
|
||||
await stripeAdapter.PaymentMethodAttachAsync(token,
|
||||
new PaymentMethodAttachOptions { Customer = subscriber.GatewayCustomerId });
|
||||
|
||||
// Find the customer's existing setup intents that should be canceled.
|
||||
var existingSetupIntentsForCustomer = (await getExistingSetupIntentsForCustomer)
|
||||
.Where(si =>
|
||||
si.Status is "requires_payment_method" or "requires_confirmation" or "requires_action");
|
||||
|
||||
// Cancel the customer's other open setup intents.
|
||||
var postProcessing = existingSetupIntentsForCustomer.Select(si =>
|
||||
stripeAdapter.SetupIntentCancel(si.Id,
|
||||
new SetupIntentCancelOptions { CancellationReason = "abandoned" })).ToList();
|
||||
|
||||
var metadata = customer.Metadata;
|
||||
|
||||
if (metadata.TryGetValue(BraintreeCustomerIdKey, out var value))
|
||||
@@ -653,16 +624,14 @@ public class SubscriberService(
|
||||
}
|
||||
|
||||
// Set the customer's default payment method in Stripe and remove their Braintree customer ID.
|
||||
postProcessing.Add(stripeAdapter.CustomerUpdateAsync(subscriber.GatewayCustomerId, new CustomerUpdateOptions
|
||||
await stripeAdapter.CustomerUpdateAsync(subscriber.GatewayCustomerId, new CustomerUpdateOptions
|
||||
{
|
||||
InvoiceSettings = new CustomerInvoiceSettingsOptions
|
||||
{
|
||||
DefaultPaymentMethod = token
|
||||
},
|
||||
Metadata = metadata
|
||||
}));
|
||||
|
||||
await Task.WhenAll(postProcessing);
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1320,12 +1320,6 @@ public class SubscriberServiceTests
|
||||
stripeAdapter.SetupIntentList(Arg.Is<SetupIntentListOptions>(options => options.PaymentMethod == "TOKEN"))
|
||||
.Returns([matchingSetupIntent]);
|
||||
|
||||
stripeAdapter.SetupIntentList(Arg.Is<SetupIntentListOptions>(options => options.Customer == provider.GatewayCustomerId))
|
||||
.Returns([
|
||||
new SetupIntent { Id = "setup_intent_2", Status = "requires_payment_method" },
|
||||
new SetupIntent { Id = "setup_intent_3", Status = "succeeded" }
|
||||
]);
|
||||
|
||||
stripeAdapter.CustomerListPaymentMethods(provider.GatewayCustomerId).Returns([
|
||||
new PaymentMethod { Id = "payment_method_1" }
|
||||
]);
|
||||
@@ -1335,8 +1329,8 @@ public class SubscriberServiceTests
|
||||
|
||||
await sutProvider.GetDependency<ISetupIntentCache>().Received(1).Set(provider.Id, "setup_intent_1");
|
||||
|
||||
await stripeAdapter.Received(1).SetupIntentCancel("setup_intent_2",
|
||||
Arg.Is<SetupIntentCancelOptions>(options => options.CancellationReason == "abandoned"));
|
||||
await stripeAdapter.DidNotReceive().SetupIntentCancel(Arg.Any<string>(),
|
||||
Arg.Any<SetupIntentCancelOptions>());
|
||||
|
||||
await stripeAdapter.Received(1).PaymentMethodDetachAsync("payment_method_1");
|
||||
|
||||
@@ -1364,12 +1358,6 @@ public class SubscriberServiceTests
|
||||
}
|
||||
});
|
||||
|
||||
stripeAdapter.SetupIntentList(Arg.Is<SetupIntentListOptions>(options => options.Customer == provider.GatewayCustomerId))
|
||||
.Returns([
|
||||
new SetupIntent { Id = "setup_intent_2", Status = "requires_payment_method" },
|
||||
new SetupIntent { Id = "setup_intent_3", Status = "succeeded" }
|
||||
]);
|
||||
|
||||
stripeAdapter.CustomerListPaymentMethods(provider.GatewayCustomerId).Returns([
|
||||
new PaymentMethod { Id = "payment_method_1" }
|
||||
]);
|
||||
@@ -1377,8 +1365,8 @@ public class SubscriberServiceTests
|
||||
await sutProvider.Sut.UpdatePaymentSource(provider,
|
||||
new TokenizedPaymentSource(PaymentMethodType.Card, "TOKEN"));
|
||||
|
||||
await stripeAdapter.Received(1).SetupIntentCancel("setup_intent_2",
|
||||
Arg.Is<SetupIntentCancelOptions>(options => options.CancellationReason == "abandoned"));
|
||||
await stripeAdapter.DidNotReceive().SetupIntentCancel(Arg.Any<string>(),
|
||||
Arg.Any<SetupIntentCancelOptions>());
|
||||
|
||||
await stripeAdapter.Received(1).PaymentMethodDetachAsync("payment_method_1");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user