Ensuring Gift Card Integrity: Preventing Duplicates in ESHOPMAN Orders

Ensuring Gift Card Integrity: Preventing Duplicates in ESHOPMAN Orders

In the world of headless commerce, maintaining data integrity is paramount, especially when dealing with financial instruments like gift cards. ESHOPMAN, as a robust platform for managing storefronts within HubSpot CMS, offers powerful loyalty features, including comprehensive gift card management. However, a recent community insight highlighted a critical scenario where ESHOPMAN's gift card issuance mechanism could inadvertently lead to duplicate gift cards, posing a significant challenge for merchants and impacting financial accuracy.

The Challenge: Duplicate Gift Card Issuance

The core of the issue lies within ESHOPMAN's event-driven architecture, specifically how the order.placed event is handled by the built-in loyalty feature's gift card subscriber. If this event is processed more than once for a single order – a common occurrence in distributed systems due to event bus retries, worker process failures, or manual re-emissions – the system issues a new set of gift cards for every re-delivery. Since gift cards represent stored value, issuing duplicates directly translates to financial loss for the merchant and erodes trust in the commerce platform.

Reproducing the Behavior

Reproducing this behavior is straightforward, allowing ESHOPMAN developers to understand and test the idempotency of their order processing. Here’s how it can be demonstrated:

  1. Ensure ESHOPMAN's loyalty features are enabled and configured to issue gift cards.
  2. Create a product marked as a gift card (is_giftcard: true) with a defined variant and price.
  3. Place an order for multiple units of this gift card product.
  4. To simulate the duplicate event, developers can programmatically re-trigger the gift card subscriber for the same order ID. This script snippet, adapted for ESHOPMAN's Node.js/TypeScript environment, illustrates the process:
// src/scripts/replay-gift-card-subscriber.ts
import type { ExecArgs } from "@eshopman/framework/types"
import path from "node:path"

// Assuming ESHOPMAN plugins are structured similarly,
// or directly referencing the subscriber service
const loyaltyPluginRoot = path.dirname(require.resolve("@eshopman/loyalty-plugin/package.json"))
const handler = require(
  path.join(loyaltyPluginRoot, ".eshopman/server/src/subscribers/create-gift-card.js")
).default

export default async function ({ container, args }: ExecArgs) {
  await handler({ event: { name: "order.placed", data: { id: args[0] } }, container })
}

Executing this script via npx eshopman exec ./src/scripts/replay-gift-card-subscriber.ts will trigger the subscriber again.

  1. Listing gift cards associated with the order ID via the ESHOPMAN Admin API will reveal duplicate entries.

Technical Root Cause

The core issue stems from the gift card subscriber's current implementation, which does not perform a check for already issued cards for a given order line item. Each time the order.placed event is processed, it proceeds to create new gift cards without validating against existing ones. Furthermore, the loyalty_gift_card entity primarily relies on a unique code, which is randomly generated, meaning there's no inherent uniqueness constraint to prevent multiple cards being issued for the same logical 'unit' of a gift card purchase.

Proposed Solutions for ESHOPMAN Developers

The ESHOPMAN community has discussed several approaches to address this, offering different levels of robustness:

  • 1. Idempotent Check with Locking: A simpler approach involves implementing a lock on the order ID (using ESHOPMAN's internal locking mechanisms, if available) and then counting the number of existing gift cards associated with a specific line item. The subscriber would then only create quantity - existing new cards, ensuring that the total matches the ordered quantity. This effectively handles event replays and partial failures.
  • 2. Unique Issuance Keys: A more robust solution suggests introducing an 'issuance key' for each gift card, perhaps derived from the line item ID and a unit identifier (e.g., ${line_item_id}:${unit}). This key would have a unique index in the database. When a gift card is to be issued, the system would attempt to create it with this key. A unique constraint violation would then be treated as an indication that the card has already been issued, gracefully handling both sequential replays and concurrent event deliveries.

Immediate Workaround

For ESHOPMAN merchants and developers requiring an immediate solution, a common workaround involves disabling the default gift card subscriber within the ESHOPMAN loyalty features (often achievable through configuration or a package patch if direct code modification is needed). A custom subscriber is then implemented. This custom subscriber would manage gift card issuance by maintaining its own ledger, keyed by order, line item, and unit, and performing its operations under a lock to ensure idempotency.

Conclusion

Ensuring the integrity of financial transactions like gift card issuance is vital for any e-commerce platform. This community insight highlights a critical area for ESHOPMAN developers to focus on, promoting robust and idempotent event handling practices. By adopting the proposed solutions or implementing a custom workaround, ESHOPMAN merchants can safeguard their financial operations and build greater trust in their headless commerce deployments on HubSpot CMS.

Start with the tools

Explore migration tools

See options, compare methods, and pick the path that fits your store.

Explore migration tools