Loyalty Module Workflows

Workflows are a series of queries and actions, called steps, that complete a task. By using workflows, you benefit from features like data consistency and a reliable roll-back mechanism.

The Loyalty Module provides workflows and steps to manage gift cards and their usage in carts. These are provided by the @medusajs/loyalty-plugin package.

Gift Card Management Workflows#

Create Gift Cards Workflow#

Create new gift cards for customers or orders:

Code
1import { createGiftCardsWorkflow } from "@medusajs/loyalty-plugin/workflows"2
3const { result } = await createGiftCardsWorkflow(container)4  .run({5    input: {6      code: "GC-XXXX",7      value: 100,8      currency_code: "usd",9      customer_id: "cust_123",10      line_item_id: "litem_123",11      expires_at: null,12    },13  })

Update Gift Cards Workflow#

Update existing gift cards:

Code
1import { updateGiftCardsWorkflow } from "@medusajs/loyalty-plugin/workflows"2
3const { result } = await updateGiftCardsWorkflow(container)4  .run({5    input: {6      id: "gc_123",7      value: 150,8      status: "pending",9    },10  })

Delete Gift Card Workflow#

Delete a gift card:

Code
1import { deleteGiftCardWorkflow } from "@medusajs/loyalty-plugin/workflows"2
3await deleteGiftCardWorkflow(container)4  .run({5    input: {6      id: "gc_123",7    },8  })

Cart Integration Workflows#

Add Gift Card to Cart#

Apply a gift card to a cart as a credit line. This workflow validates that the gift card has not expired before adding it:

Code
1import { addGiftCardToCartWorkflow } from "@medusajs/loyalty-plugin/workflows"2
3await addGiftCardToCartWorkflow(container)4  .run({5    input: {6      code: "GC-XXXX-XXXX",7      cart_id: "cart_123",8    },9  })

validate Hook

Note: This hook is available since Medusa v2.21.0.

addGiftCardToCartWorkflow exposes a validate hook that runs after the gift card's built-in validations and before any credit line is created. Use it to add custom validation logic. Throw an error inside the hook to reject the gift card and stop the workflow.

Code
1import { addGiftCardToCartWorkflow } from "@medusajs/loyalty-plugin/workflows"2
3addGiftCardToCartWorkflow.hooks.validate(4  async ({ input, cart, giftCards }, { container }) => {5    // throw an error to reject the gift card6    if (giftCards.some((gc) => gc.currency_code !== cart.currency_code)) {7      throw new Error("Gift card currency does not match cart currency.")8    }9  }10)

The hook receives the workflow input, the resolved cart, and the resolved giftCards array. You can resolve services from container to perform database lookups or any other custom checks.

Remove Gift Card from Cart#

Remove a gift card from a cart:

Code
1import { removeGiftCardFromCartWorkflow } from "@medusajs/loyalty-plugin/workflows"2
3await removeGiftCardFromCartWorkflow(container)4  .run({5    input: {6      code: "GC-XXXX-XXXX",7      cart_id: "cart_123",8    },9  })

Refresh Cart Gift Cards#

Refresh gift card credit lines on a cart to account for balance or cart total changes. Expired gift cards are silently removed from the cart during a refresh rather than causing an error, so the cart can continue to be updated:

Code
1import { refreshCartGiftCardsWorkflow } from "@medusajs/loyalty-plugin/workflows"2
3await refreshCartGiftCardsWorkflow(container)4  .run({5    input: {6      cart_id: "cart_123",7    },8  })

Confirm Cart Credit Lines#

Confirm and debit gift card balances during checkout. This workflow also validates that none of the gift cards applied to the cart have expired before debiting any balances:

Code
1import { confirmCartCreditLinesWorkflow } from "@medusajs/loyalty-plugin/workflows"2
3await confirmCartCreditLinesWorkflow(container)4  .run({5    input: {6      cart_id: "cart_123",7    },8  })

Order Integration Workflows#

Link gift cards to an order after purchase:

Code
1import { linkGiftCardsToOrderWorkflow } from "@medusajs/loyalty-plugin/workflows"2
3await linkGiftCardsToOrderWorkflow(container)4  .run({5    input: {6      order_id: "order_123",7      gift_card_codes: ["GC-XXXX", "GC-YYYY"],8    },9  })

Claim Gift Card#

Claim a gift card for a customer:

Code
1import { claimGiftCardWorkflow } from "@medusajs/loyalty-plugin/workflows"2
3const { result } = await claimGiftCardWorkflow(container)4  .run({5    input: {6      code: "GC-XXXX",7      customer_id: "cust_123",8    },9  })

Redeem Gift Card#

Redeem a gift card by debiting its balance:

Code
1import { redeemGiftCardWorkflow } from "@medusajs/loyalty-plugin/workflows"2
3const { result } = await redeemGiftCardWorkflow(container)4  .run({5    input: {6      code: "GC-XXXX",7      amount: 50,8      reference: "cart",9      reference_id: "cart_123",10    },11  })

Reference Documentation#

For complete API references and additional workflows, refer to the Medusa Core Workflows reference.

Was this page helpful?
Ask Bloom
For assistance in your development, use Claude Code Plugins or Docs MCP server in Cursor, VSCode, etc...FAQ
What is Medusa?
How can I create a module?
How can I create a data model?
How do I create a workflow?
How can I extend a data model in the Product Module?
Recipes
How do I build a marketplace with Medusa?
How do I build digital products with Medusa?
How do I build subscription-based purchases with Medusa?
What other recipes are available in the Medusa documentation?
Chat is cleared on refresh
Line break
⇧↵