Overview

Customer synchronization ensures that customers exist in both Flexprice and Stripe with linked identifiers, enabling:
  • On-demand sync: Customers are synced to Stripe only when needed for payments
  • Payment link creation for any Flexprice customer
  • Card payment processing with automatic customer sync
  • Automatic customer creation from Stripe webhooks
  • Consistent customer data across platforms
  • Efficient payment processing workflows

Synchronization Flow

Customer sync now works on-demand with bidirectional support:

Key Concepts

  • On-Demand Sync: Customers are synced to Stripe only when payment interactions occur
  • Entity Integration Mapping: Links Flexprice customers to Stripe customer IDs
  • Metadata Storage: Customer metadata stores cross-platform references
  • Payment-Triggered Sync: Sync happens automatically during payment flows
  • Duplicate Prevention: Intelligent checks prevent duplicate customer creation
  • Performance Optimization: No unnecessary syncs for customers who never make payments

Customer Data Model

Flexprice Customer Structure

{
  "id": "cust_1234567890abcdef",
  "external_id": "customer_external_123",
  "name": "John Doe",
  "email": "john@example.com",
  "address_line1": "123 Main St",
  "address_line2": "Apt 4B",
  "address_city": "New York",
  "address_state": "NY",
  "address_postal_code": "10001",
  "address_country": "US",
  "metadata": {
    "stripe_customer_id": "cus_stripe123abc"
  },
  "environment_id": "prod",
  "tenant_id": "tenant_123",
  "status": "active",
  "created_at": "2024-01-20T10:30:00Z"
}

Stripe Customer Structure

{
  "id": "cus_stripe123abc",
  "name": "John Doe",
  "email": "john@example.com",
  "address": {
    "line1": "123 Main St",
    "line2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "postal_code": "10001",
    "country": "US"
  },
  "metadata": {
    "flexprice_customer_id": "cust_1234567890abcdef",
    "flexprice_environment": "prod",
    "external_id": "customer_external_123"
  },
  "created": 1642680600
}

Synchronization Methods

1. On-Demand Sync (Payment-Triggered)

Primary Method: Customers are automatically synced to Stripe when payment interactions occur. When creating a payment link, the system automatically ensures the customer exists in Stripe: Endpoint: POST /api/v1/payments Request:
{
    "amount": 20,
    "currency": "usd",
    "destination_id": "inv_01K3K2N0FY0Z7Z6RHR6EMGJ8AC",
    "destination_type": "INVOICE",
    "payment_method_type": "PAYMENT_LINK",
    "process_payment": true,
    "payment_gateway": "stripe",
    "success_url": "https://admin.flexprice.io/customer-management/invoices/inv_01K3K2N0FY0Z7Z6RHR6EMGJ8AC?page=1",
    "cancel_url": "https://admin.flexprice.io/customer-management/invoices/inv_01K3K2N0FY0Z7Z6RHR6EMGJ8AC?page=1"

}
Internal Flow:
  1. Check if customer has stripe_customer_id in metadata
  2. Check entity integration mapping table
  3. If not synced → Create customer in Stripe automatically
  4. Create payment link with synced customer

Card Payment Processing

When processing card payments, the system ensures customer sync: Endpoint: POST /api/v1/payments Request:
{
    "amount": 20,
    "currency": "usd",
    "destination_id": "inv_01K3K2N0FY0Z7Z6RHR6EMGJ8AC",
    "destination_type": "INVOICE",
    "payment_method_type": "CARD",
    "process_payment": true,
    "payment_gateway": "stripe",
    "success_url": "https://admin.flexprice.io/customer-management/invoices/inv_01K3K2N0FY0Z7Z6RHR6EMGJ8AC?page=1",
    "cancel_url": "https://admin.flexprice.io/customer-management/invoices/inv_01K3K2N0FY0Z7Z6RHR6EMGJ8AC?page=1"

}
Internal Flow:
  1. Validate payment amount against invoice remaining balance
  2. Ensure customer is synced to Stripe (auto-sync if needed)
  3. Process payment with Stripe customer using saved payment method

2. Manual Sync (Optional)

For advanced use cases, manual sync is still available: Endpoint: POST /api/v1/integrations/sync/customer Request:
{
  "customer_id": "cust_1234567890abcdef",
  "provider": "stripe",
  "sync_direction": "flexprice_to_provider"
}

3. Automatic Sync (Stripe → Flexprice)

Customers created in Stripe are automatically synced via webhooks. Webhook Event: customer.created Webhook Payload:
{
  "id": "evt_1234567890abcdef",
  "type": "customer.created",
  "data": {
    "object": {
      "id": "cus_stripe123abc",
      "name": "John Doe",
      "email": "john@example.com",
      "address": {
        "line1": "123 Main St",
        "city": "New York",
        "state": "NY",
        "postal_code": "10001",
        "country": "US"
      },
      "metadata": {
        "flexprice_environment": "prod"
      }
    }
  }
}

Sync Configuration

Required Fields for Sync

FieldFlexprice → StripeStripe → FlexpriceNotes
nameCustomer full name
emailPrimary email address
address_line1Street address
address_cityCity
address_stateState/province
address_postal_codeZIP/postal code
address_countryCountry code

Optional Fields

FieldDescription
address_line2Apartment/suite number
phonePhone number
external_idYour internal customer ID
metadataCustom key-value pairs

Sync Process Details

On-Demand Sync Flow (Payment-Triggered)

Stripe → Flexprice Sync Flow (Unchanged)

Customer Linking

Metadata Storage

Customer linking is maintained through metadata fields: In Flexprice Customer:
{
  "metadata": {
    "stripe_customer_id": "cus_stripe123abc",
    "stripe_sync_timestamp": "2024-01-20T10:30:00Z"
  }
}
In Stripe Customer:
{
  "metadata": {
    "flexprice_customer_id": "cust_1234567890abcdef",
    "flexprice_environment": "prod",
    "flexprice_sync_timestamp": "2024-01-20T10:30:00Z"
  }
}
You can verify customer links using the API: Endpoint: GET /api/v1/customers/{customer_id}/integrations Response:
{
  "customer_id": "cust_1234567890abcdef",
  "integrations": [
    {
      "provider": "stripe",
      "external_id": "cus_stripe123abc",
      "sync_status": "linked",
      "last_sync": "2024-01-20T10:30:00Z"
    }
  ]
}

Duplicate Prevention

Email-Based Deduplication

The system prevents duplicate customers using email addresses:
  1. Check Existing: Look for customers with same email
  2. Merge Strategy: Update existing customer with new data
  3. Link Creation: Create cross-platform links
  4. Audit Trail: Log all sync operations

External ID Matching

For customers with external IDs:
  1. Priority Matching: External ID takes precedence over email
  2. Fallback to Email: If no external ID match, use email
  3. Manual Resolution: Conflicts require manual intervention

Error Handling

Common Sync Errors

ErrorCauseResolution
”Customer not found”Invalid customer IDVerify customer exists
”Email already exists”Duplicate email in StripeCheck for existing customer
”Invalid email format”Malformed email addressFix email format
”Stripe API error”Stripe connection issueCheck Stripe credentials

Sync Failure Recovery

When sync fails:
  1. Log Error: Record failure with details
  2. Retry Logic: Automatic retry with exponential backoff
  3. Manual Intervention: Admin can retry failed syncs
  4. Notification: Alert on persistent failures

Testing Customer Sync

Test Environment Setup

  1. Test Stripe Account: Use Stripe test mode
  2. Test Customers: Create test customers in Flexprice only
  3. Webhook Testing: Use ngrok for local webhook testing

On-Demand Sync Testing Flow

  1. Create Test Customer: Add customer in Flexprice (no sync yet)
  2. Verify No Sync: Customer should NOT exist in Stripe initially
  3. Create Payment Link: Trigger payment link creation
  4. Verify Auto-Sync: Customer should now exist in Stripe
  5. Test Card Payment: Process card payment with same customer
  6. Verify Reuse: Should use existing Stripe customer (no duplicate)