First, it is important to distinguish between failures that are
- caused by the client side and
- others that have been caused by problems on the server side
The latter ones normally describe errors that the client cannot solve on its own.
The first ones should have a status code in the 400 series. The others, caused by the server side should have a status code on the 500 series.
My suggestions
Not enough funds
I would suggest 400
(Bad request) together with a meaningful error message.
Unable to retrieve funds (when no reason is given)
500
(internat server error), if the root cause is clearly the server side.
503
(Service Unavailable), if it can be determined that some necessary web service is temporarily not available. The meaning behind 503
is that this error is of a temporary nature, encouraging the client to retry the same request later.
- Maybe even set the
Retry-After
header with the amount of seconds that the client is recommended to wait before trying again.
400
(Bad request) if the root cause is a somehow invalid request by the client
Credit card expired
Again, I would suggest 400
(Bad request) + error message
A full list of return codes can be found here.