balanced / balanced-api

Balanced API specification.
221 stars 72 forks source link

Create stopOrder functionality on ACH debits and credits #661

Closed dberube closed 10 years ago

dberube commented 10 years ago

This will immediately cancel an ACH debit or credit and remove it from Balancer's batches ACH processes for the day or return false if its already been sent to ACH network for processing.

This would greatly help with edge case failures after successful ACH debit or credit were a reversal or refund can not take place until the transaction clears.

I'd imagine most stopOrders would be immediate on error.

matthewfl commented 10 years ago

atm, you can write into support and if it is before the cutoff time, then they should be able to cancel it. However, I am curious how often you are submitting ach transactions to balanced, which you want to cancel shortly thereafter (within a few hours)

dberube commented 10 years ago

Not often. Its for error handling. Last thing anyone should want when building an app that moves money is a loose end.

Without this proposed functionality you're relying essentially on a callback days later to reconcile a transaction that's already failed.

Also, I can see apps using transactional queries which might also mean if there's an error, the transactions row in the DB might not even exist when the callback is fired days later.

dberube commented 10 years ago

Any further thoughts on this?

Thanks.

mjallday commented 10 years ago

@matthewfl what do you think about implementing short circuit behavior if a reversal is created for a credit the same we optimise for refunds before captures are submitted? seems like it would be a big time saver for internal support staff.

msherry commented 10 years ago

This already exists.

matthewfl commented 10 years ago

https://github.com/balanced/precog/blob/omnibussed/precog_service/models/transactions.py#L506 was about to say

mjallday commented 10 years ago

ok, i will write a test case and see what the actual behavior is here. :sunflower:

dberube commented 10 years ago

Will save your team time and will allow me to sleep better at night... Thank you guys!

mjallday commented 10 years ago

https://github.com/balanced/balanced-python/commit/865be0b688be282fa84776becc9b631e222d4856

Here's a quick example I wrote in our python client library showing the immediate reversal of a credit.

@dberube which client library are you using? We can create an example showing you how to do this, we also have a reference in the API documentation for reversing a credit.

If you do this before credits are submitted to the bank then no money should leave the Balanced system and it will be immediate. If the reversals are created after the credits are submitted then it's essentially a ACH debit in disguise and you'll need to wait for it to clear which will take a couple of business days.

I'm going to close out this issue for now, if any problems arise with this approach feel free to re-open for discussion.

dberube commented 10 years ago

Thank you guys.

I'm using PHP library -- is this the functionality here: https://github.com/balanced/balanced-php/blob/master/scenarios/reversal_create/executable.php

Nothing else beyond just that?

If so, will it immediately return (not through callbacks) some notification if the credit either can't be removed or if it's too late and it's been sent?

mjallday commented 10 years ago

That example is correct.

If the credit has already been submitted then it will return a reversal with a state of PENDING. If it's immediately canceled then the state will be SUCCEEDED. I do not believe we offer a way to tell if a credit has already been submitted for processing.

dberube commented 10 years ago

So, if it comes back PENDING, that means it will be reversed as soon as the credit clears their bank, or does it mean it will fail once credit clears their bank?

mjallday commented 10 years ago

It is possible for it to fail. If the bank account has insufficient funds when the debit comes around it is up to the bank to decide if they will honor the debit or not.

That's definitely something to be aware of when thinking about this situation.

dberube commented 10 years ago

Implementing this now into app...

What's Balanced's payment logic here? Meaning, are you still charged a credit fee? Does calling this also cancel out any fees associated with the original transaction? And, are there any fees for doing this function?

mjallday commented 10 years ago

@dberube yes, Balanced will invoice based on number of transactions that are created.

dberube commented 10 years ago

I'm confused, perhaps you could clarify.

So, if we immediately create a credit or debit transaction (ACH), then immediately reverse/cancel it before it ever gets sent to the ACH network, the same amount as if that transaction was allowed to continue will be due by myself to Balanced?

dberube commented 10 years ago

Also -- link: https://github.com/balanced/precog/blob/omnibussed/precog_service/models/transactions.py#L506

Doesn't seem to work -- so I'm unsure how to stop an ACH debit before it hits the batch?

msherry commented 10 years ago

@dberube As @mjallday said, to stop an ACH debit before it is submitted, issue a refund on it.

dberube commented 10 years ago

Back to this, sorry...

It seems the behavior of your API has changed though.

Doing an immediate credit reversal now results in this being returned:

https://gist.github.com/dberube/116a0a65846714a12903

Making it impossible to stop an ACH credit before it goes to the bank.

Thoughts on this update? Is there a new workaround?

dberube commented 10 years ago

Where-as before, this was the typical response you'd get if you immediately reversed an ACH/bank credit:

https://gist.github.com/a10270e3676fdf5b4d29

msherry commented 10 years ago

@dberube I'm not aware of any recent changes to this -- that functionality has been in place for a while. Can you post a gist where you haven't sanitized the GUIDs? We can't take a look at the transactions in question otherwise. There is nothing sensitive about posting GUIDs -- just don't post your API key.

Is this in a live or test marketplace?

dberube commented 10 years ago

Sure thing:

https://gist.github.com/c011bd4331c732c55bf5 && https://gist.github.com/4a224eb7b1adde05a41a

Both in testing environment, and both transactions are actually in 2 different marketplaces -- but I would assume both testing marketplaces should behave the same.

msherry commented 10 years ago

Were they perhaps made with different test bank account numbers -- one of which transitions the credit's state to succeeded immediately, and one which doesn't?

dberube commented 10 years ago

I do believe they were both using the same testing numbers, of:

Routing: 021000021 Account: 9900000004

The one that is currently not working, is using that information, and I can say with 95% confidence the others ones that were working properly were since I've only used the other testing accounts to test failures once or twice.

msherry commented 10 years ago

That account number transitions credits to state failed, so you shouldn't expect a reversal to work in that situation anyway -- there is nothing to reverse.

Just checked the database -- one credit (the one where the reversal succeeded) is using a routing number of 211370545 and a bank account whose last four digits are 1111. This credit ended up in a succeeded state, so that is why your reversal worked.

dberube commented 10 years ago

You're absolutely right, I wasn't thinking in that logical order of events, it's failed already...

My bad, thanks for the prompt responses -- as always!