Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stripe - PaymentIntent is null when I create or update a subscription

I'm new to Stripe, so if I'm missing something, please advise.

Tech Stack: React (front-end) Node (back-end)

I am trying to create or update a Stripe subscription, and in either case, I get a null paymentIntent. I thought I read that I should check the paymentIntent status to make sure the payment for the subscription has gone through.

My subscription workflow, when a user signs up, I create a Stripe customer and add them to a subscription. This subscription is a free tier so no payment method is needed. The payment_intent is null.

//create a Stripe customer code here
...

//create the subscription 
const subscription = await stripe.subscriptions.create({
    customer: customer.id,
    items: [{ priceID }],
    expand: ['latest_invoice.payment_intent'],
});

const invoice = subscription.latest_invoice as Stripe.Invoice;
const payment_intent = invoice.payment_intent as Stripe.PaymentIntent;

Later after they want to upgrade to a paid plan, I request a credit card and upgrade their current subscription to a paid plan. On the front-end, I use Stripe Element and create a payment method by doing this.

if (!elements || !stripe) {
     return 
}

const cardElement = elements.getElement(CardElement);

if (!cardElement) {
     return
}

// Confirm Card Setup
const { 
     error, 
     paymentMethod 
} = await stripe.createPaymentMethod({
     type: 'card',
     card: cardElement,
     billing_details:{
          name,
          email: currentUser.email,
          phone,
          address: {
               city,
               line1: address,
               state,
          },
     }
});

if (error) {
     console.log("createPaymentMethod: ", error.message)
} else {
     const paymentMethodId = paymentMethod!.id
     // Switch to new subscription
     await switchSubscription(priceID, paymentMethodId)
}
    

And on the back-end, I get the stripe customer, add a payment method, and upgrade the subscription to the new plan. The payment_intent is null.

function switchSubscription(priceID, user, paymentMethod) {
     //get Stripe customer code here ...
     ...

     await stripe.paymentMethods.attach(paymentMethod, { customer: customer.id });
     await stripe.customers.update(customer.id, {
        invoice_settings: { default_payment_method: paymentMethod },
    });

    const currentSubscription = await getSubscriptions(user)

     const updatedSubscription = await stripe.subscriptions.update(
          currentSubscription.id,
     {
          cancel_at_period_end: false,
          proration_behavior: 'always_invoice',
          items: [
               {
                    id: currentSubscription.items.data[0].id,
                    price: priceID,
               },
          ],
          expand: ['latest_invoice.payment_intent'],
     })

     const invoice = updatedSubscription.latest_invoice as Stripe.Invoice;
     const payment_intent = invoice.payment_intent as Stripe.PaymentIntent;
}
like image 514
user1184205 Avatar asked Sep 09 '20 06:09

user1184205


People also ask

Why is my Stripe subscription status incomplete?

Sent when the subscription is created. The subscription status may be incomplete if customer authentication is required to complete the payment or if you set payment_behavior to default_incomplete .

How do I deal with failed subscription payments on Stripe?

If a payment fails for a subscription invoice, your customers can use the Stripe-hosted page to: View the details and amounts for the failed invoice and the associated subscription. Add a new card payment method for their subscription for the payment that's due and for future subscription payments.

What is a paymentintent in stripe?

A PaymentIntent tracks the lifecycle of every payment. Whenever a payment is due for a subscription, Stripe generates an invoice and a PaymentIntent. The PaymentIntent ID attaches to the invoice and you can access it from the Invoice and Subscription objects. The state of the PaymentIntent affects the state of the invoice and the subscription.

What happens if stripe subscription fails to pay?

If automatic payment fails, the subscription updates to past_due and Stripe attempts to recover payment based on your retry rules. If payment recovery fails, you can set the subscription status to canceled, unpaid, or leave it past_due. For unpaid subscriptions, the latest invoice remains open but payments aren’t attempted.

How does stripe notify customers when an invoice is past due?

The status is set to open and Stripe automatically attempts to pay it using the default payment method. If payment succeeds, the status updates to paid. If payment fails, the invoice remains open and the subscription becomes past_due. In this flow, Stripe doesn’t notify your customer about the invoice.

Can stripe send a subscription confirmation email to my customers?

Learn more about subscription statuses. For payments that require 3D Secure, Stripe can send a confirmation email to your customer at the same time as the invoice.payment_action_required event is sent. You can also configure sending up to three reminders, from one to seven days after the payment was initiated.


2 Answers

Your customer might have a balance in their account so that the amount might be taken out from the customer's available balance. I think for cases like that, Stripe doesn't create a payment intent, and therefore returns null.

like image 79
vander Avatar answered Nov 15 '22 09:11

vander


I solved this probleme by adding the quantity to items. I think the invoice is not created (null) when the total amount is 0.

like image 31
Zinedine Benkhider Avatar answered Nov 15 '22 08:11

Zinedine Benkhider