0

I will write step by step what I did and what documents I used, as follows:

1- I created a Customer and then SetupIntent

     public async Task<Stripe.Customer> CreateCustomer(Stripe.Customer stripeCustomer)
        {
            var options = new CustomerCreateOptions
            {
                Email = stripeCustomer.Email,
                Name = stripeCustomer.Name,
                Phone = stripeCustomer.Phone,
            };

            return await _customerService.CreateAsync(options);
        }

      public async Task<SetupIntent> CreateSetupIntent(string customerId)
        {
            var setupIntentOptions = new SetupIntentCreateOptions
            {
                Customer = customerId,
                PaymentMethodTypes = new List<string>
                {
                    "card"
                },

                Usage = "off_session"
            };

            var setupIntent = await _setupIntentService.CreateAsync(setupIntentOptions);

            return setupIntent;
        }

2- I set the card information received from the customer (ı used '3D required' test card) using stripe js and the clientecret of the SetupIntent that I created in my api to the 'confirmCardSetup'.

const stripeCardElement: StripeCardElement = this.card!.element;

    this.stripeService.confirmCardSetup('seti_*****', {
      payment_method: {
        card: stripeCardElement,
        billing_details: {
          name: 'Jenny Rosen',

        }

      },

3- I created a subscription with trial. (Stirpe created the paymentmethod when I confirm the setup intent) And stripe returned successful for this confirm.

  var optionsSubscription = new SubscriptionCreateOptions
                {
                    Customer = customerId,
                    ProrationBehavior = "none",
                    Items = new List<SubscriptionItemOptions>
                    {
                        new SubscriptionItemOptions
                        {
                            Price = priceId
                        }
                    },                   
                    DefaultPaymentMethod = "pm_******",
                    CollectionMethod = "charge_automatically",
                    PaymentBehavior = "allow_incomplete",
                    Currency = "usd",
                    TrialEnd = DateTime.Now.AddSeconds(30),
                    OffSession = true,
                };

                optionsSubscription.AddExpand(SubscriptonCreateOptionExpand);

                var newSubscription = await _subscriptionService.CreateAsync(optionsSubscription);

I did the first two steps by looking at this link

After the trial period is over, stripe trid to charge the payment from the customer. but the payment was 'declined'.

I know that need additional confirmation from user for this payment. Because I used 3d required test card. But Stripe did not request approval for 3D (If so, ı would see in logs). If I need to 3D confirmation while creating the setup intent, why didn't stripe return me in response when i create it?

I would be very grateful if someone could show me where I am doing wrong.

1 Answers1

2

You should be using the test cards listed under https://stripe.com/docs/testing?testing-method=payment-methods#authentication-and-setup i.e. pm_card_authenticationRequired

I'm guessing that you probably used pm_card_threeDSecureRequired. For context, Visa and Mastercard have already discontinued support for 3DS1, the legacy authentication protocol, and all related technology from 15 October 2022 except in some countries e.g. India (which will likely eventually also migrate to 3DS2 and stop supporting 3DS1).

Stripe probably simply fails the transaction and does not attempt 3DS1 since your Stripe account is not in a country that supports 3DS1 anymore.

For subscriptions, when 3DS is required for an off-session payment, Stripe does have a setting to send an email to the customer to confirm the payment if 3DS is required. See https://stripe.com/docs/billing/revenue-recovery/customer-emails#payment-confirmation-notifications. Alternatively, if you don't want to use Stripe to handle this, you can build your own flow to do so. See

alex
  • 1,923
  • 11
  • 9