Execution turns an approved dry-run plan into buyer-side Stripe mutations.
RevBridge queues execution after dry-run review when at least one subscription creation is planned. Progress is tracked at the project level with total, completed, and failed counts.
If every source subscription is already recovered as migrated, the dry-run remains available for review but execution is disabled. RevBridge does not queue a worker for a no-op migration.
Execution status
Execution uses project statuses such as:
QUEUEDRUNNINGCOMPLETEDFAILEDBLOCKED
The status tells operators whether the migration is waiting, actively running, done, or needs intervention.
The worker runs only the queued job recorded on the project. If the same job is retried while the project is still RUNNING, it can resume because Stripe writes use deterministic idempotency keys. Stale jobs for completed, failed, or different queued attempts are skipped without changing the project status.
Idempotency model
RevBridge derives deterministic mutation keys from stable project and Stripe identifiers. That makes retries safer if a worker restarts, a request times out, or a Stripe response needs to be retried.
Examples of mutation areas include:
- Creating buyer-side subscriptions.
- Retrying trial-anchor fallback subscription creation.
- Cloning shared products, prices, and coupons once per source object.
- Setting buyer customer default payment methods.
Subscription and customer mutations use project id, source subscription id, destination customer id, and action type. Source write-scope verification includes the preserved cancellation state in the key material (cancel_at_period_end true/false, or the scheduled cancel_at timestamp) so a retry cannot reuse one idempotency key for two different no-op update payloads. Shared product, price, and coupon clone mutations use project id, source object id, and action type so two subscriptions that share the same source object cannot create duplicate buyer-side clones; repeating-coupon clones additionally scope by the computed remaining months, because two subscriptions sharing one source coupon can need clones with different durations. Because Stripe expires idempotency keys after roughly 24 hours, the worker also looks for prior RevBridge clones by revbridge_source_* lineage metadata before creating a new clone, so delayed reruns reuse existing buyer-side catalog objects instead of duplicating them.
Retry behavior
Retries should continue the approved migration plan rather than creating duplicate buyer-side billing objects.
Before creating buyer-side subscriptions or setting buyer customer defaults, the worker preflights every planned subscription against the approved dry-run: price economics, coupon terms and product scope, supported discount shape, quantity, renewal timestamp, cancellation flag, billing timing, destination-subscription reuse safety, and selected source payment instrument for new buyer-side subscription creation. If any of those changed, execution stops before buyer-side default or subscription writes and the operator must rerun dry-run. If a matching buyer-side subscription already exists from a previous RevBridge attempt, payment-selection drift does not block safe recovery only when the existing destination subscription already has the expected subscription-level payment binding.
Stripe can inherit a buyer customer's customer-level discount onto newly created subscriptions when the subscription create payload has no explicit discount. RevBridge checks destination customer discounts during the global preflight, before buyer-side clone/create work for each subscription, and immediately before creating the buyer-side subscription.
When creating a buyer-side subscription, RevBridge copies a non-empty source subscription description and copies subscription metadata with RevBridge lineage metadata added. RevBridge does not store description text permanently in Postgres.
After buyer-side subscription creation, RevBridge lists invoices for that new destination subscription before touching the seller subscription. If Stripe generated a non-zero initial subscription_create invoice that is not void, execution stops and the audit explains the destination invoice state. A paid initial invoice is also unsafe because RevBridge expected no charge before the preserved renewal timestamp. Seller-side cancellation is not scheduled in that case.
There is one narrow retry exception. If a previous worker attempt already created a matching buyer-side subscription and successfully set the seller subscription to cancel_at_period_end=true, but crashed before writing the final cancellation audit row, the retry can treat that seller cancellation as completed migration work. It only does this after proving the buyer-side subscription has RevBridge lineage metadata, a safe status, the preserved renewal timestamp, matching discount state, matching payment binding, and either the destination cancellation state expected by the approved dry-run or same-user RevBridge audit history proving both buyer-side creation and seller-side cancellation succeeded.
If a fatal preflight check fails before per-subscription work begins, RevBridge marks the planned subscriptions as failed in project progress. Source cancellation write verification failures and destination write verification failures are also written as failed audit rows so the export explains why execution never reached subscription creation.
Encrypted Stripe keys and Redis mapping caches are wiped after a queued worker run reaches a terminal path, including preflight failures before any subscription is migrated. To rerun a failed project, re-save the source and destination keys, upload or confirm the customer mapping, and rerun the dry-run. The already-migrated recovery checks use audit history, destination metadata, renewal timing, discount state, and payment binding to skip subscriptions that were safely created in a prior run.
Already-migrated recovery is scoped to the mapped destination customer. A destination customer can only contain RevBridge-lineage subscriptions for source subscriptions mapped to that same destination customer in the current plan. If a buyer customer contains a RevBridge-created subscription for a different source customer, dry-run blocks the run so the CSV mapping or buyer-side data can be corrected.
Audit first
Every execution action should leave an audit trail that can be reviewed after the run.