409 status code - Duplicate-Invoice error

Hi,

I don’t know if this 50X is for me; if so, then please have a look at this.

this else is covering any other response, it is 50X or any, and considering it an ERROR, and this transaction will never be attempted again as invoice_status is changed now.

thanks

Hi Team,

Here is another challenge need to understand,

If the API failed with the following error,

ORA-29273: HTTP request failed

This means the API call was not completed. Now, it is possible that the payload was sent to ZATCA, but no response was received from ZATCA. In this case, how can we identify if our invoice was reported?

so now this invoice, if resubmitted, might be successful or might be 409?

We have an API that was discussed last year to check if an invoice already exists.

out of 345 B2C received this error just for 1, so 344 success but 1 got this response.

Waiting for your kind response. thanks

Hi @Ankit.K.Tiwari
I’m experiencing the same issue, I keep receiving a 208 error, even though the hash values are newly generated and there are no duplicates.

Example hash:
Wa083qW1y+vVK7JN8EnBaxvlumI4C8nQojJh97LrR6g=

Gp4kjxkYbiIUojvpTsVmCP8E1AVyUumvHu1r6h8hCqE=

@Asali please note that the response code 208 is not an error, it represents a successful submission and the Cleared Invoice is available in the API call response.

What proportion of your B2B invoices are receiving 208 response (as a percentage - its recommended not to give count of invoices)?

1 Like

@Ankit.K.Tiwari Thank you for clarifying that the 208 response indicates a successful submission.

Previously, I was receiving 202 response without any issues. but now I’m receiving 208 response even when submitting an invoice for the first time.
The proportion of invoices receiving a 208 response is quite high, as this occurs for most of my first-time submissions.

Thank you

@Malik
This is exactly what I meant earlier.

In this case, when the same invoice is shared again, the result is likely to be 409, which is basically one of the reasons why the Zatka team took this approach.

Of course, this usually happens during peak times or when the internet service is unstable.

Hi,

My issue remains still there as if failure response we can’t say our invoice reported as we received no success and failure can be 100% means zatca not received any data so API failed or it received processed but unable to respond.

Since no API yet there so in such cases wr have to try twice if failed to get success message if call was failed last time or 409 telling was success last time. For us without getting 409 to consider an invoice really reported is not possible. Please suggest if this is not the way or any other recommended as in my case 50X even not there as API not given any response. Thanks

@Ankit.K.Tiwari dear, any update on my query?

@Malik all the hashes you shared are found with 200 response code at ZATCA’s side. If you could not get the response for the first API calls, then you have to treat 409 as successful reporting and close the re-try loop. This is the reason, the message for 409 explicitly states that “Invoice was already Reported successfully earlier”.

@Ankit.K.Tiwari Great using the same way until there is no API to check if an invoice has already been reported. thanks

Dear @Ankit.K.Tiwari

In the first API call if our system couldn’t store the API response due to any reason then in the next call if our system receives 409 then our system should stop the resend loop by treating the same invoice as reported successfully.

Is my assumption correct?

@mohdzeeshan5c0 yes correct, once you receive a 409, please treat the invoice as “Reported successfully” and stop the resend loop.

2 Likes

Hope this community announcement helps you with clearance duplicate (208) response.

1 Like

Hi @Ankit.K.Tiwari @idaoud ,

Reporting API:

  • Scenario : When taxpayers submit B2C invoices via the Reporting API, the hash of invoice will be stored in a dedicated database for 24 hours to identify duplicates.

  • Validation: Subsequent submission of invoice(s) with same hash value within 24 hours will trigger rejection with response code “409 - Invoice was already reported successfully earlier."

  • 409 to be treated as successful reporting: When taxpayers receive 409 response, it is implied that B2C invoice with same hash value was successfully reported in first instance and saved at ZATCA’s end.

I have a question on above scenario,

Question: While we can consider that the document is reported successfully on 409 status codes, What should we consider the document status as? ‘PASS‘, ‘WARNING‘ or ‘ERROR‘?

Morning @hemanthsr

Thanks for reaching out. I hope you are doing well.

Actually, it depends on the first submission status; it can be 200 ‘PASS’ or 202 ’Accept with warning’ it can’t be ‘ERROR’ as the 400 response means that the invoice was not accepted and you need to fix the ERROR and resubmit again.

In summary, when the response is 409, your system should check the same InvoiceHash internally, and will find the same invoice with it status if it was 200 or 202 “PASS” or “PASS WITH WARNING”.

I hope it’s clear enough now.

If you have any other concerns, do not hesitate to reach out to our support team via the email below:

SP mail: sp_support@zatca.gov.sa

Thanks,

Ibrahem Daoud.

Hi @idaoud

I am pretty sure that it is not how it should work. The nature of networking - it can have gateway timeout it can have client timeout and more other errors when the server processed the request but the client did not receive the reponse.

In such situations we will receive 409, but this status does not have any information about if invoice was reported without warnings or with warnings and what warnings were there.

The proper way of implementation such software - is to use idempotency-key, what you are guys kind of using invoiceHash. But when we are using this approach, the result should be consistent between submissions. Instead of returning 208 or 409, you should return exactly the same response as you returned initially.

Could your solution (ZATCA) store the hash - response pair in some database / redis somewhere for some time (preferably 1 month) but even 1 day would be enough in 95% of situations.

A lot of people currently struggling with adopting 409 solution as it does not have clear indications of warnings, status and internals of the original response. For instance our solution was storing all this information JSON and had some special logic, we were parsing violations (warnings) and reporting internally and notifying our customers about it. Now without proper response we cannot do it anymore.

NOTE: we cannot adjust client timeout to 45-60 seconds and wait for the response as it is using our “connections”, these connections kind of “waiting” which affects the latency and availability of our solution. Therefore we are adopting 10s max timeout - due to this we are receiving a lot of client timeout and 409 eventually… Very frustrating situation…

P.S. I am pretty sure that all these people who are receiving this 409 error, is not “intentionally” double-submitting the same document. They just do not have any information about initial submission and therefore they are reporting it “again” which causing confusion and taste of not correct implementation from ZATCA side. Even the hash-check endpoint will not solve the issue as to solve it - it should return the full response back to the client that he has “full” information. In such situation, why not to implement it in original report endpoint and return original response? Otherwise it looks like “distributing” traffic from one endpiont /report to another endpoint /check.

– Best regards, Sergei

1 Like

Hello @idaoud , thank you. A related clarification: Am I correct to understand that if the system could not get any response due to a timeout but recieved a 409, then a 200 ‘PASS’ should be issued in the system to close the resend loop.

Additionally, if a 208 was recieved under the same circumstances (+ no signed XML being stored in the system since no response was recieved due to a system timeout), then a 200 ‘PASS’ should still be issued by default in the system to close the resend loop but the taxpayer should create a credit note and then reissue this invoice to get the Signed XML.

Edit: I was mistaken, the response 208 will include the signed XML: Breaking Change: Checking the duplicate (response codes 208 & 409)

cc: @Ankit.K.Tiwari

@Yatin you may treat 409 as successful reporting of Simplified Invoices. For Standard Invoices, you will get the Cleared Invoice back along with 208 response code. You need not (should not) generate credit notes for invoices either 409 or 208 responses.

1 Like

@Ankit.K.Tiwari @idaoud

Our situation also align with the way @sergei.shishov had explained the problem. we are “not intentionally” resubmitting the same document.

We sometimes/rarely face http timeout error even after waiting for 60 seconds for response and sometimes the connection itself will be reset by the peer (By ZATCA server). In these scenarios, we won’t get any response from ZATCA to store in our system. Therefore, we try resubmitting.

When you say determine the ‘PASS‘ or ‘Accept with warning‘ scenario from your first submission, we don’t have the response from first submission to determine.

If we are able to get the “actual response” for resubmitting the standard invoices with status code 208, why can’t we follow the same approach for simple invoices?

If we get the “actual response“ for simple invoices also with 208 status code that would be ideal.

Hi.
In the case of standard tax bills, the really confusing scenario is what happens as in the illustration below:

An invoice is reported for clearance, our system tries 6 times with failures accompanied by a 50x response code.

In this case the system did not receive the 400 or 20x code. This means that the hash of the current invoice is not yet in the chain. Isn’t it?

Sometimes the buyer leaves and the sale doesn’t go through because the buyer demands a Zatca-approved invoice.

In this case, the hash of this invoice cannot become the PIH of a subsequent invoice.
Also, its status will not be tracked later because its purpose no longer exists as long as the sale is not finalized with the buyer.

Our system already supports considering the invoice as a draft (incomplete invoice) and printing it to the buyer without a QR code, not allowing it to be modified or deleted, and cleared later. However, if the buyer does not want an incomplete invoice, it will be considered a draft invoice that does not affect tax, accounts, or inventory.

Unfortunately, the seller may later be surprised by an email from Zatca stating that the amounts submitted in the tax return do not match the reported invoices.

In addition, the chain (hash&pih) will not be fine and neither will the icv and irn.

I look forward to your advice and experiences.