Reputation: 763
I'm creating a Checkout session and it's working fine, but when the customer is redirected to our app, his invoices do not mention the address that was collected throughout the Checkout process. It makes no sense to me, but that's how Stripe works...
Any idea what we are supposed to do to correct that (get the billing address from the customer that was filled by him during Checkout, than modifying the invoice).
Here's how we're creating the session :
return stripe.checkout.Session.create(
customer_email=userEmail,
billing_address_collection='required', =>>> REQUIRED !
payment_method_types=['card'],
subscription_data=subscription_data,
line_items=[{
'price': priceId,
'quantity': 1,
}],
metadata={
'vatNumber': vatNumber,
'accountId': accountData['accountId'],
},
mode='subscription',
success_url='https://xxx/home/account',
cancel_url='https://xxx/home/upgrade',
)
And than here's the result from the Webhooks :
{
"object": {
"id": "cs_test_pNl9BXBCAtTEoXmTD1Ii2e8e34DK28MyUZSBZrqHjz6ZNPvft0",
"object": "checkout.session",
"allow_promotion_codes": null,
"amount_subtotal": 19000,
"amount_total": 22990,
"billing_address_collection": "required",
"cancel_url": "https://www.xxxxx/home/upgrade",
"client_reference_id": null,
"currency": "eur",
"customer": "cus_xxxxxxhL00at",
"customer_email": "xxxxxm",
"livemode": false,
"locale": null,
"metadata": {
"accountId": "f88e5bfc-3a2a-4103-bd3e-33d3ebbe2963"
},
"mode": "subscription",
"payment_intent": null,
"payment_method_types": [
"card"
],
"payment_status": "paid",
"setup_intent": null,
"shipping": null,
"shipping_address_collection": null,
"submit_type": null,
"subscription": "sub_Hxxxx",
"success_url": "https://www.xxxx/home/account",
"total_details": {
"amount_discount": 0,
"amount_tax": 3990
}
}
}
No billing addresss anywhere in the response... I would love to understand the logic behind creating an API that collects the billing address but doesn't use it, or make it easily available, because I'm a bit lost.
Upvotes: 3
Views: 2610
Reputation: 11
As mentioned by @kugel, my initial assumptions were incorrect. So you can pretty much ignore the following answer and its two edits as they don't apply for checkout sessions.
The following answer is based on a guess because although I've used many parts of the Stripe API I didn't specifically used the checkouts API yet. So you will have to try by yourself if my assumptions are correct. My guess:
When you create a session and the customer data is collected, Stripe creates a new customer object on the server or updates an existing one if e.g. the email matches.
EDIT: I just saw that they explain it in the API docs: https://stripe.com/docs/api/checkout/sessions/object#checkout_session_object-customer
The ID of the customer for this session. For Checkout Sessions in payment or subscription mode, Checkout will create a new customer object based on information provided during the session unless an existing customer was provided when the session was created.
If my guess is correct the following might work for you:
The Session object returned by Stripe does not contain the complete customer data but only the customers id (cus_xxxxxxhL00at
above).
This is to keep the response object as clean and small as possible.
You can retrieve the customer object with the correct API method using this id (see: https://stripe.com/docs/api/customers/retrieve).
How you would do this depends on how your server is set up (what programming language is used). If I understand correctly you are using python so this should work:
stripe.Customer.retrieve("cus_xxxxxxhL00at")
If you want to directly get the customer object from Stripe inside the response to your Session.create
call you can also expand the customer object. Then the whole customer object is loaded and added to the response instead of the customers id.
You simple have to add the expand
parameter to your request (you can see this explained hovering over the "expandable" hint next to "customer" here: https://stripe.com/docs/api/checkout/sessions/object#checkout_session_object-customer).
Your request then should look like this:
return stripe.checkout.Session.create(
customer_email=userEmail,
billing_address_collection='required',
payment_method_types=['card'],
subscription_data=subscription_data,
line_items=[{
'price': priceId,
'quantity': 1,
}],
metadata={
'vatNumber': vatNumber,
'accountId': accountData['accountId'],
},
mode='subscription',
success_url='https://xxx/home/account',
cancel_url='https://xxx/home/upgrade',
expand=['customer']
)
Either way the returned customer object should contain the address data that was provided by the user.
EDIT 2: I just realized that the response to Session.create
will not contain the updated customer but the customer before the user provided any new data (as the Session was just created and the user didn't interact with it yet).
Expanding the customer object in this specific request will not do the trick here but the same mechanism can be used e.g. when retrieving the session after the customer provided their data (with stripe.checkout.Session.retrieve
) so I will leave this in the answer as the basic explanation is still correct.
I also just saw your comment on another question so I think you want to get the customer data in a webhook handling method. Then you would want to use the first method I described anyways (retrieving the customer object by the customer id).
Upvotes: 0
Reputation: 838
I've contacted Stripe and the billing address is only used for fraud detection. The address will be saved with the payment method, so you can listen to the customer.created
webhook and connect the billing address from the payment method to your customer yourself.
Upvotes: 0