Skip to main content
The SpurtCommerce Coupon Add-on adds coupon functionality to an existing SpurtCommerce API without requiring you to copy the coupon module into the core application. Install the npm package, register its database entities and migrations, initialize the module, and expose its controllers through the API server. Then connect the coupon processor to the order-creation flow so a coupon validated in the storefront is applied when the customer checks out.
Documentation note: This guide is based on the published spurtcommerce-coupon package README and SpurtCommerce v6 release information. Some integration points depend on the exact checkout implementation in your project. Where the package README does not define a request shape or function signature, this guide identifies what you must confirm in the package source instead of inventing values.

What you will build

After completing this guide, your SpurtCommerce API will expose three groups of coupon endpoints:
  • Admin: manage coupons, inspect usage, and export coupon reports.
  • Vendor: manage vendor-specific coupons and their active status.
  • Storefront: validate a coupon against the customer’s cart and return the discount data needed by checkout.
The add-on also exports a checkout processor that calculates and persists coupon discounts and coupon usage.

How the integration fits together

The storefront validation endpoint and the checkout processor have different responsibilities:
  1. apply-coupon checks whether a coupon can be applied to the submitted cart and returns the discount information.
  2. process() is called during order creation to calculate and persist the discount against the order.
Do not treat a successful storefront response as a substitute for checkout processing.

Before you begin

Compatibility requirements

The package README lists the following requirements: SpurtCommerce v6.0.0 release notes specify Node.js 22.23.1 and TypeORM 0.3.26, so that release meets the package’s stated TypeORM requirement. Check your own project’s installed versions before proceeding. Run these commands from the SpurtCommerce API project root:
If your project uses TypeORM 0.2.x, stop before integrating this package. The package requires TypeORM 0.3.x or later and uses the DataSource API. Do not attempt to resolve this by changing only the package version in package.json; upgrade and test the application’s TypeORM integration as a separate compatibility task.

Back up and use a non-production environment

Before adding the module:
  1. Commit or back up your current application changes.
  2. Take a database backup.
  3. Perform the integration in a development or staging environment.
  4. Review the package migrations before running them against an existing database.
  5. Confirm the coupon endpoints do not conflict with routes already registered by your application.

1. Install the package

Open a terminal in the SpurtCommerce API project root — the directory containing the API’s package.json.
Confirm that npm installed the package:
For local development where the add-on package is available in your repository under add-ons/Coupon, the package README also supports a local path installation:
Use the npm installation for normal application integration. Use the local path when you are actively developing or testing the add-on package itself.

2. Register the coupon database entities

The add-on stores coupon definitions, product/category restrictions, and redemption records in the application’s database. TypeORM must know about the add-on entities before the application initializes its DataSource. Open the TypeORM configuration used by your API. The package README gives src/loaders/typeormLoader.ts as an example location. Import the entities:
Append them to the existing entities array:
Keep your existing entities. The important change is adding ...CouponEntities to the array; do not replace the application’s entity list with only the coupon entities.

Tables provided by the add-on

The package also exports BaseModel, a base entity with timestamp audit columns.

3. Register the coupon migrations

Import the migration collection:
Append it to the migrations array in the same TypeORM configuration:
Do not create a second database configuration just for the add-on. Register its migrations in the DataSource used by the SpurtCommerce API.

Migrations included in the package

Run and verify the migrations

Use the migration command configured by your SpurtCommerce project’s package.json. The command can differ between project setups, so use the script defined by your checked-out version rather than copying a generic TypeORM command. After the migration completes, verify that the four coupon tables exist and inspect the plugins table for the coupon metadata changes. If the migration fails, stop and resolve the schema or migration-history issue before starting the API with the add-on enabled.

4. Initialize the coupon module

The package must receive the same TypeORM DataSource that the host application uses. Import initCoupon:
Call it after the database connection has initialized successfully. The package README uses this pattern:
For example, if your loader exposes a getDataSource() helper, the setup can be organized as follows:
Call setupCouponModule() only after dataSource.initialize() has completed. Adapt the example to your actual loader lifecycle; do not initialize a second DataSource for the add-on.

Optional host adapters

The add-on supports adapters so it can work with the host application’s product, customer, order, logging, and vendor-middleware implementations.
The adapter methods shown above are examples from the package README. Use the actual exported TypeScript interfaces to confirm parameter and return types before implementing a custom adapter. Use a custom adapter when the default adapter cannot correctly access your host application’s product, customer, or order data. In particular, test product lookup and order-item discount updates with your own entity structure.

5. Register the coupon controllers

The add-on’s controllers must be included when the Express server is created. In the API’s Express loader — the package README gives src/loaders/expressLoader.ts as an example — import the controller collection:
Append the controllers to the existing controller array:
Alternatively, the package exports a helper:
Use one approach only. Do not add the same coupon controllers through both methods, because duplicate registration can create confusing route behavior. Restart the API after registration. The route tables in the API reference below should then be available under the application’s configured API base URL.

6. Understand the coupon application flow

A typical storefront integration has two distinct stages.

Stage A — Validate the coupon against the cart

When a customer enters a coupon code, the storefront sends the coupon code and the current cart product details to:
Example request body:
In this example, the cart contains two units of a product priced at 1,000 each. The example uses a coupon named SUMMER20; it does not imply that this coupon exists in your database. The API checks coupon eligibility and calculates the applicable discount. The package README identifies checks for:
  • Percentage or fixed-amount discounts.
  • Minimum and maximum order amounts.
  • Restricted customer email addresses.
  • Product and category eligibility.
Example successful response:
The grandDiscountAmount in this example is illustrative. The actual amount is determined by the coupon configuration and eligible cart products.

What the storefront should do with the response

When the API accepts the coupon:
  1. Read the returned coupon information.
  2. Display the returned discount amount in the cart summary.
  3. Retain the encrypted appliedProducts value for the checkout flow required by your application.
  4. Recalculate or revalidate when the cart changes.
  5. Do not let the browser calculate the authoritative discount independently.
Treat appliedProducts as an opaque encrypted payload. Do not decode, edit, or recreate it in storefront code. The package README does not specify the complete storefront state model or the exact checkout request property used to carry this payload. Confirm the expected property from the package implementation and your checkout controller before wiring the frontend.

Stage B — Process the coupon during checkout

Coupon validation is not the final order operation. During order creation, the API must call the add-on’s exported process() function so the coupon discount is calculated and recorded against the order. Import the function with an alias to avoid confusion with other functions named process:
The package README documents this call shape:
The arguments represent: The function returns:
  • total is the net total after the coupon discount.
  • couponCode identifies the coupon processed.
  • discountAmount is the total discount applied.

Where to call processCoupon()

The package README identifies the customer order controller as the integration point: src/api/store/controllers/CustomerOrderController.ts Place the call inside the existing order-creation flow, where the application has the order ID, customer ID, cart/SKU pricing data, gross total, and coupon data available. The following is an integration outline, not a drop-in replacement for your controller:
Important integration detail: The README gives the shape of couponData, but does not document the exact mapping from the storefront’s appliedProducts response to that argument. Inspect the package’s process() implementation and the checkout controller to confirm how the encrypted payload is passed and decrypted. Do not assume that the entire apply-coupon response can be passed directly as couponData.

Keep order totals consistent

When integrating the processor, verify that:
  • The gross total passed to the processor is the intended pre-discount order amount.
  • dynamicData contains the SKU names and prices expected by the package.
  • The returned total is used consistently in the order’s final amount.
  • Product-level discounts are reflected in the appropriate order items.
  • Coupon usage is recorded only for the successfully created order.
  • A failed order does not leave inconsistent coupon usage or discount records.
The package provides an OrderAdapter for updating product-level order discounts. If your order item structure differs from the package’s default expectations, implement and test a custom adapter.

7. Cart changes and coupon revalidation

A coupon can become invalid after it has been applied. For example, a customer may remove an eligible product, change a quantity, or reduce the cart below the coupon’s minimum order amount. The package README identifies a procedural function named CouponProccess() for removing invalid coupon product-category entries when products change. Before calling it, inspect the exported function signature in the installed package to confirm its parameters and expected return behavior. The README does not provide a call signature, so a safe copy-and-paste invocation cannot be supplied here. At the storefront level, revalidate the coupon whenever a cart change could affect eligibility. Do not continue displaying a previously calculated discount after the cart contents have changed unless the coupon has been validated for the updated cart.

8. API reference

All routes below are supplied by the package README. The application must register CouponControllers (or use registerCouponControllers()) before these routes are available. Replace <API_BASE_URL> with the base URL of your SpurtCommerce API.

Admin coupon APIs

Controller: AdminCouponController
Base path: /api/admin-coupon
The package README does not include the query parameters, request DTOs, or response schemas for these routes. Use the controller DTOs and route implementation in the installed package as the source of truth when preparing API calls.

Vendor coupon APIs

Controller: VendorCouponController
Base path: /api/vendor-coupon
Vendor routes must use the appropriate vendor authorization and middleware configuration for your installation. The package supports an optional vendorMiddleware during initialization; verify that it is connected to the correct host middleware.

Storefront customer coupon API

Controller: CustomerCouponController
Base path: /api/customer-coupon
This is the storefront endpoint documented in the package README. The README does not list separate customer endpoints for removing or listing applied coupons.

9. Services and repositories

The package exports the following services and repositories for its internal coupon operations.

Repositories

Services

Most integrations should use the documented module initialization, controllers, and checkout processor rather than directly manipulating repositories. Use the service and repository exports only when you have a specific extension requirement and have checked their public method signatures.

10. Verify the integration

Complete these checks in a development or staging environment before releasing the add-on.

Installation and startup

  • npm ls spurtcommerce-coupon shows the installed package.
  • The API starts without TypeORM metadata or dependency-resolution errors.
  • The coupon entities are registered with the application’s DataSource.
  • The coupon migrations complete successfully.
  • The coupon controllers are registered once.

Admin and Vendor

  • An authorized Admin can create and list a coupon.
  • An authorized Admin can update and delete a coupon.
  • An authorized Vendor can manage their own coupon.
  • Vendor authorization prevents access to another vendor’s coupon data.
  • Coupon usage history and exports return the expected records.

Storefront and checkout

  • A valid coupon is accepted for an eligible cart.
  • An invalid or expired coupon is rejected.
  • Minimum and maximum order amount rules are enforced.
  • Restricted customer email rules are enforced.
  • Product/category restrictions are enforced.
  • The storefront treats the encrypted payload as opaque data.
  • Changing the cart causes coupon eligibility to be checked again.
  • Checkout applies the expected order-level and product-level discounts.
  • Coupon usage records match successful orders.
  • A failed checkout does not leave incorrect order or coupon usage data.

11. Troubleshooting

12. Production deployment considerations

Before enabling the add-on in production:
  1. Test the complete Admin → Storefront → Checkout flow in staging.
  2. Review the migrations and take a verified database backup.
  3. Confirm that Admin and Vendor routes enforce the intended authorization.
  4. Keep the encrypted applied-products payload unchanged between validation and checkout.
  5. Ensure checkout recalculates and persists discounts on the server; never trust a client-supplied discount amount as authoritative.
  6. Test failed checkout and retry scenarios for duplicate or inconsistent coupon usage.
  7. Monitor API errors and database migration results after deployment.

13. Package development

These commands are for developers modifying the coupon add-on package itself, rather than applications that simply install it. Run them from the add-on package directory. Build the package:
Run the development script:
Check the files that would be included in the npm package: