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

# Migrate from Stripe

> Step-by-step guide for migrating subscription contracts from Stripe to Circuly Subscriptions

## Overview

This guide walks you through migrating subscription contracts from a Stripe-based system to Circuly Subscriptions on Shopify.

## Step 1: Prepare Your Data

You need to export your subscription data into a JSON file. Each subscription requires:

* The **Shopify customer ID** (the customer must already exist in Shopify)
* The **Stripe customer ID** (cus\_xxx) and **payment method ID** (pm\_xxx)
* The **Shopify product variant ID** for the subscribed product
* Billing details (price, interval, next billing date)
* The customer's delivery address

### JSON Format

Your file must be a JSON array of subscription objects:

```json theme={null}
[
  {
    "shopifyCustomerId": "gid://shopify/Customer/123456789",
    "paymentReference": {
      "gateway": "stripe",
      "customerId": "cus_abc123",
      "paymentMethodId": "pm_def456"
    },
    "productVariantId": "gid://shopify/ProductVariant/987654321",
    "recurringPrice": "29.99",
    "currencyCode": "EUR",
    "billingInterval": "MONTH",
    "billingIntervalCount": 1,
    "nextBillingDate": "2026-04-01",
    "deliveryAddress": {
      "firstName": "Jane",
      "lastName": "Doe",
      "address1": "Musterstr. 1",
      "city": "Berlin",
      "zip": "10115",
      "country": "DE"
    },
    "status": "ACTIVE"
  }
]
```

### Required Fields

| Field                              | Type   | Description                                              |
| ---------------------------------- | ------ | -------------------------------------------------------- |
| `shopifyCustomerId`                | string | Shopify customer GID (`gid://shopify/Customer/XXX`)      |
| `paymentReference.gateway`         | string | Must be `"stripe"`                                       |
| `paymentReference.customerId`      | string | Stripe customer ID (`cus_xxx`)                           |
| `paymentReference.paymentMethodId` | string | Stripe payment method ID (`pm_xxx`)                      |
| `productVariantId`                 | string | Shopify variant GID (`gid://shopify/ProductVariant/XXX`) |
| `recurringPrice`                   | string | Price per billing cycle (e.g., `"29.99"`)                |
| `currencyCode`                     | string | ISO 4217 currency code (e.g., `"EUR"`, `"USD"`)          |
| `billingInterval`                  | string | `"WEEK"`, `"MONTH"`, or `"YEAR"`                         |
| `billingIntervalCount`             | number | Number of intervals between charges                      |
| `nextBillingDate`                  | string | ISO date for the next charge (e.g., `"2026-04-01"`)      |
| `deliveryAddress`                  | object | Customer's shipping address                              |
| `status`                           | string | `"ACTIVE"` or `"PAUSED"`                                 |

### Optional History Fields

Include these to preserve billing history from your old system:

| Field               | Type   | Description                                    |
| ------------------- | ------ | ---------------------------------------------- |
| `currentCycleIndex` | number | How many billing cycles have completed         |
| `totalBilled`       | string | Total amount billed to date (e.g., `"179.94"`) |
| `totalPaid`         | string | Total amount paid to date                      |
| `cyclesBilled`      | number | Number of successful billing cycles            |
| `minCycles`         | number | Minimum commitment cycles                      |
| `maxCycles`         | number | Maximum cycles before auto-cancel              |

## Step 2: Find Your IDs

### Shopify Customer IDs

You can find customer GIDs in the Shopify admin URL. When viewing a customer, the URL contains the numeric ID:

`admin.shopify.com/store/your-store/customers/123456789`

The GID format is: `gid://shopify/Customer/123456789`

### Stripe IDs

In your Stripe Dashboard:

* **Customer ID**: Found on the customer detail page (starts with `cus_`)
* **Payment Method ID**: Found under the customer's payment methods (starts with `pm_`)

### Shopify Variant IDs

Product variant IDs can be found in the Shopify admin URL when editing a variant, or exported via the Shopify Products CSV export.

## Step 3: Run the Migration

1. Navigate to the **Migration** page in the Circuly Subscriptions app
2. Upload your JSON file using the drop zone
3. Review the **validation preview** — check that all subscriptions show as "Valid"
4. Click **Migrate** to start the process
5. Wait for the migration to complete (approximately 2-4 seconds per subscription)
6. Review the **results** — download the results JSON for your records

## Step 4: Verify

After migration:

1. Check the **Subscriptions** page in Circuly — migrated contracts should appear
2. Open a few contracts in the Shopify admin to verify billing policies
3. Check the **customer portal** — migrated contracts should be visible to customers
4. Verify payment methods on customer records in Shopify admin

## Troubleshooting

### Validation Errors

These errors appear during the file upload/validation step:

| Error                                       | Solution                                                                            |
| ------------------------------------------- | ----------------------------------------------------------------------------------- |
| "Customer ID is required"                   | Add a `shopifyCustomerId` field with a valid string value                           |
| "Customer ID must be a Shopify GID"         | Use the format `gid://shopify/Customer/123456789`                                   |
| "Product variant ID is required"            | Add a `productVariantId` field with a valid string value                            |
| "Product variant ID must be a Shopify GID"  | Use the format `gid://shopify/ProductVariant/123456789`                             |
| "Payment reference is required"             | Add a `paymentReference` object with `gateway`, `customerId`, and `paymentMethodId` |
| "Unsupported gateway"                       | Use one of: `stripe`, `braintree`, `authorize_net`, `paypal`                        |
| "Recurring price must be a positive number" | Provide a numeric string greater than zero (e.g., `"29.99"`)                        |
| "Currency code is required"                 | Add an ISO 4217 currency code (e.g., `"EUR"`, `"USD"`)                              |
| "Billing interval is not supported"         | Use `WEEK`, `MONTH`, or `YEAR`                                                      |
| "Billing interval count must be at least 1" | Provide a number >= 1                                                               |
| "Next billing date must be a valid date"    | Use ISO date format (e.g., `"2026-04-01"`)                                          |
| "Delivery address is required"              | Add a `deliveryAddress` object with shipping details                                |
| "Status is not supported"                   | Use `ACTIVE` or `PAUSED`                                                            |

### Migration Errors

These errors appear after migration starts:

| Error                                    | Error Code                  | Solution                                                                    |
| ---------------------------------------- | --------------------------- | --------------------------------------------------------------------------- |
| "Payment method import failed"           | `PAYMENT_IMPORT_FAILED`     | Check that Stripe is connected as a payment provider in Shopify             |
| "Payment method was revoked"             | `PAYMENT_METHOD_REVOKED`    | The Stripe payment method may be invalid or expired                         |
| "Payment method not ready after 30s"     | `PAYMENT_METHOD_TIMEOUT`    | The payment method import is taking too long — retry or check Shopify admin |
| "Contract creation failed"               | `CONTRACT_CREATION_FAILED`  | Check that the product variant exists and the billing policy is valid       |
| "ContractRecord not found after waiting" | `BACKFILL_RECORD_NOT_FOUND` | The webhook may not have fired — check webhook logs in the app              |
| "Invalid customer GID"                   | `INVALID_CUSTOMER_GID`      | Use the format `gid://shopify/Customer/123456789`                           |
| "Invalid variant GID"                    | `INVALID_VARIANT_GID`       | Use the format `gid://shopify/ProductVariant/123456789`                     |
| "Invalid recurring price"                | `INVALID_PRICE`             | Provide a numeric string greater than zero (e.g., `"29.99"`)                |
| "Invalid billing interval count"         | `INVALID_INTERVAL_COUNT`    | Provide a number >= 1                                                       |
| "Invalid next billing date"              | `INVALID_BILLING_DATE`      | Use ISO date format (e.g., `"2026-04-01"`)                                  |
| "Payment reference requires..."          | `INVALID_PAYMENT_REFERENCE` | Ensure all required fields for the gateway are provided                     |
| "Unsupported payment gateway"            | `UNSUPPORTED_GATEWAY`       | Use one of: `stripe`, `braintree`, `authorize_net`, `paypal`                |
