feat(api): stripe surface wave 1 — trial_end preview/confirm parity, default-amount refunds, credit note memo/oob/refund_amount - #72
Merged
Conversation
…credit note memo/oob/refund_amount
Newer Stripe SDK surfaces that clients actually send, wired end to end:
- invoices/create_preview accepts subscription_details[trial_end] (unix or
"now") and prices the first paid cycle instead of rejecting with
parameter_unknown.
- subscriptions/{id} trial_end=now (or a non-future unix) actually ends the
trial: trialing -> active through the existing proration/invoice path, so
preview and confirm produce the same amount (test pins subtotal/tax/total).
A future unix keeps updating trial_end only. Previously the param was
echoed into metadata and silently ignored.
- refunds: omitted amount defaults to the remaining refundable balance
(charged minus non-canceled refunds); explicit over-refunds are rejected.
- credit_notes: memo / out_of_band_amount / refund_amount are accepted,
persisted (migration 021) and echoed; amount defaults to oob+refund.
out_of_band settlement does not credit customer cash balance.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HapqvjSLa6A6zRqe6dYyvu
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.
Context
Follow-up to #71: a census of what current stripe-java 31 clients actually send found a family of gaps — some rejected (
parameter_unknown), some worse: accepted-but-ignored, where the API returns 200 and drops the semantics.Changes
POST /v1/invoices/create_preview×subscription_details[trial_end](was REJECT): allowlist + unix/nowvalidation; previewing a trial ending now prices the first paid cycle (items + tax), not a $0 trial window.POST /v1/subscriptions/{id}×trial_end(was IGNORED — echoed into metadata, no state change):now/non-future unix ends the trial through the existing proration+invoice path (trialing→active); future unix updates the timestamp only.TestInvoicePreviewTrialEndNowMatchesConfirmpins preview↔confirm parity:subtotal=4900 tax=490 total=5390on both sides.POST /v1/refunds(omittedamountwas REJECT): defaults to the remaining refundable balance (charged − non-canceled/failed refunds); explicit amounts above the remainder are rejected.POST /v1/credit_notes×memo/out_of_band_amount/refund_amount(was REJECT): accepted, persisted (migration 021), echoed;amountdefaults to oob+refund; out-of-band settlement never credits customer cash balance (pinned by test).Verification
go build/go vetclean;go test ./internal/api/ ./internal/billing/ ./internal/storage/ -count=1all green🤖 Generated with Claude Code
https://claude.ai/code/session_01HapqvjSLa6A6zRqe6dYyvu