All notable changes to this project will be documented in this file.

This project adheres to Semantic Versioning.

Publishing note: Releases are published automatically via Release Please + Hex CI. Install: {:lattice_stripe, "~> 2.0"}.

2.0.0 (2026-07-29)

⚠ BREAKING CHANGES

  • 65: public test-fixture builders are renamed to the <object>_json convention already used by 15 of 18 fixture modules. These are called from adopters' own test suites, so the rename is free now and breaking after the 1.8.0 tag.

Features

  • 61-01: wire default Finch pool end-to-end, relax :finch requirement (f7fc710)
  • 65: zero human UAT — mechanize phase 65's verification checkpoints (#47) (cd1f896)
  • entitlements: stripe-native entitlements surface (ENT-01..05) (#45) (a22e197)

Bug Fixes

  • 61-01: use fully-qualified Config.validate!/1 in Client typedoc (bb39266)

[Unreleased]

Features

  • client: ship an optional LatticeStripe.Application that starts a default LatticeStripe.Finch pool at boot; :finch is no longer required and now defaults to LatticeStripe.Finch, so you can call Stripe without wiring a Finch pool yourself. This change is additive and backwards-compatible — existing callers that pass :finch or start their own pool are unaffected. BYO-supervision users who already run their own Finch pool can disable the default with config :lattice_stripe, start_default_finch: false to avoid a duplicate idle pool.

1.7.13 (2026-05-29)

Bug Fixes

  • docs: cut patch release for README hex.pm guide links (326d155)

1.7.12 (2026-05-28)

Bug Fixes

  • docs: graduate Connect/Webhook docs_truth clusters and close JTBD narrative (a49a0f7)
  • drift: patch known_fields for Balance, BalanceTransaction, and Portal Session (79f6baf)

1.7.11 (2026-05-28)

Bug Fixes

  • docs: portal-flow sibling cluster and inter-guide .md links (aca7b4c)

1.7.10 (2026-05-28)

Bug Fixes

  • docs: flatten fence helper for credo nesting limit (3341409)
  • docs: graduate docs_truth fence and payment-flow sibling checks (a5efa3b)

1.7.9 (2026-05-28)

Bug Fixes

  • docs: align docs_truth with automated CHANGELOG publishing note (4679a2a)

1.7.8 (2026-05-28)

Bug Fixes

  • release: dispatch CI on main after automerge merge (599b97a)

1.7.7 (2026-05-28)

Bug Fixes

  • release: dispatch Release after automerge merge (a519a9d)

1.7.6 (2026-05-28)

Bug Fixes

  • release: single CI path on release PR and retry automerge (2c87f6a)

1.7.5 (2026-05-28)

Bug Fixes

  • release: automerge PAT-authored PRs and bootstrap open release CI (783711d)
  • release: use squash merge and -R in release PR automerge (c1c1120)

1.7.4 (2026-05-28)

Bug Fixes

  • credo map_join in drift report formatting (d5c8ee4)
  • release: auto-dispatch CI and merge Release Please PRs (284a174)
  • release: pass -R to gh workflow run in bootstrap CI job (0fea646)

1.7.3 (2026-05-28)

Bug Fixes

  • release: only skip release-please on merged release PR reruns (9c488d3)
  • release: poll for ci-gate before Hex publish (3934bef)

1.7.2 (2026-05-28)

Bug Fixes

  • filter .claude paths from hygiene dirty-tree check (61da051)
  • hygiene script version parse and worktree allowlist (c80de18)
  • indent Phase moduledoc heredoc for compile warning (c3f4786)
  • relax RELEASE-TRAIN ledger grep in hygiene script (2236e6f)

[Unreleased]

No unreleased changes.

1.7.1 (2026-05-28)

Documentation

  • Public docs UX audit — fixed broken guide links, corrected cheatsheet list pagination example, removed GSD/planning vocabulary from guides, standardized inter-guide .md links, and extended docs_truth regression locks.
  • Adopter-facing polish — README scope consolidation, JTBD routing and LiveBook pointer, checkout/customer-portal/payments guide corrections, and CHANGELOG copy suitable for HexDocs readers.

No API changes — documentation and HexDocs only.

1.7.0 (2026-05-27)

Highlights

This release publishes 1.7.0 to Hex — the first package since 1.1.0, bundling v1.4 adoption closure, v1.5 thin-event webhooks, v1.6 Tax, and v1.7 Charge expansion plus operator playbooks. Adopters on ~> 1.1 resolve to 1.7.0.

v1.x scope and maintenance posture: see README and User Flows & JTBD.

Upgrading from 1.1.x or 1.3.x: Update your mix.exs dependency to {:lattice_stripe, "~> 1.7"}. Review the milestone sections below for additive surfaces (Tax, thin events, Charge list/search/update/capture) and the 1.5.0 webhook tolerance migration if you use tolerance: 0 in tests.

Added

  • Charge surface expansionLatticeStripe.Charge gains list/3, list!/3, stream!/3, search/3, search!/3, search_stream!/3, update/4, update!/4, capture/4, and capture!/4 for support, audit, and Connect reconciliation. PaymentIntent remains the payment-initiation path (create/cancel intentionally omitted). See Charge moduledoc.
  • Operator playbooksguides/production-checklist.md (pre-launch boundaries) and guides/event-debugging.md (webhook diagnostic ladder from delivery boundary inward).
  • Install contract — README, Getting Started, and other public surfaces document {:lattice_stripe, "~> 1.7"} aligned with the published package version.

[1.6.0] — Tax

Milestone included in 1.7.0. Not published separately to Hex.

Added

  • Tax.Calculationcreate/3, retrieve/3, list_line_items/3 for standalone tax calculation (90-day expiry documented in moduledoc).
  • Tax.Transactioncreate_from_calculation/3, create_reversal/3, retrieve/3, list_line_items/3 for recording and reversing tax liability.
  • Tax.Settings — singleton retrieve/update for account-level tax configuration.
  • Tax.Registration — jurisdiction registration CRUDL with stream!/3.
  • TaxId — dual-path customer and account tax ID management.
  • guides/tax.md — canonical Tax adoption guide with scope boundary vs Invoice.AutomaticTax.

[1.5.0] — Thin-Event Webhooks

Milestone included in 1.7.0. Not published separately to Hex.

Fixed

  • Webhook.check_tolerance/2 tolerance: 0 semantics reconciled. Before this release, tolerance: 0 returned {:error, :timestamp_expired} on every call — directly contradicting the verify_signature/4 docstring which has always documented 0 as "disable staleness check". The code clause has been corrected to match the docstring (and every canonical Stripe SDK: stripe-node's if (tolerance > 0 && ...) gate, stripe-go's IgnoreTolerance flag, stripe-ruby's if tolerance && ... guard).
  • Webhook.Plug NimbleOptions :tolerance schema relaxed. Changed from :pos_integer to :non_neg_integer so the documented "Set 0 to disable" lever is reachable through the public Plug surface. Negative tolerances are still rejected at init/1 time. Testing only — never set tolerance: 0 in production; it removes replay-attack protection. See guides/webhooks-thin-events.md for the canonical thin-event path.

Added

  • Thin-event SDK surfaceWebhook.parse_event_notification/4, fetch_event/3, fetch_related_object/3 with typed EventNotification struct and Event extensions for related_object and context.
  • guides/webhooks-thin-events.md — canonical Phoenix thin-event guide: fetch-after-verify idempotency on event.id, verification-vs-payload-shape failure boundary, Stripe 100 req/s rate-limit ceiling, Connect routing via event.context.
  • Testing helpers — thin-event payload builders in LatticeStripe.Testing for signed wire-format fixtures.

[1.4.0] — Adoption Closure

Milestone included in 1.7.0. Not published separately to Hex.

Added

  • Flagship recipesguides/checkout-signup-and-portal.md, guides/connect-platform-flow.md, guides/metering-runtime-and-reconciliation.md, guides/quote-to-billing-operator.md with cross-linked discovery ladder.
  • Guide discovery — JTBD routing layer, cheatsheet, and README docs ladder for evaluating and navigating shipped surfaces.

1.3.0 (2026-05-25)

Changed

  • Expand deserialization — When you pass expand: ["customer"] (or any expandable field), the response struct now contains a fully typed struct (e.g., %Customer{}) instead of a raw map. Fields that are not expanded remain as string IDs, unchanged. This applies to all resource modules.

    Migration note: If your code pattern-matches on expanded fields expecting a raw map, update to match on the typed struct:

    # Before (v1.1):
    {:ok, %PaymentIntent{customer: %{"id" => id}}} = PaymentIntent.retrieve(client, id, expand: ["customer"])
    
    # After (v1.2):
    {:ok, %PaymentIntent{customer: %Customer{id: id}}} = PaymentIntent.retrieve(client, id, expand: ["customer"])

    If you were not passing expand:, your code is unaffected — unexpanded fields are still string IDs.

  • Status atomization — All resource modules with a documented finite status field now return atoms (e.g., :active, :succeeded) instead of strings from from_map/1. Unknown or future status values pass through as raw strings for forward-compatibility.

    Migration note: If your code compares status as a string, update to atom comparison:

    # Before (v1.1):
    if pi.status == "succeeded" do ...
    
    # After (v1.2):
    if pi.status == :succeeded do ...

    Affected modules: PaymentIntent, Subscription, SubscriptionSchedule, Charge, Refund, SetupIntent, Payout, BalanceTransaction, BankAccount, Checkout.Session, Billing.Meter, Account.Capability.

  • Deprecated Billing.Meter.status_atom/1 and Account.Capability.status_atom/1 — status is now automatically atomized in from_map/1/cast/1. Access .status directly on the struct.

  • Docs/package truth — README, ExDoc extras, and public guide discovery align with the shipped 1.3.x surface instead of presenting the line as unreleased.

Added

  • v1.3 surface — adds File/FileLink upload/download support, Disputes, Credit Notes, Mandates, SetupAttempts, Quotes, public testing fixture builders, a compact recipes guide, and a canonical Phoenix webhook quickstart.

  • Docs: User Flows & JTBD guide — Added a new conceptual guide aimed at experienced Elixir/Phoenix SaaS integrators. It explains LatticeStripe through real product jobs and end-to-end flow choices, including when to use Checkout vs direct APIs, how subscriptions, invoices, portal sessions, metering, and webhooks fit together, and where current roadmap gaps still exist.

  • Internal object-type dispatch module for expandable Stripe resources (not part of public API).

  • Union type specs (Customer.t() | String.t() | nil) on all expandable fields across all resource modules.

Fixed

  • Getting Started guide version drift — Updated the install snippet to {:lattice_stripe, "~> 1.3"} and aligned the first PaymentIntent example output with atomized status values.

1.1.0 (2026-04-14)

Highlights

The first post-1.0 minor release. Adds the two downstream unblockers needed by Accrue: usage-based billing (Billing Metering) and customer self-service (Customer Portal). Full phase history is in PR #9.

What's new:

  • Billing Metering. Billing.Meter CRUDL plus deactivate/3 and reactivate/3, usage event ingestion via MeterEvent.create/3, and late corrections via MeterEventAdjustment.create/3. A pre-flight guard (GUARD-03) raises ArgumentError on malformed value_settings before the network call, preventing Stripe's silent-zero trap for sum/last aggregation formulas.
  • Customer Portal. BillingPortal.Session.create/3 returns a short-lived portal URL for a given customer. Full deep-link flow support (subscription_cancel, subscription_update, subscription_update_confirm, payment_method_update) via a 5-module nested FlowData struct tree. A pre-flight guard raises ArgumentError with actionable messages for missing required flow sub-fields, so malformed requests fail before they hit Stripe. The Inspect protocol masks the portal URL and flow to keep short-lived secrets out of log output.
  • Docs. New guides/metering.md (usage-reporting idiom, idempotency two-layer explainer, reconciliation, backdating window, aggregation semantics) and guides/customer-portal.md (all 4 flow types with required sub-fields, Accrue-style Phoenix controller example, Inspect masking security teaching). New ExDoc groups: "Billing Metering" and "Customer Portal". Reciprocal cross-links from existing guides/subscriptions.md and guides/webhooks.md.

Verification. 1488 tests passing. Integration tests run against stripe-mock. mix compile --warnings-as-errors, mix credo --strict, and mix docs --warnings-as-errors all clean. Phase 20 and Phase 21 verification reports: passed.

Upgrading from 1.0.x. No breaking changes. Additive only — Billing.Meter, Billing.MeterEvent, Billing.MeterEventAdjustment, and BillingPortal.Session are new public modules. Existing code keeps working unchanged.

Features

  • Billing.Meter: create/3, retrieve/3, update/4, list/2, deactivate/3, reactivate/3
  • Billing.Meter.ValueSettings, DefaultAggregation, CustomerMapping, StatusTransitions: nested typed structs with :extra forward-compat
  • Billing.MeterEvent: create/3 with two-layer idempotency (identifier vs idempotency_key:)
  • Billing.MeterEventAdjustment: create/3 with nested Cancel struct for late corrections
  • Billing.Guards.check_meter_value_settings!/1: pre-flight shape guard for value_settings (GUARD-03, prevents silent-zero trap)
  • BillingPortal.Session: create/3 returns {:ok, %Session{url: ..., flow: ...}}
  • BillingPortal.Session.FlowData: 5-module nested struct tree — FlowData, AfterCompletion, SubscriptionCancel, SubscriptionUpdate, SubscriptionUpdateConfirm
  • BillingPortal Guards: pre-flight check_flow_data!/1 raises ArgumentError for missing flow sub-fields, enumerating valid flow types on unknown input
  • Inspect masking for BillingPortal.Session: hides :url and :flow fields via explicit allowlist to keep short-lived portal URLs out of logs
  • guides/metering.md: usage-reporting idiom, idempotency layers, reconciliation, aggregation semantics
  • guides/customer-portal.md: all 4 flow types, Accrue-style Phoenix controller example, Inspect masking security teaching
  • mix.exs: groups_for_modules entries for "Billing Metering" and "Customer Portal"; both guides added to extras

1.0.0 (2026-04-13)

Highlights

LatticeStripe 1.0 marks our commitment to API stability for the Elixir + Stripe integration story. The 0.2 → 1.0 journey spans four major milestones: a solid foundation of transport, retries, pagination, and observability (Phases 1-11); full Billing coverage for Invoices, Subscriptions, SubscriptionItems, and Subscription Schedules (Phases 14-16); end-to-end Connect support including accounts, onboarding links, external accounts, transfers, payouts, balance, and balance transactions (Phases 17-18); and a formalized public API surface with @moduledoc false internals and an explicit semver contract (Phase 19). Starting with 1.0.0, LatticeStripe follows standard semver: patch releases for bug fixes, minor releases for additive features, major releases for breaking public API changes — see API Stability for the full contract.

What's in the box:

  • Payments. Customers, PaymentIntents, SetupIntents, PaymentMethods, Refunds, Checkout Sessions.
  • Billing. Invoices (create, finalize, pay, void, send, search), Subscriptions with lifecycle verbs and pause helpers, Subscription Schedules with proration guards, Invoice Items.
  • Connect. Accounts (Standard/Express/Custom), Account Links, Login Links, External Accounts (BankAccount/Card), Transfers + TransferReversals, Payouts (with TraceId), Balance + BalanceTransactions, Charge retrieve for fee reconciliation.
  • Webhooks. Timing-safe signature verification, Event struct, Phoenix Webhook.Plug, Webhook.Handler behaviour.
  • Operational glue. Pluggable Transport/Json/RetryStrategy behaviours, Telemetry events for every request, LatticeStripe.Testing helpers with TestClock support.

Upgrading from 0.2.x. No breaking API changes from 0.2. The public surface has been frozen; previously-visible internal modules (FormEncoder, Request, Resource, Transport.Finch, Json.Jason, RetryStrategy.Default, Webhook.CacheBodyReader, Billing.Guards) are now documented as private via @moduledoc false and are excluded from the semver contract.

Supported versions. Elixir 1.15+ on OTP 26+, tested up to Elixir 1.19 on OTP 28.

Features

  • 17-01: add canonical Account/AccountLink/LoginLink fixtures (a1a101c)
  • 17-01: add stripe-mock reject probe script and record result in VALIDATION.md (e3539e9)
  • 17-02: Account.Capability (D-02) with safe status_atom/1 (3a80de4)
  • 17-02: PII-safe nested structs — TosAcceptance, Company, Individual (fddb864)
  • 17-02: plain nested structs — BusinessProfile, Requirements, Settings (4bd03c9)
  • 17-03: LatticeStripe.Account resource module — CRUD + reject + stream + from_map (92747d0)
  • 17-04: LatticeStripe.AccountLink — create/3, create!/3, from_map/1 + tests (7161f34)
  • 17-04: LatticeStripe.LoginLink — create/4, create!/4, from_map/1 + tests (0bd48d7)
  • 17-05: Account full-lifecycle integration test + fix cast_capabilities for stripe-mock (e1364a6)
  • 17-05: AccountLink + LoginLink integration tests (9 tests each) (ecb7494)
  • 17-06: add guides/connect.md — Connect onboarding narrative (874dda9)
  • 18-01: add BankAccount + Card structs with F-001 and PII Inspect (f775aff)
  • 18-01: add ExternalAccount polymorphic dispatcher + Unknown fallback (91148ac)
  • 18-02: add LatticeStripe.Charge retrieve-only resource (44a0adb)
  • 18-03: add LatticeStripe.Transfer CRUDL with embedded reversals decoding (90b1234)
  • 18-03: add LatticeStripe.TransferReversal standalone module (5cddcb9)
  • 18-04: add Payout CRUDL + cancel + reverse with TraceId integration (79605ae)
  • 18-04: add Payout.TraceId nested typed struct (52f6d11)
  • 18-05: add Balance singleton with Amount and SourceTypes nested structs (5304b80)
  • 18-05: add BalanceTransaction retrieve/list/stream + FeeDetail struct (6873c5f)
  • 19-01: rewrite mix.exs groups_for_modules to nine-group D-19 layout (c66223b)

Bug Fixes

  • 17-02: align nested struct tests with 17-01 canonical fixture values (025082a)
  • 18: IN-01 correct BankAccount docstring account_number reference (b720afa)
  • 18: IN-02 normalize nil/empty id guards to 'id in [nil, ""]' style (542fc1b)
  • 18: IN-03 derive ExternalAccount.Unknown.cast drop list from @known_fields (00d618e)
  • 18: IN-04 add is_map(params) guard to Payout.update/update! (bdc4ab8)
  • 18: IN-05 preserve unexpected Transfer reversals shape in extra (ae1c85e)
  • 18: WR-01 add map() to Transfer expandable typespecs (772795e)
  • 18: WR-01 add map() to TransferReversal expandable typespecs (fe9bbdd)
  • 18: WR-02 add map() to Charge destination/source_transfer typespecs (c26187d)
  • 18: WR-03 add nil/empty id guards to BalanceTransaction.retrieve/3 and retrieve!/3 (e60f220)
  • 18: WR-03 add nil/empty id guards to Payout.update/4 and update!/4 (4614b1c)
  • 18: WR-03 restore balance_transaction id error message for test contract (10a8827)

0.2.0 (2026-04-04)

Features

  • 01-01: configure test infrastructure with Mox mocks, formatter, and Credo (d75666e)
  • 01-01: scaffold Elixir project with Phase 1 dependencies (2e4ae58)
  • 01-02: implement JSON codec behaviour and Jason adapter with tests (bb63aac)
  • 01-02: implement recursive Stripe-compatible form encoder with tests (2c232e4)
  • 01-03: implement Error struct with Stripe error response parsing and tests (8438a4c)
  • 01-03: implement Transport behaviour and Request struct with tests (192ddc9)
  • 01-04: implement Finch transport adapter with tests (b0951e3)
  • 01-04: implement NimbleOptions config schema and validation with tests (9441d19)
  • 01-05: implement Client struct with new!/1, new/1, and request/2 (8c384d8)
  • 02-01: add non-bang decode/1 and encode/1 to Json behaviour and Jason adapter (1666da4)
  • 02-01: enrich Error struct with new fields, idempotency_error, String.Chars (33da331)
  • 02-02: implement RetryStrategy behaviour and Default implementation (f2394e7)
  • 02-02: update Config and Client with retry_strategy field and max_retries default 2 (f3df360)
  • 02-03: wire retry loop, auto-idempotency, bang variant, non-JSON handling into Client (9501f91)
  • 03-01: add List struct, api_version/0, update Config/Client defaults and User-Agent (f7b30af)
  • 03-01: add Response struct with Access behaviour, get_header/2, custom Inspect (8a97dc8)
  • 03-02: wrap responses in %Response{} with list auto-detection (9051f8c)
  • 03-03: implement stream!/2 and stream/2 auto-pagination on List (dc2b01a)
  • 04-01: implement LatticeStripe.Customer resource module (420f4a2)
  • 04-02: implement LatticeStripe.PaymentIntent resource module (30b55c8)
  • 05-01: build SetupIntent resource module with full CRUD, lifecycle actions, list/stream, and tests (7908ede)
  • 05-01: extract Resource helpers, refactor Customer/PaymentIntent, add PI search, shared test helpers (0a85316)
  • 05-02: implement PaymentMethod resource with CRUD, attach/detach, validated list, stream, and tests (ec48dca)
  • 06-01: extract Phase 4/5 test fixtures into dedicated fixture modules (bd69567)
  • 06-01: implement Refund resource with CRUD, cancel, list, stream, and tests (8e4ecad)
  • 06-02: implement Checkout.Session and LineItem with all endpoints and tests (99dbadd)
  • 07-01: add Event struct, Handler behaviour, SignatureVerificationError, deps (1c04f4b)
  • 07-01: implement LatticeStripe.Webhook with HMAC-SHA256 verification (b524010)
  • 07-02: add CacheBodyReader and Webhook.Plug with NimbleOptions, path matching, handler dispatch, MFA secrets (08eed78)
  • 08-01: create LatticeStripe.Telemetry module with event catalog and span helpers (c8e514e)
  • 08-02: implement webhook_verify_span, attach_default_logger, integrate webhook telemetry (63de0a4)
  • 09-01: add 6 resource integration test files (87cb6ab)
  • 09-01: add integration test infrastructure (c37a9ec)
  • 09-02: add mix ci alias, Credo strict mode, and fix all violations (152eacc)
  • 09-02: implement LatticeStripe.Testing public module (60506ed)
  • 10-01: complete cheatsheet with two-column layout (52368ea)
  • 10-01: ExDoc config, README quickstart, CHANGELOG, guide stubs (677b034)
  • 10-02: add @typedoc and Stripe API reference links to resource modules (70ab5f4)
  • 10-02: add @moduledoc/@doc/@typedoc to core and internal modules (32b1917)
  • 10-03: write checkout and webhooks guides (3b04b13)
  • 10-03: write getting-started, client-configuration, and payments guides (781f10e)
  • 11-02: add Dependabot config and auto-merge workflow (12078f6)
  • 11-02: add Release Please workflow and manifest config (a478928)
  • 11-03: add community files — CONTRIBUTING, SECURITY, issue templates, PR template (36d6a7a)

Bug Fixes

  • 01: resolve verification gaps — update REQUIREMENTS.md traceability and fix flaky test (4edc9ad)
  • 01: revise plans based on checker feedback (3226334)
  • 03: remove deferred requirements EXPD-02, EXPD-03, EXPD-05 from Plan 02 (ca8372e)
  • 04: Customer Inspect uses Inspect.Algebra to prevent PII field name leakage (63ae62e)
  • 04: remove unused aliases in test files (9780bdf)
  • 09: revise plans based on checker feedback (9a59458)
  • remove deprecated 'command' input from release-please-action v4 (3ff8a12)
  • skip invalid-id integration tests — stripe-mock returns stubs for any ID (e986f1b)
  • update GitHub org from lattice-stripe to szTheory (ad46956)