18

Regarding Stripe fee calculation, is there is any way to get the Stripe fee according to the amount provided.

We have to implement this in such away that, we have to pay x amount to one dealer and y amount to another.

1st case:

Let say we have $100 to pay to Stripe.

According to our needs, we want to calculate the Stripe fee first and then add that fee to the $100 amount.

e.g:

Amount to be Paid is $100 + $3 (Stripe fee) = $103 (Total) you need to cut from the customers account.

2nd Case:

We need to pay $95 to the dealer and the $5 left we want to keep in our account (excluding the Stripe fee).

If this is possible, how do we implement this?

Community
  • 1
  • 1
sher bahadur
  • 409
  • 1
  • 5
  • 7
  • What has this to do with SilverStripe PHP Framework? – wmk Apr 28 '16 at 07:09
  • @wmk probably he is using the module... sher what you want is split payments and it's not all too common I can advise a payment gateway if that is the answer you'd like, but I don't think stripe do – Barry Apr 28 '16 at 07:26

12 Answers12

24

the easiest way is to add expand for balance transaction

$charge = \Stripe\Charge::create(array(
              "amount" => $totalAmount,
              "currency" => $currency_code,
              "source" => $stripeToken,
              "transfer_group" => $orderId,
              "expand" => array("balance_transaction")
            ));

This will give you what stripe has charged as fee and then you can do remaining calculations

Lonare
  • 3,581
  • 1
  • 41
  • 45
  • And if anyone is interested into how it should look like in the POST request, here it is: &expand%5B%5D=balance_transaction – FlorianB Jun 08 '19 at 21:03
19

for someone looking for the javascript code to calculate stripe fee (maybe to ask customers to cover the stripe fee). i wrote small script to do it

/**
 * Calculate stripe fee from amount
 * so you can charge stripe fee to customers
 * lafif <hello@lafif.me>
 */
var fees = { 
    USD: { Percent: 2.9, Fixed: 0.30 },
    GBP: { Percent: 2.4, Fixed: 0.20 },
    EUR: { Percent: 2.4, Fixed: 0.24 },
    CAD: { Percent: 2.9, Fixed: 0.30 },
    AUD: { Percent: 2.9, Fixed: 0.30 },
    NOK: { Percent: 2.9, Fixed: 2 },
    DKK: { Percent: 2.9, Fixed: 1.8 },
    SEK: { Percent: 2.9, Fixed: 1.8 },
    JPY: { Percent: 3.6, Fixed: 0 },
    MXN: { Percent: 3.6, Fixed: 3 }
};

function calcFee(amount, currency) {
    var _fee = fees[currency];
    var amount = parseFloat(amount);
    var total = (amount + parseFloat(_fee.Fixed)) / (1 - parseFloat(_fee.Percent) / 100);
    var fee = total - amount;

    return {
        amount: amount,
        fee: fee.toFixed(2),
        total: total.toFixed(2)
    };
}

var charge_data = calcFee(100, 'USD');
alert('You should ask: ' + charge_data.total + ' to customer, to cover ' + charge_data.fee + ' fee from ' + charge_data.amount );
console.log(charge_data);

https://gist.github.com/c3954950798ae14d6caabd6ba15b302b

Lafif Astahdziq
  • 3,788
  • 29
  • 38
  • 1
    Are you sure the fees depend on the payment currency? I thought that was determined by the platform account's currency. So, for example: If your platform is in the US, every payment will be "Percent: 2.9, Fixed: 0.30" regardless of the payment currency. – Jim Smith Feb 16 '18 at 23:41
  • From what I can see on Stripe's website (December 23 2018), all EU fees are 1.4% + 0.20p and all non-EU fees are 2.9% + 20p. – Martin James Dec 23 '18 at 11:53
  • 2
    No, the fees depend on the origin of the card, not the currency of the transaction – w00t Feb 18 '19 at 14:18
  • 1
    This formula is really helpful thanks a lot, but is it possible to have a formula for international charges? I know there's additional internation charges on top of this – Tsuna Sep 11 '19 at 19:50
  • 1
    for example once upon a time in future the fee in USA can change, so hard coded fees like USD: { Percent: 2.9, Fixed: 0.30 } needs to be updated. Is there any api for getting fee calculations? Such we ask for the appropriate fees then get a response from Stripe. – zacoder Mar 03 '22 at 10:26
12

From the Stripe Charge ID we can get the processing fee taken from the amount

stripe.Charge.retrieve("ch_1DBKfWECTOB5aCAKpzxm5VIW", expand=['balance_transaction'])

    "id": "txn_1DBKfWECTOB5aCAKtwwLMCjd",
    "net": 941,
    "object": "balance_transaction",
    "source": "ch_1DBKfWECTOB5aCAKpzxm5VIW",
    "status": "pending",
    "type": "charge"

"net": 941 is the amount credited to merchant account
Akhilraj N S
  • 9,049
  • 5
  • 36
  • 42
5

Currently, Stripe's API does not have a way of computing the fees before creating the charge. You'd need to do this yourself.

If you want to pass the fees to the paying customer, the following support article will be very helpful: https://support.stripe.com/questions/can-i-charge-my-stripe-fees-to-my-customers

To process payments on behalf of another account, and optionally take a cut out of the transactions, you need to use Stripe Connect. You can read more in the documentation: https://stripe.com/docs/connect.

Ywain
  • 16,854
  • 4
  • 51
  • 67
3

Just wanted to pop in and add to Harshal Lonare's answer, for sending Payment Intent confirmations you can get the balance transaction data back with:

"expand" => array("charges.data.balance_transaction")
Mitch
  • 51
  • 2
1

With managed account Finally I am able to implement the above scenario.

For the calculation of Stripe Fee.

stripe_fixed_fee = 0.30; //cent stripe_charge = 0.029; //cent

You can refer this link http://www.blackdog.ie/stripe/ https://support.stripe.com/questions/can-i-charge-my-stripe-fees-to-my-customers

Thanks!

sher bahadur
  • 409
  • 1
  • 5
  • 7
1

You can calculate the Stripe fee in advance. Just have a look at their latest calculation formulas here: https://stripe.com/us/pricing (rememeber to change the URL to match your country, for example for me (France) the URL is https://stripe.com/fr/pricing)

So, in my case, it's a bit special:

  • for european cards, the Stripe fee is 1.4% + 0.25€
  • for non-european cards, the Stripe fee is 2.9% + 0.25€

And for US, the Stripe fee is 2.9% + 0.30 USD

Note: the percentage is taken from the total amount. Example: for a US account, if I sell a product for 100 USD, the Stripe fee will be:

(100 * 0.029) + 0.30 = 3.2 USD

Then feel free to split the Stripe fee to your convenience

Amaury
  • 126
  • 10
0

You can use function like this to calculate absolute paying amount ("need to pay" amount + stripe "tax"):

const stripeFee = (amount) => {
  if (amount <= 0) return 0;
  const amountTax = amount / 100 * stripeProcessingFee;
  const minFeeTax = stripeProcessingMinFee / 100 * stripeProcessingFee;
  const tax = amountTax
    + (amountTax + minFeeTax) / 100 * stripeProcessingFee
    + minFeeTax
    + stripeProcessingMinFee;
  return Math.ceil(amount + tax);
};

*stripeProcessingFee - Stripe pay-as-you-go pricing percent (2.9 %)
*stripeProcessingMinFee - Stripe pay-as-you-go pricing minimal value in cents (30 cents)

AveCezar17
  • 26
  • 3
0

Even tho, most of the fee calculations are correct, I still think the smoothest way is to ask the report api instead of doing the calculation. I only have done it with node, not with PHP, but this is my code:

require('dotenv').config()
const stripe = require('stripe')(process.env.STRIPE_SECRET)
const { DateTime } = require('luxon')
const fetch = require('node-fetch')
const { encode } = require('base-64')
const CSV = require('csv-string')


//Important Timestamps
const dt = DateTime.local().setZone('America/Los_Angeles')
const endOfLastMonth = dt.startOf('month').toSeconds()
const startOfLastMonthLA = dt.minus({ month : 1 }).startOf('month').toSeconds()

const params = {
    created : {
        gt : startOfLastMonthLA, lt : endOfLastMonth
    }
}

const gather = async () => {

    const reportRun = await stripe.reporting.reportRuns.create({
        report_type : 'balance_change_from_activity.summary.1', parameters : {
            interval_start : startOfLastMonthLA, interval_end : endOfLastMonth
        }
    })
    let reportTest
    console.time('generateReport')
    while ( true ) {
        console.log('start')
        await new Promise(resolve => {
            setTimeout(resolve, 2000)
        })
        reportTest = await stripe.reporting.reportRuns.retrieve(reportRun.id)

        if (reportTest.status === 'succeeded') {
            console.log(reportTest.id)
            break
        }
    }
    console.timeEnd('generateReport')
    const actualReport = await fetch(reportTest.result.url, {
        headers : {
            'Authorization' : 'Basic ' + encode(process.env.STRIPE_SECRET + ':')
        }
    })
    const data = await actualReport.text()
    //This is the net profit!
    console.log(CSV.parse(data)[4][5])

}

gather().catch(e => console.log(e))

the information is all in data, I would recommend to have a look at the data string. It is basically the report you get, when you click on report in the dashboard and they have different report types. Semantically it is more correct to get your reports via the report api, then vs the api that is more for handling/checking single charges. I would prefer stripe to send me that information straight as JSON, but the csv works too.

Julian Wagner
  • 674
  • 6
  • 16
0

In NodeJs using the payment intent id to get the processing fee taken by the stripe

 const paymentIntent = await this.stripe.paymentIntents.retrieve(id, {
  expand: ['charges.data.balance_transaction'],
});

//Stripe fee
const stripe_fee = paymentIntent.charges.data[0].balance_transaction.fee;

It will give following response in paymentIntent inside charges object (fee_details of balance_transaction)

"balance_transaction": {
                    "id": "txn_3JQ9ddddgRF81Q43rnFI1Zn2US9u",
                    "object": "balance_transaction",
                    "exchange_rate": null,
                    "fee": 76,
                    "fee_details": [
                        {
                            "amount": 76,
                            "application": null,
                            "currency": "usd",
                            "description": "Stripe processing fees",
                            "type": "stripe_fee"
                        }
                    ],
                },
Satish Mali
  • 61
  • 1
  • 3
0

Stripe processing fees can be retrieved using the id of payment intent.

\Stripe\Stripe::setApiKey('{{secret}}');

$paymentIntent = \Stripe\PaymentIntent::retrieve([
  'id' => '{{payementIntentid}}',
  'expand' => ['charges.data.balance_transaction'],
]);

$feeDetails = $paymentIntent->charges->data[0]->balance_transaction->fee_details;
Mustapha GANGA
  • 505
  • 7
  • 12
0

These answers don't take into account the fact that fees are charged on the total amount. So if you bill $100 + ($100 * 2.9% + $0.30) = $103.20, Stripe is charge you fees on the $103.20 now, not the original $100.

There's a helpful formula in this post that I've adapted into Ruby.

def calculate(desired_total, percent_fee, fixed_fee)
  return 0 if desired_total <= 0

  # X = what to charge
  # Y = what we want
  #
  # The basic formula is:
  #   X - (X * 0.029) - 0.30 = Y
  #
  # First... we want our percentage (0.029) to be a whole number so we will
  # multiply each variable by 1000
  multiplier = 1000
  y = desired_total * multiplier

  percent_component = (percent_fee) * multiplier # => 29
  base_component = fixed_fee * multiplier # => 300
  coefficient = multiplier - percent_component # => 971

  # This gives us
  #    1000X - 29X - 300 = Y
  #
  # Which we then re-arrange the terms to
  #    971X = Y + 300
  #
  # And can then calculate the total we need to charge as
  #   X = (Y + 300) / 971
  total_charge = (y + base_component) / coefficient
end

p calculate(100, 0.029, 0.30) => # 103.29557157569516
p calculate(200, 0.029, 0.30) => # 206.2821833161689
Alex Dunae
  • 1,290
  • 3
  • 17
  • 28