#ironbeard_subscription-update-pmt
1 messages ยท Page 1 of 1 (latest)
๐ Welcome to your new thread!
โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
๐ This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1463955430417105142
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
- ironbeard_confirmation-token-flow, 1 day ago, 53 messages
๐ heyo
Hi ๐
That is rather specific. I can see you are expanding the latest_invoice.payment_intent in your subscription creation API request.
Let me take a look at the response.
โค๏ธ thanks!
Well, for starters the only valid payment method type for this Invoice is card
Why is that?
Do you have bank transfers enabled as a payment method for Invoices on this account?
Yeah. I've been able to get it to display as an option in PaymentElement
That does not mean it's enabled for Invoices. They are separate payment method configurations
Oh wait
You specified you only accept card payments in your request
payment_settings: {
payment_method_types: {
0: "card",
},
save_default_payment_method: "on_subscription",
},
Creation
You then updated it to send_invoice
and then updated it to use bank transfers
What is it you are trying to do here?
The latest Invoice hasn't been paid yet so that is still the current Invoice.
And that Invoice was created when you only accepted cards
It doesn't matter how you update the Subscription, that Invoice will remain the same
Those changes will show up on the next Invoice
oh, gotcha. Can that be updated? Here's my flow:
Following the two-step ConfirmationToken flow with PaymentElements and Subscription:
When the customer is on /checkout/payment, the PE shows up with Card only (and CustomerSession to display previously saved cards). The next page is the /checkout/review/ page, and they have two options: submit the PE and get the ConfirmationToken or click "Pay by bank transfer", which doesn't create a CT.
Either way, the POST of /checkout/payment will create the Subscription. In the GET of /checkout/review I'll either display the payment_method_preview if the ConfirmationToken exists, or payment_intent.next_action.display_bank_transfer_instructions
Unfortunately, I think you would need to adjust your flow so you defer creating the Subscription until the Customer has selected their preferred payment method type. So whatever you need to do in your UI to collect the necessary information to determine the desired payment method type before you create the Subscription, that is what you should do so you can provide the correct payment_settings parameter when you create the Subscription
Because you are going to create an Invoice when you create the Subscription and that Invoice will be finalized instantly
So you cannot update it
Gotcha. Well, the updating of the sub is only an issue if someone is on the review page and decides to go back and change the payment method. So I suppose in that case I just delete the Subscription and create a new one?
Yeah that would work.
If I want to avoid the possibility of creating Subscriptions that get deleted when someone changes their mind, could I create the Subscription (with a CT?) on the POST of /checkout/review/ and confirm payment on the backend? If I only want to support cards and bank tranfers, there shouldn't be any need for client redirecting, right?
I can't tell if it's bad practices to create Subscriptions that might get deleted if someone changes their mind during checkout (either adds items or changes PM)
That's not bad practice. In fact, we even have a canonical guide for that specific flow: https://docs.stripe.com/payments/finalize-payments-on-the-server?platform=web&type=subscription
It's really useful for situations where there is some final confirmation step that needs to occur on the server (e.g. checking available stock).
Hmm, but in this case I wouldn't have a Subscription on GET /checkout/review/ to display virtual bank details if they choose to do push payment. I think I read I could get it from stripe.Customer.retrieve(id, expand=['cash_balance']) but that would still require a bank transfer payment intent
although, I suppose I could display it on the confirmation page, .e.g /checkout/done/
As a test, can you try updating the payment_settings on both the Subscription and the Invoice?
Hmm yes let see
InvalidRequestError: Request req_ffKqc50IwnAqJU: The payment method type customer_balance cannot be used with invoices that have the collection_method set to charge_automatically.
So I tried to update the invoice for send_invoice and got:
InvalidRequestError: Request req_76OTZLaisFyn7Y: Non-draft invoices can't be updated
hello! fyi i'm taking over the thread
So, yeah I think having a flow that would allow a customer to change their payment method from card to bank_transfer after the Subscription has been created is probably not a good idea. I'd either need to delete the subscription, or defer creating it until they POST on the /checkout/review/ page (point of no return).
The only sort of issue with that second option is wanting to display the bank transfer details. but I think I can do that on the /checkout/done/ page.
i'm still getting caught up on context, but i think that makes sense to me. do you think you're good to go at this point or are there any outstanding questions / concerns?
I think I'm good for now ๐ Thanks for steppin in!
yep of course! always happy to jump in when the issue is already resolved ๐
i'll keep the thread open for a bit in case you have followups
Oh, I just thought of something.
Can you confirm the following?
- I can create a PaymentElement on the front end (FE) and tell it to only display cards:
paymentMethodTypes: ["card"], if they choose to pay by card, they can fill out the PE and click the submit button and I create a CT and send that to my server. They can click another button to skip the CT creation and go to/checkout/review/ - On
GET /checkout/review/I can displaypayment_element_previewor say "You've chosen to pay by bank tranfer, details will be emailed to you and displayed after you confirm. - On
POST /checkout/review/I can create the Subscription, and I can specify both["card", "customer_balance"]inpayment_method_types. If the ConfirmationToken exists, setcollection_method="charge_automatically", otherwise setcollection_method="send_invoice". - On
GET /checkout/done/If the invoice hasn't been paid, I can displaypayment_intent.next_action.display_bank_transfer_instructions(or maybe get it fromcustomerwithexpand=['cash_balance']).
In this setup, someone who was send_invoice, would get an email with the bank transfer instructions. Would it also include a link for them to pay the invoice on Stripe's webpage with a card?
...I probably just need to test this out lol, I know I'm getting into the weeds.
sorry for the slow response, a few other things cropped up
no worries ๐ take your time
ok so basically your question is if you send them an invoice when they have ["card", "customer_balance"] as payment methods on the invoice, what do they see in the invoice email?
I was hoping to create a Subscription in such a way that the email sent to them will display bank transfer details (as the customer originally intended), but also allow them to pay by card on the stripe hosted invoice page if they change their mind
yep, as long as you include a link to the payment page in your invoice it should allow them to pay with either payment method
I was just able to confirm that it does display both, so that's nice. I had to call stripe.Invoice.send_invoice in order to finalize the invoice, though.
But even if i do stripe.Invoice.send_invoice(id, expand=['payment_intent']), I don't get payment_intent.next_action.display_bank_transfer_instructions, which is something I can't figure out how to get.
i think there's a dashboard setting for including the payment link in the email, but i forget what it's called at the moment
i think that only shows once the payment intent is confirmed with a customer_balance payment method
what's the status of your payment intent?
ok yeah, it won't show a next_action until it's confirmed, so you will need to confirm it first
So, regardless of if the person pays by card (and has a ConfirmationToken) or chooses to push payment (bank tranfer, no CT), I still need to make a second call to Stripe API (after creating the Subscription) to confirm the payment intent?
How do I confirm a PaymentIntent if I don't have at CT or PM?
Hi ๐
Sorry this went a little ways while I was out. Let me catch up
No worries. ๐ I've settled on creating the Subscription with payment_methods=['card', 'customer_balance'] so that any hosted invoice will allow both. If the customer wanted to pay with card, then i'll have a ConfirmationToken to confirm the payment intent with on the backend.
But I'd like to find out a way to get the bank transfer details. I'm not sure how to confirm a PI if I don't have a CT, and I think I need to confirm the PI in order to display the virtual bank details to the customer on the /checkout/done/ screen (e.g. after Subscription has been created)
Casn you share the ID of the latest Payment Intet you generated?
'pi_3SsTaSE3d1saT86k1GGVtxqx'
my subscription creation call was:
s = stripe.Subscription.create(
customer=cart.customer.id,
items=[{
'price': price.id,
'quantity': 1,
} for price in cart.prices.all()],
payment_behavior='default_incomplete',
collection_method='send_invoice',
days_until_due=30,
discounts=[{
'promotion_code': cart.promotion_code.id
}] if cart.promotion_code else [],
#off_session=?
payment_settings={
'payment_method_types': ['card', 'customer_balance'],
'payment_method_options': {
'customer_balance': {
'funding_type': 'bank_transfer',
'bank_transfer': {'type': 'us_bank_transfer'},
},
},
},
expand=['latest_invoice.payment_intent'],
)
i = stripe.Invoice.send_invoice(s.latest_invoice.id, expand=['payment_intent'])
Okay and have you tried confirming the Payment Intent using our method specifically for Customer Balance?
https://docs.stripe.com/js/payment_intents/confirm_customer_balance_payment
If you take a look at the JavaScript snippet you can see this method is expected to return a Payment Intent with a status of requires_action and the bank transfer details in paymentIntent.next_action.display_bank_transfer_instructions
Is that only available in the JS lib?
This is for displaying the info to the Customer, so yes this is only in Stripe.js
If you were finalizing on the server and then needed to go through this step, you could send the client secret back to your application and trigger the process in your front-end
Okay, so I think I'm back to
- Create Subscription on
POST /checkout/payment/which redirects toGET /checkout/review/, and passes alonglatest_invoice.client_secretand possiblyconfirmation_token, if they decided to pay by card. - On
/checkout/review/, when they click "Submit Order" button, then in JS I either callstripe.confirmPayment(client_secret, {confirmParams: confirmation_token})orstripe.confirmCustomerBalancePayment(client_secret). Then redirect to/checkout/done - On
GET /checkout/done/I could fetch the latest payment_intent from Stripe and get bank transfer details to display to the customer?
I think that will work! As always, I recommend testing end-to-end to confirm the desired behavior.
thanks for your help, I think I'm seeing the light ๐
one last thing: Does it always require two API calls to create and then pay for a Subscription? Is passing a confirmation token to stripe.Subscription.create() possible?
I don't think so. Using the confirmation token always requires an existing Payment Intent and you only get access to that once you have created the Subscription. Since the token isn't an actual payment method, you cannot provide it to the default_payment_method parameter.
Gotcha, in order for a Subscription to create+charge in one API call, I'd have to pass default_payment_method?
Correct!
Great, thanks for everything. Have a good one!
You too ๐