#ernezto_api

1 messages ยท Page 1 of 1 (latest)

calm jayBOT
#

๐Ÿ‘‹ 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/1225856140848664709

๐Ÿ“ Have more to share? Add more details, code, screenshots, videos, etc. below.

pseudo lanternBOT
simple heron
#

Hi ๐Ÿ‘‹

I'm having a little trouble following what you are doing with the requests. The Payment Method is added to the Customer using the Billing Portal.

Then you are attempting charge it and it fails due to a missing mandate?

#

First question, the Billing customer portal is used to manage payments for Stripe billing (E.g. Subscriptions and Invoices). Are you attempting to use it to collect payment methods for other reasons?

crude blaze
#

Well, essentially I understand that the mandate id is required. But in our case, how to do control the mandate id? We open the customer portal for our users and let them add any of the supported payment methods. But we're not registering anything on our end (at least not yet) then we use the API to get the payment method information (the default one) and create a payment intent with it

#

The only purpose of the Billing Customer Portal is to collect payment information, that's correct

simple heron
#

Okay that is not how you should be using the Customer Portal in this case and I think that is the cause of the problem.

crude blaze
#

I see, what should I be using instead?

simple heron
crude blaze
#

So, I guess the mandate id be available in the checkout session we get via webhook call or synchronously with the redirect url, right?

#

Yeah, ok I see that the SetupIntent has the information in it

simple heron
#

So something like setup_intent = stripe.SetupIntent.retrieve(set_XXXX, expand=['payment_method'])

crude blaze
#

Understood. Thanks for that info. There is a follow-up question tho. I would still like the customer to handle its payment preferences. Is there a recommended way to do that without the Billing Customer Portal?

simple heron
#

By "payment preferences", do you mean setting a different payment method as the default?

crude blaze
#

exactly

#

If the customer wants to change the payment method we rely on the portal to allow the user to manage that information. But it seems like this is not the way to go.

#

We also have historical data (meaning users that already have a payment method with it's mandate id) and then isn't clear how to handle the migration to now be able to save the mandate_id on our end for upcoming payments

simple heron
#

For the historical data, can you share a Payment Method ID I can review?

crude blaze
#

well, this is not for a specific stripe subscription. We have an accounting system that uses stripe for many things but one of them is to collect money from subscriptions created internally in our software

#

here is an example: cus_M0JyYvtbsijuht

simple heron
#

Right, I'm thinking about the Payment Methods and how you can get the mandate ID from the PM and use it when generating Payment Intents.

crude blaze
#

that's been my attempt the whole morning, trying to figure out if there were a possibility of fetching the mandate id from the PM (which seems possible in the UI were I can see it gets aggregated) but not using the API

#

or at least none that I could find

simple heron
#

Correct, I'm not seeing a field where you can access this via the API.

crude blaze
#

yes, that was part of the testing, I tried using the mandate_id visually copied from the UI

#

but for thousands of customers, it's not feasible to go one by one in the UI and save the mandate_id into our system.

#

this could also represent a great disruption to some of our existing clients who expect us to reuse their customer's payment methods without any manual intervention, which is possible for credit/debit cards but for banks it seems we're hitting a wall

simple heron
#

Yes that makes sense. This is why I'm somewhat confused by the behavior because we usually pass the mandate on our end.

simple heron
#

Unfortunately I cannot view that link since it's unique to your dashboard

crude blaze
#

Would you say this is a fair summary of what we chat today:

  • To attach payment methods to a customer we should switch to the checkout session and drop using the customer billing portal
  • If a customer wants to change the payment method we can kick off the checkout session again in setup mode and rewrite the information
  • If the payment method is a bank (or anything that requires a mandate id) we should save that information on our end for future reference (there is no way to get it back after it)
  • For pre-existing payment methods that require a mandate id we cannot reuse them and should be re-entered by the client (big concern here)
simple heron
#

I think that is a fair summary but I still want to check on some things

crude blaze
#

Do you mean creating a payment intent with that pm?

simple heron
#

Yes

#

In Test mode

crude blaze
#

pi_3P2HLZBnWDNfT9Wn1X0SnEWf

simple heron
#

Okay, so that was successful

crude blaze
#

but I know the mandate_id upfront which is not the case for pre-existing customers we have

#

if I try the way we're using it now for credit/debit cards without the mandate id it will fail

simple heron
#

OH, I was asking you to test just passing the payment method via the API

crude blaze
#

{
"error": {
"message": "A mandate is required. Please either provide the id of an existing mandate on confirmation, or provide payment_method_options[acss_debit][mandate_options].",
"message_code": "acss_debit_provide_mandate_explicitly",
"request_log_url": "https://dashboard.stripe.com/test/logs/req_2Yqqh9O64ojf4F?t=1712341297",
"type": "invalid_request_error"
}
}

#

the payment_method_options parameter sounds appealing, but from what I understood, the information we should pass through is relevant when you have a checkout session or a user intervention, which is not the case for us

simple heron
crude blaze
#

I think I was trying to reference this part of the payment intent

simple heron
#

Ah, yes. That is specified in the Custom flow section of the ACSS guide

crude blaze
#

Given majority of our customers consented to be automatically debited I wonder if mandate_data.customer_acceptance.offline is a valid argument we can send, especially for customers that come as historical data

simple heron
#

That definitely could be a valid approach! I wasn't sure how much coding you wanted to do on your end.

crude blaze
#

well, we have the Java implementation already in place for the PaymentIntent, so adding an extra parameter shouldn't be a problem. I was hesitant about the approach tho

simple heron
#

Okay, in that case I think that approach would be ideal for your situation and alleviate that last pain point

crude blaze
#

So, if I understand correctly, by sending the mandate_data.customer_acceptance.offline value I'm "bypassing" the mandate_id requirement assuming that we have an offline agreement with the customer at hand, is that correct? I wonder if there is an easy way to test it

simple heron
#

Correct

pseudo lanternBOT
crude blaze
#

I'm testing this out quickly using the Stripe CLI and this command but I'm not getting success responses

#

tripe payment_intents create --amount "2000" --currency "cad" --customer "cus_ODQ2iNpfVPJCes" --confirm "true" -d "automatic-payment-methods[enabled]"="true" --return-url "http://example.com" --payment-method "pm_1P2FLUBnWDNfT9WnvA6cO8Ap" -d "mandate_data[customer_acceptance][type]"=offline -d "mandate_data[customer_acceptance][offline]"=true

ocean vine
#

Hi taking over here

#

What's the issue with your cli command exactly?

crude blaze
#

Hello, thanks for jumping in. I think what we were trying to quickly prove is if it's possible to create a payment intent for a payment method that requires a mandate by sending the offline information in the mandate_data dictionary

ocean vine
#

So what was the problem with that command

#

what was the error

crude blaze
#

it should contain information about the offline acceptance but it requires no parameters...I'm a bit confused..

ocean vine
#

Oh I don't think you should be passing mandate_data actually

#

Scrolling up I see the error message you originally got was: A mandate is required. Please either provide the id of an existing mandate on confirmation, or provide payment_method_options[acss_debit][mandate_options].

crude blaze
#

oh, because this is specific for acss_debit I guess?

ocean vine
#

yeah

crude blaze
#

ok, but then still the question remains open to me regarding the best way to reuse payment methods attached to existing customers that were not setup using at platform and require a mandate_id to create a payment intent

#

is stripe open to consider an api implementation to support this?

ocean vine
#

best way to reuse payment methods attached to existing customers that were not setup using at platform
what do you mean by this

crude blaze
#

ok, sorry if I'm not explaining correctly. We have clients that connect their stripe accounts to our stripe. They come with customers that already have payment methods attached to them. Our clients expect that we can reuse those payment methods to keep charging their customers but instead of using stripe subscriptions we charge amounts based of invoices created in our system. When these customers have PMs that require a mandate id to be sent in order to create a payment intent there is no way we can use those right now. We haven't been able to find a way to fetch the mandate id associated to any of those PMs

ocean vine
crude blaze
#

Yep, that could work for new subscriptions. For pre-existing ones tho, it's very hard to tell our clients that their customers have to reenter the payment information. I do see a few of our clients churning from our services if we deliver that message

ocean vine
#

Why would that not work for pre-existing?

#

Also you're saying subscription now

#

I thought you were charging via payment intents?

crude blaze
#

sorry for the confusion, by subscriptions I mean new customers subscribing to our platform and registering for automatic payments via stripe

#

Why would that not work for pre-existing?
if there is a customer with a payment method entered using which ever way we didn't control at that time. We cannot access programmatically to the mandate id associated to the existing payment method

ocean vine
#

The link I shared above shows you how to

#

You need to list setupintents by that customer

#

Or payment intents if it was collected via a payment intent

#

Then grab the mandate id from those objects

#

Unfortunately there's not a list mandates endpoint

#

But the payment method in your sample request you shared earlier: pm_1P2FLUBnWDNfT9WnvA6cO8Ap was created via a setupintent

crude blaze
#

so, as long as they have been charged at least once with that payment method, we should have the mandate id whether on the PaymentIntent -> charge or the SetupIntent

ocean vine
#

yeah

#

if payment method was created via a setupintent, they wouldn't need to have a charge

#

you'd just grab mandate from the setupintent

#

setupintent isn't a charge

#

It's just a way to set up a payment method for future use

crude blaze
#

I see, that's the link I think I've been looking for. Thanks a lot for the patience and all the clarifications.

ocean vine
#

No problem!

#

It's a common piece of feedback we get that we need to add a list mandates endpoint

#

Unfortunately I have no idea when it will be implemented

crude blaze
#

I guess there is a good reason why is so low in priority, but at least this chat saved me a lot of headaches. I've been trying to find the correlation for a few hours already

ocean vine
#

Glad we could help

crude blaze
#

well, that's all on my end for now. Thanks again for the help and have a great rest of the day!