#marka-paymentelement-migration
1 messages ยท Page 1 of 1 (latest)
marka-paymentelement-migration
๐ @cosmic olive Can I ask for a lot more specific context with detailed code and exact request ids/object ids so that I can help you debug this?
Well, there's not request IDs, as it's rejected at the javascript level using stripe.js at confirmPayment call if I add the setup_future_usage param. And the confirmPyament call is pretty basic with/without that param:
confirmPaymentIntent(paymentIntentKey, callback) {
let self = this;
console.log("Start confirmPmt...");
if (!self.stripe) {
self.stripe = Stripe(self.supportData.skey);
}
if (self.elements) {
console.log("confirmPayment...");
let elements = self.elements;
let data = {
payment_method_data: {
billing_details: {
address: {
line1: self.paymentData.addressLine1,
line2: self.paymentData.addressLine2,
city: self.paymentData.city,
state: self.paymentData.state,
postal_code: self.paymentData.zipCode,
country: self.paymentData.countryCode,
},
name: self.paymentData.name,
},
},
//setup_future_usage: "off_session",
};
self.stripe.confirmPayment({ elements, clientSecret: paymentIntentKey, confirmParams: data, redirect: "if_required" })
.then((result) => {
if (result.error) {
sure but I'm trying to grasp what you were doing before, what's working, what's not working, etc.
You said
We have very complex payment flows with lots of options.
which means it's not a simple question and I barely understand for now what you are trying to get at, while helping other people.
If you can help me understand what you were doing before, what the context it, why you are trying to pass that parameter client-side, etc. I can then look
Here's the primary use case, of the two I mentioned above:
Use case: I have a failed subscription invoice payment intent, and I subsequently use the Payment Element to collect new payment method data for that payment intent. On the call to Stripe.js confirmPayment, the payment intent is processed successfully with the new payment method, but the new payment method is not attached to the customer or subscription (req_1FsygjfMhEkuVc).
The documentation for Stripe.js confirmPayment says to refer to the PaymentIntent API to see all confirm params for use during the confirmPayment call (https://stripe.com/docs/js/payment_intents/confirm_payment#confirm_payment_intent-options-confirmParams). The PaymentIntent API docs clearly (and logically) show that "setup_future_usage" is one of those confirm params, and would be needed to attach the new payment method to the payment intent's customer (https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-setup_future_usage), which makes sense.
However, on subsequent attempts for a different payment intent (pi_3NqpreAUoPbSaQbf3u01xJCS) when setup_future_usage is added to the confirmPayment confirmParams for the confirmPayment call, it fails with: "Payment method not updated: IntegrationError: stripe.confirmPayment(): do not pass setup_future_usage at confirm time. Instead, pass setup_future_usage when the PaymentIntent is created."
This is contrary to the documentation, and logic, as the payment intent in question is a previously failed payment intent where we're trying to setup a new payment method, which is where we want the future usage setting, and for it to attach to the customer in confirmation.
The second use case is a simple one-off invoice for a customer (payment intent already exists), not attached to subscription. In some cases we give the customer the option of using current payment method, OR selecting a NEW payment method. For the new payment method case, we want to attach it to the customer for future use. The payment method clears the confirmPayment call, and does make the payment, but it won't attach. We don't want to go through another round of setup intents to be able to attach this new payment method for future use.
Let's take this one at a time because that's a lot of text
Some of these customers have subscriptions and one-off invoices.
Use case: I have a failed subscription invoice payment intent, and I subsequently use the Payment Element to collect new payment method data for that payment intent. On the call to Stripe.js confirmPayment, the payment intent is processed successfully with the new payment method, but the new payment method is not attached to the customer or subscription (req_1FsygjfMhEkuVc).
and to be clear you are saying this works absolutely fine withconfirmCardPayment()and you can passsetup_future_usagewithout any error there?
Yes, been doing it for at least a few years now.
That code looked (looks like) in our prod environment:
//confirmCardPayment(paymentIntentKey, callback) {
// let self = this;
// console.log("Start confirmPmt...");
// if (!self.stripe) {
// self.stripe = Stripe(self.supportData.skey);
// }
// if (self.elements) {
// let data = {
// payment_method: {
// card: self.paymentElement,
// billing_details: {
// address: {
// line1: self.paymentData.addressLine1,
// line2: self.paymentData.addressLine2,
// city: self.paymentData.city,
// state: self.paymentData.state,
// postal_code: self.paymentData.zipCode,
// country: self.paymentData.countryCode,
// },
// name: self.paymentData.name,
// },
// },
// };
// if (!self.hasExistingCard || self.isNewDefaultCard) {
// data.payment_method_options = {
// card: {
// setup_future_usage: "off_session",
// }
// }
// }
// self.stripe.confirmCardPayment(paymentIntentKey, data)
// .then((result) => {
Ack so that really looks like a feature request to me overall in that case, not really something we can help with here. But in the meantime you can update that PaymentIntent server-side before rendering it in PaymentElement and set setup_future_usage on it right?
We can't. Those attempts resulted in these:
- Modify PaymentIntent to allow more payment method types:
var options = new PaymentIntentUpdateOptions();
if (allowBankDebits)
{
List<string> paymentMethods = new List<string> {
Models.Billing.PaymentMethod.CARD,
Models.Billing.PaymentMethod.US_BANK_ACCOUNT,
Models.Billing.PaymentMethod.ACSS_DEBIT,
};
options.PaymentMethodTypes = paymentMethods;
}
var paymentIntent = _paymentIntentService.Update(paymentIntentId, options);
This failed with:
Some of the parameters you provided (payment_method_types) cannot be used when modifying a PaymentIntent that was created by an invoice. You can try again without those parameters.
- Modify PaymentIntent to set off_session:
var options = new PaymentIntentUpdateOptions();
options.SetupFutureUsage = "off_session";
var paymentIntent = _paymentIntentService.Update(paymentIntentId, options);
This guts the existing payment intent, removing the last_payment_error section and charges section, makikng it worthless.
- req_SpXXv9cypOu19a
- pi_3NqotPAUoPbSaQbf28bHnu4t
- cus_Oe75ZlUoJaGuNK
1/ You can change payment_method_types so that's expected and I never said to do this right?
2/ I don't really get what all you mean, did it work or not, what's worthless?
3/ Is this a separate discussion?
Sorry, the payment method type change is part of this, which is a separate but related discussion. Pasted the from notes. What's worthless in the 2nd example there is that if one modifies an existing payment intent that had a last_payment_error section and a charges section, they get eliminated, basically destroying that payment intent's content.
sorry for #1 I meant you can not my bad
if one modifies an existing payment intent that had a last_payment_error section and a charges section, they get eliminated, basically destroying that payment intent's content.
why is that an issue though? Every new attempt destroys the previous attempt, I don't really get what the problem is. But that's the only way
If we modify the payment intent, and the charges section is gone, there's nothing left to charge, and if the last_payment_error section is gone, and the customer decides to cancel mid-transaction, all of that history is gone for later. That payment intent doesn't know what it's for, why it failed or what charges are associated with it.
These are existing payment intents, created previously, and failed. That failure data is still needed, as is the charges section.
what do you call "the charges section" I really don't get it
And not sure it's really a feature request, as the documentation seems to show it's available (setup_future_usage). Seems like more of an ommision in confirmPayment.
The documentation for Stripe.js confirmPayment says to refer to the PaymentIntent API to see all confirm params for use during the confirmPayment call (https://stripe.com/docs/js/payment_intents/confirm_payment#confirm_payment_intent-options-confirmParams).
Charges and last_payment_error sections from an invoice with expanded payment intent:
charges was removed a year ago and replaced by latest_charge: 'ch_123'. But it was really just a sublist with the most recent Charge attempt if any. The information has not disappeared, you can still use the List Charges API https://stripe.com/docs/api/charges/list and pass payment_intent: 'pi_123' to list all Charge(s) associate with that PaymentIntent
ok, how about last_payment_error. In my testing, that gets removed on modification of the payment intent.
sure and that's normal and that shouldn't be a problem, since you have the Charge with the failure already right?
My thought is that if we modify the payment intent, and it removes needed info, it won't render/charge correctly when it's time to pay. Though I don't recall testing this specifically after modifcation, it just seemed like too much info was removed from it. Let me go back and look at the payment intent I referenced above in the second test.
yeah that's absolutely not a thing that would happen
While we talked I built 2 separate repro and clearly see that setup_future_usage can be passed to confirmCardPayment() and not confirmPayment(). This isn't a documentation issue per se, it is a feature request
OK, yep, it does look like there's still fee data, etc., in at least that sample above. I'll explore that more to confirm.
On the docs issue, it says refer to the payment intent API to see a full list of confirm parameters, one of which is setup_future_usage. And regardless, seems like it should still be there, even if it is a feature request. It's functionality that isn't in that component which was in confirmCardPayment.
Now though it's separate, but related, how about #1 sample above where I want to add additional allowable payment methods to an existing payment intent that was originally set up with just card, so it renders the additional in the Payment Element? Any way to make that happen?
I mean we could add support for it, we just don't support it and for now we do not plan to support it. So if you want support for it it is a feature requests and you would have to reach out to our support team to flag your interest for that feature request: https://support.stripe.com/contact
As for the second question: https://stripe.com/docs/api/invoices/update#update_invoice-payment_settings-payment_method_types
Ah also const response = await stripe.confirmPayment({ elements: elements, confirmParams: { // does not work // setup_future_usage: 'off_session', return_url: `${window.location}`, payment_method_options: { card: { setup_future_usage: 'off_session', } } }, }); works for me, someone on my team shared it
OK, cool. I'll try that.
On the invoice modification for payment method types, I don't think I tried that yet, will try, but what about a payment intent that is not associated with an invoice? (we carete these for one-off charges for services where a customer does not have an active subscription, and no invoice is created either).
but what about a payment intent that is not associated with an invoice?
then you can updatepayment_method_typesalready and wouldn't hit the error you mentioned
OK, very well. Lots to try here. I appreciate the lively discussion and help. Will report back if still issues. Thanks.