# Pathrule Pattern: Refunds, Chargebacks, and Disputes (1.0.0)
# ::pathrule:package:refunds-chargebacks-disputes

### [RULE] Create one refund intent before calling the provider  (path: /src/payments/refunds)
<!-- scope: folder | priority: high | strict -->

A refund API response can time out after the processor accepted the request, and support may retry from another screen. Create one internal refund intent first with a stable operation key, original charge, amount, currency, affected items, reason, actor, and expected allocation. Reuse that intent until the provider outcome is known.

- Validate cumulative confirmed and pending refunds against the refundable amount in the original currency.
- Send the stable idempotency key on every provider retry and resolve ambiguity by provider lookup.
- Distinguish requested, submitted, pending, succeeded, failed, canceled, and reversed states instead of setting refunded immediately.
- Authorize partial and full refunds through explicit policy and preserve the original charge unchanged.

Verification: Inject timeouts before and after provider acceptance, race two agents, and attempt overlapping partial refunds; confirm at most one external mutation per intent.

---

### [RULE] Dispute cases preserve deadlines and evidence provenance  (path: /src/payments/disputes)
<!-- scope: folder | priority: high | strict -->

A dispute is a time-bounded case, not a boolean on a payment. Capture each provider event, deadline, reason code, contested amount, currency, liability, and current stage in an append-only case timeline. Evidence must be traceable to its source and reviewed for relevance, accuracy, privacy, and provider limits before submission.

- Assign an owner and escalation clock as soon as a dispute or inquiry becomes actionable.
- Store hashes or immutable references for submitted documents and the exact field set accepted by the provider.
- Never fabricate, backdate, or alter customer communications to improve a case.
- Record whether the case was accepted, lost, won, withdrawn, or moved to another stage and retain the provider receipt.

Verification: Simulate duplicate events, an updated deadline, partial evidence failure, and a late case; confirm the timeline, alerting, and submission record remain coherent.

---

### [RULE] Post reversals without rewriting the original payment  (path: /src/ledger)
<!-- scope: folder | priority: high | strict -->

The original charge remains historical truth even when value later moves back. Post a linked set of immutable entries for refund principal, non-returned fees, dispute withdrawal, dispute fee, provisional credit, reversal, win, or loss as the provider lifecycle requires. Keep provider effective time separate from the business decision time.

- Balance each posting set per currency and store the original payment, refund, dispute, and balance movement references.
- Represent partial outcomes explicitly instead of replacing a payment status or netting unrelated cases.
- Use actual settlement conversion evidence for cross-currency bank effects while retaining the original transaction currency.
- Reconcile every provider balance movement to exactly one recognized internal intent or classified exception.

Verification: Replay a partial refund, a lost dispute, a won dispute with fee treatment, and a reversed refund; confirm the original payment is unchanged and totals reconcile.

---

### [MEMORY] Money reversal and product access are separate decisions  (path: /src/payments/disputes)

Do not let a provider status directly delete user data or revoke product access. A full refund may end a future service, a partial refund may not change access, an inquiry may require only monitoring, and a dispute may trigger a temporary risk hold while evidence is reviewed. Define these outcomes by product type, fulfillment state, fraud signal, contractual terms, and applicable policy.

Store the policy version and reason behind every access transition, make the action reversible where possible, and preserve customer data under retention rules rather than destructive shortcuts. Notify the customer through approved language when required and separate support visibility from sensitive risk notes. See /src/ledger for financial postings and /ops/risk for case handling evidence.

---

### [MEMORY] Refund reason taxonomy drives reporting and controls  (path: /src/payments/refunds)

One free-form refund reason cannot serve the customer, support, product, risk, and finance at the same time. Keep a controlled internal reason code, optional subreason, customer-visible explanation, actor note, affected items, and evidence reference as separate fields. Version the taxonomy so historical reporting does not change when labels are reorganized.

Use reason codes to route approval thresholds, fraud review, supplier recovery, product defect follow-up, and accounting treatment, but never let a code alone authorize money movement. Restrict sensitive risk notes from customer-facing exports and analytics with broad access. Review high use of generic or other codes as a data-quality failure. See /ops/risk for dispute evidence handling and /src/ledger for financial classification.

---

### [MEMORY] Dispute state is a timeline, not the latest webhook label  (path: /ops/risk)

The latest provider label may omit earlier deadlines, provisional withdrawals, reopened stages, appeal rights, or final settlement timing. Preserve every state transition and provider event with effective time, received time, evidence deadline, actionability, financial effect, and source id. Derive the current case view from that timeline without deleting superseded facts.

Keep operational status separate from ledger settlement: a case can be won while a fee remains, or decided before money returns. Alert from the authoritative deadline and require explicit acknowledgment, ownership transfer, and escalation. Map provider-specific reason and stage values to an internal model while retaining the raw value. See /src/payments/disputes for submission evidence and /src/ledger for money effects.

---

### [SKILL] prepare-dispute-evidence  (path: /ops/risk)

---
name: prepare-dispute-evidence
description: Build a truthful and deadline-aware payment dispute evidence package from retained records.
---

# Prepare Dispute Evidence

1. Confirm provider case id, reason, stage, contested amount, currency, response deadline, owner, and the exact evidence fields allowed.
2. Assemble only relevant records from the original order, payment authorization, customer identity checks, terms acceptance, delivery or usage, refund policy, and communications.
3. Verify timestamps, identities, document provenance, completeness, and privacy; remove unrelated personal or secret data.
4. Write a concise case narrative that connects each claim to attached evidence without inventing intent or altering source material.
5. Submit before the internal cutoff, retain the exact payload and provider receipt, and schedule outcome follow-up.

If evidence is missing or contradictory, record that limitation and escalate. Never create retrospective evidence to fill a gap.

---

### [SKILL] audit-refund-controls  (path: /src/payments/refunds)

---
name: audit-refund-controls
description: Review refund authorization, idempotency, limits, reconciliation, and downstream effects.
---

# Audit Refund Controls

1. Trace full and partial refunds from support or API request through authorization, internal intent, provider call, webhook confirmation, customer notice, access policy, and ledger posting.
2. Test duplicate clicks, concurrent agents, network timeouts, provider retry, stale order state, currency mismatch, and cumulative over-refund attempts.
3. Compare internal refund records with provider refunds and balance movements, then classify every missing, duplicate, failed, reversed, or amount-different case.
4. Sample approved refunds for actor, reason, evidence, policy version, item allocation, and immutable audit history.
5. Record control failures, affected period and amount, remediation owner, and proof from a clean rerun.

A green audit requires explainable money movement, not merely matching order labels.
