> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flexprice.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Stripe Customer Synchronization

> Complete guide to on-demand customer synchronization between Flexprice and Stripe

## 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:

```mermaid theme={null}
graph LR
    A[Flexprice Customer] -->|On-Demand Sync| B[Stripe Customer]
    C[Payment Link Request] -->|Triggers Sync| B
    D[Card Payment Request] -->|Triggers Sync| B
    E[Stripe Customer] -->|Webhook Sync| F[Flexprice Customer]
    B -->|Metadata Link| A
    F -->|Metadata Link| E
```

### 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

```json theme={null}
{
  "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

```json theme={null}
{
  "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.

#### Payment Link Creation

When creating a payment link, the system automatically ensures the customer exists in Stripe:

**Endpoint:** `POST /api/v1/payments`

**Request:**

```json theme={null}
{
    "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:**

```json theme={null}
{
    "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:**

```json theme={null}
{
  "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:**

```json theme={null}
{
  "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

| Field                 | Flexprice → Stripe | Stripe → Flexprice | Notes                 |
| --------------------- | ------------------ | ------------------ | --------------------- |
| `name`                | ✅                  | ✅                  | Customer full name    |
| `email`               | ✅                  | ✅                  | Primary email address |
| `address_line1`       | ✅                  | ✅                  | Street address        |
| `address_city`        | ✅                  | ✅                  | City                  |
| `address_state`       | ✅                  | ✅                  | State/province        |
| `address_postal_code` | ✅                  | ✅                  | ZIP/postal code       |
| `address_country`     | ✅                  | ✅                  | Country code          |

### Optional Fields

| Field           | Description               |
| --------------- | ------------------------- |
| `address_line2` | Apartment/suite number    |
| `phone`         | Phone number              |
| `external_id`   | Your internal customer ID |
| `metadata`      | Custom key-value pairs    |

## Sync Process Details

### On-Demand Sync Flow (Payment-Triggered)

```mermaid theme={null}
graph TD
    A[Payment Request] --> B[EnsureCustomerSyncedToStripe]
    B --> C{Check Metadata}
    C -->|Has stripe_customer_id| D[Return Existing Customer]
    C -->|No stripe_customer_id| E[Check Integration Mapping]
    E --> F{Mapping Exists?}
    F -->|Yes| G[Update Customer Metadata]
    F -->|No| H[CreateCustomerInStripe]
    G --> I[Return Customer Info]
    H --> J[Update Metadata & Mapping]
    J --> I
    I --> K[Process Payment]
```

### Stripe → Flexprice Sync Flow (Unchanged)

```mermaid theme={null}
graph TD
    A[Webhook Received] --> B[Verify Signature]
    B --> C[Parse Customer Data]
    C --> D[Check Existing Flexprice Customer]
    D --> E{Exists in Flexprice?}
    E -->|Yes| F[Update Flexprice Customer]
    E -->|No| G[Create Flexprice Customer]
    F --> H[Update Metadata]
    G --> H
    H --> I[Return 200 Success]
```

## Customer Linking

### Metadata Storage

Customer linking is maintained through metadata fields:

**In Flexprice Customer:**

```json theme={null}
{
  "metadata": {
    "stripe_customer_id": "cus_stripe123abc",
    "stripe_sync_timestamp": "2024-01-20T10:30:00Z"
  }
}
```

**In Stripe Customer:**

```json theme={null}
{
  "metadata": {
    "flexprice_customer_id": "cust_1234567890abcdef",
    "flexprice_environment": "prod",
    "flexprice_sync_timestamp": "2024-01-20T10:30:00Z"
  }
}
```

### Link Verification

You can verify customer links using the API:

**Endpoint:** `GET /api/v1/customers/{customer_id}/integrations`

**Response:**

```json theme={null}
{
  "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

| Error                  | Cause                     | Resolution                  |
| ---------------------- | ------------------------- | --------------------------- |
| "Customer not found"   | Invalid customer ID       | Verify customer exists      |
| "Email already exists" | Duplicate email in Stripe | Check for existing customer |
| "Invalid email format" | Malformed email address   | Fix email format            |
| "Stripe API error"     | Stripe connection issue   | Check 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)
