I try to use the new Stripe's PaymentIntent system to be ready when SCA will be launched in EU.
I only use one-time payment.
I succeed to make the payment with the PaymentIntent following Stripe's documentation. But I'm unable to create an invoice for every payment (I must have one according to the law), and I tried a lot of things.
But first, I think I need to show my code to introduce the troubles I have.
In my view, I create a Stripe Session :
public_token = settings.STRIPE_PUBLIC_KEY
stripe.api_key = settings.STRIPE_PRIVATE_KEY
stripe_sesssion = stripe.checkout.Session.create(
payment_method_types=['card'],
line_items=[{
'name':'My Product',
'description': description,
'amount': amount,
'currency': 'eur',
'quantity': 1,
}],
customer=customer_id,
success_url=f'{settings.SITE_URL}/ok.html',
cancel_url=f'{settings.SITE_URL}/payment_error.html',
)
Then, the user click on the "Purchase" button on my web page and is redirected to the Stripe's Checkout page.
After the user filled his payment card informations, Stripe call my Webhook (according to the checkout.session.completed event triggered).
Here's my webhook function code :
@csrf_exempt
def webhook_payment_demande(request):
payload = request.body
sig_header = request.META['HTTP_STRIPE_SIGNATURE']
event = None
if settings.DEBUG is False:
endpoint_secret = "whsec_xxx"
else:
endpoint_secret = "whsec_xxx"
try:
event = stripe.Webhook.construct_event(
payload, sig_header, endpoint_secret
)
except ValueError as e:
# Invalid payload
return HttpResponse(status=400)
except stripe.error.SignatureVerificationError as e:
# Invalid signature
return HttpResponse(status=400)
# Handle the event
if event['type'] == 'checkout.session.completed':
stripe_session = event['data']['object']
invoice_item = stripe.InvoiceItem.create(
customer=customer_id,
amount=str(amount),
currency="eur",
description=description
)
invoice = stripe.Invoice.create(
customer=customer_id,
)
invoice_payment = stripe.Invoice.pay(
invoice,
source=card
)
[...] Deliver product by e-mail and stuff [...]
- If I execute that code, the payment is done a first time (PaymentIntent) but also a second time to finalize the invoice I create after. So my customer payed twice the amount.
- If I remove the Invoice.pay function, Stripe will charge my client one hour after anyway using an existing payment card into Stripe.
- If I don't create any invoice manually inside my Web hook function, Stripe doesn't make one automatically.
- If I create the invoice into my first view, just right after the Stripe Checkout Session and before my customer fill his card informations, he will be charged for the amount even if he didn't finalize the payment (because he had a existing card into Stripe).
I'm reading the documentation for days and I've not found a good tutorial to make a one-time Payment with SCA compatibility and having a bill after that.
Is a nice person has already fixed his/her Stripe payment API system for SCA compliance and have found a way to deal with this ?
A lot of thanks for your help ! :)