Skip to content

fix(sdk): preserve payment instrument extensions - #333

Open
shibutatsu wants to merge 2 commits into
google-agentic-commerce:mainfrom
shibutatsu:codex/preserve-payment-instrument-extensions
Open

fix(sdk): preserve payment instrument extensions#333
shibutatsu wants to merge 2 commits into
google-agentic-commerce:mainfrom
shibutatsu:codex/preserve-payment-instrument-extensions

Conversation

@shibutatsu

Copy link
Copy Markdown

Problem

AP2 allows a payment instrument type to define additional properties, but the generated Python PaymentInstrument currently uses Pydantic's default extra='ignore' behavior. Callers can pass a type-specific field without an error, yet the field disappears before model_dump() and is therefore absent from the signed mandate.

The Python x402 sample exposes the effect: it supplies payee_address and facilitator, but the generated model drops both values before signing.

Root cause

The common Payment Instrument JSON Schema leaves additional properties implicit. datamodel-code-generator does not translate that implicit JSON Schema default into an explicit Pydantic setting, so the generated model silently ignores fields outside id, type, and description.

Fix

  • Set additionalProperties: true explicitly in payment_instrument.json.
  • Regenerate PaymentInstrument, which adds ConfigDict(extra='allow').
  • Add a regression test using the generated model and the existing x402 sample fields.

The test checks the full boundary requested in #299:

  1. PaymentInstrument construction and model_dump() retain the fields.
  2. Nesting the instrument in PaymentMandate retains them.
  3. SD-JWT creation, presentation, verification, and PaymentMandateChain.parse() return the same signed values on the typed instrument.

This keeps the common AP2 model extensible as described by the specification. Validation of a type-specific field's format and semantics remains the responsibility of that payment-instrument profile; this change only prevents accepted values from being silently removed.

Verification

  • Python 3.12 targeted tests: 5 passed.
  • Full SDK tests: 187 passed. Two existing intermediate KB-SD-JWT audience/nonce tests failed; the same two tests also fail unchanged on upstream/main in a clean Python 3.12 environment.
  • JSON Schema parsing and git diff --check passed.

Addresses the remaining extension-preservation item in #299. It does not overlap the verified-amount fix in #300 or the (type, id) matching fix in #301.

@google-cla

google-cla Bot commented Aug 13, 2026

Copy link
Copy Markdown

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.

@shibutatsu

Copy link
Copy Markdown
Author

Spellcheck now passes after adding the four project terms used by the generated model and regression test.

The remaining Lint Code Base failure appears unrelated to this PR's three-file diff. The job reports 75 existing BIOME_LINT errors across code/web-client and docs/assets even though VALIDATE_ALL_CODEBASE is set to false; none of those files are changed here. Could a maintainer advise whether changed-file detection needs different handling for fork PRs, or rerun the check with the intended diff scope?

The Google CLA check is a separate contributor action and is not a code failure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant