Open matin opened 11 years ago
There's actually another example where the issuing bank's processing systems are down. It happens more than expected.
I can document some of the declination codes here.
For recurring billing, current transaction model works like this
Transactions are yielded from subscription periodically, they will be processed at scheduled time. Once failed, it will go into RETRYING status, when the error count exceeds the limit, then it will go into FAILED. When the subscription is canceled, it will go into CANCELED status. If it is done, then it will be in DONE status.
And for invoicing, I am thinking about the process. Here is the state transition diagram
Current transaction model is pretty solid, so I think I can build the invoicing based on it. When an invoice is issued, it is in INIT status. Say, at the end of month, the cloud service provider issues an invoice to John. Upon receiving the invoice, John decides to settle it via credit card, so he updates the payment method (get a tokenized credit card number and assign it to the invoice). Then the invoice goes into PROCESSING status, a corresponding InvoiceTransaction will be generated. If the credit card has no enough fund for charging, and the InvoiceTransaction fails after some attempts, then the invoice goes into PROCESS_FAILED status. John was notified for this problem, he updates his payment method then. By doing that, invoice goes back into PROCESSING status. A while later, the charging is done, then it is SETTLED now.
For some reasons, the service provider want to refund the invoice, then the invoice goes into REFUNDING status. By the time, the upstream balanced API server is down, so its refunding transaction will retry. For a while later, it is done. Then it is REFUNDED eventually.
So, there will be invoice transactions look like this
This is pretty much the story in my mind so far. It basically tries a couple of times when a payment method is set, when it fails, goes into fail status and wait actions from users. The under-layer transaction model provides a retrying mechanism, so temporary issues (server downtime or anything like that) can be avoided. If there are some corner cases are missing, please let me know.
@victorlin do you consider what the failure reason is? You shouldn't retry if there is a Hard Failure such any of the following:
@matin make sense. will do.
@mahmoudimus @mjallday @msherry
What kind of hard failure errors (code or message) we are expecting from Balanced API? I try to read the source code, but cannot find something useful. I think they are from under-layer API.
@victorlin I think the Balanced API should return a flag indicating if it's a hard failure or not. the current error codes are vendor specific and it shouldn't be the job of services that consume the Balanced API to interpret 3rd party error messages.
There's an open issue to address this - https://github.com/balanced/balanced-api/issues/412
@mjallday So, how can I tell is it a hard failure or not from the response? For example, I received a response like this
{
"status": "Conflict",
"category_code": "bank-account-already-associated",
"description": "Bank account has already been associated with an account. Your request id is OHMbaa8b6620a2b11e3adde026ba7c1aba6.",
"status_code": 409,
"extras": {},
"category_type": "logical",
"_uris": {},
"request_id": "OHMbaa8b6620a2b11e3adde026ba7c1aba6",
"additional": null
}
New transaction state diagram, upon encountering hard failure, it will go into FAILED status immediately.
Why would the API expose a flag telling you to retry? Just retry over intervals. Google for "dunning recurring billing" and you'll see a wealth of resources.
One of the things that we've seen with companies that have recurring billing or delayed invoicing is a higher than normal rate of Soft Failures when charging a card. A Soft Failure is a card declination where you can retry later and possibly have the card approved.
Here are a few examples:
How will this be handled by billy?