I used to see the negative balance issue in accounts quite often as it seems that the wallet just picks a random account to send out of sometimes so I've started using the sendfrom method on my daemon based sites as you can directly specify the account the funds come out of.
I know exactly what you mean about scam accusations. They don't even bother raising it with you privately or even giving you the opportunity to resolve it before essentially labelling you a scammer and usually over something that amounts to a few cents worth of coins.
The mysql database for this site has every input to the account tracked.
There are no random accounts or addresses at any time it is 100% restricted.
Transactions as they are incoming to either of two specific addresses sharing an account, each of which has a separate purpose.
Receive transactions to the betting address are read from the mem pool once they're recognized by the wallet. The transaction is analyzed for one of three conditions.
Under limit transactions are ignored. Thank you for your donation. (edit: I double checked and I posted too fast. These are stored as unspent inputs not ignored. Still, the thanks )
Over limit transactions are refunded. The transaction it was send in is used as the sole input for a return transaction which sends the user back 99% of their funds, a tx fee, and if anything is left, some change to the script, which is logged to the database as an input for recycling at the funding/change address.
Transactions which might result in a payout of more than the sum of the script's stored inputs are refunded to the customer. If the system is literally 100% depleted of funds, I would end up having to do this manually as it wouldn't generate an outgoing tx at 0 fee.
So once those conditions are met, the script calculates the bet according to the published rules. If the bet is a loss, the customer is notified with a .0001 payout (and a .1 fee). If the bet is a win...
The script adds .1 to the payout amount for the win. It then requests a list of inputs from the db and adds them (oldest to newest) to the amount of the original tx until it has sufficient inputs to send the tx.
Each input is removed from the unspent inputs as it is added to the tx for sending.
Once the necessary total is achieved a tx is constructed using the gathered inputs. Any overage once the payout and fees are covered is returned to the specific change address for the script.
It's then processed in three phases by the wallet; encode, sign, send.
So, when send returns that friendly generic error message, the fun begins.
Step by step troubleshooting it I have gotten to here. If it slips it should be slipping in favor of caution - I suspect it's more likely to lose inputs than to double spend them for instance as they're deleted before there's any actual confirmation of being spent. If in doubt about the ability to pay out it attempts to refund the money.
This is so that it can move along smoothly without a lot of double and triple checking and still be unlikely to screw a customer. While still covering my butt in the end of course. I won't mind taking my payment in fragmented coins that I eventually have to sort out of a confused wallet - as long as I get paid. Based on what I have read it seems as if the "bind the original input into the output" is a relatively sound method of covering against being double-spent, etc..
So for me it was a goal of the project to have it run as securely as it can in 0 confirmations and be fast. Even with the limitation to private wallets (not being able to play from an exchange account) - a trade off for a multiple alt-coin game right now when a lot of people hold coins they don't have wallets for.
Once I realized that I would have to track the inputs independent of the wallet to get this performance into the game, it seems a next reasonable step to keep things moving is to touch the wallet as little as possible. It still has to be scanned fairly frequently to keep the script moving if no one is camped at the web page.
But for now I need to use the encode, sign, send procedure. To be entirely honest I'm not up to doing the encoding or the signing myself right now I need these.
Anyways I'm not saying that I'll never fix this but right now I think I'll let it lie with some frustration, and maybe look at a refactor in a couple of days. Obviously i've missed a large hole in the queuing process that's causing me some slippage.
And after all of that, a move to an account based system with balances does sound refreshingly simple indeed.