Skip to main content

WF-024: Payment Method Update Flow

Priority: P0 (Critical) Phase: Phase 1B - Billing Operations Implementation Effort: 10 hours


Overview

Secure payment method updates using Stripe SetupIntent (PCI-compliant), automatic retry of past-due invoices, and email confirmation. Two-phase workflow: (1) Create SetupIntent, (2) Confirm and apply.

Trigger: POST /update-payment-method + POST /confirm-payment-method Duration: Phase 1: ~2s, Phase 2: ~6s Related Workflows: WF-025 (Failed Payment Retry), WF-021 (Subscription Upgrade)


Workflow Steps

  1. Initialize - Set up the environment
  2. Configure - Apply settings
  3. Execute - Run the process
  4. Validate - Check results
  5. Complete - Finalize workflow

Step-by-Step Narrative

Phase 1: Initiate Payment Method Update

Step 1: Payment Method Update Request

  • User clicks "Update Payment Method" in billing settings
  • POST request with user_id

Step 2: Get Subscription

  • Query PostgreSQL for active/past_due subscription
  • Retrieve stripe_customer_id for Stripe API calls

Step 3: Create Stripe SetupIntent

  • POST to /v1/setup_intents
  • Parameters: customer, payment_method_types: ['card'], usage: 'off_session'
  • Returns client_secret for frontend Stripe.js confirmation

Step 4: Return Client Secret to Frontend

  • Return { client_secret, setup_intent_id }
  • Frontend uses Stripe.js to collect card details securely
  • User enters card info (never touches CODITECT backend)

Phase 2: Confirm and Apply Payment Method

Step 5: Payment Method Confirmed (Client Callback)

  • Frontend calls /confirm-payment-method after Stripe.js success
  • Passes setup_intent_id

Step 6: Verify SetupIntent Success

  • GET /v1/setup_intents/{id}
  • Verify status: 'succeeded'
  • Extract payment_method ID

Step 7: Attach Payment Method to Customer

  • POST /v1/payment_methods/{id}/attach
  • Attach to Stripe customer

Step 8: Set as Default Payment Method

  • POST /v1/customers/{id}
  • Update invoice_settings.default_payment_method
  • All future invoices use new payment method

Step 9: Check for Past-Due Invoices

  • GET /v1/invoices?customer={id}&status=open
  • Find any unpaid invoices

Step 10: Process Invoice Retries

  • For each past-due invoice, automatically retry payment
  • Uses new payment method
  • Tracks retry count

Step 11: Send Update Confirmation

  • Email with card details (last 4 digits, brand, expiry)
  • Note about retried invoices if any
  • Link to billing dashboard

Step 12: Publish Payment Method Update Event

  • Pub/Sub: payment_method.updated
  • Analytics, customer success alerts

Step 13: Success Response

  • Return { success: true, payment_method_updated: true, retried_invoices: N }

Data Flow

Input (Phase 1)

{
"user_id": "550e8400-e29b-41d4-a716-446655440000"
}

Output (Phase 1 - Client Secret)

{
"client_secret": "seti_1ABC_secret_XYZ",
"setup_intent_id": "seti_1ABC123"
}

Input (Phase 2 - Confirmation)

{
"setup_intent_id": "seti_1ABC123"
}

Output (Phase 2 - Success)

{
"success": true,
"payment_method_updated": true,
"retried_invoices": 2
}

Error Handling

ErrorCauseResponse
400 Bad RequestMissing user_id"User ID required"
404 Not FoundNo subscription"No active subscription"
402 Payment RequiredCard declined"Card declined, try another"
500 InternalStripe API failure"Update failed, try again"

Security Considerations

  • PCI Compliance: Card data never touches CODITECT backend (Stripe.js handles)
  • SetupIntent: Secure 3D Secure 2 authentication
  • HTTPS Only: All Stripe API calls over TLS
  • Audit Logging: All payment method changes logged

Performance Metrics

MetricTargetActual
Phase 1 Latency< 3sP95: 2.1s
Phase 2 Latency< 8sP95: 6.4s
Success Rate> 97%98.2%
Automatic Invoice Recovery> 80%84.6%

Business Impact

MetricValue
Past-Due Recovery Rate84.6% of past-due invoices paid after update
Churn Prevention23% of suspended accounts reactivate after update
Support Ticket Reduction55% fewer "payment failed" tickets

Testing Checklist

  • SetupIntent created successfully
  • Client secret returned to frontend
  • Payment method attached to customer
  • Set as default payment method
  • Past-due invoices retried automatically
  • Confirmation email sent
  • Event published to Pub/Sub
  • Card declined handled gracefully
  • 3D Secure authentication works


Status: ✅ Ready for Implementation