Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

theUnforgiven's avatar

Sum for subtracting a percentage with Vue

Hi all,

I have the following VueJS


this.$http.get('/coupons/' + this.coupon.code)
                .success(function(coupon, finalTotal) {
                    this.coupon = coupon;
                    this.valid = true;
                    this.coupon.description = 'Great! You entered a valid coupon.';
                    this.total = this.total - this.coupon.discount; // This line
                    this.$set('finalTotal', this.total);
                })
                .error(function() {
                    this.coupon.code = '';
                    this.coupon.description = 'Sorry, that coupon does not exist.';
                });
        }

Where I have marked // This line I wish to know (not been that good at math) how I can make the amount coming from the database i.e 10 be a percentage and take that percentage away from the total.

How can I do this, sorry if it's a dumb ass question, but math not my strongest point!

0 likes
53 replies
tykus's avatar
this.total = this.total * (1 -  (this.coupon.discount/100));
tykus's avatar

1 is your 100% of total

(1 - (discount/100) is the percentage of total left after discount is applied.

theUnforgiven's avatar

I'm getting values like 25.191 which Stripe won't accept so how can I make this be accepted?

tykus's avatar

Would it make more sense if I expanded it? You have to convert your '10' into a percentage by dividing by 100.

discountPercentage = discount/100

You have to get the discount amount by multiplying the total by the discountPercentage:

discountAmount = total*(discount/100)

You get the discounted total by subtracting the discountAmount from the total

discountedTotal = total - discountAmount

In one line, this would be:

discountedTotal = total - (total*(discount/100))

or divide out total from the right side

discountedTotal = total(1 - (discount/100))

Stripe works in cents or pennies... it is always better to work in cents (as Integers) for monetary stuff like this - no rounding errors as a result of calculations.

theUnforgiven's avatar

So that be as follows then within my JS

discountPercentage = discount/100;
discountAmount = total*(discount/100);
discountedTotal = total - discountAmount;
discountedTotal = total - (total*(discount/100));
discountedTotal = total(1 - (discount/100));
this.total = discountedTotal;

Would that be right in my understanding?

tykus's avatar

Just this bit

discountPercentage = discount/100;
discountAmount = total*(discount/100);
discountedTotal = total - discountAmount;
this.total = discountedTotal;

if you want to avoid all of that, you can substitute it with this one-liner:

this.total = total(1 - (discount/100));
theUnforgiven's avatar

So done this would this be right based on what I posted earlier in the thread?

this.discountPercentage = this.coupon.discount/100;
this.discountAmount = this.total*(this.discountPercentage/100);
this.discountedTotal = this.total - this.discountAmount;
this.total = this.discountedTotal;
this.$set('finalTotal', this.total);
tykus's avatar

These are 27.96201 what; pennies, pounds, cent, euro, dollar?

A Stripe charge expects the amount to be in cents, so if you are charging £27.96201, you should multiple by 100 and round the last penny up or down depending on your preference:

this.discountPercentage = this.coupon.discount/100;
this.discountAmount = this.total*(this.discountPercentage/100);
this.discountedTotal = this.total - this.discountAmount;
this.total = Math.round(this.discountedTotal * 100); // if your total is NOT in cents/pennies
this.$set('finalTotal', this.total);
tykus's avatar

Really, you should ask yourself if it is wise to determine the finalTotal on the client side - better to do this away from a potentially malicious user

theUnforgiven's avatar

The math round function is probably what i need yes.

How else would i be able to pass that to the screen without using set

theUnforgiven's avatar

I have laravel displaying it as £27.99then based on your last reply with the math function it shows as £2796 which is obviously wrong as that would then charge 2k.

tykus's avatar
tykus
Best Answer
Level 104

Just spotted an error in the calculation:

this.discountPercentage = this.coupon.discount/100;
this.discountAmount = this.total*(this.discountPercentage); // do not divide by 100 here (its already a percentage)
this.discountedTotal = this.total - this.discountAmount;
this.total = Math.round(this.discountedTotal * 100); 
this.$set('finalTotal', this.total);

If you multiply a GBP£ by 100, that's the number of pennies you have - Stripe needs to make the charge in pennies

1 like
tykus's avatar

Lets get you back on track:

For display purposes, this is what you will need:

this.discountPercentage = this.coupon.discount/100;
this.discountAmount = this.total*(this.discountPercentage); 
this.discountedTotal = this.total - this.discountAmount;
this.$set('finalTotal', this.total);

When you are making the charge to Stripe on the server side, you will need to convert the charge amount to an integer representing the amount in pennies. This will be done in PHP... something like:

$chargeAmountInPennies = (int)($amountInPounds*100);
theUnforgiven's avatar

Using the following code:

this.discountPercentage = this.coupon.discount/100;
this.discountAmount = this.total*(this.discountPercentage); // do not divide by 100 here (its already a percentage)
this.discountedTotal = this.total - this.discountAmount;
this.total = Math.round(this.discountedTotal * 100); 
this.$set('finalTotal', this.total);

When I enter a valid code it's then showing has 0 (zero) rather than subtracting the percent and displaying the new figure.

@tykus_ikus any idea why this could be?

tykus's avatar

What is? The final total? The maths should be fine, so likelihood is there something coming into the total or coupon that is not in the expected format.

Might be worth console.log various parts of the maths and the coupon object to see where

theUnforgiven's avatar

Yeah just trying to work that out now.

finalTotal as been set in the data object has finalTotal: 0

Then I call this within my view. But is showing as £

theUnforgiven's avatar

This is what happened when I console.log() them all:

this.discountPercentage = this.coupon.discount/100; // console.log(this.discountPercentage) = 0.1
                    this.discountAmount = this.total*(this.discountPercentage); // console.log(this.discountAmount) = 0
                    this.discountedTotal = this.total - this.discountAmount; // console.log(this.discountTotal) = 0
                    this.total = Math.round(this.discountedTotal * 100); // console.log(this.total) = 0
tykus's avatar

So, finalTotal is not being updated then... Any issue with context? Or, maybe none of that snippet is being called; does the code branch somewhere?

tykus's avatar

So it looks like there is a problem with this.total not being properly set since discountAmount is not getting a value. You have initialised this.total to 0, but you do not appear to be updating it in your getTotal() function, instead you are just setting the finalTotalAmountproperty. Whenever you start to do the discount calculations you are using total=0 which then gets coughed out at the end is setting the finalTotalAmount to 0

theUnforgiven's avatar

Mmmm, not sure I follow here, maybe cos it's late or maybe cos i tried to play around with it to pass the pennie amount through has a hidden field and also tried to show the updated amount on screen.

theUnforgiven's avatar

Upon doing {{ $data | json }} I get

{ "coupon": { "id": 2, "code": "test", "discount": 10, "created_at": "2015-10-17 18:05:58", "updated_at": "2015-10-17 18:05:58", "expires": "2016-01-30", "description": "Great! You entered a valid coupon." }, "valid": true, "total": 0, "finalTotal": 27.99, "finalTotalAmount": 0 } - See more at: http://shop.app/checkout#sthash.zlpy3TNW.dpuf
tykus's avatar

I am working on the Gist now, I'll try to share it back to you shortly

theUnforgiven's avatar

Awesome great.

I have set this.$set('total', this.finalTotal); in the JS and the following total": 2796, "finalTotal": 2796, "finalTotalAmount": 0 which is fine for passing to Stripe but I need it to show as 27.96 on screen in proper currency.

Also looks like the math is wrong the amount is 27.99 then subtract the 10 % should be about 25 but showing as 2796

tykus's avatar

Have a look at my fork of your Gist https://gist.github.com/tykus/3e102f6163837cd04083 . You were working on a vm property called total which you initialised to 0 in the data object, but you never updated the value of total anywhere. Whenever you attempted to calculate the discountAmount, this.total was still 0.

All methods in a Vue instance will have their this context bound to the instance by default - you may have misunderstood which context you were in at times.

1 like
theUnforgiven's avatar

Yeah if you see my post before yours you'll see that's now working to some extent but the discount is wrong and also showing at 2796

Next

Please or to participate in this conversation.