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

implement automated withdrawals / payouts #22

Closed
chadwhitacre opened this issue Jun 6, 2012 · 28 comments
Closed

implement automated withdrawals / payouts #22

chadwhitacre opened this issue Jun 6, 2012 · 28 comments

Comments

@chadwhitacre
Copy link
Contributor

It'd be nice to get to this before the blogosphere does.

BIG PRE-REQUISITE: #160

@chadwhitacre
Copy link
Contributor Author

Currently if you have a positive balance, you get a message on your profile page:

Release early! Release often! Automated withdrawals have not been 
implemented yet. Email [email protected] or call +1-412-925-4220 to 
work something out if you need your cash now.

That's my cell phone number.

The first payout happened already. I need to update his balance in the db. See #53.

@chadwhitacre
Copy link
Contributor Author

Balance updated. See #53.

@chadwhitacre
Copy link
Contributor Author

I think this is the next big piece we need.

@chadwhitacre
Copy link
Contributor Author

Balanced (#78) apparently handles both sides of this. Does Braintree (#77) have a solution for the deposit side?

@chadwhitacre
Copy link
Contributor Author

Balanced's pricing is reasonable enough that I think we should just make this the default, to automatically deposit into tippee bank accounts on Friday. That way we're not accruing money in a central bank account, and I like that very much. I guess we'd set a minimum threshold, like $10 or something. It's $0.25 per deposit transaction. Let's markup a few cents--also gotta pay Heroku.

We still need the central account in order to keep tips anonymous, and also to keep per-transaction fees low by batching tips. I think really we want to require tippees to have a bank account set up, though. So just like tips to unclaimed accounts don't "count" right now, tips to accounts without a bank account connected wouldn't be processed nor included in aggregates. Nah, we definitely want people to accrue money within Gittip and pay it back out to other people on Gittip.

@chadwhitacre
Copy link
Contributor Author

Bumping to next week to make room for #95.

@matin
Copy link
Contributor

matin commented Jul 5, 2012

@whit537 how are you planning on doing the withdrawals for this week?

@chadwhitacre
Copy link
Contributor Author

For the record @mjallday is working on integrating Balanced for payments in and out. #78

@chadwhitacre
Copy link
Contributor Author

See also: http://sync.in/gittip-balanced

@valpackett
Copy link

Why not PayPal? It's easier to integrate and it's international.

@matin
Copy link
Contributor

matin commented Jul 13, 2012

@myfreeweb

  • recurring: PayPal would require the payer to go through the checkout flow every time they want to pay
  • escrow: PayPal transactions happen immediately. You can't charge $10 and pay out from that later, which makes micro-transactions painful

@valpackett
Copy link

  • PayPal has recurring payments; Instapaper uses this.
  • You can charge $10 and put a record in your database and then subtract the amount you paid from the db record when you pay out or something

@jkwade
Copy link

jkwade commented Jul 16, 2012

@myfreeweb

For Gittip to do the one-to-many flow of money that makes it valuable, it would likely have to use PayPal's Adaptive Payments API, which is cumbersome when it comes to recurring payments, as is explained by Massimo Arrigoni in the comments of the following article: http://developer.practicalecommerce.com/articles/2589-Subscriptions-and-Payment-Plans-with-PayPal-s-Adaptive-Payments-API

Specifically, Gittip would have to set a max total pre-approval amount and a recurring subscription end date when creating the subscription, constraints (which to the best of my research) Instagram doesn't have to worry about because they're using PayPal's Express Checkout API.

As for Gittip accepting recurring payments directly and then paying those funds out to recipients; that's what got one of our former partners, Vayable, shut down by PayPal (http://vayable.blogspot.com/2011/03/how-to-get-paypal-to-freeze-your.html), something I'm sure @whit537 is tired of by now ;) (#67)

@mjallday
Copy link
Contributor

@whit537 check out the changes i've made over at my branch and let me know what you think about the settlements table.

I think it will work with satisfying your requirements of balancing out tips. e.g. if I receive some tips and need to pay out some tips (and all these exist in the exchanges table) then we can SUM the totals together and then settle whatever the difference between the two would be.

@chadwhitacre
Copy link
Contributor Author

Here's a user story:

I have a positive $50 balance in my Gittip account and want to get it into my bank account. I connect my bank account to my Gittip account on a Tuesday. On Thursday of week N, Gittip payday runs (changed from Friday so that cash clears bank accounts on Friday). I am set up to give $20 and receive $30, so after the first, payin, loop, I have a positive $60 in my Gittip account. During the payout loop, $40 is credited in my bank account, leaving a positive $20 balance in my Gittip account.

A week later, Gittip payday runs again. The $20 in my account funds my gifts, and I receive $30, so I now have a $30 balance in my Gittip account after the payin loop. During the payout loop, $10 is credited to my bank account, less a $0.30 fee, leaving $20 in my account for next week.

During week N+2, I change my gifts. Now I am set up to give $30. On Thursday of week N+2, payday runs. During the payin loop, I receive $30 and give $30. My balance is now $20, and nothing is credited to my bank account, because my balance is less than my obligations.

For week N+3, my credit card is charged $10.71 during the payin loop, bringing my balance up to $30. I give away $30, and receive $30, so my balance is now $30. Nothing is credited to my bank account.

For week N+4, my credit card is charged $0 during the payin loop, leaving my balance at $30. I give away $30, and receive $30, so my balance is now $30. Nothing is credited to my bank account.

In week N+5, I change my gifts. Now I am set up to give $40. On Thursday of week N+5, payday runs. During the payin loop, I am charged $10.71, and my balance is now $40. I give $40 and receive $30. My balance is $30, and nothing is credited to my bank account.

In week N+6, I am charged another $10.71, bringing my balance up to $40. I give away the $40 and receive $30, leaving my balance at $30.

The characteristic behavior here is that it takes one week for adjustments in my net flow on Gittip to stabilize into a recurring pattern. If my flow is net positive, then I get a big deposit the first week that I connect my bank account, and then smaller ones after that. If my flow is negative, I get one big charge the first week that I connect my credit card (up to the full amount of my obligations), and then after that I am charged the difference between my receipts and my obligations. The receipts from week N are available to meet obligations in week N+1. If my flow is a wash, then I have one week of correction (depending on which direction I am coming from to this stasis point) before neither being charged nor receiving deposits.

chadwhitacre added a commit that referenced this issue Aug 20, 2012
I haven't run this one let alone tested it, but this is on the right
track. Should update the paydays table to take stats about ACH credits
(see commented out mark_* calls in record_credit. Also make ach_credit
more robust against failure scenarios listed inline.
@mjallday
Copy link
Contributor

The settlements table may reflect a lack of my understanding of your architecture so it may be that we need to refactor or remove it. No big deal from this side. I envisioned each Settlement as reflecting an aggregation of group of funds transfers. If exchanges can meet that then that's great.

Ideally you would then change the app to reflect what each entry in exchanges consists of. So if there are 2 debits and 1 credit that have a nett positive value of $1 that you want to pay out, you should have some record showing that the exchange which represents the credit of $1 consists of those debits and credits. This isn't 100% necessary, the app will still work without this but I personally find it much better to be explicit when doing anything with payments as it makes debugging and accountability much easier.

Where I feel the settlements table will come in handy is when you want to maintain the minimum balance and give a breakdown of what each exchange payday consisted of. If I'm missing this, and it's already in Gittip then please give me a quick tutorial with your vision so I can get on the same page.

Another issue you're going to run into is how to reconcile the credits/debits charged on Balanced with what's in your system. So, for example, if you get halfway through the payday cycle and the power goes out on your server, how will you reconcile what's been paid with what's in Balanced? The settlements table is designed for this by calculating what funds need to move where in one transaction and then running through separately and reconciling/crediting. Admittedly, checking to see if each debit/credit has been made before re-creating the exchange should not be too hard.

@chadwhitacre
Copy link
Contributor Author

Going to focus on getting the bank account info form going. Incorporating that into the payday script is second.

Punchlist

Done

  • odd that identity validation disappears; what if that changes?
  • clean up account loading on server side
  • make sure "is connected" text is working properly
  • highlight "Bank account" link on profile appropriately
  • preen error messages for client-side validation
  • delete credit card and bank account separately
  • should invalidate previous {cc,bank} accounts when saving a new one reticketed as should invalidate previous {cc,bank} accounts when saving a new one #247
  • make sure credit cards still work
  • drop "name on account" if we can can't quite
  • explore impact on aggregate queries
  • populate form when visited a second time nothing to populate in this context, except maybe name on account?
  • clean up test suite
  • do we need to do a 1c deposit to validate? reticketed as consider validating bank accounts #252
  • experience escalation flow reticketed as nail down escalation flow #253

@mjallday
Copy link
Contributor

@whit537 - I like the sound of breaking this into two discreet chunks, merchant account creation and payouts respectively.

Let's nail merchant account creation like you mention. Which of those tasks do you want me to focus on? I'm a little useless this week, next week is going to be better.

@chadwhitacre
Copy link
Contributor Author

@mjallday Is the "name on bank account" field optional?

Also, I'm having difficulty triggering the escalation workflow. The docs tell me to use EX and 99999 for region and ZIP, but I'm getting a successful response from add_merchant in that case, not a MoreInformationRequiredError. Maybe it's because I'm calling add_merchant on an account that already has the merchant role?

chadwhitacre added a commit that referenced this issue Aug 23, 2012
I tweaked the UI to hopefully be a little less confusing wrt the
identity verification step. I also tweaked the error messages and
"account connected" messages a bit. Lastly, I refactored the
billing module to avoid duplicate code.
@chadwhitacre
Copy link
Contributor Author

Forgot to mention in that last commit that I took balanced_destination_uri out of Gittip's db. Now we're fetching it from Balanced as needed.

@chadwhitacre
Copy link
Contributor Author

@mjallday Is this expected behavior?

(Pdb) self._account.cards.total
18
(Pdb) self._account.cards[13]
Card(...)
(Pdb) self._account.cards[14]
*** IndexError: list index out of range
(Pdb) self._account.cards[-1]
*** IndexError: list index out of range
(Pdb) 

@chadwhitacre
Copy link
Contributor Author

Python client bug: balanced/balanced-python#10

@mjallday
Copy link
Contributor

Also, I'm having difficulty triggering the escalation workflow. The docs tell me to use EX and 99999 for region and ZIP, but I'm getting a successful response from add_merchant in that case, not a MoreInformationRequiredError. Maybe it's because I'm calling add_merchant on an account that already has the merchant role?

This will not work. You can only add the merchant role once to an account. Balanced is actually ignoring the merchant param in this case which may not be ideal behavior.

@chadwhitacre
Copy link
Contributor Author

Reticketed:

Blam, people. Blam.

!m @mjallday
!m @balanced

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

5 participants