What a payments provider port looks like, and which billing code belongs behind it #80

Open
opened 2026-09-21 07:18:24 +00:00 by cgalo5758 · 2 comments
Owner

The question

Core billing code calls the Stripe client library directly. The fulfillment package imports it throughout despite its provider-neutral name, and the checkout handler, the catalog sync, the product readiness check and the member products page each call it from core as well, alongside the Stripe test helpers. The provider contract that other integrations are written against describes a lifecycle (create, set status, delete, read), which is not the shape of payments, so there is nothing for these calls to be written against. What operations does a payments port expose, and which of these behaviours moves behind it?

What depends on the answer

Whether a second payment provider is possible at all, whether the provider-specific action vocabulary that core carries for the outbox can move out of core, and whether the packages that read as provider-neutral become so or are renamed.

Options known so far

  • A payments port defined against the billing model, with the Stripe integration as its first implementation and fulfillment moving behind it.
  • Payments stays core-owned and single-provider by decision, and the packages that imply otherwise are renamed to say so.
  • Only fulfillment moves behind a port; the checkout hand-off stays provider-specific because its redirect is.

Decided when

The billing model states the port's operations and which package owns each side of it, and the integration contract says whether payments is a capability it describes or a separate seam.

Migrated from status/issues.md at b7a0e15

## The question Core billing code calls the Stripe client library directly. The fulfillment package imports it throughout despite its provider-neutral name, and the checkout handler, the catalog sync, the product readiness check and the member products page each call it from core as well, alongside the Stripe test helpers. The provider contract that other integrations are written against describes a lifecycle (create, set status, delete, read), which is not the shape of payments, so there is nothing for these calls to be written against. What operations does a payments port expose, and which of these behaviours moves behind it? ## What depends on the answer Whether a second payment provider is possible at all, whether the provider-specific action vocabulary that core carries for the outbox can move out of core, and whether the packages that read as provider-neutral become so or are renamed. ## Options known so far - A payments port defined against the billing model, with the Stripe integration as its first implementation and fulfillment moving behind it. - Payments stays core-owned and single-provider by decision, and the packages that imply otherwise are renamed to say so. - Only fulfillment moves behind a port; the checkout hand-off stays provider-specific because its redirect is. ## Decided when The billing model states the port's operations and which package owns each side of it, and the integration contract says whether payments is a capability it describes or a separate seam. Migrated from status/issues.md at b7a0e15
cgalo5758 added the
kind
design
area/billingarea/integrations
labels 2026-09-21 07:18:24 +00:00
Author
Owner

Part of the question is now answered. The integration contract that outside applications will be written against covers provisioning applications only; payments stay in process as a separate seam, not a capability of that contract. That settles the last condition under "Decided when" and leaves the rest open: which operations a payments port exposes, and which billing code moves behind it. Nothing in 23d5bad touches billing; the Stripe outbox, relay and dead-letter list are unchanged.

Part of the question is now answered. The integration contract that outside applications will be written against covers provisioning applications only; payments stay in process as a separate seam, not a capability of that contract. That settles the last condition under "Decided when" and leaves the rest open: which operations a payments port exposes, and which billing code moves behind it. Nothing in 23d5bad touches billing; the Stripe outbox, relay and dead-letter list are unchanged.
Author
Owner

The operations a port would have to cover, as the code calls them today: the plan switch, Keep and Cancel (internal/fulfillment/plan_change.go) read, update and cancel subscriptions and create, read, update and release subscription schedules; the reconcile (reconcile.go) reads and lists subscriptions and releases a schedule; the sweep (sweep.go) cancels and updates subscriptions; Checkout (internal/server/billing.go) creates the customer itself. That is nine operations on three Stripe objects, plus the Checkout session.

The operations a port would have to cover, as the code calls them today: the plan switch, Keep and Cancel (`internal/fulfillment/plan_change.go`) read, update and cancel subscriptions and create, read, update and release subscription schedules; the reconcile (`reconcile.go`) reads and lists subscriptions and releases a schedule; the sweep (`sweep.go`) cancels and updates subscriptions; Checkout (`internal/server/billing.go`) creates the customer itself. That is nine operations on three Stripe objects, plus the Checkout session.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: wiki-cafe/member-console#80