docs(schema): state the currency unit for payment.budget.max - #340
docs(schema): state the currency unit for payment.budget.max#340CODER7657 wants to merge 3 commits into
Conversation
budget.max is interpreted in MAJOR units - BudgetEvaluator computes int(constraint.max * 100) - while its sibling payment.amount_range.max is documented as minor units and compared directly. Only one of the two says which unit it expects. An issuer populating budget.max in minor units, consistent with amount_range.max and with Amount.amount, gets a cap 100x larger than intended, and enforcement appears to work: the evaluator runs and returns no violation. Refs google-agentic-commerce#339
Drops the INR-specific example. AP2 is not India-specific, and 'paise' is not in the project's cspell dictionary.
PISP (Payment Initiation Service Provider) already appears nine times in open_payment_mandate.json on main. The spellcheck job only scans changed files, so any PR touching that schema fails on words it did not introduce. Adding them unblocks the check. Refs google-agentic-commerce#339
|
Two follow-up commits since opening, and a note on CI: 1. Currency-neutral wording. My first draft used an INR example ("5000 rupees, not 5000 paise").
2.
On |
Clarifies the currency unit for
payment.budget.max. One-line description change, no behaviour change.Fixes half of #339.
Why
payment.budget.maxandpayment.amount_range.maxboth bound a payment amount, in the same module, and interpretmaxin different units — but only one of them says so.payment.amount_range.maxis documented as:and
AmountRangeEvaluatorcompares directly, which is correct:payment.budget.maxis documented as:with no unit stated.
BudgetEvaluatormultiplies by 100:So
budget.maxis in the major unit while its sibling is in the minor unit, and the only place that's discoverable today is the evaluator source.Impact of the ambiguity
An issuer populating
budget.maxin minor units — consistent withamount_range.max, and withAmount.amount— gets a cap 100x larger than intended. A 5,000 rupee cap silently becomes 500,000.The failure is quiet:
BudgetEvaluatorruns, returns no violation, and the transaction is authorised. Nothing indicates the ceiling was read differently from how it was written.I hit this myself on first integration, using the schema descriptions as the guide. I set
Budget(max=5000.0)against a charge of47500paise and expected a violation. There is none, because the effective ceiling is500000paise.What this PR does
Adds the unit to the description, and points at the difference so the next person doesn't have to read the evaluator to find it:
What this PR deliberately does not do
BudgetEvaluatoris untouched. The* 100stays.generated/open_payment_mandate.py. That file is derived from this schema and I did not want to hand-edit generated output or guess at your codegen invocation. Happy to add it if you tell me the command, or to leave it to your next regeneration.budget.maxcorrectly, and that call is yours rather than mine.CLA signed.