Skip to main content
Glama

create-discount

Generate discount codes for Shopify stores by specifying title, code, value type, amount, and validity period to apply promotions.

Instructions

Create a basic discount code

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
titleYesTitle of the discount
codeYesDiscount code that customers will enter
valueTypeYesType of discount
valueYesDiscount value (percentage as decimal or fixed amount)
startsAtYesStart date in ISO format
endsAtNoOptional end date in ISO format
appliesOncePerCustomerYesWhether discount can be used only once per customer

Implementation Reference

  • src/index.ts:372-429 (registration)
    Full registration of the 'create-discount' MCP tool, including name, description, Zod input schema, and inline handler function that delegates to ShopifyClient.createBasicDiscountCode
    server.tool( "create-discount", "Create a basic discount code", { title: z.string().describe("Title of the discount"), code: z.string().describe("Discount code that customers will enter"), valueType: z .enum(["percentage", "fixed_amount"]) .describe("Type of discount"), value: z .number() .describe("Discount value (percentage as decimal or fixed amount)"), startsAt: z.string().describe("Start date in ISO format"), endsAt: z.string().optional().describe("Optional end date in ISO format"), appliesOncePerCustomer: z .boolean() .describe("Whether discount can be used only once per customer"), }, async ({ title, code, valueType, value, startsAt, endsAt, appliesOncePerCustomer, }) => { const client = new ShopifyClient(); try { const discountInput: CreateBasicDiscountCodeInput = { title, code, valueType, value, startsAt, endsAt, includeCollectionIds: [], excludeCollectionIds: [], appliesOncePerCustomer, combinesWith: { productDiscounts: true, orderDiscounts: true, shippingDiscounts: true, }, }; const discount = await client.createBasicDiscountCode( SHOPIFY_ACCESS_TOKEN, MYSHOPIFY_DOMAIN, discountInput ); return { content: [{ type: "text", text: JSON.stringify(discount, null, 2) }], }; } catch (error) { return handleError("Failed to create discount", error); } } );
  • Core handler method createBasicDiscountCode in ShopifyClient that performs validation, prepares GraphQL query and variables, executes the mutation to Shopify, and processes the response
    async createBasicDiscountCode( accessToken: string, shop: string, discountInput: CreateBasicDiscountCodeInput ): Promise<CreateBasicDiscountCodeResponse> { if (discountInput.valueType === "percentage") { if (discountInput.value < 0 || discountInput.value > 1) { throw new CustomError( "Invalid input: percentage value must be between 0 and 1", "InvalidInputError", { contextData: { discountInput, shop, }, } ); } } if (discountInput.valueType === "fixed_amount") { if (discountInput.value <= 0) { throw new CustomError( "Invalid input: fixed_amount value must be greater than 0", "InvalidInputError", { contextData: { discountInput, shop, }, } ); } } const myShopifyDomain = await this.getMyShopifyDomain(accessToken, shop); const isEligibleForSubscription = await this.checkSubscriptionEligibility( accessToken, myShopifyDomain ); const graphqlQuery = this.graphqlQueryPreparationForCreateBasicDiscountCode(); const variables = this.prepareBasicDiscountCodeVariable( discountInput, isEligibleForSubscription ); const res = await this.shopifyGraphqlRequest<BasicDiscountCodeResponse>({ url: `https://${myShopifyDomain}/admin/api/${this.SHOPIFY_API_VERSION}/graphql.json`, accessToken, query: graphqlQuery, variables, }); const id = res.data.data.discountCodeBasicCreate.codeDiscountNode.id; const codeDiscount = res.data.data.discountCodeBasicCreate.codeDiscountNode.codeDiscount.codes .nodes[0]; const userErrors = res.data.data.discountCodeBasicCreate.userErrors; if (userErrors.length > 0) { throw getGraphqlShopifyUserError(userErrors, { shop, discountInput, }); } return { id, code: codeDiscount.code, }; }
  • TypeScript type definition for CreateBasicDiscountCodeInput used as input schema for the discount creation
    export type CreateBasicDiscountCodeInput = { title: string; code: string; startsAt: ISODate; endsAt?: ISODate; valueType: string; value: number; usageLimit?: number; includeCollectionIds: string[]; excludeCollectionIds: string[]; appliesOncePerCustomer: boolean; combinesWith: { productDiscounts: boolean; orderDiscounts: boolean; shippingDiscounts: boolean; }; };
  • Private helper method providing the GraphQL mutation query for discountCodeBasicCreate
    private graphqlQueryPreparationForCreateBasicDiscountCode(): string { return gql` mutation discountCodeBasicCreate( $basicCodeDiscount: DiscountCodeBasicInput! ) { discountCodeBasicCreate(basicCodeDiscount: $basicCodeDiscount) { codeDiscountNode { id codeDiscount { ... on DiscountCodeBasic { title codes(first: 10) { nodes { code } } startsAt endsAt customerSelection { ... on DiscountCustomerAll { allCustomers } } customerGets { appliesOnOneTimePurchase appliesOnSubscription value { ... on DiscountPercentage { percentage } ... on DiscountAmount { amount { amount currencyCode } appliesOnEachItem } } items { ... on AllDiscountItems { allItems } } } appliesOncePerCustomer } } } userErrors { field code message } } } `;
  • Private helper method that prepares the variables object for the GraphQL mutation from the discount input
    private prepareBasicDiscountCodeVariable( discountInput: CreateBasicDiscountCodeInput, isEligibleForSubscription: boolean ): any { return { basicCodeDiscount: { title: discountInput.title, code: discountInput.code, startsAt: discountInput.startsAt, endsAt: discountInput.endsAt, customerSelection: { all: true, }, customerGets: { appliesOnOneTimePurchase: isEligibleForSubscription ? true : undefined, appliesOnSubscription: isEligibleForSubscription ? true : undefined, value: { percentage: discountInput.valueType === "percentage" ? discountInput.value : undefined, discountAmount: discountInput.valueType === "fixed_amount" ? { amount: discountInput.value, appliesOnEachItem: false, } : undefined, }, items: { all: discountInput.excludeCollectionIds.length === 0 && discountInput.includeCollectionIds.length === 0, collections: discountInput.includeCollectionIds.length || discountInput.excludeCollectionIds.length ? { add: discountInput.includeCollectionIds.map( (id) => `gid://shopify/Collection/${id}` ), remove: discountInput.excludeCollectionIds.map( (id) => `gid://shopify/Collection/${id}` ), } : undefined, }, }, appliesOncePerCustomer: discountInput.appliesOncePerCustomer, recurringCycleLimit: isEligibleForSubscription ? discountInput.valueType === "fixed_amount" ? 1 : null : undefined, usageLimit: discountInput.usageLimit, combinesWith: { productDiscounts: discountInput.combinesWith.productDiscounts, orderDiscounts: discountInput.combinesWith.orderDiscounts, shippingDiscounts: discountInput.combinesWith.shippingDiscounts, }, }, }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/smithery-ai/shopify-mcp-server-main-1'

If you have feedback or need assistance with the MCP directory API, please join our Discord server