Skip to main content

Selling Plans

Selling plans define the terms and pricing for subscription products. They specify how often customers are billed, delivery frequencies, and any discounts applied to recurring orders. Selling plans are grouped together in selling plan groups, which are then attached to products.

Selling Plan Groups

A selling plan group is a collection of related selling plans that can be applied to products. Each group contains:
  • A unique merchant code for identification
  • One or more selling plans with different billing frequencies
  • Associated products or product variants
export interface SellingPlanGroupListItem {
  id: string;
  merchantCode: string;
  productsCount?: number;
  productVariantsCount?: number;
  products?: SellingPlanGroupListItemProduct[];
  sellingPlans: SellingPlanGroupListItemSellingPlan[];
  sellingPlansPageInfo: PaginationInfo;
}
The merchantCode is a human-readable identifier you can use to reference the selling plan group in your code or external systems.

Selling Plans Structure

Each selling plan within a group defines specific subscription terms:
export interface SellingPlanGroupListItemSellingPlan {
  id?: string;
  pricingPolicies?: SellingPlanPricingPolicy[];
  deliveryPolicy: RecurringPolicy;
}

Recurring Policies

Both billing and delivery use recurring policies to define frequency:
export interface RecurringPolicy {
  interval: 'DAY' | 'WEEK' | 'MONTH' | 'YEAR';
  intervalCount: number;
}
Examples:
  • Every month: { interval: 'MONTH', intervalCount: 1 }
  • Every 2 weeks: { interval: 'WEEK', intervalCount: 2 }
  • Every 3 months: { interval: 'MONTH', intervalCount: 3 }

Pricing Policies

Selling plans can include pricing policies that apply discounts to subscription purchases:
export interface SellingPlanPricingPolicy {
  adjustmentType: SellingPlanAdjustmentType;
  adjustmentValue: SellingPlanAdjustmentValue;
}

export const SellingPlanAdjustment = {
  Percentage: 'PERCENTAGE',
  Fixed: 'FIXED_AMOUNT',
  Price: 'PRICE',
} as const;

export type SellingPlanAdjustmentValue = Percentage | Money;

export interface Percentage {
  percentage: number;
}

Discount Types

Applies a percentage discount to the product price.
{
  adjustmentType: 'PERCENTAGE',
  adjustmentValue: { percentage: 10 } // 10% off
}

Querying Selling Plans

The app uses GraphQL to fetch selling plan group details:
query SellingPlanGroup(
  $id: ID!
  $firstProducts: Int = 1
  $productsAfter: String
  $variantsAfter: String
) {
  sellingPlanGroup(id: $id) {
    id
    name
    merchantCode
    sellingPlans(first: 31) {
      edges {
        node {
          id
          billingPolicy {
            ... on SellingPlanRecurringBillingPolicy {
              interval
              intervalCount
            }
          }
          pricingPolicies {
            ... on SellingPlanFixedPricingPolicy {
              adjustmentType
              adjustmentValue {
                ... on SellingPlanPricingPolicyPercentageValue {
                  percentage
                }
                ... on MoneyV2 {
                  amount
                  currencyCode
                }
              }
            }
          }
        }
      }
    }
    products(first: $firstProducts, after: $productsAfter) {
      edges {
        node {
          id
          title
          featuredImage {
            url
            altText
          }
        }
      }
    }
    productsCount {
      count
    }
    productVariantsCount {
      count
    }
  }
}
Selling plans support up to 31 different billing frequencies per group, giving merchants flexibility in offering various subscription options.

Billing vs Delivery Policies

Selling plans can have different billing and delivery frequencies:
Pre-paid subscriptions: Bill monthly, deliver monthly
{
  billingPolicy: { interval: 'MONTH', intervalCount: 1 },
  deliveryPolicy: { interval: 'MONTH', intervalCount: 1 }
}
Quarterly billing with monthly delivery: Bill every 3 months, deliver monthly
{
  billingPolicy: { interval: 'MONTH', intervalCount: 3 },
  deliveryPolicy: { interval: 'MONTH', intervalCount: 1 }
}
Weekly subscriptions: Bill and deliver weekly
{
  billingPolicy: { interval: 'WEEK', intervalCount: 1 },
  deliveryPolicy: { interval: 'WEEK', intervalCount: 1 }
}

Attaching Plans to Products

Selling plan groups can be attached to:
  • Entire products: All variants of a product get the selling plan
  • Specific variants: Only selected variants have subscription options
export interface SellingPlanGroupListItemProduct {
  id: string;
  title: string;
}
The productsCount and productVariantsCount fields help you understand the scope of each selling plan group.

Cycle Discounts

Selling plans support cycle-based discounts that change over time:
export interface CycleDiscount {
  adjustmentType: DiscountTypeType;
  adjustmentValue: CycleDiscountAdjustmentValue;
  afterCycle: number;
  computedPrice: Money;
}
Example: Offer a larger discount for the first 3 orders to incentivize sign-ups:
[
  {
    adjustmentType: 'PERCENTAGE',
    adjustmentValue: { percentage: 20 },
    afterCycle: 0, // First 3 cycles
    computedPrice: { amount: '19.99', currencyCode: 'USD' }
  },
  {
    adjustmentType: 'PERCENTAGE',
    adjustmentValue: { percentage: 10 },
    afterCycle: 3, // After 3 cycles
    computedPrice: { amount: '22.49', currencyCode: 'USD' }
  }
]
Cycle discounts are applied based on the billing cycle index, not the delivery cycle. Make sure your discount strategy aligns with your billing policy.

Creating Selling Plans

Selling plans are created through the Shopify Admin API using the sellingPlanGroupCreate mutation. The reference app provides a UI for merchants to:
  1. Create a new selling plan group
  2. Define billing and delivery frequencies
  3. Configure pricing policies and discounts
  4. Select products or variants to attach the plan to

Best Practices

  1. Use descriptive merchant codes: Make it easy to identify selling plan groups in your code
  2. Limit plan options: Too many options can overwhelm customers - offer 2-4 frequency choices
  3. Align billing and delivery: Unless you have a specific reason, keep billing and delivery frequencies the same
  4. Test cycle discounts: Ensure your cycle-based pricing displays correctly to customers
  5. Consider margins: Make sure subscription discounts still maintain healthy profit margins

Common Use Cases

Monthly billing and delivery with a 10% discount:
{
  billingPolicy: { interval: 'MONTH', intervalCount: 1 },
  deliveryPolicy: { interval: 'MONTH', intervalCount: 1 },
  pricingPolicies: [{
    adjustmentType: 'PERCENTAGE',
    adjustmentValue: { percentage: 10 }
  }]
}

Build docs developers (and LLMs) love