One Click, Two Orders
The buyer clicked Place order once. The application returned two purchase references: Order #21 and Order #22, each for BRL 2,098. Both were confirmed. Neither looked like a failed transaction.
In The Incident Is the Prompt, an exception gave the investigation a starting point. Here, success was the symptom. Before looking for a faulty line, we had to establish whether the records represented two legitimate purchases or one intention processed twice.
This is the second case in B2B Order Forensics, an Oracle APEX laboratory with synthetic purchases, deliberate faults and simulated integration. The reproduction uses a controlled replay. It is not evidence of a human double click or duplicate payment.
Two references are a starting point
The buyer’s screen showed a warning that two orders had been received for the purchase, with links to both references. That made the complaint concrete, but it did not explain what happened behind the screen.

Figure 1. The original portal reports two order references for one purchase.
Equal products and amounts would not be enough. A customer can buy the same things twice. Even nearby timestamps can describe separate purchases. We needed to connect the order references to the operation the buyer intended to perform.
I gave Codex, in VS Code, the complaint, the incident window and the authorized evidence interfaces. The request was read-only: separate facts from inferences, keep competing explanations open, and request source when the evidence indicated what to inspect.
What the records established
The identity check returned BF_MCP_RO. The agent then found two completed orders with the same purchase-intention key, the same recorded APEX session and different correlation IDs. Each had its own successful simulated delivery record. There were no recorded errors in the queried surfaces.
The intention key connects retries of one purchase. A correlation ID identifies a processing attempt. Keeping those meanings separate was essential: these were two persisted orders for one intention, not one order appearing twice in a report.
The timeline placed the second receipt roughly 419 milliseconds after the first order’s confirmation. That supported repeated processing after success. It did not identify the browser action that initiated it.

Figure 2. The investigator confirms the read-only identity and distinguishes duplicate orders from evidence about clicks.
The agent kept duplicate handlers, a retry and repeated server-side invocation open as explanations. It rejected display-only duplication and a logged delivery rejection followed by retry. It also avoided turning the absence of recorded errors into a claim that no browser or network problem could have occurred.
That was the first useful result: the complaint had become a bounded question about how a second execution reached the same saved intention. The query scope and selected timeline appear in the technical reference.
The second submission was in the application
The agent requested the checkout page source. After I supplied it, the agent followed the referenced packages available in the local workspace, including the laboratory’s scenario code. This was source-assisted investigation, not a blind diagnosis from logs alone.
The code showed a successful checkout entering a waiting-for-retry state. The page then rendered a marker called bf-finishing. When that marker was present, page-load JavaScript submitted RETRY_ORDER automatically.

Figure 3. The checkout page submits RETRY_ORDER automatically when the finishing marker is rendered.
No second click was required by that path. The separate browser trace from the reproduction recorded the corresponding sequence: a PLACE_ORDER POST, a checkout GET, then a RETRY_ORDER POST. The GET rendered the page; the JavaScript initiated the second POST.
There was another discovery: the package wrote PLACE_ORDER into the access log as a fixed label. Both timeline entries therefore carried that label, even though it did not establish the actual request name. Reading the source changed how we could interpret an apparently precise log field.
The investigator retained a qualification: the local source had not independently been matched to the deployed incident-time version. Its explanation fit the database evidence. The browser trace additionally established the request sequence, but neither should be presented as a complete historical deployment audit.
A lock did not make the purchase idempotent
The original receipt routine locked the intention, calculated the next attempt number and inserted another order using the same intention key. The second attempt therefore received a new order ID and another copy of the saved items.

Figure 4. The original routine locks the intention, then inserts a new order for its next attempt.
The code already avoided reprocessing a completed order ID. That protection did not help when the retry created a different ID. The database also allowed different attempt numbers under one intention.
The lock made the executions take turns. It did not change what each execution was allowed to create. Both could finish successfully while producing the wrong business outcome.
This is why disabling the button would not resolve the demonstrated defect. The second submission was automatic, and the business boundary still accepted another order for the same intended purchase.
Repeat the intention, return the order
I implemented and tested the correction separately from the investigative session, in another schema and APEX application. The original laboratory and its duplicate orders remain available.
The corrected rule is simple: one saved purchase intention resolves to one order. An authorized repeat returns that reference and records another receipt attempt separately. A completed order is not dispatched again; an order in error stays in error. A genuinely new purchase receives a new intention key, even if its contents are identical.
The original user and session checks remain in place. Knowing a key is not permission to reuse someone else’s purchase.
In the corrected browser reproduction, order #11 completed for BRL 2,098. The database recorded a creation receipt and a replay receipt, but only one order and one simulated dispatch for that intention. A previous purchase with identical contents had a different key and remained a separate order.

Figure 5. The corrected replay retained order #11; separate database checks found two receipt attempts and one simulated dispatch.
| Check | Observed outcome |
|---|---|
| Same intention replayed | Original: two orders. Corrected: one order, two receipt attempts, one simulated dispatch. |
| Equal contents, new intention | Separate purchases remained separate. |
| Overlapping database calls | Two SQLcl connections returned one order; one simulated dispatch was recorded. |
| Existing failure cases | Overflow and missing-account errors remained observable, without a dispatch. |
These checks use different mechanisms. The concurrency result came from database connections with the same authorized logical identity. Separate browser sessions tested cart isolation. Neither result substitutes for the other.
What the investigation contributed
The useful progression was from two references, to one repeated intention, to the source path that created another order. The agent also caught a misleading log label and preserved uncertainty about the deployed version.
Instrumentation and accessible source made that work possible. I supplied the scope, provided the page, and performed the separate reproduction and correction tests. There was no measured comparison of time saved, and this small laboratory does not establish production readiness or exactly-once delivery to a real external service.
The public laboratory keeps the original and corrected variants separate. The next case, The Missing Log Proves Nothing, examines what happens when an expected record is absent and several explanations still fit.
Technical reference
The narrative above can be followed without this section. These details document the evidence boundaries, implementation and reproduction checks.
Investigation scope and retained record
The user-supplied VS Code outputs report SESSION_USER, CURRENT_USER and CURRENT_SCHEMA as BF_MCP_RO. Queries were bounded to September 20, 2026 00:00 UTC inclusive through September 21 00:00 UTC exclusive, with limits no greater than 500 rows. The authorized surfaces were BF_V_ORDER_HEALTH, BF_V_INCIDENT_TIMELINE, BF_V_ERROR_PATTERN_SUMMARY and the read-only BF_INCIDENT_PKG interface in APP_DEMO.
The retained conversation and screenshots show the conclusions and source inspection. They are not a complete ordered transcript of every tool call. The exact SQL inputs of the author’s VS Code session have not been recovered for this article; no reconstruction is presented as an original invocation. The bundle and timeline expose related records, so agreement between them is a consistency check rather than independent corroboration.
Application 107 and BRL were supplied context. The investigator correctly noted that the queried views did not independently establish those attributes. The preparation package was discovered locally during source inspection; this access is part of the method.
Selected timeline and browser requests
The following is an editorial projection of the reported timeline, not a screenshot of raw query output. Times are UTC on September 20, 2026.
| Time | Original order | Recorded event |
|---|---|---|
| 15:57:40.131113 | 21 | Received, attempt 1 |
| 15:58:25.473433 | 21 | Access label PLACE_ORDER |
| 15:58:25.484877 | 21 | Simulated delivery succeeded |
| 15:58:25.490323 | 21 | Completed |
| 15:58:25.909576 | 22 | Received, attempt 2, same intention |
| 15:58:25.923211 | 22 | Access label PLACE_ORDER |
| 15:58:25.925274 | 22 | Simulated delivery succeeded |
| 15:58:25.926227 | 22 | Completed |
The separately retained, sanitized browser HAR records POST PLACE_ORDER at 15:58:24.328Z, GET checkout at 15:58:25.527Z, POST RETRY_ORDER at 15:58:25.825Z and GET details at 15:58:25.958Z. Those are browser request timestamps, not database event timestamps. Raw HAR headers, cookies, sessions and checksums are excluded from publication.

Figure 6. The original checkout process handles the retry before placing the order and choosing its redirect.
Corrected database boundary
The original uniqueness rule allowed (request_hash, attempt_no). The corrected BF_ORDER additionally enforces:
constraint bf_order_intention_uq unique(request_hash)
Despite its name, request_hash is a generated intention identifier, not a cart-content digest. The public package signatures remain unchanged. receive_attempt locks the intention, checks customer/user/session ownership and returns an existing order when authorized. BF_SUBMISSION_ATTEMPT retains accepted receipts with their own correlations. Order processing is serialized separately; completed and failed outcomes are not automatically dispatched again.
A lock coordinates transactions; a constraint states which persisted outcomes are permitted. See Oracle’s data concurrency and consistency documentation.
The lab’s autonomous logging can commit independently of the main transaction. It is not a transactional outbox or proof of exactly-once external delivery. Crash recovery and recipient idempotency require a separate production design. See autonomous transactions.
Test mechanisms and limits
All listed executions occurred on September 20, 2026, using APEX 26.1.4. Original app 107 parses as APP_DEMO; corrected app 101 parses as APP_DEMO_IDEM. Order numbers are local to each schema: original orders 21/22 are the duplicate symptom; corrected orders 21/22 below are different regression purchases.
| Mechanism | Case | Observed result |
|---|---|---|
| Original browser | Controlled replay, orders 21/22 | Same intention, two completed orders, one simulated dispatch each. |
| Corrected browser | Controlled replay, orders 10 and later 11 | Each purchase had its own key; each replay retained its order and one dispatch. |
| Corrected SQLcl suite | Sequential repeats before/after completion; equal contents/new keys | Existing reference reused; distinct intentions remained distinct. |
| Corrected SQLcl suite | Wrong/null session, wrong user; direct duplicate insertion | Unauthorized repeats rejected; unique constraint rejected duplicate intention. |
| Two SQLcl connections | Same authorized identity and intention, order 9 | Overlapping intervals; one order, two receipts, one dispatch. |
| Corrected browser | Overflow order 21; missing-account order 22 | Both ERROR, zero integrations; overflow resubmission rejected. |
| Corrected browser | Narrow 390 × 844 purchase, order 23 | Completed, one dispatch; refresh/back/forward created no extra order; cart cleared. |
| Chrome and Safari | Separate authenticated sessions and cookies | Keyboard cart BRL 249 and mouse cart BRL 129 stayed separate after alternating reloads. |
| Browser and keyboard | Search, filters, add/edit/remove, invalid quantities, totals, focus | Recorded checks passed after quantity and checkout-visibility repairs. This is not a complete accessibility audit. |
| Corrected browser | Altered signed order-details URL | APEX checksum protection rejected the request. A separate different-user browser test was not performed. |
For the concurrency run, connection A entered at 15:43:34.145567Z and finished at 15:43:39.163638Z; B entered at 15:43:34.572987Z and finished at 15:43:39.163849Z. These intervals overlap. They describe database concurrency, not concurrent checkout from different browser identities.
The original application was intentionally preserved, including its empty-quantity UI defect. The corrected variant rejects that edit. The scenario selector was restored to RANDOM; previous laboratory orders were retained. The main replay captures precede the last visibility-only repair; that repair’s empty/processed checkout states and a successful purchase were retested separately.
Versions and reproduction
Use post-2-before for the original laboratory and post-2-after for the separate corrected variant. The tag comparison includes implementation, tests and installation documentation. Install the variant in an empty isolated schema and allocate an unused APEX application ID; do not overwrite the original schema or assume the author’s ID is free.
The original source snapshot matches the pre-test file hashes. APEX changes were expressed in APEXLang, checked locally and against the live runtime, and imported after explicit post-check approval. This provenance records the controlled work; it does not replace an independent byte-for-byte audit of the historical deployed application and packages. Preserve that distinction when repeating the investigation.

One Comment