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.