Skip to content
Proud to collaborate with Microsoft for Startups

subscription.renewal ​

Tracks and handles subscription renewals

Tracks subscription renewals.

States: upcoming → notified (optional) → processing → renewed (terminal/success) → payment_failed (terminal/fail) → failed (terminal/fail)

Key features: - Tracks upcoming renewals from invoice.upcoming webhook - Optional renewal reminder notifications - Handles payment success and failure outcomes

Overview ​

PropertyValue
Workflow typeLinear
LibraryApp-subscription
Version2.0

Triggers ​

SourceEndpoint / EventDescription
WEBHOOKinvoice.upcomingStripe webhook for upcoming invoice — starts the workflow
WEBHOOKinvoice.paidStripe webhook when payment succeeds — call action='payment_succeeded'
WEBHOOKinvoice.payment_failedStripe webhook when payment fails — call action='payment_failed'

Input Schema ​

FieldTypeRequiredDefaultDescription
subscription_uuiduuidYes—OrganizationSubscription UUID
organization_uuiduuidYes—Organization UUID
stripe_subscription_refstringYes—Stripe subscription reference
stripe_invoice_refstringYes—Stripe invoice reference
stripe_customer_refstringNo—Stripe customer reference
amount_dueintegerYes—Amount due in cents
currencystringNo—Currency code (default: usd)
due_datestringYes—Due date ISO timestamp

Output Schema ​

FieldTypeRequiredDefaultDescription
subscription_uuiduuidNo——
organization_uuiduuidNo——
stripe_subscription_refstringNo——
stripe_invoice_refstringNo——
stripe_customer_refstringNo——
amount_dueintegerNo——
currencystringNo——
due_datestringNo——
detected_atstringNo——
notified_atstringNo——
processing_started_atstringNo——
payment_processing_started_atstringNo——
notification_sentbooleanNo——
notification_sent_atstringNo——
paid_atstringNo——
renewed_atstringNo—ISO timestamp when renewal succeeded
amount_paidintegerNo—Amount actually paid in minor units
payment_intent_refstringNo——
keys_expiry_bumpedjsonNo——
payment_failed_atstringNo——
failure_reasonstringNo——
failure_codestringNo——
next_retry_atstringNo——
failed_atstringNo——
failure_typestringNo——
failed_actionstringNo——
failed_at_statestringNo——
failed_stepstringNo——
failed_layerstringNo——
errorstringNo——
error_typestringNo——

States ​

StateInitialTerminalSuccessAuto-advanceDescription
upcomingYesNo——Renewal approaching, invoice created
notifiedNoNo——Renewal reminder sent to customer
processingNoNo——Payment is being processed by Stripe
failedNoYesNo—Workflow failed
payment_failedNoYesNo—Renewal payment failed
renewedNoYesYes—Subscription renewed successfully

State Diagram ​

Transitions ​

FromActionToDescription
upcomingsend_notificationnotifiedSend renewal reminder
upcomingpayment_processingprocessingPayment started from upcoming
notifiedpayment_processingprocessingPayment started from notified
processingpayment_succeededrenewedPayment succeeded
upcomingpayment_succeededrenewedQuick renewal from upcoming
notifiedpayment_succeededrenewedRenewal from notified
processingpayment_failedpayment_failedPayment failed from processing
upcomingpayment_failedpayment_failedPayment failed from upcoming
notifiedpayment_failedpayment_failedPayment failed from notified
* (any state)failfailedCatch-all failure handler

Outcomes ​

OutcomeTypeDescriptionState Data Keys
renewedSUCCESSSubscription renewed successfullyrenewed_at, amount_paid
payment_failedFAILURERenewal payment failed (may trigger recovery workflow)payment_failed_at, failure_reason, failure_code
failedFAILUREWorkflow error — see failure_reasonfailed_at, failure_reason

Alarms ​

NameTypeStateSeverityDescription
renewal_payment_failedstate_enteredpayment_failedwarningSubscription renewal payment failed

API Usage ​

bash
# Step 1: Start the workflow
POST /api/workflows/start
Content-Type: application/json

{
  "workflow_type": "subscription.renewal",
  "initial_data": {
    "subscription_uuid": "value",
    "organization_uuid": "value",
    "stripe_subscription_ref": "value",
    "stripe_invoice_ref": "value"
  }
}

# Step 2: Webhook triggers transition (invoice.upcoming)
POST /api/workflows/{workflow_id}/transition
Content-Type: application/json

{ "action": "...", ... webhook payload ... }