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.
The authenticated GraphQL client instance
variables
SellingPlanGroupsQueryVariables
required
Query parameters including pagination cursors Show variables properties
Number of selling plan groups to retrieve
Cursor for forward pagination
Cursor for backward pagination
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.
The authenticated GraphQL client instance
Show variables properties
The selling plan group ID (e.g., gid://shopify/SellingPlanGroup/123)
Number of products to retrieve per page (automatically paginates if more exist)
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.
The authenticated GraphQL client instance
input
CreateSellingPlanGroupInput
required
Configuration for the new selling plan group Display name of the selling plan group
Unique merchant code for the selling plan group
Array of product IDs to associate with this selling plan group
Array of product variant IDs to associate with this selling plan group
discountDeliveryOptions
DiscountDeliveryOption[]
required
Array of delivery frequency and discount configurations
discountType
'PERCENTAGE' | 'FIXED_AMOUNT'
required
Type of discount to apply
Whether to offer a discount on subscriptions
Currency code for pricing (e.g., ‘USD’, ‘CAD’)
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.
The authenticated GraphQL client instance
input
UpdateSellingPlanGroupVariables
required
Update configuration The selling plan group ID to update
Array of selling plan IDs to remove
discountDeliveryOptions
DiscountDeliveryOption[]
required
Updated delivery and discount configurations
Product IDs to add to the group
Product IDs to remove from the group
Product variant IDs to add to the group
productVariantIdsToRemove
Product variant IDs to remove from the group
discountType
'PERCENTAGE' | 'FIXED_AMOUNT'
required
Type of discount
Whether to offer a discount
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.
The authenticated GraphQL client instance
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.
The authenticated GraphQL client instance
sellingPlans
SellingPlanGroupListItemSellingPlan[]
required
Array of selling plans to translate
shopLocalesWithoutPrimary
Array of shop locales (excluding the primary locale)
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 ;
}[];
}