How to change destination of paymentintent in Stripe? - stripe-payments

I run a marketplace, where customers pay and reserve for a specialised service.
We use Stripe with Stripe Connect to handle payments.
In my business, we don't know who is going to do the job when the customer pay and it can even change several times. I tried to update the paymentIntent with no success, and the API documentation is not clear about the possibility.
Is it possible to change the destination of an existing paymentIntent ? And more precisely how?

Two options :
You could use Separate Charge and Transfers (SCT) where you charge the customer first and then transfer the funds to the service provider later. [0]
You could also use auth and capture [1] where you "reserve" the funds first with no destination (i.e. a charge on your platform). Once you know who the service provider is, you can cancel the charge, and then immediately create another charge and capture it with the correct destination.
[0]https://stripe.com/docs/connect/charges-transfers
[1]https://stripe.com/docs/payments/capture-later

Related

Taking fee and payment reservation Stripe

Pretty new to Stripe, we're building an online marketplace. Each user can buy assets from any other user. We also take fees for each payment.
We go with connected accounts. Seller goes through the onboarding flow (create connected account, create account link etc), while buyer is registered as a customer of our platform on Stripe.
Now, whenever buyer makes a payment we create a payment intent to pay to us (amount + 20% fee via):
stripe.paymentIntents.create(params)
Then we create new payout to seller (amount) using source transaction from payment intent above:
await stripe.transfers.create({
amount: payment.amount * 100,
currency: payment.currency,
destination: seller.stripeAccountId,
source_transaction: sourceTransaction,
});
Is this the preferred and best way of handling this? In terms of time, we need first to wait for payment to settle to our bank account to be able to payout seller?
Is there any better way of doing this instead of manual payouts?
Is there a way to make direct transfer to connected account when user does payment?
I tried with payment intent, specifying connected account id in request, but API is complaining that customer id is on our platform but account id is specified, so it's not possible obviously.
Also, manual payouts would come handy to simulate payment escrow/deposit. When user create a request for some asset, we would immediately transfer certain amount to our account, like reserving that amount. And if the seller accepts the offer, we would do a payout. If seller rejects the offer, we would do payout to the buyer, giving him back his money.
Does this make sense?
Thanks in advance
You don't need Payout (yet) in your use case. You are doing Separate Charges and Transfers, and fund simply moves from your Account's balance to Connected Account's balance. It hasn't been out of your Connected Account's balance to your Connected Account's bank account yet, which is called "Payout".
In another word, Payout is separated process than Charges and Transfers. Charges and Transfers can happen immediately, and Payouts normally happen later on a daily basis or manually.
Find more explanation on Connect Balance.
There is also Destination Charge which is simpler than Separate Charges and Transfers. I recommend Destination Charge unless you have specific reason to use Separate Charges and Transfers, ie. you need to transfer to multiple Connected Accounts on one payment.

Stripe Connect - share customers without payment method

I am currently hitting a roadblock implementing Stripe Connect into our platform. We want to allow multiple connected accounts to use our platform to sell some sort of tickets. For this we wanted to use Standard accounts with Direct Charges (since we want to take a cut and also not have to deal with refunds/disputes etc.).
On our end the end-user has to either select or create a customer on our platform (created in our Stripe account) and then provide their payment method details through Stripe Elements. The documentation states that you need to create a PaymentIntent for the connected account, but this is not possible while also supplying the previously saved customer (because the customer only exists on our platform).
Now another documentation outlines that it is possible to share customers between connected accounts. The issue with this is that for this step you already seem to need a payment method attached to the customer:
If your platform uses the Payment Methods API, you must create a PaymentMethod from that customer.
The linked documentation outlines how to clone payment methods of customers between linked accounts, but this once again assumes that we already have a confirmed/attached payment method.
So my question is: How can we allow customers to be shared between all connected accounts without having to supply a payment method first? After the first payment (and if the customer chooses to do so) we want to save (and later clone if necessary) this payment method for future payments on all connected accounts.
For normal payments you can create a PaymentIntent with a customer but without a payment method and only supply the latter on the client (in our case stripe.js)
Since you're using Standard accounts, you have to use Direct Charges when accepting payments on behalf of that connected account. This means that the PaymentIntent has to live on the connected account, alongside the Customer and the PaymentMethod if any.
If you want to re-use the payment method details for other accounts in the future though, the PaymentMethod itself and its associated Customer has to live on the platform account.
Unfortunately, there's no way to "clone" a PaymentMethod from the connected account back to the platform today. This means that you have to change your integration logic slightly and approach the overall flow differently.
The idea is that you first need to collect payment method details in the platform. Since you're not taking an immediate payment during that step, you want to use the SetupIntent API. This is the flow documented here that will let you create the SetupIntent on the platform and collect card details securely client-side.
Once you have this information, you will now have a Customer cus_A in the platform, with the PaymentMethod pm_123 attached to it. That is the first step of the flow.
Now, you want to accept a payment on the connected account. So you first need to clone the PaymentMethod on that account as documented here. That will give you a brand new PaymentMethod pm_xyz that lives on that connected account. You can then use that PaymentMethod to confirm a new PaymentIntent on that connected account and passing payment_method: 'pm_xyz' to attempt to charge that saved card.
Note that it is possible this requires a "next action" such as doing 3D Secure as it's on a different account which could come with different restrictions.
In the future, if that customer comes back and wants to pay another connected account, you'd do a new clone of the PaymentMethod on that account and a new PaymentIntent for that cloned card and you can repeat it each time they pay a new business.
It can seem a bit convoluted at first, but once you grasp the flow of all the objects it does make sense overall!

With Stripe, make an hold on a payment and confirm it when the subscription starts

We are working on a service that can start a subscription later in the future: users say today they want the service, but it actually starts some days later.
We are now collecting the payment method through a SetupIntent, which allows the user to verify they own card, but it actually doesn't verify the credit availability. When we collected the payment method, we create a scheduled subscription with the verified payment method; then, when the subscription starts, Stripe uses that payment method to collect money.
It happens, sometimes, that users do not have enough credit to pay for the service when the subscription starts. Otherwise, it also happens that, when Stripe tries to get money, the customer's bank requires 3D-secure verification.
Since our subscriptions start at midnight, we would like to avoid having to involve users again in the payment process.
So, we thought: would it be possible to immediately collect the payment method through an hold on a PaymentIntent and confirm that hold only when the subscription starts? I can't find a way to do this with Stripe (don't know if it exists). It seems impossible, with Stripe, to generate a PaymentIntent (with capture_method set to manual) for a scheduled subscription.
Do you have some ideas on how we can avoid payment problems when the subscription starts?
Otherwise, it also happens that, when Stripe tries to get money, the
customer's bank requires 3D-secure verification.
This shouldn't be the case if you complete any required 3DS authentication as a part of the SetupIntent confirmation flow. Call confirmCardSetup whilst the user is present and that way the payment method is successfully verified and can be used to process off-session payments for your subscription as you need.
You can use Stripe to place a hold on a card, but this generally doesn't apply to the use case you've described.
I found a workaround for this by first creating a paymentIntent with setup_future_usage="off_session" and capture_method="manual" to first place a hold and save the paymentMethod, and then, only after capturing this paymentIntent, creating a subscription using the newly saved paymentMethod with billing_cycle_anchor that equals your subscription's interval from now.
This way it's like your customer has paid for the first interval using the paymentIntent, but will be charged from the second interval using the subscriptions API, which allows you to cancel the hold on the first payment and not create a subscription if something goes wrong.

How to charge a customer and direct funds to another account

I am currently only seeing a way to charge customers to yourself based on https://stripe.com/docs/api/charges/object
. Is there any way to set the destination to another stripe account? Basically, charge a customer whos funds then go directly to another account? The platform is acting as a facilitator and is not intended to take control of the funds during this process, but instead simply move them from one custoemr to another.
This is what Stripe Connect is for: https://stripe.com/docs/connect/

Stripe API v3: When to use Invoice vs PaymentIntent (Node SDK)

I've been reading Stripe's api documentation (v3) and it's not apparent to me when to use Stripe's Invoice vs PaymentIntent objects. From reading the documentation, here's what I understand:
Stripe sees payment intents being the primary way of facilitating payments through their API going forward and Charges will be deprecated at some point.
Processing an Invoice creates a PaymentIntent under the hood and and initiates payment right away. What I don't understand is why is there no destination account field for the Invoice? If the Invoice is defaulted to be sent to the platform's Stripe account (this is an assumption I am making since there is no destination field), why there is an application_fee_amount field which is essentially the platform's "cut" of the transaction?
A PaymentIntent allow you to specify a destination account while taking an "application" or "platform" fee so you don't have to generate a transfer yourself.
A PaymentIntent and Invoice can be processed at time of creation or deferred until later in your payment lifecycle.
My use case requires me to conduct payments between two parties and take a "platform fee" for each transaction. I have successfully done this by creating a PaymentIntent and using the connected Customer account's credit card on file and populating the transfer_data field with the amount to send to the 2nd party involved in the transaction.
I started looking into Stripe's invoicing api since I am planning on building an invoicing solution for my platform and thought it'd be best to leverage what Stripe has to offer, but I'm failing to see a benefit for me to leverage it since I also need to keep track of transaction ids for the payment intents and taxes based on zip code (it looks like Stripe doesn't do this automatically so I might be out of luck here).
I couldn't find a way to get a transactionId for processing an Invoice but I see that the chargeId gets returned as part of the response when you confirm a PaymentIntent (https://stripe.com/docs/api/payment_intents/confirm).
So the questions I have are:
Why is there no destination account field for the Invoice? Does it automatically get send to the platform's Stripe account and require you to manually create a transfer?
Is there an easy way to get a transactionId from an Invoice?
Is there a way to get a transactionId when creating a PaymentIntent and setting the confirm=true so the PaymentIntent gets processed immediately?
For a platform that will have an invoicing flow and facilitate transactions on behalf of two parties, is it recommended to use payment intents, invoicing, or both?
What's the difference between a charge and transaction? When paying an Invoice, a charge id gets returned in the response but when paying a payment intent, a transaction id gets returned.
Thanks in advance!
You can think of invoices as subsets of payment intent, kind of the same way subscriptions are subsets of invoices.
What I don't understand is why is there no destination account field for the Invoice?
Actually there is one, but the field is transfer_data[destination]. Also, note that whenever an invoice is finalized, it will contain a payment intent, which is expandable, and with which you should be able to solve most of the issues you rose in your question.
To sum up:
Yes there is, as explained above.
Expand the invoice's payment intent object.
I'm not used to work with transactions, but I guess you could leverage their metadata to reference your invoice or vice verse to help you retrieve the need object in needed time.
As explained above, their is not dichotomy between those, if your invoicing your clients, the you should use stripe's invoicing system.
From what I see in the docs, transactions only concern purchase 'internal' to stripe, with issued cards. Charges are the attempts stripe will make to charge your bank account through the network, when a charge succeeds, the payment intent status is set to succeeded otherwise the payment intent might attempt more charges or stop trying at some point, and the payment intent will be set to canceled more about payment intent statuses here. In short payment intents are a subset of charges.
I hope this helped and didn't come too late, the answer might still be improve in the future, if others edit it or as I will learn more about stripe's issuing product.

Resources