How to set commission fee on stripe while Creating Separate Charges and Transfers? - node.js

How to set commission for Buyer & Seller both using stripe connect. I am using https://stripe.com/docs/connect/charges-transfers.
we want to hold money on our stripe account until job completed by seller. The amount is submitted by client(buyer) to out stripe platform .then, on job completing, it would be transferred to seller stripe account. (how to set commission for both while creating charge by the client(buyer) to our stripe platform account )?
input : Only pass application_fee without accountId
let chargeEntity = await stripe.charges.create({
amount,
//description: "Sample Charge",
source: sourceTokenId,
currency: currency,
customer: customerId,
application_fee_amount:application_fee,
//on_behalf_of:accountId
});
output :
"message": "Can only apply an application_fee when the request is made on behalf of another account (using an OAuth key, the Stripe-Account header, or the destination parameter)."

If you're using separate charges and transfers, there's no ability to pass an application fee.
Instead, simply withhold the funds you'd like to keep on your platform when you create the transfer, calling stripe.transfers.create. For example, if you created a charge for $100, only transfer $90, your platform retains $10 (minus any Stripe fees on the original $100 charge).
If you would rather use application_fee_amount, look at the destination payment flow; you could create the charge with destination but pass capture: false and then capture funds once work is completed.
https://stripe.com/docs/connect/destination-charges#application-fee

Related

Which payment method to use for Stripe Payment intent

I'm trying to auto charge customers on stripe in NodeJS
I have an issue where some customers have a:
default_source
and some have
invoice_settings.default_payment_method
My current workflow (C# WPF):
Create customer + Add subscription to customer
Get URL for portal
Customer adds card details on stripe portal
This works fine and payment are running well.
I also charge for SMS fees using a nodejs api:
async function chargeSMS(stripeCusID,chargeValue,chemistName,chemistID,countSMS){
//console.log(stripeCusID);
//console.log(chargeValue);
let customerObject;
let payMethodID;
customerObject = await stripe.customers.retrieve(
);
console.log("PaymentID received:" + customerObject.invoice_settings.default_payment_method);
payMethodID = customerObject.invoice_settings.default_payment_method;
await stripe.paymentIntents.create({
amount: chargeValue,
currency: 'aud',
customer: stripeCusID,
description: 'SMS Charges: ' + countSMS + " sent",
payment_method: payMethodID,
confirm: true
},
function(err, response) {
if (err) {
console.log("Charge", err.message,stripeCusID,chargeValue,chemistName);
return;
}
console.log("Successful SMS Charge:", response.id,chemistName);
chemCharged(chemistID);
})
}
This has also been working fine as a Cron on 1st of each month.
My issue is that recently one of my customer's cards expired.
They used my WPF to open the portal and add a new card
This worked.
HOWEVER this new card on the portal is only listed as
customer.default_source
Their
invoice_settings.default_payment_method
Is now null!
So my code above fails.
I've checked and:
All new customers using portal have their cards saved as invoice_settings.default_payment_method
any time a customer adds a new card it is only added as defult_source
I ahve no idea why this is the situation but I'm using the stripe customer portal so i would have thought they would add in the same way!
Any ideas how I can fix this or figure out what I've done wrong?
On the stripe web portal (my business) I can see that this customer DOES have a default card, and it looks the same as any other customer, but the api side has it registered under the different section!
You can add the Card as the Customer's invoice_settings.default_payment_method yourself by calling the Update Customer API.
FYI in a subscription the precedence chain is:
Subscription's default_payment_method
Subscription's default_source
Customer's invoice_settings.default_payment_method
Customer's default_source

Creating a subscription using bank account number using stripe js in node js

I have created subscription by accespting credit/debit card number, exp month, exp year and cvc from front end angular app and creating
Customer
Product
Product Price
Payment Method
Subscription
In payment method i provide following details:
async function createPaymentMethod(data) {
let body = {
type: 'card',
card: {
number: data.card?.number,
exp_month: data.card?.exp_month,
exp_year: data.card?.exp_year,
cvc: data.card?.cvc
}
};
return await stripe.paymentMethods.create(body);
}
Now i want to create payment method but want to use customer's bank account number but i am unable to find a way to do it. I want to add "type: bank_account"
Note: I am using Strip JS and Node JS. All of this I want to do on server side i.e node js
Collecting Credit Card server-side is a bad idea, since you will expose yourself to the burden on PCI-Compliance. You would want to review Stripe's Integration Security Guide. Generally you would want to use client-side SDK to collect credit card information instead.
To the question of a bank account, it depends on which specific PaymentMethod you're gonna use (which country's bank transfer?) Ie. If you are talking about ACH in the US, you should follow the ACH Guide. Similarly it will collect bank account information client-side in exchange of a token, then passing it up to your back end.

Stripe adding paymentMethod to trial subscription and later validate credit card

I'm working on stripe integration with react node.js
While creating a subscription without trial, I have no issues, and all use-cases are much simple.
But, I'm trying to create free trial without collecting credit card details, later when trial expired, I would like to collect credit card details
Server side: Creating Trial Subscription without payment method:
const subscription = await stripe.subscriptions.create({
customer: customer.id,
items: [{ price: priceId }],
trial_end: expiredAt.unix(),
expand: ['latest_invoice.payment_intent'],
});
ClientSide: Later when trial expired, I would like to collect credit card details(paymentMethod), check if user action is required due to failures or 3ds and update the subscription by updating the customer's default payment_method:
const updateCustomerDefaultPaymentMethod = await stripe.customers.update(
customerId,
{
invoice_settings: {
default_payment_method: req.body.paymentMethodId,
},
}
);
How can I update the subscription to perform paymentIntent or charge the user, and return to client same subscription object with status 'in_complete' same as when creating subscription without trial_period?
Currently when running my code, I keep getting status='active' because the first invoice is in status='paid' with price of '0$'.
In the case of a free trial, creating a subscription won't result in an initial payment, and Stripe will instead create a SetupIntent under the hood for you automatically. This SetupIntent is meant to be used when collecting the customer's payment method. So at any point during the trial, the customer would need to return to your app to enter their credit card details, which you would then save using the SetupIntent:
subscription.pending_setup_intent
Confirm the SetupIntent with the collected card details
Once the payment method is setup and saved to the customer (as the default payment method for invoices) it will be used to pay for the subscription's first invoice when the trial ends. The first payment after a trial is considered an off-session payment (last FAQ), so if that payment fails Stripe will attempt to recollect the payment using the usual smart retries and dunning functionality.
In a nutshell, you need to use the SetupIntent that's created (and attached to the subscription) to save the user's payment information.

How to collect billing address through Stripe Payment Request Button

I'm creating a payment request like this:
const paymentRequest = stripe.paymentRequest({
country: config.stripeCountry,
currency: config.currency,
total: {
label: 'Total',
amount: parseInt((paymentAmounts.totalAmount * 100).toFixed())
},
requestShipping: true,
requestPayerEmail: true,
requestPayerName: true,
// It seems this one is not working
shippingOptions: config.shippingOptions
})
Now I'd like to collect a customer's billing address. But the doc says:
Requesting the payer’s name, email, or phone is optional, but highly
recommended, as it also results in collecting their billing address
for Apple Pay. The billing address can be used to perform address
verification and block fraudulent payments. For all other payment
methods, the billing address is automatically collected when
available.
So how shall I collect their billing address with the payer's name, email or phone?
For Apple Pay, requesting one of name, email, or phone (which you're already doing via requestPayerEmail and requestPayerName) triggers billing address to be collected. For other payment methods, you don't have to do anything.
In other words, you're all set as-is.
https://stripe.com/docs/stripe-js/reference#stripe-payment-request
We highly recommend you collect at least one of name, email, or phone as this also results in collection of billing address for Apple Pay. The billing address can be used to perform address verification and block fraudulent payments. For all other payment methods, the billing address is automatically collected when available.

Must stripe destinations by account ids in order to make a charge

Is there anyway to make a customer be the recipient of a charge? From everything I see, it appears that the platform would have to create a stripe account for any individual that may receive charges on the platform. The following code works as long as the destination is a stripe account. Inside destination, I would like to be able to make the destination a customer instead of a stripe account, but I get errors when changing the destination[account] to destination[customer] as well as when I use a customer id in destination[account].
var arbitrary_charge = 100;
stripe.charges.create({
amount: arbitrary charge,
currency: "usd",
customer: stripe_customer_key,
destination: {
amount: .8*arbitrary_charge, //https://stripe.com/docs/connect/destination-charges
account: "acct_xxxxxxxxxxxx"
},
}).then(function(charge) {
console.log(charge)
})
There's no way to make a Customer the destination.
When developing a Platform there are two functions you're generally interested in, paying out and taking payments.
Stripe divides these functions up into separate object types: Accounts and Customers, respectively. You may have a case where you want to pay out AND take payments, in which case you'll usually want to create both a Customer and Account object for a given entity. Stripe also added a feature recently that allows you to debit from some Accounts.
to charge the customer and credit it to the connected account you have to do something like this
charge = Stripe::Charge.create({
amount: amount,
currency: "usd",
card: token.id,
description: "Charge for #{email}",
receipt_email: email,
}, {stripe_account: stripe_user_id})
stripe_user_id is the account id of the connected account of format "acct_xxxxxxxxxxxx"

Resources