Skip to content

feat(payments): integrate Stripe Checkout lifecycle - #12

Merged
arapsum merged 9 commits into
mainfrom
feature/stripe-payments
Jul 14, 2026
Merged

arapsum merged 9 commits into
mainfrom
feature/stripe-payments

Conversation

@arapsum

@arapsum arapsum commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • configure an environment-driven Stripe client without exposing payment secrets
  • persist payment attempts and webhook events so checkout and reconciliation are idempotent
  • add customer-only Checkout Session creation with server-owned pricing and inventory reservation
  • verify Stripe webhook signatures and reconcile completed, delayed, failed, and expired payments
  • prevent staff order updates from directly mutating Stripe-owned payment status
  • document local Stripe test setup and add model, request, and payment lifecycle coverage

Why

Orders previously had no payment provider lifecycle. This change introduces Stripe-hosted checkout while keeping totals, inventory, authorization, and payment-state transitions under backend control. Durable attempt and webhook records make retries safe and provide recovery across duplicate delivery or interrupted processing.

Impact

  • customers can start checkout for their own eligible orders
  • verified Stripe events become the source of truth for payment outcomes
  • staff retain order-management controls without being able to forge a successful payment
  • Stripe remains optional in environments where its configuration is absent

Validation

  • cargo test --all-features (583 passed, 1 ignored)
  • cargo clippy --all-features -- -D warnings -W clippy::pedantic -W clippy::nursery -W rust-2018-idioms
  • pnpm run fmt:check
  • pnpm run lint
  • pnpm exec tsc --noEmit
  • pnpm run build

Configuration

Stripe test credentials and the webhook signing secret must be supplied through environment variables. No credentials are committed in this branch.

arapsum added 9 commits July 14, 2026 16:05
Pin async-stripe 0.41.0 with Checkout, webhook, and compatible Connect resources while retaining the stable pre-1.0 API.

Load Stripe secrets and hosted Checkout settings from explicit APP_STRIPE environment variables, redact credentials from debug output, and disable payments cleanly when configuration is incomplete.

Construct one reusable Stripe client in AppContext and cover optional and environment-backed configuration with serial tests.
Add payment attempt and webhook event tables with active-attempt uniqueness, provider state constraints, event deduplication, and supporting indexes.

Model locked, idempotent payment transitions that confirm orders, reject terminal regressions, compensate failed Checkout creation, and restore reserved inventory exactly once on expiry.

Cover conflicts, replay behavior, terminal transition boundaries, paid-versus-expired races, error metadata, and webhook deduplication with rstest and reviewed insta snapshots.
Add a customer-only checkout endpoint protected by the existing RBAC middleware and derive customer ownership from authenticated claims.

Create Stripe-hosted Checkout Sessions from server-priced order snapshots, persist the session against an idempotent payment attempt, and compensate inventory after definitive failures.

Cover monetary conversion and checkout authorization boundaries with rstest cases and reviewed Insta snapshots.
Expose a public raw-body webhook endpoint that authenticates Stripe signatures without relying on Silk sessions.

Deduplicate deliveries transactionally, recover interrupted Checkout Session persistence, and reconcile mode, metadata, order identity, amount, and currency before applying payment transitions.

Handle immediate and delayed success, delayed failure, expiry, and unknown events while proving replay safety and single inventory restoration through reviewed snapshots.
Remove paymentStatus from staff order update payloads and reject it as an unknown field at the service boundary.

Keep payment state visible for operations while limiting the admin dialog to order, fulfillment, and internal-note updates.

Add a request regression test proving even authorized staff cannot mark an order paid through the general update endpoint.
List the required Stripe environment variables, local test-mode defaults, and the live-mode safety switch.

Document Stripe CLI webhook forwarding and the new checkout and webhook API routes without adding the private integration guide under docs/.
Move payment tests into a module directory so Cargo does not also compile the same source as a standalone integration-test crate.

Preserve the existing rstest cases and reviewed Insta snapshots while allowing cargo test --all-features to discover the suite correctly.
@arapsum
arapsum marked this pull request as ready for review July 14, 2026 15:38
@arapsum
arapsum merged commit d0e83cb into main Jul 14, 2026
7 checks passed
@arapsum
arapsum deleted the feature/stripe-payments branch July 14, 2026 15:40
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