Skip to content
This repository has been archived by the owner on Feb 8, 2018. It is now read-only.

investigate credit card processing fee computation #1664

Closed
chadwhitacre opened this issue Nov 12, 2013 · 14 comments
Closed

investigate credit card processing fee computation #1664

chadwhitacre opened this issue Nov 12, 2013 · 14 comments

Comments

@chadwhitacre
Copy link
Contributor

I'm working with Heroku on another $5,000 payin. I used the same fee as last time, which was $187.98. However, I don't believe this is correct.

@chadwhitacre
Copy link
Contributor Author

5,000.00 * 0.971 = 4,855.00
4,855.00 - 0.30 = 4,854.70
5,000.00 - 4854.70 = 145.30

@chadwhitacre
Copy link
Contributor Author

When we run credit cards during payday, we upcharge to cover the fee. Do we upcharge too much? Is that where I got the 187.98 from originally? We used to upcharge based on 3.9% + $0.30. Maybe that explains it?

@chadwhitacre
Copy link
Contributor Author

Here's the upcharge algorithm:

FEE_CHARGE = ( Decimal("0.30")   # $0.30
             , Decimal("0.029")  #  2.9%
              )

def upcharge(amount):
    """Given an amount, return a higher amount and the difference.
    """
    typecheck(amount, Decimal)
    charge_amount = (amount + FEE_CHARGE[0]) / (1 - FEE_CHARGE[1])
    charge_amount = charge_amount.quantize(FEE_CHARGE[0], rounding=ROUND_UP)
    return charge_amount, charge_amount - amount

@chadwhitacre
Copy link
Contributor Author

The change in fee does not explain it. Here's what 3.9% + $0.30 looks like:

5,000.00 * 0.961 = 4,805.00
4,805.00 - 0.30 = 4,804.70
5,000.00 - 4804.70 = 195.30

@chadwhitacre
Copy link
Contributor Author

Okay, figured it out. Per 20b5fa0, the upcharge algorithm used to be:

FEE_CHARGE = ( Decimal("0.30")   # $0.30
             , Decimal("1.039")  #  3.9%
              )

def upcharge(amount):
    """Given an amount, return a higher amount and the difference.
    """
    typecheck(amount, Decimal)
    charge_amount = (amount + FEE_CHARGE[0]) * FEE_CHARGE[1]
    charge_amount = charge_amount.quantize(FEE_CHARGE[0], rounding=ROUND_UP)
    return charge_amount, charge_amount - amount

That is, we used to multiply by 1.039 instead of dividing by .971. This explains the $6.21 upcharge I'm seeing on 151.00 on May 23, 2013, as well as the $187.98 on $4,812.02 I'm seeing on May 30. In other words, I had ran numbers through upcharge until I got one approximating $5,000.00, and had used that.

@chadwhitacre
Copy link
Contributor Author

I guess I should leave this open to adjust the fee for their latest payin.

@chadwhitacre chadwhitacre reopened this Nov 12, 2013
@chadwhitacre
Copy link
Contributor Author

187.98 - 145.30 = 42.68

@chadwhitacre
Copy link
Contributor Author

So that's the amount to add to their balance in Gittip. The fee in the exchanges table should be modified to 145.30.

@chadwhitacre
Copy link
Contributor Author

And of course the amount should be 4854.70.

@chadwhitacre
Copy link
Contributor Author

Done.

@zbynekwinkler
Copy link
Contributor

What was actually the problem here? Does it involve anyone else? Why was Heroku balance wrong?

@chadwhitacre
Copy link
Contributor Author

@zwn The problem is that I applied the wrong fee when I charged Heroku $5,000 a couple days ago. I applied the fee that I applied when I charged them $5,000 six months ago, but we've changed our fee algorithm since then (in 20b5fa0).

I was confused and afraid the problem ran deeper, because when yesterday I double-checked the fee (ahead of providing them with an invoice, see #1199 (comment)), I wasn't using the correct algorithm to compute the old fee. The fee six months ago was different in two ways:

  1. We marked up from 2.9% + 30¢ to 3.9% + 30¢.
  2. The function was (x + 30¢) * (1 + y) instead of (x + 30¢) / (1 - y) (where x is the base amount and y is the percentage).

In other words, the old algorithm for upcharging a base amount (which is what we usually do when we charge credit cards during payday) was not strictly the opposite of the usual algorithm for skimming a fee off the top (which is what we wanted to do in Heroku's case here). When I was double-checking the fee on the $5,000 this time around (which was after I had already recorded the new $5,000 exchange), I took into account the first change but not the second. Taking both together accounts for the fee we charged six months ago, both against the $5,000 and also against the $151 from the week before that.

@rcross
Copy link

rcross commented Mar 18, 2014

So it seems that there was a decision made to change the fee computation function, though there doesn't seem to be a rationalisation for why it was changed. In my opinion, the new function is actually incorrect based on the stated fees.

I would expect (X * 1.029) + .30.

However, even if it is (X + .30) * 1.029 this is not the same as (x + .30) / .0971

It is usually a negligible difference that is rounded out, but on large amounts it does make a difference.

For $100:

100_1.029 + .30 = 103.20
(100 + .30)_1.029 = 103.21 (103.2087)
(100 + .30) / .0971 = 103.30 (103.29557158)

for $5000 = [5145.30, 5145.31, 5149.64]

Is this rounding error intentional?

Related issues: #1031

@chadwhitacre
Copy link
Contributor Author

@rcross Reticketed as #2158.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants