Remove the Paddle-backed subscriptions code path #416

Open
opened 2026-08-10 02:03:28 +00:00 by caution-bot · 0 comments
caution-bot commented 2026-08-10 02:03:28 +00:00 (Migrated from codeberg.org)

Summary

Remove the recurring Paddle subscription path for managed/self-managed enclaves. Self-managed capacity and lifecycle should be controlled by the platform's self_managed_plans model rather than by creating, changing, canceling, or projecting Paddle subscriptions.

This is specifically about Paddle recurring subscriptions. Keep the Paddle integration used for one-time prepaid credit purchases, payment-method/customer setup where still required by that flow, and verified transaction fulfillment.

Coordinate this with PR #412: preserve its separation of billing records from authoritative self-managed entitlements, but remove the provider-subscription lifecycle rather than retaining Paddle subscription rows as an active billing path.

Scope

  • Remove BYOC_PADDLE_SUBSCRIPTIONS_ENABLED and its API, metering, pricing-validation, deployment, and test branches.
  • Remove recurring-subscription checkout, tier-change, and cancellation calls to Paddle, including the associated provider-backed intent workflow.
  • Stop handling Paddle subscription.* webhooks as an entitlement or lifecycle source.
  • Remove the managed-enclave subscription checkout/change/cancel UI while continuing to show authoritative self-managed plan capacity/status where useful.
  • Remove Paddle recurring catalog configuration and provisioning (paddle_catalog, recurring tier price IDs/products, and subscription-specific provisioner behavior) without breaking credit-package provisioning.
  • Remove subscription-specific fixtures, E2E targets, and active runtime wiring.
  • Add a forward migration for obsolete live subscription-provider state where appropriate; do not rewrite historical migrations merely to erase old references.

Migration and safety requirements

Before deleting the provider path, define and implement an explicit disposition for any existing non-canceled Paddle subscriptions. The removal must not silently leave customers being charged after Caution stops processing lifecycle events. Migration should either cancel/migrate known provider subscriptions through an operator-controlled procedure or fail closed with a reconciliation report that identifies remaining provider-backed rows.

Preserve billing/audit history needed for reconciliation, even if active provider IDs and intent tables are no longer used for authorization. Existing self-managed resources and contractual/manual plans must retain the intended capacity semantics during migration.

Acceptance criteria

  • No production path creates, updates, cancels, or derives entitlements from a Paddle subscription.
  • self_managed_plans is the sole authority for self-managed/BYOC deployment capacity and lifecycle.
  • Paddle subscription checkout/change/cancel endpoints and dashboard controls are gone or replaced with non-provider plan views/actions.
  • Subscription lifecycle webhooks no longer mutate plans, resources, or subscription intent state.
  • One-time Paddle credit purchases still work, including checkout, signature verification, idempotent fulfillment, and the required frontend SDK/CSP configuration.
  • Recurring Paddle catalog fields and provisioning are removed while credit-package catalog provisioning remains functional.
  • Existing provider-backed subscriptions cannot be orphaned into continued billing; migration/reconciliation behavior is documented and tested.
  • A focused repository regression test prevents the removed environment flag, routes, provider /subscriptions mutations, webhook handlers, recurring catalog fields, and subscription checkout UI from being reintroduced, while explicitly allowing historical migrations/audit compatibility references.
  • Relevant API, metering, frontend, migration, provisioner, and credit-purchase tests pass.

Likely affected areas

  • src/api/src/subscriptions.rs
  • src/api/src/main.rs
  • src/api/migrations/045_paddle_byoc_subscriptions.sql plus a new forward migration
  • src/metering/src/webhooks.rs, billing.rs, calculator.rs, and main.rs
  • src/caution-config/src/pricing.rs
  • frontend/src/views/Dashboard.vue
  • prices.json.example
  • utils/provision-paddle.sh
  • Makefile, tests/e2e/test_paddle_subscriptions.sh, and subscription-specific fixtures/tests
  • PR #412 — separates self-managed plan entitlements from billing subscriptions; this removal should retain the authoritative-plan model while deleting the recurring Paddle lifecycle.
## Summary Remove the recurring Paddle subscription path for managed/self-managed enclaves. Self-managed capacity and lifecycle should be controlled by the platform's `self_managed_plans` model rather than by creating, changing, canceling, or projecting Paddle subscriptions. This is specifically about **Paddle recurring subscriptions**. Keep the Paddle integration used for one-time prepaid credit purchases, payment-method/customer setup where still required by that flow, and verified transaction fulfillment. Coordinate this with PR #412: preserve its separation of billing records from authoritative self-managed entitlements, but remove the provider-subscription lifecycle rather than retaining Paddle subscription rows as an active billing path. ## Scope - Remove `BYOC_PADDLE_SUBSCRIPTIONS_ENABLED` and its API, metering, pricing-validation, deployment, and test branches. - Remove recurring-subscription checkout, tier-change, and cancellation calls to Paddle, including the associated provider-backed intent workflow. - Stop handling Paddle `subscription.*` webhooks as an entitlement or lifecycle source. - Remove the managed-enclave subscription checkout/change/cancel UI while continuing to show authoritative self-managed plan capacity/status where useful. - Remove Paddle recurring catalog configuration and provisioning (`paddle_catalog`, recurring tier price IDs/products, and subscription-specific provisioner behavior) without breaking credit-package provisioning. - Remove subscription-specific fixtures, E2E targets, and active runtime wiring. - Add a forward migration for obsolete live subscription-provider state where appropriate; do not rewrite historical migrations merely to erase old references. ## Migration and safety requirements Before deleting the provider path, define and implement an explicit disposition for any existing non-canceled Paddle subscriptions. The removal must not silently leave customers being charged after Caution stops processing lifecycle events. Migration should either cancel/migrate known provider subscriptions through an operator-controlled procedure or fail closed with a reconciliation report that identifies remaining provider-backed rows. Preserve billing/audit history needed for reconciliation, even if active provider IDs and intent tables are no longer used for authorization. Existing self-managed resources and contractual/manual plans must retain the intended capacity semantics during migration. ## Acceptance criteria - No production path creates, updates, cancels, or derives entitlements from a Paddle subscription. - `self_managed_plans` is the sole authority for self-managed/BYOC deployment capacity and lifecycle. - Paddle subscription checkout/change/cancel endpoints and dashboard controls are gone or replaced with non-provider plan views/actions. - Subscription lifecycle webhooks no longer mutate plans, resources, or subscription intent state. - One-time Paddle credit purchases still work, including checkout, signature verification, idempotent fulfillment, and the required frontend SDK/CSP configuration. - Recurring Paddle catalog fields and provisioning are removed while credit-package catalog provisioning remains functional. - Existing provider-backed subscriptions cannot be orphaned into continued billing; migration/reconciliation behavior is documented and tested. - A focused repository regression test prevents the removed environment flag, routes, provider `/subscriptions` mutations, webhook handlers, recurring catalog fields, and subscription checkout UI from being reintroduced, while explicitly allowing historical migrations/audit compatibility references. - Relevant API, metering, frontend, migration, provisioner, and credit-purchase tests pass. ## Likely affected areas - `src/api/src/subscriptions.rs` - `src/api/src/main.rs` - `src/api/migrations/045_paddle_byoc_subscriptions.sql` plus a new forward migration - `src/metering/src/webhooks.rs`, `billing.rs`, `calculator.rs`, and `main.rs` - `src/caution-config/src/pricing.rs` - `frontend/src/views/Dashboard.vue` - `prices.json.example` - `utils/provision-paddle.sh` - `Makefile`, `tests/e2e/test_paddle_subscriptions.sh`, and subscription-specific fixtures/tests ## Related - PR #412 — separates self-managed plan entitlements from billing subscriptions; this removal should retain the authoritative-plan model while deleting the recurring Paddle lifecycle.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
public/platform#416
No description provided.