Docs

ChargeShield has two halves: the evidence-pack assembler (dispute JSON in, submission-ready pack out) and the Stripe integration service (dispute webhooks in, packs assembled and — when you enable it — submitted via the Stripe API, with every case tracked in the case ledger).

Build an evidence pack

python3 assemble.py --dispute dispute.json --out cases/dp_123/
# stdout: {"dispute_id":"dp_123","category":"fraudulent",
#          "evidence_required":[...],"evidence_provided":[...],
#          "evidence_missing":[...],"ready_to_submit":false,
#          "pack_path":"cases/dp_123/evidence_pack.zip"}
#
# WARNING: 2 evidence item(s) missing: tracking_history, refund_record

Outputs: cover_letter.md, evidence_checklist.md, order_summary.json, evidence_pack.zip. Exit codes: 0 built, 2 bad input, 1 write error.

Dispute JSON

{
  "dispute_id": "dp_123",
  "reason": "fraudulent",            // or a Visa/MC code: "10.4", "13.1"
  "amount_cents": 4999,
  "merchant_name": "Acme",
  "customer": {"name": "...", "email": "..."},
  "order": {"id": "...", "date": "...", "items": [...]},
  "fulfillment": {"carrier": "UPS", "tracking_number": "...",
                  "delivered_date": "...", "tracking_history": [...]},
  "payment": {"avs_match": "Y", "cvc_match": "M",
              "descriptor": "ACME", "device_ip": "..."},
  "communications": [{"at": "...", "note": "..."}],
  "refund_policy_url": "https://..."
}

Required: dispute_id, reason, amount_cents (non-negative integer). Everything else feeds the evidence mapping.

Python library

from assemble import build_pack, validate_dispute
from reason_codes import categorize, CATEGORIES

validate_dispute(dispute)   # [] if valid, else a list of problems
categorize("10.4")          # -> "fraudulent"
summary = build_pack(dispute, Path("cases/dp_1/"))

Reason families

fraudulent · product_not_received · product_not_as_described · duplicate · subscription_canceled · credit_not_processed — see reason_codes.py for Visa/MC code aliases and the required evidence per family.