6
votes

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;
}
1
Does the updatedSubcription.latest_invoice have the other properties present, or is the invoice itself not present? If it is present, make sure that the amount is greater than zero (otherwise there won't be a payment intent present). - taintedzodiac
@taintedzodiac, The documentation says to check the status of the paymentIntent but for the first subscription, the price is 0.00 (it's the free tier) what status should I be checking to make sure everything was setup properly in that use case? I want to make sure the subscription was created and invoiced because on that date every month they will get charged either 0.00 or greater depending on their plan. - user1184205
@taintedzodiac I checked the invoice and all other values are there, just payment Intent is null. updatedSubcription.latest_invoice.total is 14900, so there should be a payment Intent - user1184205
Facing same issue. - Kunal Awasthi
Did you find any solution for this? facing the same. - jones

1 Answers

1
votes

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.