OpenChainGraph · Explainer

Art 777: PSP Dispute Reason Crosswalk

One lookup turns any PSP’s dispute reason into its equivalents at PayPal, Stripe, Adyen and Square, with a match grade and the snapshot clause behind every cell. Nothing is inferred: a mapping no snapshot supports is simply none. Quotes come from the four primary-text snapshots (fetched 2026-10-25/26); the kernel is static, credential-free, zero network.

Presenter mode shows one step per screen. Arrow keys move, A toggles autoplay, Esc exits.
1
Step 1

The same buyer dispute wears four vocabularies

A buyer says “I never authorized this charge,” and each PSP’s paperwork names that condition differently.

one buyer condition PayPalUNAUTHORISED Stripefraudulent Adyen10.4 SquareFRAUDULENT same dispute, four spellings; nothing renames them

Each PSP’s values are reproduced verbatim from that PSP’s own published tables: PayPal’s dispute_reason enum (schema v1.12, including the British UNAUTHORISED), Stripe’s reason, Adyen’s Visa scheme reason codes, Square’s DisputeReason. The crosswalk never renames or normalizes anyone’s vocabulary; it maps between them.

2
Step 2

The snapshots are the only authority

Every mapping cell cites the snapshot clause that justifies it: id, verbatim quote, URL.

snapshotpaypal-disputes-2026-10S5 · schema v1.12fetch 2026-10-25T03Z crosswalk cellvalue: UNAUTHORISEDmatch: exactclauses: S5 no clause,no cell.

Four primary-text snapshots (PayPal S1–S9, Stripe S1–S6, Adyen A1–A6, Square Q1–Q5) are the authority here. Quotes are verbatim and short. Where a snapshot itself states an absence (Stripe’s Visa table mapping Unrecognized to None; Square publishing no network mapping), that stated absence is cited, not guessed around.

3
Step 3

What one lookup returns

Give it one PSP’s reason; get the equivalents at the other three, each graded exact, partial or none.

input{psp: paypal,reason: UNAUTHORISED} stripe: fraudulentpartial (S2, S5) adyen: 10.4partial (A4) square: FRAUDULENTexact (Q4) each cell:basis + clauses +evidence categories

Why partial for Stripe: Stripe’s own Visa row makes “Fraudulent” broader than a buyer-unauthorized claim (it spans card-present, card-absent and monitoring-program fraud). The grade is that cell’s own clauses speaking, not a judgment call, and the output carries the per-PSP match, the concept label, and every cited clause with its quote.

An agent asks at this stepMCP
crosswalk_psp_dispute_reasons {psp: "paypal", reason: "UNAUTHORISED"}
4
Step 4

When the answer is none

A reason no other PSP’s snapshot supports crosses to none, with the absence stated, not papered over.

paypal singletonPROBLEM_WITH_REMITTANCE stripe: none adyen: none square: none a none cell carries no valueand no invented clause,silence stays silence

The proptest floor (P5) asserts this on singletons: the one designed partial exception (Adyen’s singleton reaching Stripe’s aggregate S5 category) is cited-partial, never silent, never upgraded to exact. Fixture singleton_paypal_crosses_to_none pins the PayPal case end to end.

5
Step 5

Start from the card network, when the snapshot maps it

A Visa 13.1 or Mastercard 4855 code also enters the crosswalk wherever a snapshot publishes the mapping.

network input{network: visa, code: "13.1"} stripe: Fraudulent, 13.1 (S5) adyen: 13.1 in Visa table (A4) square: no network mappingpublished (Q1–Q5),so none is returned, cited

Network-code lookups use only the tables the snapshots actually reproduce (Stripe’s Visa and Mastercard category tables; Adyen’s Visa scheme codes). An unknown network or a code no table carries is refused by name: REFUSED_UNKNOWN_NETWORK, REFUSED_UNKNOWN_NETWORK_CODE.

6
Step 6

How bad input is refused

Bad input gets a named refusal in refusal_reason and domain_errors, never a stack trace.

{psp: "wepay", ...}REFUSED_UNKNOWN_PSP {psp: "paypal", reason: 42}REFUSED_UNKNOWN_REASON UNAUTHORIZED (US spelling)REFUSED_UNKNOWN_REASON both shapes at onceREFUSED_INPUT_SHAPE {network: "amex", code: "1"}REFUSED_UNKNOWN_NETWORK the guard fix from the proptestfloor (P6): a non-string reason isrefused by name, with no .trim() crash

Seven refusal vectors are pinned in the fixtures: unknown PSP (the categorical check fires first: an empty object is REFUSED_UNKNOWN_PSP, a recorded nuance), the PayPal American-vs-British spelling distinction, unknown reason, both-or-neither input shape, unknown network and unknown network code.

An agent asks at this stepMCP
crosswalk_psp_dispute_reasons {network_code: {network: "visa", code: "13.1"}}
7
Step 7

Manifest & provenance

One input surface, one output contract, one kernel digest, and the whole thing runs offline.

Kernel: chaingraph/kernels/art-777-psp-dispute-reason-crosswalk.kernel.mjs: pure data tables plus lookup, no hashing inside the kernel, no iteration bound from inputs. Identity: sha256:8932a23abee00ab938d8cbc12ccc3cc44bd59addb232c25e4097e343e4383037 (SPEC §17.1 compute_images). Prove: deferred (a new gpu:false node excluded from §18 proving until the next batch). Fixtures: 14 vectors with pinned golden hashes; the manifest’s example_execution_hash (2e76d901…) equals the golden vector’s pinned hash. Clause authority: research/clause-snapshots/{paypal,stripe,adyen,square}-disputes-2026-10/SNAPSHOT.md.

input  : {psp: paypal|stripe|adyen|square, reason: <that PSP's exact enum value>}
        | {network_code: {network: visa|mastercard, code: <published code>}}
output : {concept, concept_label, match, per_psp_match,
          crosswalk: {<psp>: {value, match, basis, evidence_categories, clauses[]}},
          network_codes, network_codes_note, cited_clauses[], domain_errors[], refusal_reason}
refuse : REFUSED_UNKNOWN_PSP | REFUSED_UNKNOWN_REASON | REFUSED_INPUT_SHAPE
        | REFUSED_UNKNOWN_NETWORK | REFUSED_UNKNOWN_NETWORK_CODE
🔒 All inputs are processed locally in your browser. No data is transmitted. Do not enter real personal data — use synthetic or anonymised inputs only.

Ask your agent

Copy this paragraph into Claude, OpenClaw, or any MCP-aware agent to run this exact tool, with this sample, and verify the artifact.

Run the AINumbers MCP tool `crosswalk_psp_dispute_reasons`. Task: Crosswalk a dispute reason across PayPal, Stripe, Adyen and Square: from one PSP's own reason value (or a Visa/Mastercard reason code), return the equivalents at the other three with per-cell match grades and the snapshot clause citations that justify each cell; unsupported mappings are none, never inferred.
Call it with arguments: {"policy_parameters":{"psp":"paypal","reason":"UNAUTHORISED"}}
Verify before trusting: call `verify_execution_hash` on mcp.ainumbers.co (https://mcp.ainumbers.co/mcp) with the parameter `claimed_hash` set to the returned `execution_hash`, passing the full artifact the run returned (the object containing `policy_parameters` + `output_payload` + `execution_hash`; equivalently `policy_parameters` + `output_payload` with `claimed_hash`), not the bare hash string.
Return the ledger link https://ledger.ainumbers.co/ so a human can re-verify without contacting us.
PII rule: All inputs are processed locally in your browser. No data is transmitted. Do not enter real personal data — use synthetic or anonymised inputs only.
Open the tool with the sample prefilled: https://ainumbers.co/chaingraph/art-777-psp-dispute-reason-crosswalk.html#p=v1.H4sIAAAAAAAA_wEoANf_eyJwc3AiOiJwYXlwYWwiLCJyZWFzb24iOiJVTkFVVEhPUklTRUQifYp0f1soAAAA