fix(orders): tighten shipping address, line, and item schema constraints#121
Open
leofischer wants to merge 7 commits into
Open
fix(orders): tighten shipping address, line, and item schema constraints#121leofischer wants to merge 7 commits into
leofischer wants to merge 7 commits into
Conversation
Align the OpenAPI schemas with the validations enforced by payments-api's v200 param sanitizers, which were previously under-documented. - Extract the shipping-contact address into a shared schemas/customers/shipping_contact_address.yml and reference it from the create and update shipping-contact schemas, removing the duplicated inline address blocks. - Mark street1, postal_code, and country as required on the create path (matching ShippingContacts::Validator#validate_on_create); the update path keeps them optional. - Document the MX 5-digit postal code rule and add field descriptions. - Add maxLength: 250 to address fields, shipping line carrier/tracking_number/ method, and line-item name/brand/sku and tag items. - Regenerate _build/api.yaml. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Align the OpenAPI schemas with the validations enforced by payments-api's v200 param sanitizers, which were previously under-documented. - Extract the shipping-contact address into a shared schemas/customers/shipping_contact_address.yml and reference it from the create and update shipping-contact schemas, removing the duplicated inline address blocks. - Mark street1, postal_code, and country as required on the create path (matching ShippingContacts::Validator#validate_on_create); the update path keeps them optional. - Document the MX 5-digit postal code rule and add field descriptions. - Add min/max length constraints matching StringValidator (strict bounds: less_than/greater_than). String fields cap at maxLength 249 (the sanitizer rejects length >= 250); minLength derives from greater_than + 1. postal_code keeps maxLength 250, its only cap being the model-level zip validation. Applies to address fields, shipping line carrier/tracking_number/method, and line-item name/description/brand/sku/tags (create and update). - Regenerate _build/api.yaml. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ations
Applies verified corrections from the payments-api validator audit:
- exclude_card_networks: real accepted vocabulary is [visa_master_card,
amex] (exact-membership options_array validator); visa/mastercard as
separate values are rejected. Responses echo stored values in CamelCase.
- three_ds_mode: add the accepted value not_strict (shared constant
ALLOWED_TYPES_FOR_3DS_BY_API allows strict/not_strict/smart); note the
field is create-only and nullable.
- metadata (orders, products, shipping/tax lines): values must be scalar
string(<=249)/integer/number/boolean per nested_json_subtypes; replaces
the too-loose additionalProperties:true and too-narrow {type: string}.
- bnpl: cancel_url is optional by design (spec-pinned in payments-api);
remove can_not_expire (not in the cleaner allowlist, silently stripped);
add expires_at (the real expiry control).
- card: document the enforced two-word cardholder name rule and maxLength;
expose contract_id (10-char bank contract reference, create-only).
- fiscal entity address: remove residential (stripped by cleaner and not
storable on FiscalEntityAddress).
- Rebuild _build/api.yaml.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…data schemas Four skeptic reviewers re-derived every changed constraint from payments-api source. Corrections from confirmed findings: - metadata additionalProperties: oneOf -> anyOf. type integer and type number both match an integer value, so strict oneOf validators reject integers the API accepts. - exclude_card_networks: remove the CamelCase echo claim and the CamelCase enum values. The mapper camelizes only the internal checkout service payload; Checkout.to_snake_case underscores values on every read (checkout.rb:418-420), so API responses return snake_case. - order three_ds_mode: drop "accepted on creation only" (the orders cleaner permits it on update via permitted_params_shared; it is only validated on create). Checkout keeps create-only wording (its update cleaner permits nothing). - three_ds_mode null semantics: null defers to the company-level 3DS configuration; it does not disable 3DS. - not_strict description: behaviorally identical to strict in payments-api; attempt acceptance is governed by company configuration. - shipping address city: document the enforced two-consecutive-letters pattern. - card name / bnpl expires_at descriptions enriched per review. - Rebuild _build/api.yaml. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…cement payments-api will not change validation behavior for existing customers, so the partial per-key enforcement in NestedTypeValidator stays. State that nested objects/arrays in metadata are "not supported" rather than "rejected" — the contract is accurate without promising server-side rejection in every position. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Five reviewers (two removal deep-dives + three full-quadrant passes) re-derived every changed line from payments-api validators, views and specs. Both questioned removals were confirmed correct: - can_not_expire (bnpl): never existed in the bnpl sanitizer (git -S empty since creation); all 26 code references are checkout/cash flows. Also cleaned the two stale bnpl request examples still sending it. - residential (fiscal address): unstorable (no Mongoid field, not in attr_accessible), stripped or blocked on every route including nested customer create, never rendered. Corrections from confirmed findings: - order three_ds_mode: explicit null is rejected (type: String check on create, empirically reproduced) -> type string, enum without null; omitting the field means no 3DS via the API (company-level 3DS applies only via Checkout or antifraud), replacing the wrong deferral claim. - checkout three_ds_mode: stays nullable (response schema) but explains null-in-responses vs omit-on-creation. - not_strict summaries: 3DS2 "flow" not "challenge" (challenge vs frictionless is issuer-side). - card name description: the regex allows , . ' - and accented letters; no longer implies punctuated names are rejected. - tax description minLength 2 -> 3 (greater_than: 2 is strict). - between_streets: document enforced maxLength 249 and two-letter pattern (city_validations). - klarna_bnpl intentionally NOT added to product_type despite being parser-accepted: not publicly available. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Member
Author
Second adversarial review — consolidated verdictFive independent reviewers (two removal deep-dives + three full-quadrant passes) re-derived every changed line of this PR from payments-api validators, views, and specs. One reviewer empirically executed the TypeValidator to settle null handling. Both questioned removals confirmed correct:
Errors found in the previous revision, now fixed:
Pre-existing spec-modeling issues flagged for follow-up (not touched):
🤖 Generated with Claude Code |
fcarrero
reviewed
Jul 3, 2026
…h CI CI bundles with redocly/cli 2.34.0 and diffs against the committed _build/api.yaml, but the Makefile still used openapi-generator-cli v7.23.0, producing an incompatible serialization — so any bundle committed via `make merge` failed the up-to-date check. Regenerate the bundle with the CI command and point `make merge` at the same redocly invocation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Summary
Aligns the OpenAPI schemas for order shipping address, shipping line, line item, checkout, card/BNPL payment methods, and metadata with the validations actually enforced by
payments-api's sanitizers at v2.3.0. Every constraint was verified against payments-api source, then adversarially re-reviewed by four independent passes that re-derived each bound from code; their confirmed findings are incorporated.Targets
release/v2.3.0.Changes
Shipping (original scope)
schemas/customers/shipping_contact_address.yml; create requiresstreet1/postal_code/country(update does not); MX 5-digit postal-code rule; min/max lengths per the strictStringValidatorbounds (max =less_than− 1 = 249; min =greater_than+ 1).postal_codekeeps 250 (its only cap is the inclusive model-levelziprule). City documents the enforced two-consecutive-letters pattern.Checkout / order (validated with team rulings)
exclude_card_networksenum →[visa_master_card, amex](exact-membership validator;visa/mastercardare rejected). Responses return snake_case — an earlier CamelCase-echo claim was refuted in adversarial review (Checkout.to_snake_caseunderscores values on every read) and removed.three_ds_mode→ adds accepted valuenot_strict; null defers to company-level 3DS configuration (it does not disable 3DS);not_strictis behaviorally identical tostrictin payments-api (attempt acceptance is company-config, not mode). Create-only wording kept for checkouts (update cleaner permits nothing) and dropped for orders (permitted+persisted on update, validated on create).string(≤249)/integer/number/booleanviaanyOf(adversarial review caught thatoneOfrejects integers, which match bothintegerandnumber). Worded as "not supported" rather than "rejected": per team direction payments-api keeps its current partial per-key enforcement, so the docs state the contract without over-promising server-side rejection.maxProperties: 100retained/extended as the documented contract. Known gap: payments-api does not enforce it (characterization specs pinning this landed in conekta/payments-api#6466); closing it is a future product decision.Payment methods
cancel_urlis optional by design (spec-pinned in payments-api);can_not_expireremoved (silently stripped by the cleaner);expires_atadded (unix seconds; defaults to one month). Note: its datatype is currently unvalidated server-side (non-Integer 500s) — documented contract is integer.namerule (letters only) +maxLength: 249;contract_idexposed (exactly 10 chars, create-only, stored asbank_contract_id, echoed in charge responses since v2.1.0; carries a do-not-put-sensitive-data caveat).residentialremoved — stripped by the cleaner and not storable onFiscalEntityAddress(the field exists only onShippingAddress).Verification
make mergerebuilds cleanly; bundler deduplicates the metadata value schema into a single shared component.oneOf→anyOf, CamelCase echo claim removed, orderthree_ds_modecreate-only wording dropped, null semantics corrected,not_strictdescription made honest, city pattern documented.Related
🤖 Generated with Claude Code