#shashankbk-currency-restrictions
1 messages ยท Page 1 of 1 (latest)
Hi there ๐ some types of payment methods have country or currency limitations. Looking at Afterpay as an example, it's availability is restricted based on the country that your Stripe account is based in:
https://stripe.com/docs/payments/afterpay-clearpay#domestic-transactions-only
Hello, we've already gone through this document. Afterpay is supported in CAD.
Hello ๐
Give me a moment to catch up here and I'll respond as soon as I can ๐
Sure, thank you.
Can you share the version of the SDK you're running?
one second, let me get this for you.
Here you go.
@stripe/stripe-js": "^1.11.0",
"expo-payments-stripe": "^8.2.3
"expo-stripe-checkout": "^1.0.1",
"expo-stripe-purchase": "^1.2.3",
"stripe": "^8.129.0",
Thanks! taking a look ๐
Just for some additional context for you. When we generate a build for android, google pay does not show up as well. (I have the google pay app installed on my phone and have mutiple valid cards in it). We have not tested an IOS build, but I assume it might be a similar issue.
how are you testing the app exactly? Apple Pay/Google Pay aren't supported in expo go
there are a few limitations with expo <> stripe
https://docs.expo.dev/versions/latest/sdk/stripe/#limitations
Yes, this part is clear, we know that apple pay/google pay are not supported in expo go. So we generate an apk for android to test it.
are you seeing any errors in your logs related to GPay/wallet?
I'm checking with the team about the logs but I don't think so, when we're creating the payment intent on our backend server - we're able to see all the payment method types - cards, afterpay and canadian pre auth debit. Just that it does not show up in the front end on the payment sheet.
Its pretty weird because when we create a payment intent with the curreny type as EUR then all the different methods that support EUR show up on the payment sheet. Only when its set to CAD, it only shows cards.
This is with EUR
This is with CAD
these are the payment methods enabled in our stripe dashboard.
I suspect this is somehow related to expo (could be wrong) but would need a deeper investigation
Can you write in to support@stripe.com and provide as much as details as you can like example PaymentIntent IDs as well as a sample test app that we can use to reproduce the issue?
Right, that makes sense. We can compile this information and send it over to the support email.
Our developers are based in India and are away for the day. I can get this done monday am EST time.
Are you testing it from India as well?
Google Pay in India isn't currently supported via Stripe
They have been testing from India, but I have the build as well (based in Toronto) and it does not show up for me as well.
Even afterpay/canadian pre auth debits dont show up for me.
Let me ask you a question, if we were to use manual implementation of the payment methods as opposed to using the payment sheet, do you think it might work for us ?
So we can have custom buttons on our checkout screen for google pay or afterpay etc and integrate them individually.
You could try that, yes. However, if you're testing it from Canada PaymentSheet should show these PaymentMethods if everything is configured correctly.
Yes, so if there was something wrong with our config then when we set the currency to EUR then nothing other than cards should have showed up right ?
But all methods that support EUR show up perfectly.
Yeah I think so but would need to dig deeper to make sure ๐
Yes, that makes sense.
Just a final question for you on direct charges. So the scenario we're looking to implement is
User pays on our platform
Money goes into connected stripe account
Stripe Fees deducted from connected stripe account
Our platform fee comes to our stripe account (application_fee)
I understand we have to use direct charges for this, so when we create the payment intent should we be using the on_behalf_of field to make this happen ?
Hi ๐ I"m stepping in as @scarlet lodge had to run. You don't need to specify OBO for Direct Charges since the charge already occurs on the Connect Account. So as far as the Customer/Bank is concerned the Connect Account business is the one creating the charge
Hello @calm orbit - when we tried to do this without OBO it was saying there is client secret mismatch on the front end.
OBO should have no impact on this. This has to do with the API keys used for both back and front end code
With Direct Charges you make the request specifying the Stripe Account header.
You need to do the same thing when initializing Stripe.js
https://stripe.com/docs/js/initializing#init_stripe_js-options-stripeAccount
So we're using the same keys. This is the code we're using to create the payment intent.
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://dashboard.stripe.com/apikeys
const stripe = require('stripe')('our secret key');
const paymentIntent = await stripe.paymentIntents.create({
amount: 1000,
currency: 'cad',
application_fee_amount: 123,
}, {
stripeAccount: '{{CONNECTED_STRIPE_ACCOUNT_ID}}',
});
Sign in to the Stripe Dashboard to manage business payments and operations in your account. Manage payments and refunds, respond to disputes and more.
We're specifying the connected stripe account ID here.
In this situation where is the payment intent being created ? In the connected stripe account ?
Okay so yes the Payment Intent is created on the Connect Account and that is correct for Direct Charges.
So this means you should just need to provide the Stripe Account when initializing Stripe.js on the front-end. The error you are seeing is because Stripe.js is trying to confirm a Payment Intent on your Platform account.
So we're a marketplace business so we have many buyers and sellers on our app. All transactions are made on our app.
So a user can buy from multiple sellers, so are you saying in the front end we need to have all their stripe account keys ?
That doesn't sound like a Direct Charge situation. The design for Direct Charges is that the end-customer deals most directly with the Connect Account and the Platform is behind the scenes.
Destination Charges is more designed for a scenario where the end-customer engages with the Platform but the goods/services are provided by the Connect Account
what does the on behalf of field do actually ?
It changes the "settlement merchant" or the account who is responsible for settling the charge and/or any associated refund
so in this case as well I'll have to use stripe ID of the connected account in the front end ?
Because of how you are creating the charges, yes. In that case you may need to defer the initialization of Stripe.js until you know the Connect Account
Oh man, so this direct charges won't work with our marketplace model.
So with destination charges I have a couple of questions:
- How do i make sure that the connected account is responsible to pay the stripe fees ?
- How can I make the connected account responsible for refunds ?
I think you should review the matrix we show here to perhaps reconsider what account/charge types you use
https://stripe.com/docs/connect/accounts
For your specific questions please review the docs we have for each charge type and pay special attention to the Funds Flow diagrams as they explain this in detail:
https://stripe.com/docs/connect/charges
Thanks for sending me this diagram, it makes sense to me. But it brings up a couple of questions.
-
i want to make sure that the connected account is responsible to pay the stripe fees. In the destination charges model, our acount is responsible for the stripe fees. I can deduct the amount before sending it to the connected account. But my question is, how will I know what the stripe fee amount is while creating the payment intent ?
-
In the case of refunds, I see that our account will be responsible for processing the refunds. I see that there is a parameter to reverse the transcation as well. So what is the order in which the transcation occurs ? Does the charge first get reversed from the connected account to our stripe account and then the refund is processed after ? The reason this is important to us is because we may not have the funds in our stripe account to process the refund. How do we deal with this situation ?
Hi @flint latch, sure no problem.
Okay so for your two questions above:
- You won't know and imo you shouldn't try to pass these fees on perfectly. You should just build it in to how much you keep from each charge. Otherwise, you want direct charges + Standard accounts.
- Yes you can reverse the associated transfer when you refund via: https://stripe.com/docs/api/refunds/create#create_refund-reverse_transfer. The reversal is a separate balance transaction from the refund itself but we won't fail the refund if your balance is negative... we will just hold the refund in pending if your balance is too far in the negative. So effectively yes, you can count on the reversed funds for the refund.
Okay on point 1, this is why we chose direct charges. But it seems like when I create a direct charge payment intent, the front end should have the associated client secret from the connected stripe account ?
Yes that's correct.
Are you having an issue there?
It is the client secret from the PaymentIntent that was created on the Connected Account. You still have access to this as the platform.
Is there a way to get this client secret when I'm making the payment ?
how do I get this ?
When you create the PaymentIntent on the backend the clientsecret is returned with the PaymentIntent object: https://stripe.com/docs/api/payment_intents/object#payment_intent_object-client_secret
ohhhhhh I see and I need to use this client secret when we make the payment on the front end then ?
Yep.
You want to read through https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements if you haven't.
so the mistake we've been making is that we were using our clinet secret on the front end while we were creating these charges.
You mean you were creating the PaymentIntnets on your platform instead of the Connected Account?
So we did this..
const paymentIntent = await stripe.paymentIntents.create({
amount: 1000,
currency: 'cad',
application_fee_amount: 123,
}, {
stripeAccount: '{{CONNECTED_STRIPE_ACCOUNT_ID}}',
});
This I assume creates the payment intent on the connected stripe account.
while accepting payments on the front end, the client secret we had been using is ours and not the connected account I think
Just for context we're a marketplace business with multiple sellers.
and we want to be able to process payments through our app, but we want the charges to be made directly on the connected accounts
I think you are mixing up client secret with publishable API key
You can't mix up client secrets....
This is the error we get.
Unless you somehow have the client secret from the wrong PaymentIntent.
Right
That error is due to API key
Not client secret
So when you initialize Stripe on the frontend you need to still use your publishable key but also pass the Connected Account. See: https://stripe.com/docs/connect/authentication#adding-the-connected-account-id-to-a-client-side-application
You are doing this server-side already by passing stripeAccount: '{{CONNECTED_STRIPE_ACCOUNT_ID}}',
And you mirror that client-side when you initialize stripe
I see, so in our situation we have multiple sellers on our platform. Will we have to initialize all their accounts ?
Yes
You would pass the corresponding account ID for which you are creating the payment
When you initialize stripe client-side.
You can initialize multiple times if needed.
is this something that is dynamic that I can do at the time of payment ?
Sorry for these questions - my development team is based out of india and they're asleep so I'm just filling in for them and trying to figure this piece out.
No problem! We are here to help!
Yes you can init at time of payment. It will depend a little bit on your UI.
For instance, Payment Element can't be rendered without a clientsecret
So you will need to know the Connected Account that you are creating a payment for when the customer sees Payment Element.
So for example in this situation:
Let's say there are 2 sellers on our platform and 1 buyer.
Let's assume that the buyer wants to buy things from both sellers.
The user would come onto our app, select Seller 1, pick the items and pay. We want this to be a direct charge to the connected account of seller 1
Once that is done then the user selects seller 2, picks the items and pay - again we want this to be a direct charge on our platform directly in the connected account for seller 2.
All this happens in our marketplace app.
Is this scenario possible with direct charges ?
Yes but with that scenario you actually want to collect the PaymentMethod on your platform and then clone it to your Connected Accounts so that you only have to collect the payment method from the Customer once. See: https://stripe.com/docs/payments/payment-methods/connect#cloning-payment-methods which discusses how to clone a payment method.
why would we need to clone the payment method ? So we're not creating customers as it is optional. Assume users payment methods will not be stored.
Well you don't have to. But why would you want your customer to have to input the same card details twice?
Right I understand that, but before we go there (which is more about convenience) I'm just trying to get the direct charges to work and then we do next steps.
Well the flow will be completely different if you aren't going to clone versus if you are.
So you should decide this ahead of time.
Else you are going to do a lot of extra work to change to cloning later.
I mean it is fine if you don't want to go that route... just making you aware of the options.
Right I understand this and we will probably do the cloning piece, but in terms of direct charges. We have to specify the connected stripe account ID when we create the payment sheet and we can do it dynamically for each transaction. IS that correct ?
Does the payment intent return the necessary parameters to use in the front end for this ?
Yes that is correct.
Yep, all you need is the client secret (to pass to confirmPayment()) and the account ID (to initialize stripe using the Connected Account)
Okay this makes sense to me. Is there a doc that shows the parameters returned from the payment intent so I can show my developers which field to use ?
Yep it is all in the API reference: https://stripe.com/docs/api/payment_intents/object. But really they should just follow our guide here: https://stripe.com/docs/payments/accept-a-payment and include passing the Stripe Account as we discuss here: https://stripe.com/docs/connect/direct-charges.
Those guides discuss all the necessary parameters.
this makes a lot of sense to me. I think the issue here is just that our front end developer is not using the connected account ID and is instead using our stripe account ID.
while creating the payment sheet.
Yep they just aren't passing the Connected Account ID when initializing Stripe
Which leads to the error you are seeing since the PaymentIntent isn't on your platform account so you get the "doesn't exist" error
Exactly. THANK YOU SO MUCH for helping me with this. I'll pass this along to them and hopefiully we should have this working.
Happy to help!
If we run into any issues I'll reach out. THANKS A LOT!!
We'll be here!