diff --git a/README.md b/README.md index a79e5f1..2005a52 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,10 @@ Stripe-like API subset, React checkout/portal/dashboard surfaces, signed webhook delivery controls, YAML scenario runs, fixture apply/snapshot/assert APIs, and diagnostic bundles that explain what happened when a billing test failed. -It is **not** a payment processor and it is **not** full Stripe parity. Use it as -the fast deterministic lane, then keep Stripe testmode or the real provider -sandbox as the high-fidelity fallback lane. +It is **not** a payment processor. Billtap's goal is practical Stripe +compatibility for the documented local-test subset: use it as the fast +deterministic lane, then keep Stripe testmode or the real provider sandbox for +behavior outside the published contract. ![Billtap dashboard showing billing objects, timeline, webhook attempts, and debug bundle export](docs/assets/dashboard-screenshot.png) @@ -189,6 +190,7 @@ curl -fsS "http://localhost:8080/api/diagnostics?limit=100" \ | Fixtures | Apply/snapshot/assert APIs | JSON/YAML input, fixture metadata isolation, structured pass/fail reports | | SaaS profile | Generic workspace billing profile | Plans, seats, members, export quota, extra export, payment history, support bundle, platform/connect-style webhook evidence | | Release state | Source plus GHCR image | Local Docker image builds and GHCR image workflow; no package/Homebrew/signed binary yet | +| Stripe API inventory | `144 / 587` operations, `24.5%` L1+ | OpenAPI route inventory is schema-visible for all `587` operations; implemented coverage is tracked in `docs/STRIPE_COMPATIBILITY_90_TARGET.md` | Detailed compatibility matrix: `docs/COMPATIBILITY.md`. diff --git a/docs/API_VALIDATION_AND_ERROR_SIMULATION.md b/docs/API_VALIDATION_AND_ERROR_SIMULATION.md index 46e2aa4..0702445 100644 --- a/docs/API_VALIDATION_AND_ERROR_SIMULATION.md +++ b/docs/API_VALIDATION_AND_ERROR_SIMULATION.md @@ -25,6 +25,12 @@ Current release status: - Prices search now has focused tests for the documented search subset used by one-time price lookup paths: `active`, `type`, `lookup_key`, metadata equality, `limit`, and unsupported-clause validation. +- Invoice preview responses include the common Stripe Invoice default fields + needed by generated SDK models, including status transitions, automatic tax, + payment settings, tax totals, period bounds, and array-shaped `discounts`. +- The `stripe-node` SDK smoke lane remains the automated CI adoption check; a + local `stripe-java` 31.1.0 smoke confirmed `Invoice` deserialization for + `/v1/invoices/create_preview` after the preview schema update. - Live Stripe calls and the external `stripe-mock` oracle lane remain optional outside normal CI. diff --git a/docs/COMPATIBILITY_TRACKING.md b/docs/COMPATIBILITY_TRACKING.md index fe2e145..7d1fe9b 100644 --- a/docs/COMPATIBILITY_TRACKING.md +++ b/docs/COMPATIBILITY_TRACKING.md @@ -1,6 +1,6 @@ # Compatibility Tracking -Status date: 2026-05-11 +Status date: 2026-05-12 This document defines how Billtap tracks Stripe API compatibility as a measurable, long-running body of work. The public claim is the generated @@ -84,7 +84,7 @@ The long-running expansion goal is at least 90% OpenAPI operation coverage at The concrete target and chunk plan live in `docs/STRIPE_COMPATIBILITY_90_TARGET.md`. In short: -- current baseline: `110 / 587`, `18.7%` +- current baseline: `144 / 587`, `24.5%` - target: at least `529 / 587`, `90.0%` - maximum remaining `L0`: `58 / 587` - P0/P1 billing-lab flows still need deeper `L3-L6` evidence, not just broad diff --git a/docs/GATE_STATUS.md b/docs/GATE_STATUS.md index 8f5a4a4..f4e61a4 100644 --- a/docs/GATE_STATUS.md +++ b/docs/GATE_STATUS.md @@ -18,7 +18,7 @@ This is the public gate snapshot. Internal adoption evidence and raw handoff not | G11 Assertion Ergonomics | Passed locally | Structured pass/fail fixture assertions and fixture-scoped snapshots | | G12 Public Release Readiness | Passed locally | Public claims are tied to tests/scorecard cases; scorecard corpus has 49 release-blocking cases; Apache-2.0 `LICENSE` and `NOTICE` are present | | G13 Stripe API Expansion | In progress | Roadmap defines compatibility levels and endpoint-family priorities; OpenAPI inventory generator and optional workflow write JSON/Markdown coverage artifacts | -| G14 Stripe API 90% Program | In progress | `docs/STRIPE_COMPATIBILITY_90_TARGET.md` defines 90% L1+ target, current 110/587 baseline, family thresholds, and chunk plan | +| G14 Stripe API 90% Program | In progress | `docs/STRIPE_COMPATIBILITY_90_TARGET.md` defines 90% L1+ target, current 144/587 baseline, family thresholds, and chunk plan | ## Current Public Claim @@ -35,20 +35,22 @@ under Apache-2.0. - Coverage focus: request validation, protocol parameter acceptance, idempotency mismatch, deterministic checkout payment-error aliases, direct intent state machines, and billing lifecycle retry/renewal mutations -- OpenAPI operation baseline: `110 / 587`, `18.7%` +- OpenAPI operation baseline: `144 / 587`, `24.5%` - Long-running OpenAPI operation target: at least `529 / 587`, `90.0%`, at `L1+` with deeper P0/P1 behavior gates ## Last Local Code Verification -Verified on 2026-05-11 from branch `codex/connect-people-complete`: +Verified on 2026-05-12 from `origin/main` after PR #50: - `go test ./... -count=1` -- `go run ./cmd/billtap compatibility scorecard --output-dir /tmp/billtap-compat-scorecard-connect-people` +- `go run ./cmd/billtap compatibility scorecard --output-dir /tmp/billtap-scorecard-current` - result: `imported=49 skipped=1 unsupported=1 mismatch=0 error=0` -- `go run ./cmd/billtap compatibility inventory --openapi /tmp/stripe-openapi-spec3.json --output-dir /tmp/billtap-inventory-connect-people --source stripe-openapi-master` - - result: `operations=587 implemented=110 inventory_only=477 schema_validated=587 implemented_percent=18.7` -- `npm run build` +- `go run ./cmd/billtap compatibility inventory --openapi /tmp/stripe-openapi-spec3.json --output-dir /tmp/billtap-inventory-current --source stripe-openapi-local` + - result: `operations=587 implemented=144 inventory_only=443 schema_validated=587 implemented_percent=24.5` +- PR #50 release gate passed on `main`, including Go tests, compatibility scorecard, frontend typecheck/build, sample app smoke, Stripe SDK smoke, web UI smoke, binary build, scenario smoke, and Docker build. +- `docker pull ghcr.io/midagedev/billtap:main` + - result: `ghcr.io/midagedev/billtap@sha256:66072bae9d5dfc346df8cf24099f1ca184711aed0d9a7eacaf19c9d381369136` Release verification should still be rerun on the final release branch or tag. diff --git a/docs/PUBLIC_RELEASE_READINESS.md b/docs/PUBLIC_RELEASE_READINESS.md index ca2694b..a603962 100644 --- a/docs/PUBLIC_RELEASE_READINESS.md +++ b/docs/PUBLIC_RELEASE_READINESS.md @@ -1,6 +1,6 @@ # Public Release Readiness -Status date: 2026-05-09 +Status date: 2026-05-12 Billtap has a clear community-facing strength: it is a stateful local billing lab for deterministic subscription, fixture, scenario, and webhook reliability @@ -39,6 +39,11 @@ Do not describe Billtap as: - Direct intent state machines: PaymentIntent and SetupIntent create, confirm, capture/cancel, and deterministic failure aliases can run without Stripe testmode or real card data. +- Invoice preview compatibility: subscription-update previews calculate local + proration amounts and return Stripe SDK-friendly Invoice response fields. +- Discount coverage: coupons and promotion codes can be applied as a bounded + single-discount subset to customer defaults, checkout sessions, + subscriptions, invoice previews, and renewal invoices. - Webhook lab: delivery attempts record signature evidence, retry scheduling, duplicate delivery, delay, out-of-order metadata, replay, endpoint failure, timeout, and signature-mismatch evidence. @@ -79,7 +84,7 @@ The scorecard evidence should state: - imported/skipped/unsupported/mismatch/error counts - whether `passed` is `true` -Current scorecard evidence on 2026-05-11: +Current scorecard evidence on 2026-05-12: - Scorecard version: `l3-public-readiness-v7` - Scorecard result: `imported=49 skipped=1 unsupported=1 mismatch=0 error=0` diff --git a/docs/STRIPE_API_COMPATIBILITY_ROADMAP.md b/docs/STRIPE_API_COMPATIBILITY_ROADMAP.md index 97f0320..5b98699 100644 --- a/docs/STRIPE_API_COMPATIBILITY_ROADMAP.md +++ b/docs/STRIPE_API_COMPATIBILITY_ROADMAP.md @@ -1,12 +1,11 @@ # Stripe API Compatibility Roadmap -Status date: 2026-05-11 +Status date: 2026-05-12 -This roadmap extends Billtap beyond one SaaS adoption path. The goal is not to -be a real payment processor or a complete Stripe clone. The goal is to make -Stripe compatibility measurable, versioned, and progressively useful across -common integration shapes while keeping Billtap's stateful local billing-lab -strength. +This roadmap extends Billtap beyond one SaaS adoption path. The goal is to make +Billtap progressively Stripe-compatible across a measured, versioned API +surface while keeping its stateful local billing-lab strength and never +processing real payments. ## Reference Model @@ -64,7 +63,7 @@ The concrete expansion target is defined in `docs/STRIPE_COMPATIBILITY_90_TARGET.md`: - reach at least `90.0%` OpenAPI operation coverage at `L1+` -- move from the current `110 / 587` baseline to at least `529 / 587` +- move from the current `144 / 587` baseline to at least `529 / 587` - keep P0/P1 billing-lab families on deeper `L3-L6` gates where behavior matters - use broad `L1-L2` validation/fixture coverage for safe low-state and @@ -275,12 +274,12 @@ questions quickly. "openapi_version": "3.0.0", "stripe_api_version": "2026-04-22.dahlia", "source": "stripe/openapi master", - "generated_at": "2026-05-11T00:00:00Z", + "generated_at": "2026-05-12T00:00:00Z", "summary": { "total_operations": 587, - "implemented_operations": 110, - "inventory_only_operations": 477, - "implemented_percent": 18.7, + "implemented_operations": 144, + "inventory_only_operations": 443, + "implemented_percent": 24.5, "families": [ { "family": "connect", @@ -314,7 +313,7 @@ questions quickly. "scorecard_cases": ["subscription.update.items.price"], "sdk_smoke": ["stripe-node"], "docs": "docs/COMPATIBILITY.md#supported-stripe-like-api-subset", - "risks": ["no proration invoice yet"] + "risks": ["proration invoice creation remains bounded to local preview/update paths"] } ] } diff --git a/docs/STRIPE_COMPATIBILITY_90_TARGET.md b/docs/STRIPE_COMPATIBILITY_90_TARGET.md index 527144a..201d22c 100644 --- a/docs/STRIPE_COMPATIBILITY_90_TARGET.md +++ b/docs/STRIPE_COMPATIBILITY_90_TARGET.md @@ -1,6 +1,6 @@ # Stripe Compatibility 90% Target -Status date: 2026-05-11 +Status date: 2026-05-12 Billtap's long-running Stripe API compatibility target is measurable coverage of at least 90% of the public Stripe OpenAPI operation inventory, without @@ -11,8 +11,8 @@ claiming that every operation has deep payment-processing behavior. The 90% target is based on generated `stripe-api-inventory.json`: - **Overall target:** `summary.implemented_percent >= 90.0`. -- **Current baseline:** `110 / 587` operations, `18.7%`, using Stripe OpenAPI - `2026-04-22.dahlia` from `stripe/openapi` master on 2026-05-11. +- **Current baseline:** `144 / 587` operations, `24.5%`, using Stripe OpenAPI + `2026-04-22.dahlia` from the local OpenAPI snapshot on 2026-05-12. - **Minimum target count:** `529 / 587` operations at `L1` or higher. - **Remaining inventory-only budget:** at most `58 / 587` operations at `L0`. @@ -52,20 +52,20 @@ toward the 90% target after it has an explicit tested claim at `L1+`. ## Baseline By Family -Latest measured baseline from `stripe/openapi` master on 2026-05-11: +Latest measured baseline from the local Stripe OpenAPI snapshot on 2026-05-12: | Priority | Family | Total | Implemented | Coverage | 90% target count | First target | | --- | --- | ---: | ---: | ---: | ---: | --- | | P0 | webhooks | 7 | 7 | 100.0% | 7 | Expand connected-account routing, thin event fixtures, and replay evidence. | | P0 | checkout | 6 | 3 | 50.0% | 6 | Close checkout route gaps and SDK smoke. | -| P0 | billing | 39 | 11 | 28.2% | 36 | Add remaining invoice, schedule, coupon, discount, and deeper credit-note/test-clock behavior. | +| P0 | billing | 39 | 12 | 30.8% | 36 | Add renewal, trial, dunning, subscription schedule, coupon, and credit-note scenarios. | | P0 | billing_portal | 5 | 1 | 20.0% | 5 | Add portal configurations and session retrieval fixtures. | -| P1 | catalog | 54 | 9 | 16.7% | 49 | Add coupon, promotion code, tax-rate, and product/price search validation. | -| P1 | customers | 31 | 4 | 12.9% | 28 | Add search, sources, tax ids, cash balance, and validation fixtures. | -| P1 | payments | 41 | 12 | 29.3% | 37 | Add PaymentMethod lifecycle breadth and remaining PaymentIntent/SetupIntent adjunct routes. | +| P1 | catalog | 54 | 19 | 35.2% | 49 | Add coupon, promotion code, tax-rate, and product/price search validation. | +| P1 | customers | 31 | 11 | 35.5% | 28 | Add OpenAPI-backed validation, search/list parity, and payment source fixtures. | +| P1 | payments | 41 | 15 | 36.6% | 37 | Add PaymentIntent and SetupIntent create/confirm/capture/cancel state machines. | | P1 | connect | 53 | 53 | 100.0% | 48 | Deepen Connect SDK/adoption smoke, connected-account webhook routing, and v2 Core account inventory evidence. | -| P1 | payment_history | 30 | 6 | 20.0% | 27 | Add charges, deeper refunds, balance transactions, disputes, credit history. | -| P3 | auxiliary | 321 | 4 | 1.2% | 289 | Add generic L1/L2 schema and fixture smoke for safe low-state endpoints. | +| P1 | payment_history | 30 | 13 | 43.3% | 27 | Add charge, refund, balance transaction, dispute, and payment history evidence. | +| P3 | auxiliary | 321 | 10 | 3.1% | 289 | Keep inventory visible and add schema/fixture smoke only when adoption requires it. | ## PR Chunk Plan @@ -114,10 +114,18 @@ retrieval, local account deletion markers, and people/persons stateful evidence. This raises the generated inventory from `98 / 587` (`16.7%`) to `110 / 587` (`18.7%`), with Connect moving from `41 / 53` to `53 / 53`. +The post-Connect billing, catalog, customer, payments, and payment-history +chunks raised the generated inventory from `110 / 587` (`18.7%`) to +`144 / 587` (`24.5%`). The most recent visible changes include coupon and +promotion-code application, price search, direct PaymentIntent outcomes, +invoice payment failure evidence, dispute/refund/credit-note coverage, +subscription-update proration previews, and Stripe SDK-friendly invoice preview +response shape. + T10 also does not increase `summary.implemented_operations` by itself. It raises confidence and levels for already counted operations; new operation coverage must come from T3-T9. The planned T3-T9 delta is intentionally larger -than the `+419` operations needed to move the current `110 / 587` baseline to +than the `+385` operations needed to move the current `144 / 587` baseline to the `529 / 587` target. ## Derived Gate Checks diff --git a/docs/runbooks/local-dev.md b/docs/runbooks/local-dev.md index cf5df31..9a3cebd 100644 --- a/docs/runbooks/local-dev.md +++ b/docs/runbooks/local-dev.md @@ -5,7 +5,7 @@ This runbook covers the local runtime shell and Docker image. ## Start Billtap ```bash -npm install +npm ci npm run build go run ./cmd/billtap ``` diff --git a/specs/000-product/contracts/api.md b/specs/000-product/contracts/api.md index fe5d6ac..4f9a218 100644 --- a/specs/000-product/contracts/api.md +++ b/specs/000-product/contracts/api.md @@ -133,8 +133,14 @@ Preview endpoints accept Stripe SDK-style `subscription`, `subscription_details[billing_cycle_anchor]`. Billtap calculates a local subscription-update proration line from the current period bounds and old/new price totals. The bounded single-discount subset updates preview `subtotal`, -`total`, and `total_discount_amounts`. Taxes, pending invoice items, and -collection behavior are outside the modeled subset. +`total`, and `total_discount_amounts`. Preview responses include the common +Stripe Invoice defaults needed by generated SDK models, including +`attempt_count`, `attempted`, `auto_advance`, `automatic_tax`, +`billing_reason`, `collection_method`, `metadata`, `paid`, `payment_settings`, +`period_start`, `period_end`, `status_transitions`, `subtotal_excluding_tax`, +`total_excluding_tax`, `total_tax_amounts`, and array-shaped `discounts`. +Taxes, pending invoice items, and collection behavior are outside the modeled +subset. ### Payment Intents diff --git a/specs/000-product/quickstart.md b/specs/000-product/quickstart.md index 1258210..a98f193 100644 --- a/specs/000-product/quickstart.md +++ b/specs/000-product/quickstart.md @@ -5,7 +5,7 @@ Billtap can run as a local binary or Docker image. ## Build Locally ```bash -npm install +npm ci npm run build go build -o /tmp/billtap ./cmd/billtap ``` @@ -38,7 +38,7 @@ http://localhost:8080 ## Configure App ```bash -export STRIPE_API_BASE=http://localhost:8080/v1 +export STRIPE_API_BASE_URL=http://localhost:8080/v1 export STRIPE_WEBHOOK_SECRET=webhook_secret_local ``` @@ -76,7 +76,7 @@ PORT=3300 npm --prefix examples/sample-app start Run the scenario in another terminal: ```bash -billtap scenario run examples/subscription-payment-retry.yml \ +/tmp/billtap scenario run examples/subscription-payment-retry.yml \ --report-json billtap-report.json \ --report-md billtap-report.md ```