Real-world processor adapter delegating to :lattice_stripe.
This is the ONLY module in the codebase allowed to alias, import, or
reference LatticeStripe (D-07). All raw Stripe errors cross this
facade and are translated to Accrue.Error subtypes via
Accrue.Processor.Stripe.ErrorMapper — downstream Billing code never
sees raw LatticeStripe.Error shapes. A CI-enforced facade-lockdown test
in test/accrue/processor/stripe_test.exs walks lib/accrue/**/*.ex
and fails if LatticeStripe appears anywhere except stripe.ex and
stripe/error_mapper.ex.
Config keys (READ-ONLY)
This module reads (never writes) the following Phase 1 keys that
Accrue.Config already defines:
:stripe_secret_key— runtime only (CLAUDE.md §Config Boundaries). An unset key raisesAccrue.ConfigErrorat call time rather than atApplication.compile_env!/2load time so secrets never leak into compiled release artifacts.:stripe_api_version— runtime only, defaults to"2026-03-25.dahlia".
PII discipline
Raw Stripe responses often contain PII in fields like email, name,
address, phone, shipping. This adapter:
- Does not log
processor_errorverbatim — T-PROC-01 mitigation. - Does not auto-inject params or responses into telemetry metadata
— only
%{adapter: :stripe, operation: ...}at this layer. - Converts
LatticeStripe.Customerstructs to plain maps viacustomer_to_map/1so downstream code never pattern-matches on%LatticeStripe.Customer{}.
Phase 1 scope
Only the three customer callbacks are implemented (PROC-01, PROC-03, PROC-07). Wire-level integration tests against Stripe test mode are deferred to Phase 3 (PROC-02) — Phase 1 only proves the behaviour conformance, the error-mapping contract, and the facade lockdown.
Summary
Functions
Computes a deterministic idempotency key from the operation, subject ID, and a seed (D2-11). The seed resolution chain is (D2-12)
Resolves the Stripe API version using three-level precedence (D2-14)
Resolves the Stripe-Account header using three-level precedence (D5-01)
Functions
Computes a deterministic idempotency key from the operation, subject ID, and a seed (D2-11). The seed resolution chain is (D2-12):
opts[:operation_id](explicit)Accrue.Actor.current_operation_id/0(process dict)- Random UUID +
Logger.warning(non-deterministic fallback)
Returns a string like "accr_<22 url-safe base64 chars>".
Resolves the Stripe API version using three-level precedence (D2-14):
opts[:api_version](explicit per-call override)Process.get(:accrue_stripe_api_version)(scoped viaAccrue.Stripe.with_api_version/2)Accrue.Config.stripe_api_version/0(application config default)
Resolves the Stripe-Account header using three-level precedence (D5-01):
opts[:stripe_account](explicit per-call override)Process.get(:accrue_connected_account_id)(viaAccrue.Connect.with_account/2— scoped pdict key; theAccrue.Connectmodule itself lands in Plan 05-02)Accrue.Config.connect/0[:default_stripe_account](config fallback)
Returns nil when no connected-account context is set, which preserves
platform-scoped behavior: lattice_stripe omits the Stripe-Account
header when the client is built with stripe_account: nil.