Skip to content

feat(api): invoice item create accepts pricing[price] + quantity (newer Stripe SDK shape) - #71

Merged
midagedev merged 1 commit into
mainfrom
feat/invoiceitem-pricing-quantity
Aug 24, 2026
Merged

feat(api): invoice item create accepts pricing[price] + quantity (newer Stripe SDK shape)#71
midagedev merged 1 commit into
mainfrom
feat/invoiceitem-pricing-quantity

Conversation

@midagedev

Copy link
Copy Markdown
Owner

Problem

stripe-java 31 (Stripe API 2025+) creates invoice items with pricing[price] + quantity instead of amount. billtap's validateInvoiceItemCreate allowlist rejects these with parameter_unknown, so any client on a current SDK cannot create invoice items at all (observed as extra-usage payment flows failing with the client mapping the rejection to a 503).

The OpenAPI-generated request schema (internal/stripecompat/validation_generated.go, PostInvoiceitems) already lists both params — only the hand-written validation/handler/model/storage path was missing.

Changes

  • validation: allow pricing[price]/quantity; require amount XOR pricing[price]; reject amount+quantity and amount+pricing with Stripe's exclusive-params message; keep the amount-path non-zero + currency checks.
  • handler: resolve the price (resource_missing on unknown id), derive amount = unit_amount × quantity (quantity defaults to 1), currency from the price.
  • model/storage: persist price_id/product_id/quantity (migration 020) — without the columns the create response carried the fields but GET/LIST silently dropped them (read-back test included).
  • serialization: quantity + pricing: {type: "price_details", price_details: {price, product}, unit_amount_decimal} per the current Stripe response shape.

Verification

  • go build ./... / go vet ./internal/... clean
  • go test ./internal/api/ ./internal/billing/ ./internal/storage/ -count=1 all green
  • New TestInvoiceItemPricingCreate: 6 subtests — pricing×quantity drives finalize amount_due, quantity default, both exclusivity rejections, missing price, amount-path regression + persistence read-back.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HapqvjSLa6A6zRqe6dYyvu

Newer Stripe SDKs (stripe-java 31 / API 2025+) create invoice items with
pricing[price] and quantity instead of amount, which the allowlist rejected
as parameter_unknown. Accept the new shape: resolve the price, derive
amount = unit_amount x quantity (quantity defaults to 1), enforce
amount XOR pricing with Stripe's exclusive-params error, and serialize
quantity plus the pricing.price_details block on responses.

Persist price_id/product_id/quantity (migration 020) so the fields survive
reads — without the columns the create response carried them but GET/LIST
silently dropped them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HapqvjSLa6A6zRqe6dYyvu
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