You will probably do well to review Jim Webber's 2011 talk. Among his early points; HTTP is an application protocol, the application domain is the transfer of documents over a network.
Your API is a facade designed to provide the illusion that the HTTP requests are being handled by a "document store" - that's what allows us to leverage all of the general purpose appliances that have been built for HTTP; they all agree on the same semantics of the messages.
So when you are trying to identify what the right status code to use for your particular circumstances, you need to be thinking in terms of what a general purpose client will assume is going on when it gets that response from a general purpose server, rather than about how a bespoke client would interact with your bespoke server.
With that in mind, you can start working through the flow chart.
For an unsafe request (PUT, POST, PATCH, ...), the first important thing to figure out is whether you should be signaling that the request was successful -- general purpose caching uses "non-error status codes" to signal cache invalidation. So if you want the client to keep its currently cached copy(-ies) of the resource, then you need to choose an error status.
Broadly, the important distinction between 4xx and 5xx is simply this: is the problem in the request?
The 5xx class of status codes is deliberately coarse grained, because there isn't much that the client can do to solve any problem on the server. You've got 500 (the server fell over), and 503 (the server is out of service), and that's it.
That doesn't seem to fit the scenarios you describe, where the root cause of the problem is the information that was contained within the request. So you should be looking into options in the 4xx class.
403 Forbidden is a reasonable starting point here; "I understood what you wanted, and I'm choosing not to do it." You could also consider 409 Conflict and 422 Unprocessable Entity. The latter has the advantage of highlighting the message-body of the request as the source of the problem.
One of the reasons for this can be that the user used an expired card.
Fine grained domain-specific semantics belong in the response body. "The server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition."
One way to think of the distinction is to consider what happens on the web; when you do a POST, the thing you get back is a web page, explaining to the human being what has happened, and what additional resources are available to proceed (if any). The meta data, like the response code, is information for the browser, not the human being.
Which means, in practice, that you can be a little bit loose with 403/409/422 -- because the general purpose components, like the web browser, really don't care very much about those distinctions.
See also Mark Nottingham's How To Think About HTTP Status Codes.