I’m implementing payments with Stripe and I’ve run into a flow I don’t know how to solve. I’d like to know the right or recommended way.
First payment with UI: The user goes to my frontend, I use the normal Checkout Session flow. Stripe shows the card form, the customer pays, I store the customer_id.
Extra charges (no UI): After that first payment, in the frontend I have “extra purchase” buttons (e.g., pay $20 for another advice), but in this case I do not want the user to enter card details again or see the Stripe form. Just click and charge (one-click, not subscription, just a second one-off charge).
When I create the customer in Stripe, I see the payment_method is null. I try to create a new PaymentIntent to charge, but it needs a payment_method.
ChatGPT says I should get the PaymentMethod ID, but I don’t know how. When I try to list the customer’s payment methods, it’s empty or null.
If I try to reuse the PaymentMethod ID from the first charge, Stripe says I can’t use it again.
I don’t know if I’m doing something wrong, or if it’s really not possible to charge again without asking for card details.
How do I associate the card or PaymentMethod with the customer so I can charge them later with no UI, just from backend, no card details again?
# Django DRF, backend
@api_view(['POST'])
def create_payment(request):
session = StripeSingleton().checkout.Session.create(
success_url=f'{settings.STRIPE_SUCCESS_URL}?session_id={{CHECKOUT_SESSION_ID}}',
line_items=[{'price': 'price_XXXX', 'quantity': 1}],
mode='payment',
)
return Response({'success_url': session['url']}, status=200)
# Validation
@api_view(['GET'])
def validate_payment(request):
session_id = request.GET.get('session_id')
session = StripeSingleton().checkout.Session.retrieve(session_id)
# Here I save the customer_id and email
Then for the extra payment, I try:
payment_intent = stripe.PaymentIntent.create(
amount=2000, # 20 pesos in cents
currency='mxn',
customer=customer_id,
payment_method=payment_method_id, # I try to reuse this from the first charge
off_session=True,
confirm=True,
description="Extra advice - one-off charge",
)
But Stripe gives me an error: You cannot use a PaymentMethod that was already used. And if I try to list customer’s payment methods, it shows empty or null.
When you create the Checkout Session for the first payment, you need to configure to save the card details automatically on the resulting Customer object. This is done using the payment_intent_data[setup_future_usage]
parameter. This is documented here.
If you configure this, the resulting Customer will have a PaymentMethod (pm_1234) attached automatically that you can then use for future payments. You can find the PaymentMethod id by looking at the payment_method
property on the PaymentIntent associated with the Checkout Session for example.