PHP cURL duplicating calls

Hi

I am using PHP cURL to make API calls to an accounting site, but some of our invoices are being duplicated. From a Fiddler report, I can see that the two calls are being made milliseconds apart.

This is how I have configured the logic:

  1. check internal database if order is invoiced
  2. stop if it is invoiced, continue if its not
  3. gather all required variables (customer ID, product codes) from internal database
  4. do first API call to get product descriptions & prices using product codes
  5. do second API call to get customer details using Customer ID
  6. do third API call to create new invoice using above details
  7. get invoice ID and invoice document number
  8. do fourth API call to email invoice to customer, using above details
  9. update internal database - change order status to “invoiced”

It is the third and fourth API calls (creating invoice & sending email) that are periodically duplicated (about 1 in every 50 or so - the others don’t duplicate). I have made sure that the operator who triggers the process does not refresh their browser while waiting for the process to complete.

Is there any way that I can prevent this from happening (maybe with a delay between the calls)?

Thanks.

I have seen issues some time ago (and not in a PHP environment) where submitting a HTTP form can “bounce”, that is the same form gets submitted twice, only a very short time apart, similar to the way you are seeing. I can’t quite remember exactly what was causing it.

Can you “re-arrange” things so that after step 2, rather than doing the (relatively) time-consuming gathering of product information, you introduce a step “2a” which is to set a “pending” flag of some sort in the order table? That way, the second “hit” won’t go anywhere.

Hi

Thanks for the input. Are you suggesting something like this:

  1. check internal database if order is invoiced
  2. stop if it is invoiced, continue if its not
    2a. change status of order in internal db to “pending”
  3. gather all required variables (customer ID, product codes) from internal database
  4. do first API call to get product descriptions & prices using product codes
  5. do second API call to get customer details using Customer ID
    5a. check if order status in internal db is “pending” - stop if not, else continue
  6. do third API call to create new invoice using above details
  7. get invoice ID and invoice document number
  8. do fourth API call to email invoice to customer, using above details
  9. update internal database - change order status to “invoiced”

I cannot see that this would make any difference though. The "bouncing seems to be happening in step 6, so step 5a won’t stop the duplication.

Or am I understanding you wrong?

The way I read it is that the second attempt runs somewhere before the internal database status has been updated to show the order is invoiced, so anywhere between the start and step 6. There is significant time delay between your status check at step 2, and when you create the invoice at step 6.

What I was really thinking is:

  1. check internal database if order is invoiced
  2. stop if it is invoiced or pending, continue if its not
    2a. change status of order in internal db to “pending”
  3. gather all required variables (customer ID, product codes) from internal database
  4. do first API call to get product descriptions & prices using product codes
  5. do second API call to get customer details using Customer ID
  6. do third API call to create new invoice using above details
  7. get invoice ID and invoice document number
  8. do fourth API call to email invoice to customer, using above details
  9. update internal database - change order status to “invoiced”

If it’s already pending when the second instance checks, there’s surely no need to do any of the other steps because the first instance will be doing that.

The only issue is what the user sees, and I suspect that it would be along the lines of waiting a few seconds, checking that it has now changed to “invoiced” and display the confirmation from there.

Actually, reading your original post again, you may have a different issue to the one I had. In mine, the problem was that the “submit” from the web page form was coming in twice, which was firing the CGI code twice, hence the above solution would do it. If yours is not doing that, it may be no help. So I guess the question is, is it only duplicating those two steps, or is it actually duplicating all of them, from your local logs / debug?

Hi

From the logs, it is only duplicating steps 6 through 8.

Oh, OK. Sorry for taking it down the wrong road then.

I’d say it’s probably impossible to say why it would duplicate those specific sections without seeing the code.

I think I found the problem - I had “$curl = curl_init($api_url);” repeated in my code.

Thanks for the input.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.