01The ticket and the API view
The merchant's report and what the API returns for the payment and its refunds. Establish facts, name assumptions, and plan your first three queries.
Facts first, theories later
The merchant’s message contains facts and a theory. The theory is “your API refunded twice”. Keep the facts, park the theory. Then read the API responses for the payment and the two refunds and extract everything they can prove: amounts, statuses, identifiers, timestamps, and the request ids in the headers.
The request ids matter more than anything else on this step. Every API call left a row in api_requests and a line in the gateway log, and the request id is the key to both. Write them down.
Separate knowing from assuming
“The merchant sent one refund” is an assumption. “Two refunds succeeded on this payment” is a fact, proven by two GET /refunds responses with status: succeeded. “The customer received two credits” is a fact from the ticket, not yet verified by you. Be strict here: the incident review will ask which is which.
Write down what would confirm or refute each assumption. That is your query plan.
Plan the first three queries
You have limited time. Decide the three things to look up first and the question each answers. A good first query splits the problem in half: for a duplicate, the halves are “two requests arrived” versus “one request was processed twice”. The request log decides that. The next queries follow from the answer.
Your task
Write three lists: what you know (with the response or field that proves it), what you assume (and what would confirm it), and the first three things you will query or search for, in order, with the question each one answers.
Evidence for this step
Read it in the page or download it and open it in your own tools.
Mission artifact ticket.md 16 lines download show
# INC-2026-0912-07: customer refunded twice on one payment
Reporter: integrations@ateliernord.example (Atelier Nord, merchant `mer_B2X9L4M7`)
Opened: 2026-09-12 14:18 UTC, escalated to incident bridge 14:20 UTC
Priority: P1 (money movement)
## Merchant's message
> Our customer service just got a call from a customer who received two refunds of 89.00 CAD for one order. Payment `pay_2Fw6hT9jK3sR8vN1`. Our back office sent exactly one refund request at 14:03 UTC today, from our returns tool, for the full amount. Your API returned an error on it (our logs say "gateway timeout"), so the tool retried, as it always does, and the retry returned 201. Then we received two `refund.succeeded` webhooks, with two different refund ids: `re_A4kT7wQ2mL9sP8xN` and `re_C8pW3mK6tR2sL5qY`. Your API refunded twice. We need this reversed today and we need to know if any other customer is affected.
## Support first-line notes
- Dashboard: payment `pay_2Fw6hT9jK3sR8vN1`, captured 11 September, 8,900 CAD (minor units). Two refunds listed, both `succeeded`, 8,900 each.
- Merchant integration profile: REST client, webhooks verified, no `Idempotency-Key` usage recorded on any request this month.
- Incident bridge opened. Analyst assigned for timeline and blast radius. Review at 15:30 UTC. Mission artifact api-responses.json 55 lines download show
[
{
"request": "GET /v1/payments/pay_2Fw6hT9jK3sR8vN1",
"requested_at": "2026-09-12T14:24:05Z",
"status_code": 200,
"response_headers": { "Northline-Request-Id": "req_5Pm9wK2sT7rL4nQ8" },
"response_body": {
"id": "pay_2Fw6hT9jK3sR8vN1",
"object": "payment",
"status": "captured",
"amount": 8900,
"currency": "CAD",
"amount_captured": 8900,
"amount_refunded": 17800,
"capture_method": "automatic",
"payment_method": { "type": "card", "card": { "brand": "visa", "last4": "1881", "exp_month": 7, "exp_year": 2029 } },
"metadata": { "order_id": "AN-448120" },
"created_at": "2026-09-11T16:44:09Z",
"captured_at": "2026-09-11T16:44:11Z"
}
},
{
"request": "GET /v1/refunds/re_A4kT7wQ2mL9sP8xN",
"requested_at": "2026-09-12T14:24:31Z",
"status_code": 200,
"response_headers": { "Northline-Request-Id": "req_1Ws4kL8mT2pQ9rN6" },
"response_body": {
"id": "re_A4kT7wQ2mL9sP8xN",
"object": "refund",
"payment_id": "pay_2Fw6hT9jK3sR8vN1",
"amount": 8900,
"currency": "CAD",
"status": "succeeded",
"reason": "requested_by_customer",
"created_at": "2026-09-12T14:03:12Z"
}
},
{
"request": "GET /v1/refunds/re_C8pW3mK6tR2sL5qY",
"requested_at": "2026-09-12T14:24:40Z",
"status_code": 200,
"response_headers": { "Northline-Request-Id": "req_6Kt2mW9sL4pR8qN3" },
"response_body": {
"id": "re_C8pW3mK6tR2sL5qY",
"object": "refund",
"payment_id": "pay_2Fw6hT9jK3sR8vN1",
"amount": 8900,
"currency": "CAD",
"status": "succeeded",
"reason": "requested_by_customer",
"created_at": "2026-09-12T14:03:43Z"
}
}
]