feat: add a post-transaction dispute resolution sample - #352
Open
maximusrufus wants to merge 1 commit into
Open
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
maximusrufus
force-pushed
the
samples/dispute-scenario
branch
3 times, most recently
from
September 9, 2026 17:54
7296927 to
c43411e
Compare
Author
|
@googlebot I signed it! |
maximusrufus
force-pushed
the
samples/dispute-scenario
branch
2 times, most recently
from
September 9, 2026 18:19
5d34161 to
32b2a5c
Compare
6 tasks
maximusrufus
force-pushed
the
samples/dispute-scenario
branch
from
September 9, 2026 21:33
32b2a5c to
1bb29b3
Compare
maximusrufus
force-pushed
the
samples/dispute-scenario
branch
from
September 9, 2026 21:46
1bb29b3 to
ea8d324
Compare
Adds a stdlib-only sample under code/samples/python/scenarios/dispute that shows what happens after an AP2 flow completes and the parties disagree, when the disagreement is not fraud. The resolver reads only artifacts a completed flow already leaves behind: the checkout mandate hash, the payment mandate, both receipts, and the order record. It verifies the authorization chain binds, and routes a broken chain back to the network fraud process rather than deciding it. Where the chain holds, it decides performance per line under a published policy and emits a determination with per-line outcomes, the factors considered, a signer slot, a loser-pays fee disposition, and a content-hash seal. The point is narrow: the AP2 trail is sufficient evidence for a neutral third party to resolve non-fraud disputes without any data the protocol does not already emit. The sample names no provider and takes no position on who should run a resolver. No API key and no third-party dependency is required to run it. Adds ATDRP and unassessable to the project spell-check dictionary.
maximusrufus
force-pushed
the
samples/dispute-scenario
branch
from
September 9, 2026 21:51
ea8d324 to
b2c1c80
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds a stdlib-only sample under
code/samples/python/scenarios/dispute/showing what happens after an AP2 flow completes and the parties disagree, where the disagreement is not fraud.The resolver reads only artifacts a completed flow already leaves behind — the checkout mandate hash, the payment mandate, both receipts, and the order record. It:
payment_mandate.transaction_idand both receipts'referenceagainst the closed checkout mandate'scheckout_hash). A chain that does not bind is an authorization question, so the sample declines it and routes it to the network fraud process rather than deciding it;Scenario. A shopping agent completed a human-not-present purchase of 4 units under a signed Payment Mandate. The merchant issued Success receipts. The order record shows 1 of 4 units fulfilled and the merchant's own
estimated_deliverywindow has passed with no adjustment.Run it.
Line
line_item_456is overturned for 7500 minor units, fee paid by the merchant. Tamper withpayment_mandate.transaction_idand the same command returnsnot_eligible: authorization_chain_brokenwithroute: network fraud process.Why it might be useful here. The point is narrow: the AP2 trail is sufficient evidence for a neutral third party to resolve non-fraud disputes without any data the protocol does not already emit. The sample names no provider and takes no position on who should run a resolver.
Before submitting your PR, there are a few things you can do to make sure it goes smoothly:
CONTRIBUTINGGuide.ruffpasses under this repo's.ruff.toml(Google style, 80 columns) andcspellpasses under.cspell.json. The sample runs clean from the repo root. TheLint Code Basejob is red on aBIOME_LINTfailure that predates this PR: the same failure appears on unrelated open PRs, and that job'sFILTER_REGEX_EXCLUDEskipscode/samples/, so it is not evaluating anything added here. Happy to rebase once it is green on main.Two notes for reviewers:
ATDRPandunassessablewere added to.cspell/custom-words.txt, inserted in place without reordering the existing entries.code/samples/python/scenarios/dispute/is not where you would want it.Fixes #N/A — new sample, no linked issue. 🦕