@wtree/payload-ecommerce-coupon 3.70.4 → 3.70.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,6 +11,7 @@ Production-ready coupon and referral system plugin for **Payload CMS** with seam
11
11
  ### **System Modes**
12
12
  - **Coupon Mode** (`enableReferrals: false`) – Traditional discount codes
13
13
  - **Referral Mode** (`enableReferrals: true`) – Partner commissions + customer discounts
14
+ - **Hybrid Mode** (`enableReferrals: true` + `referralConfig.allowBothSystems: true`) – Both systems active
14
15
 
15
16
  ### **Coupon Mode Features**
16
17
  - ✅ **Flexible Discounts** – Percentage or fixed amount discounts
@@ -22,14 +23,17 @@ Production-ready coupon and referral system plugin for **Payload CMS** with seam
22
23
  - ✅ **Commission Rules** – Per-product/category commission rates
23
24
  - ✅ **Split Configuration** – Configurable partner/customer share ratios
24
25
  - ✅ **Partner Tracking** – Commission earnings and referral performance
25
- - ✅ **Auto-Generated Codes** – Unique referral codes for each user
26
+ - ✅ **Auto-Generated Codes** – Unique referral codes for each partner
27
+ - ✅ **Partner Dashboard** – Ready-to-use React components for partner stats
28
+ - ✅ **Single Code Per Cart** – Enforce one code (coupon or referral) per order
26
29
 
27
30
  ### **Core Features**
28
31
  - ✅ **REST API** – Validate, apply, and track codes
29
- - ✅ **Frontend Hooks** – `useCouponCode()` for React/Next.js
32
+ - ✅ **Frontend Hooks** – `useCouponCode()`, `usePartnerStats()` for React/Next.js
30
33
  - ✅ **Auto-Integration** – Extends carts/orders automatically
31
34
  - ✅ **Type-Safe** – Full TypeScript support
32
- - ✅ **Access Control** – Role-based permissions
35
+ - ✅ **Access Control** – Role-based permissions with partner role support
36
+ - ✅ **Custom Admin Groups** – Separate "Coupons" and "Referrals" categories
33
37
  - ✅ **Production-Ready** – Comprehensive testing and error handling
34
38
 
35
39
  ## 📦 Installation
@@ -62,14 +66,38 @@ export default buildConfig({
62
66
  }),
63
67
  payloadEcommerceCoupon({
64
68
  enabled: true,
65
- enableReferrals: false, // Set to true for referral system, false for coupon system
69
+ enableReferrals: true, // Enable referral system
66
70
  defaultCurrency: 'USD',
67
- allowStackWithOtherCoupons: false,
68
- autoIntegrate: true,
71
+
72
+ // Referral-specific configuration
73
+ referralConfig: {
74
+ allowBothSystems: false, // Set true to allow both coupons and referrals
75
+ singleCodePerCart: true, // Only one code per order
76
+ defaultPartnerSplit: 70, // 70% to partner
77
+ defaultCustomerSplit: 30, // 30% discount to customer
78
+ },
79
+
80
+ // Custom admin panel groups
81
+ adminGroups: {
82
+ couponsGroup: 'Coupons',
83
+ referralsGroup: 'Referrals',
84
+ },
85
+
86
+ // Partner dashboard configuration
87
+ partnerDashboard: {
88
+ enabled: true,
89
+ showEarningsSummary: true,
90
+ showReferralPerformance: true,
91
+ showRecentReferrals: true,
92
+ showCommissionBreakdown: true,
93
+ },
94
+
95
+ // Access control
69
96
  access: {
70
97
  canUseCoupons: () => true,
71
98
  canUseReferrals: () => true,
72
- isAdmin: ({ req }) => Boolean(req.user),
99
+ isAdmin: ({ req }) => req.user?.role === 'admin',
100
+ isPartner: ({ req }) => req.user?.role === 'partner',
73
101
  },
74
102
  }),
75
103
  ],
@@ -85,43 +113,140 @@ npm run payload migrate
85
113
  ```
86
114
 
87
115
  This will create collections for:
88
- - **Coupons** – Manage discount codes with flexible conditions
89
- - **Referral Programs** – Set up partner commission structures
90
- - **Referral Codes** – Track generated referral links
116
+ - **Coupons** – Manage discount codes (in "Coupons" group)
117
+ - **Referral Programs** – Set up partner commission structures (in "Referrals" group)
118
+ - **Referral Codes** – Track generated referral links (in "Referrals" group)
119
+
120
+ ### 3. Setting Up Partner Role
121
+
122
+ To enable the partner dashboard and role-based access, add a `role` field to your Users collection:
123
+
124
+ ```typescript
125
+ // collections/Users.ts
126
+ import type { CollectionConfig } from 'payload'
127
+
128
+ export const Users: CollectionConfig = {
129
+ slug: 'users',
130
+ auth: true,
131
+ fields: [
132
+ {
133
+ name: 'role',
134
+ type: 'select',
135
+ options: [
136
+ { label: 'Admin', value: 'admin' },
137
+ { label: 'Partner', value: 'partner' },
138
+ { label: 'Customer', value: 'customer' },
139
+ ],
140
+ defaultValue: 'customer',
141
+ required: true,
142
+ },
143
+ // Or use multiple roles
144
+ {
145
+ name: 'roles',
146
+ type: 'select',
147
+ hasMany: true,
148
+ options: [
149
+ { label: 'Admin', value: 'admin' },
150
+ { label: 'Partner', value: 'partner' },
151
+ { label: 'Customer', value: 'customer' },
152
+ ],
153
+ defaultValue: ['customer'],
154
+ },
155
+ ],
156
+ }
157
+ ```
91
158
 
92
- The plugin automatically integrates with your existing ecommerce collections, adding coupon fields to carts and orders.
159
+ ### 4. Frontend Integration
93
160
 
94
- ### 3. Frontend Integration
161
+ #### Apply Coupon/Referral Code
95
162
 
96
163
  ```typescript
97
164
  import { useCouponCode } from '@wtree/payload-ecommerce-coupon'
98
165
 
99
166
  function CheckoutComponent() {
100
- const [couponCode, setCouponCode] = useState('')
167
+ const [code, setCode] = useState('')
101
168
  const [cartId, setCartId] = useState('your-cart-id')
102
169
 
103
- const applyCoupon = async () => {
170
+ const applyCode = async () => {
104
171
  const result = await useCouponCode({
105
- code: couponCode,
172
+ code,
106
173
  cartID: cartId,
107
174
  })
108
175
 
109
176
  if (result.success) {
110
- console.log('Discount applied:', result.discount)
111
- // Update your cart total
177
+ if (result.coupon) {
178
+ console.log('Coupon applied! Discount:', result.discount)
179
+ } else if (result.referralCode) {
180
+ console.log('Referral applied!')
181
+ console.log('Your discount:', result.customerDiscount)
182
+ console.log('Partner commission:', result.partnerCommission)
183
+ }
112
184
  } else {
113
- console.error('Invalid coupon:', result.error)
185
+ console.error('Error:', result.error)
114
186
  }
115
187
  }
116
188
 
117
189
  return (
118
190
  <div>
119
191
  <input
120
- value={couponCode}
121
- onChange={(e) => setCouponCode(e.target.value)}
122
- placeholder="Enter coupon code"
192
+ value={code}
193
+ onChange={(e) => setCode(e.target.value)}
194
+ placeholder="Enter coupon or referral code"
123
195
  />
124
- <button onClick={applyCoupon}>Apply Coupon</button>
196
+ <button onClick={applyCode}>Apply Code</button>
197
+ </div>
198
+ )
199
+ }
200
+ ```
201
+
202
+ #### Partner Dashboard
203
+
204
+ ```typescript
205
+ import { PartnerDashboard, usePartnerStats } from '@wtree/payload-ecommerce-coupon'
206
+
207
+ // Option 1: Use the pre-built dashboard component
208
+ function PartnerPage() {
209
+ return (
210
+ <PartnerDashboard
211
+ showEarningsSummary={true}
212
+ showReferralPerformance={true}
213
+ showRecentReferrals={true}
214
+ showReferralCodes={true}
215
+ apiEndpoint="/api/referrals/partner-stats"
216
+ />
217
+ )
218
+ }
219
+
220
+ // Option 2: Build custom dashboard with the hook
221
+ function CustomPartnerDashboard() {
222
+ const [data, setData] = useState(null)
223
+
224
+ useEffect(() => {
225
+ const fetchStats = async () => {
226
+ const result = await usePartnerStats()
227
+ if (result.success) {
228
+ setData(result.data)
229
+ }
230
+ }
231
+ fetchStats()
232
+ }, [])
233
+
234
+ if (!data) return <div>Loading...</div>
235
+
236
+ return (
237
+ <div>
238
+ <h2>Your Earnings</h2>
239
+ <p>Total: ${data.stats.totalEarnings}</p>
240
+ <p>Pending: ${data.stats.pendingEarnings}</p>
241
+ <p>Paid: ${data.stats.paidEarnings}</p>
242
+
243
+ <h2>Your Referral Codes</h2>
244
+ {data.referralCodes.map(code => (
245
+ <div key={code.id}>
246
+ <span>{code.code}</span>
247
+ <span>Uses: {code.usageCount}</span>
248
+ </div>
249
+ ))}
125
250
  </div>
126
251
  )
127
252
  }
@@ -137,9 +262,12 @@ Best for traditional discount campaigns, seasonal sales, and customer loyalty pr
137
262
  #### **Referral Mode** (`enableReferrals: true`)
138
263
  Best for affiliate marketing, partner programs, and customer acquisition through referrals.
139
264
 
265
+ #### **Hybrid Mode** (`enableReferrals: true` + `allowBothSystems: true`)
266
+ Best when you need both traditional coupons AND partner referrals, but want to enforce only one code per order.
267
+
140
268
  ### **Setting Up Coupon Mode**
141
269
 
142
- 1. **Navigate to Admin Panel** → Go to "Coupons" collection
270
+ 1. **Navigate to Admin Panel** → Go to "Coupons" collection (under "Coupons" group)
143
271
  2. **Create New Coupon**:
144
272
  - **Code**: `WELCOME10` (unique identifier)
145
273
  - **Type**: `Percentage` or `Fixed Amount`
@@ -148,26 +276,19 @@ Best for affiliate marketing, partner programs, and customer acquisition through
148
276
  - **Active From/Until**: Set validity period
149
277
  - **Usage Limit**: Maximum uses (optional)
150
278
  - **Per Customer Limit**: Uses per customer (optional)
151
- - **Conditions**: Min/max order values
152
-
153
- 3. **Advanced Conditions**:
154
- ```json
155
- {
156
- "minOrderValue": 5000, // $50 minimum
157
- "maxOrderValue": 100000 // $1000 maximum
158
- }
159
- ```
279
+ - **Min/Max Order Value**: Order value constraints
160
280
 
161
281
  ### **Setting Up Referral Mode**
162
282
 
163
- 1. **Navigate to Admin Panel** → Go to "Referral Programs" collection
283
+ 1. **Navigate to Admin Panel** → Go to "Referral Programs" (under "Referrals" group)
164
284
  2. **Create Referral Program**:
165
285
  - **Name**: "Partner Affiliate Program"
166
286
  - **Description**: "Earn commissions by referring customers"
167
287
  - **Is Active**: Enable/disable program
168
- - **Active From/Until**: Program validity period
288
+ - **Referrer Reward**: Commission for the partner (e.g., 10% of order)
289
+ - **Referee Reward**: Discount for the customer (e.g., 5% off)
169
290
 
170
- 3. **Configure Commission Rules**:
291
+ 3. **Configure Commission Rules** (Optional - for product-specific rates):
171
292
  ```json
172
293
  {
173
294
  "name": "Electronics Category",
@@ -175,102 +296,47 @@ Best for affiliate marketing, partner programs, and customer acquisition through
175
296
  "categories": ["electronics"],
176
297
  "totalCommission": {
177
298
  "type": "percentage",
178
- "value": 15 // 15% of product price
299
+ "value": 15
179
300
  },
180
301
  "split": {
181
- "partnerPercentage": 70, // Partner gets 70%
182
- "customerPercentage": 30 // Customer gets 30% discount
302
+ "partnerPercentage": 70,
303
+ "customerPercentage": 30
183
304
  }
184
305
  }
185
306
  ```
186
307
 
187
- 4. **Program Conditions**:
188
- - **Min Order Value**: Minimum purchase required
189
- - **Max Referrals Per User**: Limit referrals per user
190
- - **Referral Code Prefix**: Custom prefix for codes
191
-
192
- ### **Commission Rule Examples**
193
-
194
- #### **Example 1: Electronics Category**
195
- - **Total Commission**: 15% of product price
196
- - **Partner Share**: 70% = 10.5% commission
197
- - **Customer Discount**: 30% = 4.5% discount
198
- - **Result**: $100 product = $10.50 partner commission + $4.50 customer discount
199
-
200
- #### **Example 2: Fixed Commission**
201
- - **Total Commission**: $25 per product
202
- - **Partner Share**: 80% = $20 commission
203
- - **Customer Discount**: 20% = $5 discount
204
-
205
- #### **Example 3: All Products**
206
- - **Total Commission**: 10% of order total
207
- - **Partner Share**: 60% = 6% commission
208
- - **Customer Discount**: 40% = 4% discount
209
-
210
- ### **Managing Referral Codes**
211
-
212
- 1. **Auto-Generation**: Codes are created automatically when users join
213
- 2. **Manual Creation**: Admin can create codes for specific partners
214
- 3. **Tracking**: Monitor usage, successful referrals, and commission payouts
215
-
216
- ### **Monitoring & Analytics**
217
-
218
- #### **Coupon Analytics**
219
- - Total redemptions
220
- - Revenue impact
221
- - Customer usage patterns
222
- - Expiration tracking
308
+ ### **Commission Calculation Examples**
223
309
 
224
- #### **Referral Analytics**
225
- - Total referrals generated
226
- - Successful conversions
227
- - Commission paid vs pending
228
- - Partner performance rankings
229
-
230
- ### **Access Control Setup**
231
-
232
- ```typescript
233
- payloadEcommerceCoupon({
234
- access: {
235
- // Who can use coupons/referrals
236
- canUseCoupons: ({ req }) => Boolean(req.user),
237
- canUseReferrals: ({ req }) => req.user?.subscription === 'premium',
238
-
239
- // Who can create/manage
240
- isAdmin: ({ req }) => req.user?.role === 'admin',
241
- },
242
- })
243
- ```
310
+ #### **Example 1: Simple Percentage Split**
311
+ - **Order Total**: $100
312
+ - **Referrer Reward**: 10% (percentage)
313
+ - **Referee Reward**: 5% (percentage)
314
+ - **Result**: Partner earns $10, Customer saves $5
244
315
 
245
- ### **Best Practices**
316
+ #### **Example 2: Commission Rules with Split**
317
+ - **Order Total**: $100 (Electronics category)
318
+ - **Total Commission**: 15% = $15
319
+ - **Partner Share**: 70% of $15 = $10.50
320
+ - **Customer Discount**: 30% of $15 = $4.50
246
321
 
247
- #### **For Coupons**
248
- - Use descriptive codes: `SUMMER2024` vs `ABC123`
249
- - Set reasonable expiration dates
250
- - Monitor performance and adjust conditions
251
- - Use per-customer limits to prevent abuse
322
+ #### **Example 3: Fixed Commission**
323
+ - **Referrer Reward**: $20 (fixed)
324
+ - **Referee Reward**: $10 (fixed)
325
+ - **Result**: Partner earns $20, Customer saves $10 (regardless of order value)
252
326
 
253
- #### **For Referrals**
254
- - Start with generous splits to attract partners
255
- - Set clear program rules and conditions
256
- - Monitor partner performance regularly
257
- - Provide transparent commission tracking
327
+ ### **Managing Partners**
258
328
 
259
- #### **General**
260
- - Test all codes before going live
261
- - Monitor API usage and error rates
262
- - Keep commission rules simple initially
263
- - Document your specific business rules
329
+ 1. **Create Partner Account**: Set user role to "partner"
330
+ 2. **Generate Referral Code**: Partners can create codes in "Referral Codes" collection
331
+ 3. **Track Performance**: View usage count, earnings, and successful referrals
332
+ 4. **Payout Management**: Track pending vs paid earnings
264
333
 
265
334
  ## 🌐 REST API Endpoints
266
335
 
267
- The API endpoints automatically adapt based on your `enableReferrals` configuration.
268
-
269
- ### **Coupon Mode Endpoints**
336
+ ### **Coupon/Referral Endpoints**
270
337
 
271
338
  #### POST /api/coupons/validate
272
-
273
- Validate a coupon code without applying it.
339
+ Validate a code without applying it.
274
340
 
275
341
  ```bash
276
342
  curl -X POST http://localhost:3000/api/coupons/validate \
@@ -278,24 +344,8 @@ curl -X POST http://localhost:3000/api/coupons/validate \
278
344
  -d '{"code": "WELCOME10", "cartValue": 5000}'
279
345
  ```
280
346
 
281
- **Response:**
282
- ```json
283
- {
284
- "success": true,
285
- "coupon": {
286
- "code": "WELCOME10",
287
- "type": "percentage",
288
- "value": 10,
289
- "description": "Welcome discount"
290
- },
291
- "discount": 500,
292
- "currency": "USD"
293
- }
294
- ```
295
-
296
347
  #### POST /api/coupons/apply
297
-
298
- Apply a coupon to a cart.
348
+ Apply a code to a cart.
299
349
 
300
350
  ```bash
301
351
  curl -X POST http://localhost:3000/api/coupons/apply \
@@ -303,652 +353,352 @@ curl -X POST http://localhost:3000/api/coupons/apply \
303
353
  -d '{"code": "WELCOME10", "cartID": "cart-123"}'
304
354
  ```
305
355
 
306
- **Response:**
307
- ```json
308
- {
309
- "success": true,
310
- "message": "Coupon applied successfully",
311
- "coupon": {
312
- "code": "WELCOME10",
313
- "type": "percentage",
314
- "value": 10
315
- },
316
- "discount": 500,
317
- "currency": "USD"
318
- }
319
- ```
320
-
321
- ### **Referral Mode Endpoints**
356
+ ### **Partner Stats Endpoint**
322
357
 
323
- #### POST /api/coupons/validate
324
-
325
- Validate a referral code and preview commission/discount.
358
+ #### GET /api/referrals/partner-stats
359
+ Get partner dashboard data (requires authentication).
326
360
 
327
361
  ```bash
328
- curl -X POST http://localhost:3000/api/coupons/validate \
329
- -H "Content-Type: application/json" \
330
- -d '{"code": "REF-ABC123", "cartID": "cart-123"}'
362
+ curl -X GET http://localhost:3000/api/referrals/partner-stats \
363
+ -H "Cookie: payload-token=your-auth-token"
331
364
  ```
332
365
 
333
366
  **Response:**
334
367
  ```json
335
368
  {
336
369
  "success": true,
337
- "referralCode": {
338
- "code": "REF-ABC123",
339
- "description": "Get $15.50 discount with this referral code"
340
- },
341
- "partnerCommission": 36.75,
342
- "customerDiscount": 15.50,
343
- "currency": "USD"
344
- }
345
- ```
346
-
347
- #### POST /api/coupons/apply
348
-
349
- Apply a referral code to a cart.
350
-
351
- ```bash
352
- curl -X POST http://localhost:3000/api/coupons/apply \
353
- -H "Content-Type: application/json" \
354
- -d '{"code": "REF-ABC123", "cartID": "cart-123"}'
355
- ```
356
-
357
- **Response:**
358
- ```json
359
- {
360
- "success": true,
361
- "message": "Referral code applied successfully",
362
- "referralCode": {
363
- "code": "REF-ABC123"
370
+ "data": {
371
+ "stats": {
372
+ "totalEarnings": 1250.50,
373
+ "pendingEarnings": 350.00,
374
+ "paidEarnings": 900.50,
375
+ "totalReferrals": 45,
376
+ "successfulReferrals": 38,
377
+ "conversionRate": 84.44,
378
+ "recentReferrals": [...],
379
+ "monthlyEarnings": [...]
380
+ },
381
+ "referralCodes": [...],
382
+ "program": {
383
+ "name": "Partner Program",
384
+ "commissionRate": 10,
385
+ "customerDiscount": 5
386
+ }
364
387
  },
365
- "partnerCommission": 36.75,
366
- "customerDiscount": 15.50,
367
388
  "currency": "USD"
368
389
  }
369
390
  ```
370
391
 
371
- ### **Error Responses**
372
-
373
- All endpoints return consistent error formats:
374
-
375
- ```json
376
- {
377
- "success": false,
378
- "error": "Invalid coupon code"
379
- }
380
- ```
381
-
382
- ```json
383
- {
384
- "success": false,
385
- "error": "Referral code has expired"
386
- }
387
- ```
388
-
389
- ```json
390
- {
391
- "success": false,
392
- "error": "Coupon already applied to this cart"
393
- }
394
- ```
395
-
396
392
  ## ⚙️ Configuration
397
393
 
398
394
  ### **Core Options**
399
395
 
400
396
  ```typescript
401
397
  export type CouponPluginOptions = {
402
- enabled?: boolean // Enable/disable the entire plugin (default: true)
403
- enableReferrals?: boolean // Choose mode: false=coupons, true=referrals (default: false)
404
- allowStackWithOtherCoupons?: boolean // Allow multiple coupons (coupon mode only, default: false)
405
- defaultCurrency?: string // Currency for amounts (default: 'USD')
406
- autoIntegrate?: boolean // Auto-extend carts/orders collections (default: true)
398
+ enabled?: boolean // Enable/disable the plugin (default: true)
399
+ enableReferrals?: boolean // Enable referral system (default: false)
400
+ allowStackWithOtherCoupons?: boolean // Allow multiple coupons (default: false)
401
+ defaultCurrency?: string // Currency code (default: 'USD')
402
+ autoIntegrate?: boolean // Auto-extend carts/orders (default: true)
403
+
407
404
  collections?: {
408
- couponsSlug?: string // Collection slug for coupons (default: 'coupons')
409
- referralProgramsSlug?: string // Collection slug for programs (default: 'referral-programs')
410
- referralCodesSlug?: string // Collection slug for codes (default: 'referral-codes')
411
- referralPartnersSlug?: string // Collection slug for partners (default: 'referral-partners')
405
+ couponsSlug?: string // Default: 'coupons'
406
+ referralProgramsSlug?: string // Default: 'referral-programs'
407
+ referralCodesSlug?: string // Default: 'referral-codes'
408
+
409
+ /** Override the default coupons collection configuration */
410
+ couponsCollectionOverride?: (params: { defaultCollection: any }) => any | Promise<any>
411
+
412
+ /** Override the default referral programs collection configuration */
413
+ referralProgramsCollectionOverride?: (params: { defaultCollection: any }) => any | Promise<any>
414
+
415
+ /** Override the default referral codes collection configuration */
416
+ referralCodesCollectionOverride?: (params: { defaultCollection: any }) => any | Promise<any>
412
417
  }
418
+
419
+ endpoints?: {
420
+ applyCoupon?: string // Default: '/coupons/apply'
421
+ validateCoupon?: string // Default: '/coupons/validate'
422
+ partnerStats?: string // Default: '/referrals/partner-stats'
423
+ }
424
+
413
425
  access?: {
414
- canUseCoupons?: Access // Who can use coupons (default: () => true)
415
- canUseReferrals?: Access // Who can use referrals (default: () => true)
416
- isAdmin?: Access // Who can manage codes/programs (default: () => false)
426
+ canUseCoupons?: Access // Who can use coupons
427
+ canUseReferrals?: Access // Who can use referrals
428
+ isAdmin?: Access // Who can manage codes/programs
429
+ isPartner?: Access // Who has partner access
430
+ }
431
+
432
+ referralConfig?: {
433
+ allowBothSystems?: boolean // Allow coupons + referrals (default: false)
434
+ singleCodePerCart?: boolean // One code per order (default: true)
435
+ defaultPartnerSplit?: number // Default partner % (default: 70)
436
+ defaultCustomerSplit?: number // Default customer % (default: 30)
437
+ }
438
+
439
+ adminGroups?: {
440
+ couponsGroup?: string // Admin group for coupons (default: 'Coupons')
441
+ referralsGroup?: string // Admin group for referrals (default: 'Referrals')
442
+ }
443
+
444
+ partnerDashboard?: {
445
+ enabled?: boolean // Enable dashboard (default: true)
446
+ showEarningsSummary?: boolean // Show earnings widget (default: true)
447
+ showReferralPerformance?: boolean // Show performance widget (default: true)
448
+ showRecentReferrals?: boolean // Show recent referrals (default: true)
449
+ showCommissionBreakdown?: boolean // Show breakdown (default: true)
417
450
  }
418
451
  }
419
452
  ```
420
453
 
421
- ### **Mode Selection**
422
-
423
- #### **Coupon Mode** (`enableReferrals: false`)
424
- ```typescript
425
- payloadEcommerceCoupon({
426
- enableReferrals: false, // Traditional coupon system
427
- // Creates: coupons collection
428
- // Features: percentage/fixed discounts, usage limits, conditions
429
- })
430
- ```
431
-
432
- #### **Referral Mode** (`enableReferrals: true`)
433
- ```typescript
434
- payloadEcommerceCoupon({
435
- enableReferrals: true, // Partner referral system
436
- // Creates: referral-programs, referral-codes collections
437
- // Features: commission rules, partner/customer splits, referral tracking
438
- })
439
- ```
454
+ ### **Collection Overrides**
440
455
 
441
- ### **Access Control Examples**
456
+ You can override the default collection configurations to customize fields, hooks, or other collection settings. This allows you to extend or modify the plugin's behavior without forking the code.
442
457
 
443
- #### **Basic Authentication**
444
458
  ```typescript
445
459
  payloadEcommerceCoupon({
446
- access: {
447
- canUseCoupons: ({ req }) => Boolean(req.user), // Authenticated users only
448
- canUseReferrals: ({ req }) => Boolean(req.user), // Authenticated users only
449
- isAdmin: ({ req }) => req.user?.role === 'admin', // Admin role required
450
- },
451
- })
452
- ```
453
-
454
- #### **Subscription-Based Access**
455
- ```typescript
456
- payloadEcommerceCoupon({
457
- access: {
458
- canUseCoupons: ({ req }) => req.user?.subscription !== 'free', // Paid users only
459
- canUseReferrals: ({ req }) => req.user?.subscription === 'premium', // Premium only
460
- isAdmin: ({ req }) => ['admin', 'manager'].includes(req.user?.role), // Multiple roles
461
- },
462
- })
463
- ```
464
-
465
- #### **Role-Based Permissions**
466
- ```typescript
467
- payloadEcommerceCoupon({
468
- access: {
469
- canUseCoupons: ({ req }) => {
470
- // Custom logic based on user properties
471
- return req.user?.permissions?.includes('use_coupons') ?? false
460
+ collections: {
461
+ // Override coupons collection
462
+ couponsCollectionOverride: async ({ defaultCollection }) => {
463
+ return {
464
+ ...defaultCollection,
465
+ fields: [
466
+ ...defaultCollection.fields,
467
+ // Add custom field to coupons
468
+ {
469
+ name: 'customField',
470
+ type: 'text',
471
+ label: 'Custom Field',
472
+ },
473
+ ],
474
+ hooks: {
475
+ ...defaultCollection.hooks,
476
+ // Add custom hook
477
+ beforeChange: [
478
+ ...(defaultCollection.hooks?.beforeChange || []),
479
+ async ({ data, req, operation }) => {
480
+ // Custom beforeChange logic
481
+ return data
482
+ },
483
+ ],
484
+ },
485
+ }
472
486
  },
473
- canUseReferrals: ({ req }) => {
474
- // Check multiple conditions
475
- const user = req.user
476
- return user?.verified && user?.subscription === 'active'
487
+
488
+ // Override referral programs collection
489
+ referralProgramsCollectionOverride: ({ defaultCollection }) => {
490
+ return {
491
+ ...defaultCollection,
492
+ admin: {
493
+ ...defaultCollection.admin,
494
+ defaultColumns: ['name', 'isActive', 'totalReferrals'],
495
+ },
496
+ }
477
497
  },
478
- isAdmin: ({ req }) => {
479
- // Admin or specific user IDs
480
- return req.user?.role === 'admin' || req.user?.id === 'special-user'
498
+
499
+ // Override referral codes collection
500
+ referralCodesCollectionOverride: async ({ defaultCollection }) => {
501
+ return {
502
+ ...defaultCollection,
503
+ fields: [
504
+ ...defaultCollection.fields,
505
+ {
506
+ name: 'customCodeField',
507
+ type: 'select',
508
+ label: 'Custom Code Type',
509
+ options: ['standard', 'premium'],
510
+ defaultValue: 'standard',
511
+ },
512
+ ],
513
+ }
481
514
  },
482
515
  },
483
516
  })
484
517
  ```
485
518
 
486
- ### **Collection Customization**
487
-
488
- Avoid slug conflicts with existing collections:
489
-
490
- ```typescript
491
- payloadEcommerceCoupon({
492
- collections: {
493
- couponsSlug: 'discount-codes', // Instead of 'coupons'
494
- referralProgramsSlug: 'affiliate-programs', // Instead of 'referral-programs'
495
- referralCodesSlug: 'promo-codes', // Instead of 'referral-codes'
496
- },
497
- })
498
- ```
499
-
500
- ### **Advanced Configuration Examples**
501
-
502
- #### **Multi-Tenant Setup**
503
- ```typescript
504
- payloadEcommerceCoupon({
505
- collections: {
506
- couponsSlug: 'tenant-a-coupons',
507
- referralProgramsSlug: 'tenant-a-referrals',
508
- },
509
- access: {
510
- canUseCoupons: ({ req }) => req.user?.tenantId === 'tenant-a',
511
- canUseReferrals: ({ req }) => req.user?.tenantId === 'tenant-a',
512
- isAdmin: ({ req }) => req.user?.role === 'admin' && req.user?.tenantId === 'tenant-a',
513
- },
514
- })
515
- ```
516
-
517
- #### **Development vs Production**
518
- ```typescript
519
- const isProduction = process.env.NODE_ENV === 'production'
520
-
521
- payloadEcommerceCoupon({
522
- enabled: isProduction, // Disable in development
523
- access: {
524
- isAdmin: ({ req }) => isProduction ? req.user?.role === 'admin' : true, // Allow all in dev
525
- },
526
- })
527
- ```
519
+ ### **Access Control Examples**
528
520
 
529
521
  ```typescript
530
522
  payloadEcommerceCoupon({
531
523
  access: {
532
- canUseCoupons: ({ req }) => {
533
- // Allow all authenticated users to use coupons
534
- return Boolean(req.user)
535
- },
536
- canUseReferrals: ({ req }) => {
537
- // Only allow premium users to use referrals
538
- return req.user?.role === 'premium'
539
- },
540
- isAdmin: ({ req }) => {
541
- // Only admins can create/edit coupons
542
- return req.user?.role === 'admin'
524
+ // Anyone can use coupons
525
+ canUseCoupons: () => true,
526
+
527
+ // Only authenticated users can use referrals
528
+ canUseReferrals: ({ req }) => Boolean(req.user),
529
+
530
+ // Only admins can manage
531
+ isAdmin: ({ req }) => req.user?.role === 'admin',
532
+
533
+ // Partner role check (supports both single role and array)
534
+ isPartner: ({ req }) => {
535
+ const user = req.user
536
+ if (!user) return false
537
+ if (user.role === 'partner') return true
538
+ if (Array.isArray(user.roles) && user.roles.includes('partner')) return true
539
+ return false
543
540
  },
544
541
  },
545
542
  })
546
543
  ```
547
544
 
548
- ### Collection Customization
545
+ ## 📦 API Reference
549
546
 
550
- You can customize collection slugs to avoid conflicts:
547
+ ### **Exported Functions**
551
548
 
552
549
  ```typescript
553
- payloadEcommerceCoupon({
554
- collections: {
555
- couponsSlug: 'discount-codes',
556
- referralProgramsSlug: 'affiliate-programs',
557
- referralCodesSlug: 'promo-codes',
558
- },
559
- })
560
- ```
561
-
562
- ## � Usage Examples
563
-
564
- ### **E-commerce Store Setup**
550
+ import {
551
+ payloadEcommerceCoupon,
552
+
553
+ // Collection creation functions
554
+ createCouponsCollection,
555
+ createReferralCodesCollection,
556
+ createReferralProgramsCollection,
557
+
558
+ // Frontend hooks
559
+ useCouponCode,
560
+ validateCouponCode,
561
+ usePartnerStats,
562
+
563
+ // Dashboard components
564
+ PartnerDashboard,
565
+ EarningsSummary,
566
+ ReferralPerformance,
567
+ RecentReferrals,
568
+ ReferralCodes,
569
+ } from '@wtree/payload-ecommerce-coupon'
570
+ ```
571
+
572
+ ### **Collection Creation Functions**
573
+
574
+ You can use the collection creation functions directly in your Payload config to customize collections before they're added to the config.
565
575
 
566
- #### **Basic Coupon Store**
567
576
  ```typescript
568
- // payload.config.ts
569
- import { payloadEcommerceCoupon } from '@wtree/payload-ecommerce-coupon'
577
+ import { buildConfig } from 'payload'
578
+ import { ecommercePlugin } from '@payloadcms/plugin-ecommerce'
579
+ import { payloadEcommerceCoupon, createCouponsCollection } from '@wtree/payload-ecommerce-coupon'
570
580
 
571
581
  export default buildConfig({
572
- collections: [/* your collections */],
573
582
  plugins: [
574
- ecommercePlugin({ /* config */ }),
583
+ ecommercePlugin({
584
+ // your ecommerce configuration
585
+ }),
575
586
  payloadEcommerceCoupon({
576
- enableReferrals: false, // Coupon mode
577
- defaultCurrency: 'USD',
578
- access: {
579
- canUseCoupons: ({ req }) => Boolean(req.user),
580
- isAdmin: ({ req }) => req.user?.role === 'admin',
581
- },
587
+ // plugin configuration
582
588
  }),
583
589
  ],
584
- })
585
- ```
586
-
587
- #### **Affiliate Marketing Platform**
588
- ```typescript
589
- // payload.config.ts
590
- export default buildConfig({
591
- collections: [/* your collections */],
592
- plugins: [
593
- ecommercePlugin({ /* config */ }),
594
- payloadEcommerceCoupon({
595
- enableReferrals: true, // Referral mode
590
+ collections: [
591
+ // You can also create and customize collections directly
592
+ createCouponsCollection({
593
+ enabled: true,
596
594
  defaultCurrency: 'USD',
597
- access: {
598
- canUseReferrals: ({ req }) => req.user?.subscription === 'premium',
599
- isAdmin: ({ req }) => req.user?.role === 'admin',
600
- },
601
595
  }),
602
596
  ],
603
597
  })
604
598
  ```
605
599
 
606
- ### **Commission Rule Examples**
607
-
608
- #### **Tiered Commission Structure**
609
- ```json
610
- // Referral Program Commission Rules
611
- [
612
- {
613
- "name": "High-Value Electronics",
614
- "appliesTo": "categories",
615
- "categories": ["laptops", "smartphones"],
616
- "totalCommission": { "type": "percentage", "value": 20 },
617
- "split": { "partnerPercentage": 80, "customerPercentage": 20 }
618
- },
619
- {
620
- "name": "Accessories",
621
- "appliesTo": "categories",
622
- "categories": ["cases", "chargers"],
623
- "totalCommission": { "type": "percentage", "value": 10 },
624
- "split": { "partnerPercentage": 70, "customerPercentage": 30 }
625
- },
626
- {
627
- "name": "Default Rate",
628
- "appliesTo": "all",
629
- "totalCommission": { "type": "percentage", "value": 5 },
630
- "split": { "partnerPercentage": 60, "customerPercentage": 40 }
631
- }
632
- ]
633
- ```
600
+ ## 🎨 Partner Dashboard Components
634
601
 
635
- #### **Fixed Commission per Product**
636
- ```json
637
- [
638
- {
639
- "name": "Premium Products",
640
- "appliesTo": "products",
641
- "products": ["premium-laptop", "gaming-pc"],
642
- "totalCommission": { "type": "fixed", "value": 50 },
643
- "split": { "partnerPercentage": 75, "customerPercentage": 25 }
644
- }
645
- ]
646
- ```
647
-
648
- ### **Frontend Integration Examples**
649
-
650
- #### **React Checkout Component**
651
- ```tsx
652
- import { useCouponCode } from '@wtree/payload-ecommerce-coupon'
653
- import { useState } from 'react'
654
-
655
- function Checkout({ cartId, total }: { cartId: string, total: number }) {
656
- const [code, setCode] = useState('')
657
- const [discount, setDiscount] = useState(0)
658
- const [loading, setLoading] = useState(false)
659
-
660
- const applyCode = async () => {
661
- setLoading(true)
662
- try {
663
- const result = await useCouponCode({
664
- code,
665
- cartID: cartId,
666
- })
667
-
668
- if (result.success) {
669
- setDiscount(result.discount || 0)
670
- alert(`Applied successfully! Discount: $${result.discount}`)
671
- } else {
672
- alert(`Error: ${result.error}`)
673
- }
674
- } catch (error) {
675
- alert('Failed to apply code')
676
- } finally {
677
- setLoading(false)
678
- }
679
- }
602
+ The plugin provides ready-to-use React components for building partner dashboards:
680
603
 
604
+ ```typescript
605
+ import {
606
+ PartnerDashboard, // Complete dashboard
607
+ EarningsSummary, // Earnings widget
608
+ ReferralPerformance, // Performance metrics
609
+ RecentReferrals, // Recent referrals table
610
+ ReferralCodes, // Referral codes list
611
+ } from '@wtree/payload-ecommerce-coupon'
612
+
613
+ // Use individual components
614
+ function CustomDashboard({ stats, currency }) {
681
615
  return (
682
- <div className="checkout">
683
- <div className="code-input">
684
- <input
685
- value={code}
686
- onChange={(e) => setCode(e.target.value)}
687
- placeholder="Enter coupon or referral code"
688
- disabled={loading}
689
- />
690
- <button onClick={applyCode} disabled={loading}>
691
- {loading ? 'Applying...' : 'Apply'}
692
- </button>
693
- </div>
694
-
695
- <div className="totals">
696
- <div>Subtotal: ${total}</div>
697
- <div>Discount: -${discount}</div>
698
- <div>Total: ${total - discount}</div>
699
- </div>
616
+ <div>
617
+ <EarningsSummary stats={stats} currency={currency} />
618
+ <ReferralPerformance stats={stats} />
700
619
  </div>
701
620
  )
702
621
  }
703
622
  ```
704
623
 
705
- #### **Next.js API Route**
706
- ```typescript
707
- // pages/api/apply-code.ts
708
- import { useCouponCode } from '@wtree/payload-ecommerce-coupon'
624
+ ### **Styling**
709
625
 
710
- export default async function handler(req: NextApiRequest, res: NextApiResponse) {
711
- if (req.method !== 'POST') {
712
- return res.status(405).json({ error: 'Method not allowed' })
713
- }
626
+ Import the default styles or customize:
714
627
 
715
- const { code, cartId } = req.body
716
-
717
- try {
718
- const result = await useCouponCode({
719
- code,
720
- cartID: cartId,
721
- })
628
+ ```css
629
+ /* Import default styles */
630
+ @import '@wtree/payload-ecommerce-coupon/styles.css';
722
631
 
723
- if (result.success) {
724
- return res.status(200).json(result)
725
- } else {
726
- return res.status(400).json({ error: result.error })
727
- }
728
- } catch (error) {
729
- return res.status(500).json({ error: 'Internal server error' })
730
- }
632
+ /* Or customize with CSS variables */
633
+ .partner-dashboard {
634
+ --primary-color: #3b82f6;
635
+ --success-color: #059669;
636
+ --warning-color: #d97706;
731
637
  }
732
638
  ```
733
639
 
734
- ### **Admin Panel Examples**
735
-
736
- #### **Bulk Coupon Creation**
737
- ```typescript
738
- // Admin script to create multiple coupons
739
- const coupons = [
740
- { code: 'WELCOME10', type: 'percentage', value: 10 },
741
- { code: 'SAVE20', type: 'percentage', value: 20 },
742
- { code: 'FLAT50', type: 'fixed', value: 50 },
743
- ]
744
-
745
- for (const coupon of coupons) {
746
- await payload.create({
747
- collection: 'coupons',
748
- data: {
749
- ...coupon,
750
- activeFrom: new Date(),
751
- activeUntil: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days
752
- },
753
- })
754
- }
755
- ```
756
-
757
- #### **Referral Program Setup**
758
- ```typescript
759
- // Create a complete referral program
760
- const program = await payload.create({
761
- collection: 'referral-programs',
762
- data: {
763
- name: 'Partner Program 2024',
764
- description: 'Earn commissions by referring customers',
765
- isActive: true,
766
- commissionRules: [
767
- {
768
- name: 'Electronics',
769
- appliesTo: 'categories',
770
- categories: ['electronics'],
771
- totalCommission: { type: 'percentage', value: 15 },
772
- split: { partnerPercentage: 70, customerPercentage: 30 },
773
- },
774
- ],
775
- },
776
- })
777
- ```
778
-
779
- ## �🔧 Troubleshooting
640
+ ## 🔧 Troubleshooting
780
641
 
781
642
  ### **Common Issues**
782
643
 
783
- #### **"Collection already exists" Error**
784
- **Problem**: Migration fails due to existing collections
785
- **Solution**: Customize collection slugs to avoid conflicts
786
- ```typescript
787
- payloadEcommerceCoupon({
788
- collections: {
789
- couponsSlug: 'my-coupons',
790
- referralProgramsSlug: 'my-referral-programs',
791
- },
792
- })
793
- ```
794
-
795
- #### **API Returns 404**
796
- **Problem**: Endpoints not found
797
- **Solution**: Ensure plugin is registered in `payload.config.ts`
798
- ```typescript
799
- // Correct order in payload.config.ts
800
- plugins: [
801
- ecommercePlugin({...}),
802
- payloadEcommerceCoupon({...}), // Must come after ecommerce plugin
803
- ]
804
- ```
805
-
806
- #### **Permission Denied**
807
- **Problem**: Users can't use coupons/referrals
808
- **Solution**: Check access control configuration
809
- ```typescript
810
- payloadEcommerceCoupon({
811
- access: {
812
- canUseCoupons: ({ req }) => Boolean(req.user), // Ensure this returns true
813
- canUseReferrals: ({ req }) => Boolean(req.user),
814
- },
815
- })
816
- ```
817
-
818
- #### **Commission Calculation Issues**
819
- **Problem**: Referral discounts not calculating correctly
820
- **Solution**: Verify commission rules and product relationships
821
- - Ensure products have correct category assignments
822
- - Check that commission rules match product criteria
823
- - Verify cart contains valid product references
824
-
825
- #### **Cart Integration Not Working**
826
- **Problem**: Applied coupons/referrals not showing in cart
827
- **Solution**: Check auto-integration settings
828
- ```typescript
829
- payloadEcommerceCoupon({
830
- autoIntegrate: true, // Ensure this is enabled (default)
831
- })
832
- ```
833
-
834
- ### **Debugging Tips**
835
-
836
- #### **Enable Debug Logging**
837
- ```typescript
838
- // Add to your payload.config.ts for debugging
839
- logger: {
840
- level: 'debug',
841
- },
842
- ```
843
-
844
- #### **Test API Endpoints**
845
- ```bash
846
- # Test coupon validation
847
- curl -X POST http://localhost:3000/api/coupons/validate \
848
- -H "Content-Type: application/json" \
849
- -d '{"code": "TEST123"}'
850
-
851
- # Test referral validation
852
- curl -X POST http://localhost:3000/api/coupons/validate \
853
- -H "Content-Type: application/json" \
854
- -d '{"code": "REF-ABC123", "cartID": "cart-123"}'
855
- ```
856
-
857
- #### **Check Database Collections**
858
- Verify collections are created correctly:
859
- - **Coupon Mode**: `coupons` collection
860
- - **Referral Mode**: `referral-programs`, `referral-codes` collections
861
-
862
- #### **Validate Configuration**
863
- ```typescript
864
- // Add console.log to verify config
865
- const couponConfig = payloadEcommerceCoupon({
866
- enableReferrals: true,
867
- // ... other options
868
- })
869
- console.log('Coupon plugin config:', couponConfig)
870
- ```
871
-
872
- ### **Performance Considerations**
873
-
874
- #### **Database Indexes**
875
- For high-traffic sites, add indexes on frequently queried fields:
876
- - Coupon codes: `code` field
877
- - Referral codes: `code` field
878
- - Usage counts: `usageCount` field
879
-
880
- #### **Caching Strategy**
881
- Consider caching for:
882
- - Frequently used coupon validation
883
- - Commission rule lookups
884
- - Product category mappings
885
-
886
- #### **Rate Limiting**
887
- Implement rate limiting for API endpoints to prevent abuse:
888
- ```typescript
889
- // Example: Limit to 10 requests per minute per IP
890
- const rateLimit = require('express-rate-limit')
891
- app.use('/api/coupons', rateLimit({
892
- windowMs: 60 * 1000, // 1 minute
893
- max: 10
894
- }))
895
- ```
644
+ #### **"A code has already been applied to this cart"**
645
+ This occurs when `singleCodePerCart: true` and a code is already applied.
646
+ - Solution: Remove the existing code before applying a new one, or set `singleCodePerCart: false`
647
+
648
+ #### **Partner can't see their referral codes**
649
+ - Ensure the user has `role: 'partner'` or `roles: ['partner']`
650
+ - Check the `isPartner` access control function
651
+
652
+ #### **Commission not calculating correctly**
653
+ - Verify commission rules are properly configured
654
+ - Check that products have correct category assignments
655
+ - Ensure cart has valid `subtotal` or `total` field
656
+
657
+ ## 📋 Future Features (Roadmap)
658
+
659
+ The following features are planned for future releases:
660
+
661
+ | Feature | Status | Description |
662
+ |---------|--------|-------------|
663
+ | Multi-tier commissions | 🔜 Planned | Support for tiered commission rates based on performance |
664
+ | Automatic payouts | 🔜 Planned | Integration with payment providers for automatic partner payouts |
665
+ | Referral analytics | 🔜 Planned | Advanced analytics and reporting dashboard |
666
+ | Email notifications | 🔜 Planned | Automated emails for referral events |
667
+ | Custom code generation | 🔜 Planned | Allow partners to create custom branded codes |
668
+ | Fraud detection | 🔜 Planned | Automatic detection of suspicious referral patterns |
669
+ | Bulk code import | 🔜 Planned | Import coupons/codes from CSV |
670
+ | A/B testing | 🔜 Planned | Test different commission structures |
671
+
672
+ ### **Comparison with Other Solutions**
673
+
674
+ | Feature | This Plugin | ReferralCandy | Refersion | Custom Build |
675
+ |---------|-------------|---------------|-----------|--------------|
676
+ | Payload CMS Integration | ✅ Native | ❌ | ❌ | ⚠️ Manual |
677
+ | Coupon System | ✅ | ❌ | ❌ | ⚠️ Manual |
678
+ | Referral System | ✅ | ✅ | ✅ | ⚠️ Manual |
679
+ | Partner Dashboard | ✅ | ✅ | ✅ | ⚠️ Manual |
680
+ | Commission Rules | | ⚠️ Limited | ✅ | ⚠️ Manual |
681
+ | Single Code Enforcement | | ❌ | ❌ | ⚠️ Manual |
682
+ | TypeScript Support | | ❌ | ❌ | ⚠️ Varies |
683
+ | Self-Hosted | | | | ✅ |
684
+ | Monthly Cost | Free | $49+ | $89+ | Dev Time |
896
685
 
897
686
  ## 🧪 Testing
898
687
 
899
- ### **Running Tests**
900
-
901
688
  ```bash
902
689
  # Run all tests
903
690
  npm test
904
691
 
905
- # Watch mode for development
692
+ # Watch mode
906
693
  npm run test:watch
907
694
 
908
- # Generate coverage report
695
+ # Coverage report
909
696
  npm run test:coverage
910
-
911
- # Run specific test file
912
- npm test -- tests/plugin.test.ts
913
697
  ```
914
698
 
915
- ### **Test Coverage**
916
-
917
- The plugin maintains 80%+ test coverage including:
918
- - ✅ Plugin initialization and configuration
919
- - ✅ Collection creation (conditional based on mode)
920
- - ✅ API endpoint functionality
921
- - ✅ Access control validation
922
- - ✅ Commission calculation logic
923
- - ✅ Error handling scenarios
924
-
925
- ### **Manual Testing Checklist**
926
-
927
- #### **Coupon Mode Testing**
928
- - [ ] Create coupon in admin panel
929
- - [ ] Validate coupon via API
930
- - [ ] Apply coupon to cart
931
- - [ ] Verify discount calculation
932
- - [ ] Test usage limits
933
- - [ ] Test expiration dates
934
-
935
- #### **Referral Mode Testing**
936
- - [ ] Create referral program with commission rules
937
- - [ ] Generate referral codes
938
- - [ ] Validate referral codes via API
939
- - [ ] Apply referral codes to cart
940
- - [ ] Verify commission and discount split
941
- - [ ] Test referral tracking
942
-
943
- #### **Integration Testing**
944
- - [ ] Cart total updates correctly
945
- - [ ] Order creation includes applied discounts
946
- - [ ] Frontend hooks work properly
947
- - [ ] Access control restrictions work
948
-
949
699
  ## 📚 Documentation
950
700
 
951
- For detailed usage examples and advanced configurations, see the sections above and check out:
701
+ - [API Reference](./docs/api.md)
952
702
  - [Compatibility Matrix](./COMPATIBILITY.md)
953
703
  - [Contributing Guide](./CONTRIBUTING.md)
954
704
 
@@ -957,6 +707,7 @@ For detailed usage examples and advanced configurations, see the sections above
957
707
  - **GitHub**: https://github.com/technewwings/payload-ecommerce-coupon
958
708
  - **NPM**: https://npmjs.com/package/@wtree/payload-ecommerce-coupon
959
709
  - **Payload CMS**: https://payloadcms.com
710
+ - **Payload Dashboard Docs**: https://payloadcms.com/docs/custom-components/dashboard
960
711
 
961
712
  ## 📄 License
962
713