# Shopify Flow Integration

Appstle Subscriptions integrates natively with [Shopify Flow](https://www.shopify.com/flow), Shopify's built-in automation platform. Use Flow to automate subscription management without any API tokens or external authentication — everything runs securely within Shopify's ecosystem.

> **ℹ️ Why Shopify Flow?** Shopify Flow actions run within Shopify's authenticated context, so there's no need for API tokens or credentials. This makes Flow the most secure way to automate subscription operations — perfect for merchants who want powerful automation without managing API keys.


## Getting Started

1. In the Appstle admin, go to **Settings → Integrations → Shopify Flow**
2. Enable the Shopify Flow integration
3. Open the [Shopify Flow editor](https://admin.shopify.com/store/YOUR_STORE/apps/flow) in your Shopify admin
4. Create a new workflow using Appstle triggers and actions


## Triggers

Triggers fire automatically when subscription events occur. Use them to start Flow workflows.

### Subscription Lifecycle

| Trigger | Description |
|  --- | --- |
| **Subscription Created** | Fires when a new subscription contract is created |
| **Subscription Activated** | Fires when a subscription is activated from paused or cancelled status |
| **Subscription Cancelled** | Fires when a subscription is cancelled |
| **Subscription Paused** | Fires when a subscription is paused |
| **Subscription Updated** | Fires when a subscription is updated (products, quantity, address, etc.) |


### Billing Events

| Trigger | Description |
|  --- | --- |
| **Subscription Billing Success** | Fires when a billing attempt (payment) is successful |
| **Subscription Billing Failure** | Fires when a billing attempt (payment) fails |
| **Upcoming Order Notification** | Fires when an upcoming order notification is sent (based on configured buffer days) |


### Schedule Changes

| Trigger | Description |
|  --- | --- |
| **Subscription Billing Interval Changed** | Fires when the billing frequency is changed |
| **Subscription Next Order Date Changed** | Fires when the next billing/order date is modified |


## Trigger Properties

All triggers include a full set of subscription and customer properties. Some triggers include additional context-specific fields.

### Subscription Properties

Included with every trigger:

| Property | Type | Description |
|  --- | --- | --- |
| `Subscription ID` | Number | Internal subscription contract ID |
| `GraphQL Subscription ID` | String | GraphQL ID of the subscription contract |
| `Status` | String | Current status: `ACTIVE`, `PAUSED`, `CANCELLED`, `EXPIRED`, `FAILED` |
| `Next Billing Date` | String | Next billing date in UTC ISO 8601 (`yyyy-MM-dd'T'HH:mm:ss'Z'`). Empty string if not `ACTIVE`. |
| `Billing Interval` | String | Billing frequency unit: `DAY`, `WEEK`, `MONTH`, `YEAR` |
| `Billing Interval Count` | Number | Number of intervals between billings (e.g., `2` + `MONTH` = every 2 months) |
| `Delivery Interval` | String | Delivery frequency unit: `DAY`, `WEEK`, `MONTH`, `YEAR` |
| `Delivery Interval Count` | Number | Number of intervals between deliveries |
| `Original Order ID` | Number | ID of the first order. `0` for imported contracts. |
| `Original Order Name` | String | Name of the first order. Empty string for imported contracts. |
| `Cancel Reason` | String | Reason for cancellation (empty string if not cancelled) |
| `Pause Reason` | String | Reason for pause (empty string if not paused) |
| `Total Successful Orders` | Number | Total successfully completed orders for this contract |
| `Line Items` | Array | Array of line items (see [Line Items schema](#line-items-schema) below) |
| `Order Note Attributes` | Array | Array of key-value note attributes (see [Order Note Attributes schema](#order-note-attributes-schema) below) |


### Customer Properties

Included with every trigger:

| Property | Type | Description |
|  --- | --- | --- |
| `customer_reference` | Reference | Shopify customer reference |
| `Customer Email` | Email | Customer's email address |
| `Customer Phone` | String | Customer's phone number (empty string if not available) |
| `Customer Display Name` | String | Customer's display name (empty string if not available) |
| `Customer First Name` | String | Customer's first name (empty string if not available) |
| `Customer Last Name` | String | Customer's last name (empty string if not available) |


### Billing Event Properties

For **Subscription Billing Success**, **Subscription Billing Failure**, and **Upcoming Order Notification** triggers only:

| Property | Type | Description |
|  --- | --- | --- |
| `Billing Attempt ID` | Number | ID of the billing attempt |
| `Billing Attempt Status` | String | `SUCCESS`, `FAILURE`, `PENDING`, or `SCHEDULED` |
| `Billing Attempt Count` | Number | Number of billing attempts |
| `Billing Date` | String | Scheduled billing date (UTC ISO 8601) |
| `Billing Attempt Time` | String | Actual attempt timestamp (UTC ISO 8601) |


For **Subscription Billing Success** only:

| Property | Type | Description |
|  --- | --- | --- |
| `Recurring Order ID` | Number | Order ID from successful renewal |
| `Recurring Order Name` | String | Order name from successful renewal |
| `order_reference` | Reference | Shopify order reference |


### Subscription Updated Properties

For **Subscription Updated** trigger only:

| Property | Type | Description |
|  --- | --- | --- |
| `Contract Amount` | Number | Total line item amount in contract currency |
| `Contract Amount USD` | Number | Total line item amount converted to USD |


### Line Items Schema

The `Line Items` property is an array of objects, each representing a product line in the subscription:

| Field | Type | Description |
|  --- | --- | --- |
| `lineItemId` | String | ID of the line item |
| `variantId` | Float | Shopify variant ID |
| `graphqlVariantId` | String | GraphQL variant ID |
| `productId` | ID | Shopify product ID (GraphQL format) |
| `quantity` | Int | Quantity |
| `graphqlSellingPlanId` | String | Selling plan ID associated with this line |
| `sellingPlanName` | String | Selling plan name |
| `customAttributes` | Array | Key-value custom attributes on the line item |


### Order Note Attributes Schema

The `Order Note Attributes` property is an array of key-value pairs:

| Field | Type | Description |
|  --- | --- | --- |
| `key` | String | Attribute key |
| `value` | String | Attribute value |


## Actions

Actions are operations you can perform on subscriptions from within a Flow workflow.

### Line Item Management

| Action | Description | Required Fields |
|  --- | --- | --- |
| **Add Line Item** | Add a product to a subscription | `contract_id`, `product_variant_id`, `quantity` |
| **Remove Line Item** | Remove a product from a subscription | `contract_id`, `line_id` |
| **Update Line Item Quantity** | Change product quantity | `contract_id`, `line_id`, `quantity` |
| **Update Line Item Price** | Change product price | `contract_id`, `line_id`, `base_price` |
| **Update Line Item Attributes** | Update custom attributes on a line item | `contract_id`, `line_id`, `attributes` (JSON) |
| **Replace Variant** | Swap a product variant for another | `contract_id`, `old_variant_id`, `new_variant_id` |


### Subscription Management

| Action | Description | Required Fields |
|  --- | --- | --- |
| **Update Subscription Status** | Set status to Active, Paused, or Cancelled | `contract_id`, `status` |
| **Hide Subscription** | Hide from customer portal | `contract_id` |
| **Merge Subscriptions** | Combine two subscriptions into one | `source_contract_id`, `destination_contract_id` |
| **Split Subscription** | Split into separate subscriptions | `contract_id`, `line_ids` |
| **Update Selling Plan** | Change the selling plan for a line item | `contract_id`, `line_id`, `selling_plan_id` |
| **Update Order Note** | Update the order note | `contract_id`, `order_note` |
| **Update Note Attributes** | Update custom note attributes | `contract_id`, `note_attributes` (JSON) |


### Billing & Schedule

| Action | Description | Required Fields |
|  --- | --- | --- |
| **Update Billing Interval** | Change billing frequency (e.g., monthly → weekly) | `contract_id`, `billing_interval_count`, `billing_interval` |
| **Update Frequency by Selling Plan** | Change frequency using an existing selling plan | `contract_id`, `selling_plan_id` |
| **Update Billing Date** | Reschedule the next billing date | `contract_id`, `next_billing_date` (ISO 8601) |
| **Skip Order** | Skip the next scheduled order | `contract_id`, `line_id` |
| **Attempt Billing** | Trigger immediate billing/order placement | `contract_id` or `billing_attempt_id` |
| **Update Max Cycles** | Set maximum billing cycles | `contract_id`, `max_cycles` |
| **Update Min Cycles** | Set minimum billing cycles | `contract_id`, `min_cycles` |


### Discounts & Pricing

| Action | Description | Required Fields |
|  --- | --- | --- |
| **Apply Discount Code** | Apply a discount code to a subscription | `contract_id`, `discount_code` |
| **Remove Discount** | Remove a discount from a subscription | `contract_id`, `discount_id` |
| **Update Pricing Policy** | Update pricing policy with cycle-based discounts | `contract_id`, `base_price` |


### Delivery & Shipping

| Action | Description | Required Fields |
|  --- | --- | --- |
| **Update Delivery Interval** | Change delivery frequency | `contract_id`, `delivery_interval_count`, `delivery_interval` |
| **Update Delivery Method** | Change the shipping method | `contract_id`, `delivery_method_title` |
| **Update Delivery Price** | Change shipping price | `contract_id`, `delivery_price` |
| **Update Shipping Address** | Update delivery address | `contract_id`, `address1`, `city`, `country_code` |


### Payment

| Action | Description | Required Fields |
|  --- | --- | --- |
| **Update Payment Method** | Send payment method update to customer | `contract_id` |


### Output Fields

All actions return output fields that can be used in subsequent Flow steps. Every action returns at minimum a `success_message` field indicating the result of the operation.

### Action Details

Detailed input and output fields for each action. Use the summary tables above for quick reference.

#### Add Line Item

Add a product variant to an existing subscription.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `product_variant_id` | String | ✅ | Shopify product variant ID to add |
| `quantity` | String | ✅ | Quantity to add |
| `is_one_time_product` | String |  | `"true"` or `"false"` — add as a one-time (non-recurring) line item. Default: `"false"` |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `product_variant_id` | String | Variant ID that was added |
| `quantity` | String | Quantity added |
| `is_one_time_product` | String | Whether the item was added as one-time |
| `success_message` | String | Result message |


#### Remove Line Item

Remove a product from a subscription.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `line_id` | String | ✅ | Line item ID to remove |
| `remove_discount` | String |  | Whether to remove the discount associated with this line item |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `line_id` | String | Line item ID that was removed |
| `remove_discount` | String | Whether discount was removed |
| `success_message` | String | Result message |


#### Update Line Item Quantity

Change the quantity of a product in a subscription.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `line_id` | String | ✅ | Line item ID |
| `quantity` | String | ✅ | New quantity |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `line_id` | String | Line item ID |
| `quantity` | String | Updated quantity |
| `success_message` | String | Result message |


#### Update Line Item Price

Change the price of a product in a subscription.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `line_id` | String | ✅ | Line item ID |
| `base_price` | String | ✅ | New base price |
| `remove_pricing_policy` | Boolean |  | Whether to remove the existing pricing policy. Default: `false` |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `line_id` | String | Line item ID |
| `base_price` | String | Updated price |
| `remove_pricing_policy` | Boolean | Whether pricing policy was removed |
| `success_message` | String | Result message |


#### Update Line Item Attributes

Update custom attributes on a line item.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `line_id` | String | ✅ | Line item ID |
| `attributes` | String | ✅ | JSON array of key-value pairs |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `line_id` | String | Line item ID |
| `success_message` | String | Result message |


#### Replace Variant

Swap a product variant for another in a subscription.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `old_variant_id` | String | ✅ | Comma-separated variant IDs to replace |
| `new_variant_id` | String | ✅ | Comma-separated variant IDs with optional quantities (e.g., `11111:2,22222:1`) |
| `old_line_id` | String |  | Specific line ID to replace (use when multiple lines have the same variant) |
| `carry_forward_discount` | String |  | Whether to carry the existing discount to the new variant |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `old_variant_id` | String | Variant IDs that were replaced |
| `new_variant_id` | String | New variant IDs |
| `success_message` | String | Result message |


#### Update Subscription Status

Set a subscription's status to Active, Paused, or Cancelled.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `status` | String | ✅ | `ACTIVE`, `PAUSED`, or `CANCELLED` |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `status` | String | Updated status |
| `success_message` | String | Result message |


#### Hide Subscription

Hide a subscription from the customer portal.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `success_message` | String | Result message |


#### Merge Subscriptions

Combine two subscriptions into one.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `source_contract_id` | String | ✅ | Contract ID to merge from |
| `destination_contract_id` | String | ✅ | Contract ID to merge into |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `source_contract_id` | String | Source contract ID |
| `destination_contract_id` | String | Destination contract ID |
| `success_message` | String | Result message |


#### Split Subscription

Split specific line items into a new subscription.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `line_ids` | String | ✅ | Comma-separated line item IDs to move |
| `attempt_billing` | String |  | Whether to immediately bill the new contract after splitting |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `original_contract_id` | String | Original contract ID |
| `new_contract_id` | String | Newly created contract ID |
| `line_ids_moved` | String | Line item IDs that were moved |
| `success_message` | String | Result message |


#### Update Selling Plan

Change the selling plan for a line item.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `line_id` | String | ✅ | Line item ID |
| `selling_plan_id` | String | ✅ | New selling plan ID |
| `selling_plan_name` | String |  | Display name for the new selling plan |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `line_id` | String | Line item ID |
| `selling_plan_id` | String | Updated selling plan ID |
| `success_message` | String | Result message |


#### Update Order Note

Update the order note on a subscription.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `order_note` | String | ✅ | New order note text |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `success_message` | String | Result message |


#### Update Note Attributes

Update custom note attributes on a subscription.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `note_attributes` | String | ✅ | JSON array of key-value pairs |
| `overwrite_existing` | Boolean |  | `true` to replace all existing attributes; `false` to merge with existing. Default: `false` |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `attributes_count` | Number | Number of attributes after update |
| `overwrite_existing` | Boolean | Whether existing attributes were overwritten |
| `success_message` | String | Result message |


#### Update Billing Interval

Change the billing frequency.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `billing_interval_count` | String | ✅ | Number of intervals between billings |
| `billing_interval` | String | ✅ | Interval unit: `DAY`, `WEEK`, `MONTH`, `YEAR` |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `billing_interval_count` | String | Updated interval count |
| `billing_interval` | String | Updated interval unit |
| `success_message` | String | Result message |


#### Update Frequency by Selling Plan

Change billing and delivery frequency using an existing selling plan.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `selling_plan_id` | String | ✅ | Selling plan ID to apply |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `selling_plan_id` | String | Applied selling plan ID |
| `selling_plan_name` | String | Selling plan name |
| `billing_interval_count` | String | Updated billing interval count |
| `billing_interval` | String | Updated billing interval unit |
| `delivery_interval_count` | String | Updated delivery interval count |
| `delivery_interval` | String | Updated delivery interval unit |
| `success_message` | String | Result message |


#### Update Billing Date

Reschedule the next billing date.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `next_billing_date` | String | ✅ | New billing date (ISO 8601) |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `next_billing_date` | String | Updated billing date |
| `success_message` | String | Result message |


#### Skip Order

Skip (or unskip) the next scheduled order.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `line_id` | String | ✅ | Line item ID |
| `is_skip` | Boolean |  | `true` to skip, `false` to unskip. Default: `true` |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `line_id` | String | Line item ID |
| `is_skip` | Boolean | Whether the order was skipped |
| `success_message` | String | Result message |


#### Attempt Billing

Trigger immediate billing/order placement.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅* | Subscription contract ID (*one of `contract_id` or `billing_attempt_id` required) |
| `billing_attempt_id` | String | ✅* | Billing attempt ID (*alternative to `contract_id`) |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `success_message` | String | Result message |


#### Update Max Cycles

Set the maximum number of billing cycles.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `max_cycles` | String | ✅ | Maximum billing cycles |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `max_cycles` | String | Updated max cycles |
| `success_message` | String | Result message |


#### Update Min Cycles

Set the minimum number of billing cycles.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `min_cycles` | String | ✅ | Minimum billing cycles |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `min_cycles` | String | Updated min cycles |
| `success_message` | String | Result message |


#### Apply Discount Code

Apply a discount code to a subscription.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `discount_code` | String | ✅ | Discount code to apply |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `discount_code` | String | Applied discount code |
| `success_message` | String | Result message |


#### Remove Discount

Remove a discount from a subscription.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `discount_id` | String | ✅* | Discount ID to remove (*one of `discount_id` or `discount_code` required) |
| `discount_code` | String |  | Discount code to remove (alternative to `discount_id`) |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `discount_id` | String | Removed discount ID |
| `success_message` | String | Result message |


#### Update Pricing Policy

Update pricing policy with cycle-based discounts.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `base_price` | String | ✅ | Base price for the line item |
| `line_id` | String |  | Specific line item ID (if not provided, applies to all lines) |
| `cycles` | String |  | JSON defining cycle-based pricing adjustments |
| `overwrite_existing` | Boolean |  | Whether to replace existing pricing policy or merge. Default: `false` |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `line_id` | String | Line item ID |
| `base_price` | String | Updated base price |
| `success_message` | String | Result message |


#### Update Delivery Interval

Change the delivery frequency.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `delivery_interval_count` | String | ✅ | Number of intervals between deliveries |
| `delivery_interval` | String | ✅ | Interval unit: `DAY`, `WEEK`, `MONTH`, `YEAR` |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `delivery_interval_count` | String | Updated interval count |
| `delivery_interval` | String | Updated interval unit |
| `success_message` | String | Result message |


#### Update Delivery Method

Change the shipping method on a subscription.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `delivery_method_title` | String | ✅ | Shipping method title |
| `delivery_method_code` | String |  | Shipping method code |
| `delivery_method_presentment_title` | String |  | Customer-facing title for the shipping method |
| `delivery_method_id` | String |  | Specific delivery method ID |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `delivery_method_title` | String | Updated method title |
| `delivery_method_code` | String | Updated method code |
| `success_message` | String | Result message |


#### Update Delivery Price

Change the shipping price on a subscription.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `delivery_price` | String | ✅ | New shipping price |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `delivery_price` | String | Updated shipping price |
| `success_message` | String | Result message |


#### Update Shipping Address

Update the delivery address on a subscription.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |
| `address1` | String | ✅ | Street address |
| `city` | String | ✅ | City |
| `country_code` | String | ✅ | Two-letter country code (e.g., `US`, `CA`) |
| `address2` | String |  | Apartment, suite, etc. |
| `province` | String |  | State/province name |
| `province_code` | String |  | State/province code (e.g., `CA`, `ON`) |
| `zip` | String |  | Postal/ZIP code |
| `country` | String |  | Full country name |
| `first_name` | String |  | Recipient first name |
| `last_name` | String |  | Recipient last name |
| `phone` | String |  | Recipient phone number |
| `company` | String |  | Company name |
| `location_id` | String |  | Shopify location ID |
| `method_type` | String |  | Delivery method type |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `address1` | String | Updated street address |
| `city` | String | Updated city |
| `country_code` | String | Updated country code |
| `success_message` | String | Result message |


#### Update Payment Method

Send a payment method update request to the customer.

**Input Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `contract_id` | String | ✅ | Subscription contract ID |


**Output Fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `contract_id` | String | Subscription contract ID |
| `success_message` | String | Result message |


## Example Workflows

### Auto-pause after 3 failed payments

**Trigger:** Subscription Billing Failure
**Condition:** Check if this is the 3rd consecutive failure
**Action:** Update Subscription Status → `PAUSED`

### Apply loyalty discount after 6 months

**Trigger:** Subscription Billing Success
**Condition:** Current billing cycle ≥ 6
**Action:** Apply Discount Code → `LOYAL10`

### Notify team on high-value cancellation

**Trigger:** Subscription Cancelled
**Condition:** Subscription value > $100/month
**Action:** Send Slack notification (via Shopify Flow's Slack connector)

### Auto-swap seasonal products

**Trigger:** Scheduled (monthly, via Shopify Flow's scheduler)
**Action:** Replace Variant → swap summer product for winter product

## Field Reference

### Billing Interval Values

Use these values for `billing_interval` and `delivery_interval` fields:

- `DAY`
- `WEEK`
- `MONTH`
- `YEAR`


### Status Values

Use these values for the `status` field:

- `ACTIVE`
- `PAUSED`
- `CANCELLED`


### Date Format

All date fields use ISO 8601 format: `2026-03-15T10:00:00Z`

### Attributes Format

For `attributes` and `note_attributes` fields, use JSON array format:


```json
[
  {"key": "gift_message", "value": "Happy Birthday!"},
  {"key": "delivery_instructions", "value": "Leave at door"}
]
```

### Replace Variant Format

- `old_variant_id`: Comma-separated variant IDs to replace (e.g., `12345,67890`)
- `new_variant_id`: Comma-separated variant IDs with optional quantities (e.g., `11111:2,22222:1`)


## Notes

- Shopify Flow is available on **Shopify Basic plan and above**
- Flow actions require the Appstle Subscriptions app to be installed and the Flow integration enabled
- The **Attempt Billing** action requires additional permission — contact support to enable
- All actions are logged in the subscription activity log with source `SHOPIFY_FLOW`