@shopkit/discounts
v0.1.3
Published
Discount and coupon management for e-commerce storefronts
Maintainers
Readme
@shopkit/discounts
Discount and coupon management for e-commerce storefronts.
Installation
npm install @shopkit/discounts @shopkit/cart
# or
bun add @shopkit/discounts @shopkit/cartQuick Start
1. Implement the discount service
import { IDiscountService, DiscountResult, DiscountValidationResult, OffersResult } from '@shopkit/discounts';
class MyDiscountService implements IDiscountService {
async applyDiscount(cartId: string, code: string): Promise<DiscountResult> {
const response = await fetch('/api/discount/apply', {
method: 'POST',
body: JSON.stringify({ cartId, code }),
});
return response.json();
}
async removeDiscount(cartId: string): Promise<void> {
await fetch('/api/discount/remove', {
method: 'POST',
body: JSON.stringify({ cartId }),
});
}
async validateDiscount(code: string, cartData: unknown): Promise<DiscountValidationResult> {
const response = await fetch('/api/discount/validate', {
method: 'POST',
body: JSON.stringify({ code, cartData }),
});
return response.json();
}
async getOffers(cartId: string): Promise<OffersResult> {
const response = await fetch(`/api/discount/offers?cartId=${cartId}`);
return response.json();
}
async getCartData(cartId: string): Promise<unknown> {
const response = await fetch(`/api/cart/${cartId}`);
return response.json();
}
}
export const discountService = new MyDiscountService();2. Use the discount hook
import { useDiscount } from '@shopkit/discounts';
import { discountService } from './services/discount-service';
function CouponForm() {
const {
couponCode,
setCouponCode,
applyCoupon,
removeCoupon,
appliedDiscount,
isDiscountLoading,
availableOffers,
} = useDiscount({
discountService,
onError: (error) => console.error(error.message),
});
return (
<div>
{appliedDiscount ? (
<div>
<p>Applied: {appliedDiscount.code}</p>
<p>Discount: ${appliedDiscount.amount}</p>
<button onClick={removeCoupon}>Remove</button>
</div>
) : (
<form onSubmit={(e) => { e.preventDefault(); applyCoupon(); }}>
<input
value={couponCode}
onChange={(e) => setCouponCode(e.target.value)}
placeholder="Enter coupon code"
/>
<button type="submit" disabled={isDiscountLoading}>
Apply
</button>
</form>
)}
{availableOffers.length > 0 && (
<div>
<h4>Available Offers</h4>
{availableOffers.map((offer: any) => (
<button key={offer.code} onClick={() => applyCoupon(offer.code)}>
{offer.title}
</button>
))}
</div>
)}
</div>
);
}API Reference
Types
IDiscountService
Interface for discount service implementations.
interface IDiscountService {
applyDiscount(cartId: string, code: string): Promise<DiscountResult>;
removeDiscount(cartId: string): Promise<void>;
validateDiscount(code: string, cartData: unknown): Promise<DiscountValidationResult>;
getOffers?(cartId: string): Promise<OffersResult>;
getCartData?(cartId: string): Promise<unknown>;
}AppliedDiscount
Represents an applied discount.
interface AppliedDiscount {
code: string;
message: string;
amount: number;
totalPrice: number;
}Hooks
useDiscount(options)
Main hook for managing discounts.
Options:
discountService: IDiscountService- Required discount service implementationonError?: (error: Error) => void- Error callback
Returns:
appliedDiscount: AppliedDiscount | null- Currently applied discountcouponCode: string- Current coupon code inputsetCouponCode: (code: string) => void- Set coupon codeavailableOffers: unknown[]- Available discount offersunavailableOffers: unknown[]- Unavailable discount offersisDiscountLoading: boolean- Loading stateisRemovingDiscount: boolean- Removing discount stateapplyCoupon: (code?: string) => Promise<void>- Apply a couponremoveCoupon: () => Promise<void>- Remove applied couponvalidateAfterCartChange: () => Promise<void>- Re-validate after cart changesrefreshOffers: () => Promise<void>- Refresh available offersrefreshCartData: () => Promise<unknown>- Refresh cart data
Requirements
@shopkit/cartmust be configured and initialized- React 18+
License
MIT
