Stripe difference between stripe.charges.create and stripe.transfers.create - stripe-payments

I have a platform account and some connected user account. So, I have account_id for each user. I want to send funds to some of the users. I searched in the stripe docs and saw two methods for doing this (maybe).
What is the different between stripe.charges.create and stripe.transfers.create ?
The first one:
const charge = await stripe.charges.create({
amount: 1000,
currency: "eur",
source: "tok_visa",
transfer_data: {
destination: "{{CONNECTED_STRIPE_ACCOUNT_ID}}",
},
});
The second one:
const transfer = await stripe.transfers.create({
amount: 7000,
currency: 'eur',
destination: '{{CONNECTED_STRIPE_ACCOUNT_ID}}',
transfer_group: '{ORDER10}',
});

A Charge [0] moves funds from a payment method (e.g. a Card) to a Stripe account. A Transfer [1] moves funds from one Stripe account to a connected Stripe account.
[0] https://stripe.com/docs/payments/charges-api
[1] https://stripe.com/docs/connect/destination-charges

Related

Stripe propagate paymentIntent description to Connected Account's transfer payment

I successfully created payment intents from a customer's card paying to a Standard Connected account using destination charge. In that payment intent created, I am specifying a description:
const paymentIntent = await stripe.paymentIntents.create({
amount: calculate_payment_amount(duration_minutes),
customer: "somet id",
currency: "usd",
description: `chat duration: 100`,
payment_method: paymentMethods.data[0].id,
payment_method_types: ['card'],
off_session: true,
confirm: true,
application_fee_amount: calculate_fee_amount(duration_minutes),
transfer_data: {
destination: "standard connected account ID",
},
metadata: {
metadata: "something
},
});
This payment displays the description if I view it from my platform's dashboard.
But if the standard connected account were to view this payment, the user won't be able to see the description (the same payment viewed from the standard account):
Is it possible to pass or propagate the same description of the payment intent to the same payment of the standard connected account?
Unfortunately, it doesn't look like it's currently possible to propagate the PaymentIntent description when creating destination charges. You would need to manually update the payment on the connected account with the description:
To do so, first, create the payment intent like you are doing now, except save the description as a standalone variable:
const paymentDescription = `chat duration: 100`;
const connectedAccountId = "acct_xyz";
const paymentIntent = await stripe.paymentIntents.create({
amount: calculate_payment_amount(duration_minutes),
customer: "somet id",
currency: "usd",
description: paymentDescription,
payment_method: paymentMethods.data[0].id,
payment_method_types: ['card'],
off_session: true,
confirm: true,
application_fee_amount: calculate_fee_amount(duration_minutes),
transfer_data: {
destination: connectedAccountId,
},
metadata: {
metadata: "something
},
});
Then, after the payment is confirmed, get the payment resulting from the transfer to the connected account:
const transfers = await stripe.transfers.list({
destination: connectedAccountId,
transfer_group: paymentIntent.transfer_group,
});
const paymentId = transfers.data[0].destination_payment;
The key above is that when you do a destination charge, Stripe will create a transfer and a payment (in the form of a Charge) to the connected account in the background. Here we're getting the transfer associated with the payment intent, and from that getting the associated payment. This is the py_xyz ID that you see when viewing the payment in the connected account's dashboard.
Then, update the payment to include the description:
const updatedPayment = await stripe.charges.update(
paymentId,
{
description: paymentDescription,
},
{
stripeAccount: connectedAccountId,
}
);
At that point the description will show in the standard account's payment view:

Stripe create a direct charge node.js

I am trying to create a direct charge to a standard Stripe connected account from a node.js backend. The codes I wrote are:
async function create_direct_charge(language_learner_id, native_speaker_id, call_duration) {
try {
const customer_id = "xxxxxx";
const connected_standard_account_id = "xxxxxx;
const paymentMethods = await stripe.paymentMethods.list({
customer: customer_id,
type: 'card',
limit: 1,
});
const paymentMethod = paymentMethods.data[0].id;
const paymentIntent = await stripe.paymentIntents.create({
payment_method_types: ['card'],
payment_method: paymentMethod,
amount: 1000,
customer: customer_id,
currency: "cad",
off_session: true,
confirm: true,
application_fee_amount: 100,
}, {
stripeAccount: connected_standard_account_id,
});
}
catch (error) {
console.log(error);
}
}
The above codes generate an error of: No such PaymentMethod: 'pm_xxxxxx'; OAuth key or Stripe-Account header was used but API request was provided with a platform-owned payment method ID. Please ensure that the provided payment method matches the specified account.
The thing is that the customer with the customer_id already has a valid payment method attached:
The payment method is valid, since I was able to create a destination charge with that payment method. The payment is not set as the default source though. I am wondering if that is the problem. What did I do wrong here?
The payment method is valid, since I was able to create a destination charge with that payment method.
That tells me that the PaymentMethod (e.g. pm_123) was created on the Platform Stripe account and hence lives there.
So when tell Stripe to "Charge pm_123 on Connect account acct_1 as a Direct Charge", that won't work as the PaymentMethod object pm_123 doesn't exist on the Connect account, it exists on the Platform account.
In order to get this to work, you have to first "clone" the PaymentMethod pm_123 to the Connect account, then create a Direct Charge with this newly cloned PaymentMethod token, as explained here: https://stripe.com/docs/payments/payment-methods/connect#cloning-payment-methods

How can batch multi charge from a different customer Stripe with Node.js?

I want to collect charge from group of customers and then make a transfer for connected account at the same time ,i search for something like Transaction or batch process in stripe but I don't find anything .this image explain what i want to make exactly
stripe.paymentIntents.create({
amount: 2000,
currency: 'eur',
payment_method_types: ['card'], },
function(err, paymentIntent) {
});
The recommended flow for n charges would be to create n PaymentIntents via the Stripe API. You would create a PaymentIntent for each of the Customers, and you can use metadata to connect them in your own system (Stripe tracks the key-value metadata pairs, and you can use those to reconcile each PaymentIntent against your own tracking of groups of Customers in each payment).
For example, if you have two (2) Customers that are evenly splitting amount: 2000 and the connected account's id is acct_123abc:
['cus_abc123', 'cus_xyz789'].forEach(customer_id => {
stripe.paymentIntents.create({
amount: 1000,
currency: 'eur',
payment_method_types: ['card'],
customer: customer_id,
transfer_data: {
destination: 'acct_123abc'
},
metadata: {
my_internal_id: 'internal_payment_id'
}
}).then(payment_intent => {
console.log(payment_intent.id);
}).catch(err => console.log(err));
});
});
You can use your own internal payment id in place of "internal_payment_id" from the metadata to tie each PaymentIntent to a payment in your own system.

Fund cannot be sent to accounts located in Us because its outside of your platform region

await stripe.transfers.create({
amount: amount,
currency: account.default_currency,
source_transaction: chargeId,
destination: accountId
});
from stripe account (uk) to Us stripe connected account
Stripe doesn't allow transfer to the outside of the platform region
You can use the following method to manage a business in multiple countries
First use stripe create charge API with destination charges
const charge = await stripe.charges.create({
customer: data.customer,
source: data.cardId,
amount: amount,
currency: user.currency,
description: process.env.APP_NAME,
statement_descriptor: process.env.APP_NAME,
application_fee: platformFee,
destination: accountId
});
After creating the charge, You can transfer that payout to that connected account using create payout API
await stripe.payouts.create({
amount: amount,
currency: currency,
}, {
stripeAccount: accountId,
});
This flow is working for me

When saving a customer in production, where to locate Stripe's source token

I am following Stripe's account here: https://stripe.com/docs/saving-cards
in particular where the customer information is saved:
(async function() {
// Create a Customer:
const customer = await stripe.customers.create({
source: 'tok_mastercard',
email: 'paying.user#example.com',
});
// Charge the Customer instead of the card:
const charge = await stripe.charges.create({
amount: 1000,
currency: 'usd',
customer: customer.id,
});
// YOUR CODE: Save the customer ID and other info in a database for later.
})();
in development I can input source: 'tok_mastercard' and it operates as intended, however what would the token be in production when using sk_live_... ? the doc is not clear so far as I can tell.
The token would be something you create client-side when you collect the card details securely either using Stripe Elements or Stripe Checkout. Those let you exchange card details for a Stripe Token with a unique id tok_12345 that you then send to your server to create the customer and the charge.

Resources