Skip to content
This repository has been archived by the owner on Nov 16, 2022. It is now read-only.

Respond to IRS letter #1164

Closed
chadwhitacre opened this issue Sep 14, 2017 · 166 comments
Closed

Respond to IRS letter #1164

chadwhitacre opened this issue Sep 14, 2017 · 166 comments

Comments

@chadwhitacre
Copy link
Contributor

First time for everything, friends. :)

The income and payment information we have on file from sources such as employers or financial institutions doesn't match the information you reported on your tax return. If our information is correct, you will owe $9,220 (including interest), which you need to pay by October 5, 2017.

If you agree with the changes we made, [pay us].

If you don't agree with the changes, complete the Response form on Page 9, and send it to us along with a signed statement and any documentation that supports your claim so we receive it by October 5, 2017.

@chadwhitacre
Copy link
Contributor Author

They are looking at Braintree's 1099-K for us which shows $36,428 income and we reported $18,758. In other words, they are counting our escrow as income to Gratipay. The reason we didn't file our own 1099-Ks for our own receivers is the "Exception for de minimis payments":

A TPSO is required to report any information concerning third party network transactions of any participating payee only if for the calendar year: The gross amount of total reportable payment
transactions exceeds $20,000, and The total number of such transactions exceeds 200.

We won't have anyone over the $20,000 limit for 2015, but now that I think of it we may have people that exceed the 200 limit, since we are dealing in micro-payments.

@rohitpaulk
Copy link
Contributor

rohitpaulk commented Sep 14, 2017

I think of it we may have people that exceed the 200 limit, since we are dealing in micro-payments.

We only bill people once a week, no? i.e. maximum of 52 transactions per payee, per year.

@chadwhitacre
Copy link
Contributor Author

@rohitpaulk But if someone has 10 givers that could be 520 transactions for the year. Also interacts with $10 minimum charge-in. Bottom line: we need to run the numbers.

We've got about two weeks to get a response in the (registered) mail to meet the October 5 deadline.

@chadwhitacre chadwhitacre changed the title Respond to IRS audit Respond to IRS letter Sep 14, 2017
@chadwhitacre
Copy link
Contributor Author

Just wrapped a conversation with a CPA, who serendipitously happened to be here at Paramount. I explained Gratipay to him, our status as a payment processor, etc. He reviewed the IRS letter, and he is going to put together an engagement letter to help us sort this out for an amount not to exceed $500. He doesn't think it'll escalate beyond that but of course who knows? :) He has experience with IRS audits (I guess technically this isn't an audit yet), and knows how to navigate the system (e.g., call the local office vs. responding by mail).

Engagement letter coming next week. He took the IRS letter with him. We also need to provide:

  • my whole tax return for 2015, and
  • an Excel spreadsheet detailing where the $36,428 went to.

We don't need to worry about the number of transactions in 2015 at this point.

@chadwhitacre
Copy link
Contributor Author

Emailed the CPA to establish contact. Started working up a query but it will take some thinking.

@chadwhitacre
Copy link
Contributor Author

Need to account for transfers and payments (pre- and post-Gratipocalypse).

gratipay::DATABASE=> select sum(amount) from payments where direction='to-team' and "timestamp"::text >= '2015-01-01' and "timestamp"::text < '2016-01-01' and team != 'Gratipay';
┌──────────┐
│   sum    │
├──────────┤
│ 31244.01 │
└──────────┘
(1 row)

@chadwhitacre
Copy link
Contributor Author

Sent the tax return. Need numbers ...

@chadwhitacre
Copy link
Contributor Author

Can I repro the 18,758 number, first of all?

@chadwhitacre
Copy link
Contributor Author

Phew. :)

gratipay::DATABASE=> \i irs.sql
┌──────────┐
│ ?column? │
├──────────┤
│ 18758.03 │
└──────────┘
(1 row)
select
(select sum(amount) from payments where direction='to-team' and team='Gratipay'
   and "timestamp"::text < '2016-01-01' and "timestamp"::text >= '2015-01-01')
+
(select sum(amount) from transfers where tippee='Gratipay'
   and "timestamp"::text < '2016-01-01' and "timestamp"::text >= '2015-01-01');

@chadwhitacre
Copy link
Contributor Author

🤔

gratipay::DATABASE=> \i irs.sql
┌──────────────┐
│ total volume │
├──────────────┤
│    212514.20 │
└──────────────┘
(1 row)
select
(select sum(amount) from payments where direction='to-team'
   and "timestamp"::text < '2016-01-01' and "timestamp"::text >= '2015-01-01')
+
(select sum(amount) from transfers where
   "timestamp"::text < '2016-01-01' and "timestamp"::text >= '2015-01-01')
as "total volume";

@chadwhitacre
Copy link
Contributor Author

That's way more than the 36,428 that Braintree reported. I guess the rest was Balanced? Did they not report 1099-Ks for 2015 since they went out of business? Seems likely ...

@chadwhitacre
Copy link
Contributor Author

Alright, can we repro the 36,428 figure coming in from Braintree?

@chadwhitacre
Copy link
Contributor Author

Um ... when did we start charging on Braintree?

@chadwhitacre
Copy link
Contributor Author

@chadwhitacre
Copy link
Contributor Author

@chadwhitacre
Copy link
Contributor Author

Alright, so our first Braintree charges were on 2015-05-29.

@chadwhitacre
Copy link
Contributor Author

(We have charges against network='braintree' exchange_routes dating back before that because of the potential corruption mentioned at gratipay/gratipay.com#4442 (comment).)

@chadwhitacre
Copy link
Contributor Author

Hmm ... low by $7,203 relative to Braintree's 1099-K? What am I missing? 🤔

gratipay::DATABASE=> \i irs.sql
┌──────────┐
│   sum    │
├──────────┤
│ 29225.88 │
└──────────┘
(1 row)
  select sum(amount + fee)
    from exchanges e
    join exchange_routes er
      on e.route = er.id
   where "timestamp"::text < '2016-01-01' and "timestamp"::text >= '2015-05-29'
     and network = 'braintree-cc'
        ;

@chadwhitacre
Copy link
Contributor Author

What does the Braintree dashboard report?

@chadwhitacre
Copy link
Contributor Author

$27,671.68 if I constrain to status='succeeded'.

@chadwhitacre
Copy link
Contributor Author

2,266 rows. Braintree reports 2,516 successful transactions for the time period 2015-01-01 through 2015-12-31 inclusive.

@chadwhitacre
Copy link
Contributor Author

They begin on 2015-05-29 as expected.

@chadwhitacre
Copy link
Contributor Author

Oh! My query includes some refunds ...

@chadwhitacre
Copy link
Contributor Author

@chadwhitacre
Copy link
Contributor Author

Good lord we stopped keeping ref at that point (2015-10-15)? 😞

@chadwhitacre
Copy link
Contributor Author

Looking at amount > 0 gets me to $30,232.90, but then only 1,687 transactions.

@chadwhitacre
Copy link
Contributor Author

Alright, filtering out refunds at Braintree drops it to 2,246. Do those sum to $36,428?

Card Type: All
Created At: 01/01/2015 12:00 AM - 12/31/2015 11:59 PM
Created Using: All
Customer Location: All
Payment Instrument Type: Credit Card, PayPal Account
Status: authorized, submitted_for_settlement, settlement_pending, settling, settled, voided
Transaction Source: All
Transaction Type: sale

@chadwhitacre
Copy link
Contributor Author

Let's call the rest of the receipts/pre balanced-cc.

@chadwhitacre
Copy link
Contributor Author

chadwhitacre commented Oct 6, 2017

💃

https://gist.github.com/whit537/2e24b9e83338be2caddc253c7337bc91/7b4508efa66d4de59637904c0c51fd7731e66e4b

┌─────────────┬───────────┬───────┐
│   network   │    sum    │ count │
├─────────────┼───────────┼───────┤
│ balanced-cc │ 142239.36 │  8120 │
│ bitcoin     │    349.82 │     2 │
└─────────────┴───────────┴───────┘
(2 rows)

┌──────────────┬──────────┬───────┐
│   network    │   sum    │ count │
├──────────────┼──────────┼───────┤
│ braintree-cc │ 36428.04 │  2165 │
└──────────────┴──────────┴───────┘
(1 row)

┌──────────────┬───────────┬───────┐
│   network    │    sum    │ count │
├──────────────┼───────────┼───────┤
│ unknown      │ 195636.16 │  4853 │
│ paypal       │   5457.86 │    78 │
│ braintree-cc │   2576.38 │   580 │
│ balanced-ba  │   1035.23 │    11 │
│ bitcoin      │    853.99 │     9 │
│ balanced-cc  │    101.79 │    22 │
└──────────────┴───────────┴───────┘
(6 rows)

@chadwhitacre
Copy link
Contributor Author

Now for disbursements ...

@chadwhitacre
Copy link
Contributor Author

Easy one there is PayPal, since we have a note.

@chadwhitacre
Copy link
Contributor Author

chadwhitacre commented Oct 6, 2017

Looking at those with other notes, I find 779 and 754 are related to gratipay/gratipay.com#3378, which are refunds via either balanced-cc or braintree-cc.

@chadwhitacre
Copy link
Contributor Author

Disbursements don't really fall out on pre/post quite so much, 2015-10-10 is the more important date: gratipay/gratipay.com#3810.

gratipay-bak=# SELECT network, sum(gross), count(*) FROM e WHERE direction='disbursement' GROUP BY network ORDER BY sum desc;
┌──────────────┬───────────┬───────┐
│   network    │    sum    │ count │
├──────────────┼───────────┼───────┤
│ unknown      │ 195636.16 │  4853 │
│ paypal       │   5457.86 │    78 │
│ braintree-cc │   2576.38 │   580 │
│ balanced-ba  │   1035.23 │    11 │
│ bitcoin      │    853.99 │     9 │
│ balanced-cc  │    101.79 │    22 │
└──────────────┴───────────┴───────┘
(6 rows)

gratipay-bak=#

@chadwhitacre
Copy link
Contributor Author

Went through these:

gratipay-bak=# select * from e where direction='disbursement' and note is not null and note not like 'PayPal%' and note not like 'refund of advance%';

@chadwhitacre
Copy link
Contributor Author

chadwhitacre commented Oct 6, 2017

👍

gratipay-bak=# select network, direction from e where note ilike '%bitcoin%' or note ilike '%btc%';
┌─────────┬──────────────┐
│ network │  direction   │
├─────────┼──────────────┤
│ bitcoin │ disbursement │
│ bitcoin │ disbursement │
│ bitcoin │ disbursement │
│ bitcoin │ disbursement │
│ bitcoin │ disbursement │
│ bitcoin │ disbursement │
│ bitcoin │ disbursement │
│ bitcoin │ disbursement │
│ bitcoin │ disbursement │
│ bitcoin │ disbursement │
│ bitcoin │ disbursement │
│ bitcoin │ disbursement │
│ bitcoin │ disbursement │
│ bitcoin │ disbursement │
│ bitcoin │ receipt      │
│ bitcoin │ receipt      │
└─────────┴──────────────┘
(16 rows)

@chadwhitacre
Copy link
Contributor Author

We'll wanna be careful how we handle fees for refunds (= disbursements via *-cc).

@chadwhitacre
Copy link
Contributor Author

Picked off one more by looking at:

gratipay-bak=# select * from e where network='unknown' and note is not null;

There are two left that are unknown network and non-null note. One has the empty string for a note and no fee, not seeing it in PayPal tho. 🤔 The other says "Test exchange." and gross 0.00! Is that when we added the record-an-exchange form? ¯\_(ツ)_/¯

PayPal sanity check:

gratipay-bak=# select count(*) from e where network='paypal' and not note like 'PayPal%';
┌───────┐
│ count │
├───────┤
│     0 │
└───────┘
(1 row)

gratipay-bak=# select count(*) from e where note like 'PayPal%' and not network='paypal';
┌───────┐
│ count │
├───────┤
│     0 │
└───────┘
(1 row)

@chadwhitacre
Copy link
Contributor Author

There's a couple goofball records with null note but a weird network. Forcing to balanced-ba.

gratipay-bak=# select * from e where direction='disbursement' and note is null and network != 'unknown' order by ts asc;

@chadwhitacre
Copy link
Contributor Author

Alright, I'm ready to fold the remaining unknown disbursements w/ null note into balanced-ba.

@chadwhitacre
Copy link
Contributor Author

chadwhitacre commented Oct 6, 2017

Okay, here are the escrow and income statements: financials.pdf.

Now for the balance sheet ...

@chadwhitacre
Copy link
Contributor Author

@chadwhitacre
Copy link
Contributor Author

I manually copied and pasted numbers from there into a Google Sheet for math and then from there to a Google Doc for formatting.

@chadwhitacre
Copy link
Contributor Author

We have statements for PNC and PayPal:

https://github.com/gratipay/logs/blob/master/statements/2015/12/

We don't have a good statement for New Alliance nor a balance in the CSV. The last paper statement I have is from July, 2014, so I guess we start with that balance and then run through the transactions in CSV.

@chadwhitacre
Copy link
Contributor Author

$ ./sum.py 
82923.56
$
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals

import os
import csv
from decimal import Decimal as D

balance = D('58813.78')

for year in ('2014', '2015'):
    for month in os.listdir(year):
        if not month.isdigit():
            continue
        if (year, month) < ('2014', '08'):
            continue
        path = os.sep.join([year, month])
        for filename in os.listdir(path):
            filepath = os.sep.join([path, filename])
            if filename != 'new-alliance.csv':
                continue
            rows = csv.reader(open(filepath))
            headers = next(rows)
            for row in rows:
                rec = dict(zip(headers, row))
                balance += D(rec['Amount'])

print(balance)

@chadwhitacre
Copy link
Contributor Author

Alright, let's see about escrow liability!

@chadwhitacre
Copy link
Contributor Author

chadwhitacre commented Oct 6, 2017

Okay, I have a query adapted from _check_balances that lines up with what I see on the stats page. Gonna add time constraints to it so we can get the point in time we need.

gratipay-bak=# \i escrow.sql
┌───────────┐
│ ?column?  │
├───────────┤
│ 105865.01 │
└───────────┘
(1 row)

@chadwhitacre
Copy link
Contributor Author

Actually the transfers and payment cancel out, for this we only need to look at exchanges.

@chadwhitacre
Copy link
Contributor Author

Okay, looks like escrow liability is 115,841.28 at the end of 2015-12-31. I'm only showing 92,232 in escrow assets so where was the rest?

@chadwhitacre
Copy link
Contributor Author

23,609.28

@chadwhitacre
Copy link
Contributor Author

"Other" :D

@chadwhitacre
Copy link
Contributor Author

Alright so for equity ... it's Assets - Liability ... done!

Okay! Time to print ...

@chadwhitacre
Copy link
Contributor Author

Okay WOW!!!!!!!!!!!!!!!!!!! O.o 😳 🐭 😩 💃

@chadwhitacre
Copy link
Contributor Author

@JessWhit and I and the accountant met with a lady at this tiny IRS office, the most hidden away unbranded government office you could imagine, a parody of itself. The agent was helpful though more as an ombudsman ("That's not my unit but ..."). Here's the IRS's documentation for the AUR process we're going through. We got a CP2000. At the end she was like, "You have an interesting business. I learned something today." 😅

Bottom line is we need to file an amended return for 2015 and when that clears we'll refile 2016, too. We need to show gross receipts of everything we charge (on Braintree, etc.) and then list an "Other" expense for escrow including payouts (we'd report with 1099-K if ever over $20,000 per recipient).

We have a couple weeks before the IRS sends a second notice asking if we agree to their change, and another 30 days after that before they actually assess the tax. @JessWhit is going to look at what we can do with H&R Block's app (which is what we used for 2015), and then we'll coordinate with the accountant to fax our response to the IRS, to include:

  • the CP2000 response sheet as a cover letter; we are disagreeing with their proposed change
  • a 1040X for 2015
  • our explanation and supporting documentation

She advised that if we can get it done in a week or two that we should just contact them once with our full response, rather than trying to call them and let them know a response is on its way. Two weeks is like the blink of an eye for the IRS.

If our fax gets lost in the ... fax? ... we'll get the second notice from them in a month. At that point we can call and say "Hey you turkeys!" We'll have our own record of having faxed them, and the agent today did leave a note on our file that we met with her ("They don't always read my notes. In fact, they usually don't." "I would read your notes, []." :D).

@chadwhitacre
Copy link
Contributor Author

And now we have not-too-bad financials for 2015! Bonus! :D

Gratipay Financials 2015.pdf

@chadwhitacre
Copy link
Contributor Author

I met with the CPA and we came up with a way to fit our numbers into a Schedule C by using "Other Income" for our escrow liability (a negative value).

@JessWhit went through and redid our Schedule C and 1040 based on these new numbers and also filled out a 1040X.

I'm reviewing them now. There is a $40 discrepancy that we need to fix up, it snuck in because I was used both 3115 and 3155 for the refunds amount. The former is correct:

gratipay-bak=# select sum(gross) from e where direction='disbursement' and network::text like '%-cc';
┌─────────┐
│   sum   │
├─────────┤
│ 3114.69 │
└─────────┘
(1 row)

gratipay-bak=#

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

No branches or pull requests

3 participants