Skip to main content
The SellingPlan model provides methods for creating, reading, updating, and deleting selling plan groups that define subscription offerings in your Shopify store.

Overview

Selling plan groups contain one or more selling plans that define how subscriptions work, including delivery frequencies, pricing policies, and applicable products. This model handles:
  • Creating and updating selling plan groups
  • Managing product and variant associations
  • Configuring discount and delivery options
  • Multi-language translation support

Core Methods

getSellingPlanGroups

Retrieves a paginated list of selling plan groups.
graphql
GraphQLClient
required
The authenticated GraphQL client instance
variables
SellingPlanGroupsQueryVariables
required
Query parameters including pagination cursors
Returns: Promise<{sellingPlanGroups: SellingPlanGroupListItem[], pageInfo: PaginationInfo}> TypeScript Signature:
async function getSellingPlanGroups(
  graphql: GraphQLClient,
  variables: SellingPlanGroupsQueryVariables,
): Promise<{
  sellingPlanGroups: SellingPlanGroupListItem[];
  pageInfo: PaginationInfo;
}>
Usage Example:
import { getSellingPlanGroups } from '~/models/SellingPlan/SellingPlan.server';

const { sellingPlanGroups, pageInfo } = await getSellingPlanGroups(
  graphql,
  { first: 10 }
);

console.log(`Found ${sellingPlanGroups.length} selling plan groups`);
sellingPlanGroups.forEach(group => {
  console.log(`Group: ${group.merchantCode}`);
  console.log(`Products: ${group.productsCount}`);
  console.log(`Plans: ${group.sellingPlans.length}`);
});
GraphQL Query Used:
query SellingPlanGroups($first: Int, $after: String) {
  sellingPlanGroups(first: $first, after: $after) {
    edges {
      node {
        id
        merchantCode
        productsCount { count }
        productVariantsCount { count }
        products(first: 3) {
          edges {
            node {
              id
              title
            }
          }
        }
        sellingPlans(first: 31) {
          edges {
            node {
              id
              deliveryPolicy {
                ... on SellingPlanRecurringDeliveryPolicy {
                  interval
                  intervalCount
                }
              }
              pricingPolicies {
                adjustmentType
                adjustmentValue {
                  ... on SellingPlanPricingPolicyPercentageValue {
                    percentage
                  }
                  ... on SellingPlanFixedAmountPriceAdjustment {
                    amount
                  }
                }
              }
            }
          }
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

getSellingPlanGroup

Retrieves a single selling plan group with all its details.
graphql
GraphQLClient
required
The authenticated GraphQL client instance
variables
object
required
Returns: Promise<SellingPlanGroup | null> TypeScript Signature:
async function getSellingPlanGroup(
  graphql: GraphQLClient,
  variables: { id: string; firstProducts: number },
): Promise<SellingPlanGroup | null>
Usage Example:
import { getSellingPlanGroup } from '~/models/SellingPlan/SellingPlan.server';

const sellingPlanGroup = await getSellingPlanGroup(graphql, {
  id: 'gid://shopify/SellingPlanGroup/1',
  firstProducts: 250,
});

if (sellingPlanGroup) {
  console.log('Plan Name:', sellingPlanGroup.planName);
  console.log('Merchant Code:', sellingPlanGroup.merchantCode);
  console.log('Products:', sellingPlanGroup.products.length);
  console.log('Delivery Options:', sellingPlanGroup.discountDeliveryOptions);
}
Note: This method automatically handles pagination and fetches all products and variants associated with the selling plan group.

createSellingPlanGroup

Creates a new selling plan group with associated selling plans.
graphql
GraphQLClient
required
The authenticated GraphQL client instance
input
CreateSellingPlanGroupInput
required
Configuration for the new selling plan group
Returns: Promise<{sellingPlanGroupId: string | undefined, userErrors: UserError[]}> TypeScript Signature:
interface CreateSellingPlanGroupInput {
  name: string;
  merchantCode: string;
  productIds: string[];
  productVariantIds: string[];
  discountDeliveryOptions: DiscountDeliveryOption[];
  discountType: DiscountTypeType;
  offerDiscount: boolean;
  currencyCode: string;
}

async function createSellingPlanGroup(
  graphql: GraphQLClient,
  input: CreateSellingPlanGroupInput,
): Promise<{
  sellingPlanGroupId: string | undefined;
  userErrors: UserError[];
}>
Usage Example:
import { createSellingPlanGroup } from '~/models/SellingPlan/SellingPlan.server';

const { sellingPlanGroupId, userErrors } = await createSellingPlanGroup(
  graphql,
  {
    name: 'Monthly Subscription Box',
    merchantCode: 'monthly-box-2024',
    productIds: [
      'gid://shopify/Product/123',
      'gid://shopify/Product/456',
    ],
    productVariantIds: [],
    discountDeliveryOptions: [
      {
        id: 'new-1',
        deliveryInterval: 'MONTH',
        deliveryFrequency: 1,
        discountValue: 10, // 10% off
      },
      {
        id: 'new-2',
        deliveryInterval: 'MONTH',
        deliveryFrequency: 3,
        discountValue: 15, // 15% off
      },
    ],
    discountType: 'PERCENTAGE',
    offerDiscount: true,
    currencyCode: 'USD',
  }
);

if (userErrors.length > 0) {
  console.error('Errors:', userErrors);
} else {
  console.log('Created selling plan group:', sellingPlanGroupId);
}
GraphQL Mutation Used:
mutation CreateSellingPlanGroup(
  $input: SellingPlanGroupInput!
  $resources: SellingPlanGroupResourceInput
) {
  sellingPlanGroupCreate(input: $input, resources: $resources) {
    sellingPlanGroup {
      id
      sellingPlans(first: 31) {
        edges {
          node {
            id
            name
            options
            billingPolicy {
              ... on SellingPlanRecurringBillingPolicy {
                interval
                intervalCount
              }
            }
            deliveryPolicy {
              ... on SellingPlanRecurringDeliveryPolicy {
                interval
                intervalCount
              }
            }
            pricingPolicies {
              adjustmentType
              adjustmentValue {
                ... on SellingPlanPricingPolicyPercentageValue {
                  percentage
                }
                ... on SellingPlanFixedAmountPriceAdjustment {
                  amount
                }
              }
            }
          }
        }
      }
    }
    userErrors {
      message
    }
  }
}

updateSellingPlanGroup

Updates an existing selling plan group.
graphql
GraphQLClient
required
The authenticated GraphQL client instance
input
UpdateSellingPlanGroupVariables
required
Update configuration
Returns: Promise<{sellingPlanGroupId: string | undefined, userErrors: UserError[]}> TypeScript Signature:
interface UpdateSellingPlanGroupVariables {
  id: string;
  name: string;
  merchantCode: string;
  sellingPlansToDelete: string[];
  discountDeliveryOptions: DiscountDeliveryOption[];
  productIdsToAdd: string[];
  productIdsToRemove: string[];
  productVariantIdsToAdd: string[];
  productVariantIdsToRemove: string[];
  discountType: DiscountTypeType;
  offerDiscount: boolean;
  currencyCode: string;
}

async function updateSellingPlanGroup(
  graphql: GraphQLClient,
  input: UpdateSellingPlanGroupVariables,
): Promise<{
  sellingPlanGroupId: string | undefined;
  userErrors: UserError[];
}>
Usage Example:
import { updateSellingPlanGroup } from '~/models/SellingPlan/SellingPlan.server';

const { sellingPlanGroupId, userErrors } = await updateSellingPlanGroup(
  graphql,
  {
    id: 'gid://shopify/SellingPlanGroup/1',
    name: 'Updated Monthly Subscription',
    merchantCode: 'monthly-box-2024',
    sellingPlansToDelete: [],
    discountDeliveryOptions: [
      {
        id: 'gid://shopify/SellingPlan/1',
        deliveryInterval: 'MONTH',
        deliveryFrequency: 1,
        discountValue: 12, // Updated from 10% to 12%
      },
    ],
    productIdsToAdd: ['gid://shopify/Product/789'],
    productIdsToRemove: [],
    productVariantIdsToAdd: [],
    productVariantIdsToRemove: [],
    discountType: 'PERCENTAGE',
    offerDiscount: true,
    currencyCode: 'USD',
  }
);
GraphQL Mutation Used:
mutation SellingPlanGroupUpdate(
  $id: ID!
  $input: SellingPlanGroupInput!
  $productIdsToAdd: [ID!]!
  $productIdsToRemove: [ID!]!
  $productVariantIdsToAdd: [ID!]!
  $productVariantIdsToRemove: [ID!]!
) {
  sellingPlanGroupUpdate(id: $id, input: $input) {
    sellingPlanGroup { id }
    userErrors { field, message }
  }
  sellingPlanGroupAddProducts(id: $id, productIds: $productIdsToAdd) {
    userErrors { field, message }
  }
  sellingPlanGroupRemoveProducts(id: $id, productIds: $productIdsToRemove) {
    userErrors { field, message }
  }
  sellingPlanGroupAddProductVariants(
    id: $id
    productVariantIds: $productVariantIdsToAdd
  ) {
    userErrors { field, message }
  }
  sellingPlanGroupRemoveProductVariants(
    id: $id
    productVariantIds: $productVariantIdsToRemove
  ) {
    userErrors { field, message }
  }
}

deleteSellingPlanGroup

Deletes a selling plan group.
graphql
GraphQLClient
required
The authenticated GraphQL client instance
sellingPlanGroupId
string
required
The ID of the selling plan group to delete
Returns: Promise<{data: DeleteSellingPlanGroupMutationType}> TypeScript Signature:
async function deleteSellingPlanGroup(
  graphql: GraphQLClient,
  sellingPlanGroupId: string,
): Promise<{data: DeleteSellingPlanGroupMutationType}>
Usage Example:
import { deleteSellingPlanGroup } from '~/models/SellingPlan/SellingPlan.server';

const result = await deleteSellingPlanGroup(
  graphql,
  'gid://shopify/SellingPlanGroup/1'
);

console.log('Deleted:', result.data.sellingPlanGroupDelete);

createSellingPlanTranslations

Creates multi-language translations for selling plans.
graphql
GraphQLClient
required
The authenticated GraphQL client instance
sellingPlans
SellingPlanGroupListItemSellingPlan[]
required
Array of selling plans to translate
shopLocalesWithoutPrimary
ShopLocale[]
required
Array of shop locales (excluding the primary locale)
currencyCode
string
required
Currency code for pricing display
Returns: Promise<void> TypeScript Signature:
async function createSellingPlanTranslations(
  graphql: GraphQLClient,
  sellingPlans: SellingPlanGroupListItemSellingPlan[],
  shopLocalesWithoutPrimary: ShopLocale[],
  currencyCode: string,
): Promise<void>
Usage Example:
import { createSellingPlanTranslations } from '~/models/SellingPlan/SellingPlan.server';

const sellingPlans = [
  {
    id: 'gid://shopify/SellingPlan/1',
    deliveryPolicy: {
      interval: 'MONTH',
      intervalCount: 1,
    },
    pricingPolicies: [
      {
        adjustmentType: 'PERCENTAGE',
        adjustmentValue: { percentage: 10 },
      },
    ],
  },
];

const secondaryLocales = [
  { locale: 'fr', primary: false },
  { locale: 'de', primary: false },
];

await createSellingPlanTranslations(
  graphql,
  sellingPlans,
  secondaryLocales,
  'USD'
);

console.log('Translations created successfully');

TypeScript Interfaces

SellingPlanGroupListItem

interface SellingPlanGroupListItem {
  id: string;
  merchantCode: string;
  productsCount?: number;
  productVariantsCount?: number;
  products: SellingPlanGroupProduct[];
  sellingPlans: SellingPlanGroupListItemSellingPlan[];
  sellingPlansPageInfo: PaginationInfo;
}

SellingPlanGroupListItemSellingPlan

interface SellingPlanGroupListItemSellingPlan {
  id?: string;
  deliveryPolicy: RecurringPolicy | { __typename: 'SellingPlanFixedDeliveryPolicy' };
  pricingPolicies: SellingPlanPricingPolicy[];
}

SellingPlanPricingPolicy

interface SellingPlanPricingPolicy {
  adjustmentType: string;
  adjustmentValue: SellingPlanAdjustmentValue;
}

interface SellingPlanAdjustmentValue {
  amount?: string;
  percentage?: string;
}

RecurringPolicy

interface RecurringPolicy {
  interval: SellingPlanInterval;
  intervalCount: number;
}

enum SellingPlanInterval {
  Day = 'DAY',
  Week = 'WEEK',
  Month = 'MONTH',
  Year = 'YEAR',
}

SellingPlanGroup

interface SellingPlanGroup {
  merchantCode: string;
  planName: string;
  products: {
    product: SellingPlanGroupProduct;
    productVariants?: SellingPlanGroupProductVariant[];
  }[];
  selectedProductIds: string;
  selectedProductVariantIds: string;
  offerDiscount: string;
  discountType: string;
  discountDeliveryOptions: {
    id: string;
    deliveryInterval: SellingPlanInterval;
    deliveryFrequency: number;
    discountValue: number | string;
  }[];
}

Build docs developers (and LLMs) love