This commit adds comprehensive COD support using Saleor's native Transaction system:
**Architecture:**
- Uses Saleor's native Transaction objects (not metadata)
- Modular payment method configuration
- Extensible design for future payment types (cards, bank transfer, etc.)
**New Components:**
- PaymentMethodSelector: Reusable payment method selection UI
- PaymentMethodCard: Individual payment method card
- CODInstructions: COD-specific instructions and guidance
- PaymentSection: Checkout integration wrapper
**Core Features:**
- COD selected by default for Serbia (default-channel)
- Transaction created automatically on order completion
- Transaction visible in Saleor Dashboard
- Multi-language support (EN, SR, DE, FR)
- No additional fees
- Instructions shown to customer (prepare cash, inspect order, no fee)
**Files Added:**
- docs/COD-IMPLEMENTATION-PLAN.md
- src/lib/config/paymentMethods.ts
- src/lib/saleor/payments/types.ts
- src/lib/saleor/payments/cod.ts
- src/components/payment/PaymentMethodSelector.tsx
- src/components/payment/PaymentMethodCard.tsx
- src/components/payment/CODInstructions.tsx
- src/components/payment/index.ts
- src/app/[locale]/checkout/components/PaymentSection.tsx
**Files Modified:**
- src/app/[locale]/checkout/page.tsx (added payment section, transaction creation)
- src/i18n/messages/{en,sr,de,fr}.json (payment translations)
**Technical Details:**
- Transaction status: NOT_CHARGED
- Available actions: [CHARGE]
- PSP Reference format: COD-{orderNumber}-{timestamp}
- Staff collects cash and fulfills order via Dashboard
Closes: Cash on Delivery payment implementation
320 lines
8.1 KiB
Markdown
320 lines
8.1 KiB
Markdown
# Cash on Delivery (COD) Implementation Plan
|
|
|
|
**Branch:** `feature/cash-on-delivery`
|
|
**Status:** In Development
|
|
**Created:** March 29, 2026
|
|
|
|
---
|
|
|
|
## 1. ARCHITECTURE DECISIONS
|
|
|
|
### Payment Method Type: Simple Transaction
|
|
- Uses Saleor's native `Transaction` objects
|
|
- No Payment App required (COD is manual payment)
|
|
- Creates transaction with status `NOT_CHARGED`
|
|
- Staff marks as paid via Dashboard when cash collected
|
|
|
|
### Why This Approach:
|
|
- ✅ Native Saleor data structures
|
|
- ✅ Appears in Dashboard automatically
|
|
- ✅ No metadata hacks
|
|
- ✅ Extensible to other simple payments (Bank Transfer)
|
|
- ✅ Compatible with Payment Apps later (Stripe, etc.)
|
|
|
|
---
|
|
|
|
## 2. FILE STRUCTURE
|
|
|
|
```
|
|
src/
|
|
├── lib/
|
|
│ ├── config/
|
|
│ │ └── paymentMethods.ts # Payment methods configuration
|
|
│ └── saleor/
|
|
│ └── payments/
|
|
│ ├── types.ts # Payment type definitions
|
|
│ ├── cod.ts # COD-specific logic
|
|
│ └── createTransaction.ts # Generic transaction creator
|
|
│
|
|
├── components/
|
|
│ └── payment/
|
|
│ ├── PaymentMethodSelector.tsx # Payment method selection UI
|
|
│ ├── PaymentMethodCard.tsx # Individual payment card
|
|
│ └── CODInstructions.tsx # COD-specific instructions
|
|
│
|
|
├── app/[locale]/checkout/
|
|
│ ├── page.tsx # Updated checkout page
|
|
│ └── components/
|
|
│ └── PaymentSection.tsx # Checkout payment section wrapper
|
|
│
|
|
└── i18n/messages/
|
|
├── en.json # Payment translations
|
|
├── sr.json # Payment translations
|
|
├── de.json # Payment translations
|
|
└── fr.json # Payment translations
|
|
```
|
|
|
|
---
|
|
|
|
## 3. DATA MODELS
|
|
|
|
### PaymentMethod Interface
|
|
```typescript
|
|
interface PaymentMethod {
|
|
id: string;
|
|
name: string;
|
|
description: string;
|
|
type: 'simple' | 'app';
|
|
fee: number;
|
|
available: boolean;
|
|
availableInChannels: string[];
|
|
icon?: string;
|
|
}
|
|
```
|
|
|
|
### COD Transaction Structure
|
|
```typescript
|
|
const codTransaction = {
|
|
name: "Cash on Delivery",
|
|
pspReference: `COD-${orderNumber}-${timestamp}`,
|
|
availableActions: ["CHARGE"],
|
|
amountAuthorized: { amount: 0, currency: "RSD" },
|
|
amountCharged: { amount: 0, currency: "RSD" }
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## 4. IMPLEMENTATION PHASES
|
|
|
|
### Phase 1: Configuration & Types (Files 1-3)
|
|
**Files:**
|
|
1. `lib/config/paymentMethods.ts` - Payment methods config
|
|
2. `lib/saleor/payments/types.ts` - Type definitions
|
|
3. `lib/saleor/payments/cod.ts` - COD transaction logic
|
|
|
|
**Deliverables:**
|
|
- [ ] Payment methods configuration
|
|
- [ ] TypeScript interfaces
|
|
- [ ] COD transaction creation function
|
|
|
|
### Phase 2: UI Components (Files 4-6)
|
|
**Files:**
|
|
4. `components/payment/PaymentMethodCard.tsx`
|
|
5. `components/payment/PaymentMethodSelector.tsx`
|
|
6. `components/payment/CODInstructions.tsx`
|
|
|
|
**Deliverables:**
|
|
- [ ] Payment method selection UI
|
|
- [ ] COD instructions component
|
|
- [ ] Responsive design
|
|
|
|
### Phase 3: Checkout Integration (Files 7-8)
|
|
**Files:**
|
|
7. `app/[locale]/checkout/components/PaymentSection.tsx`
|
|
8. `app/[locale]/checkout/page.tsx` (updated)
|
|
|
|
**Deliverables:**
|
|
- [ ] Payment section in checkout
|
|
- [ ] Integration with checkout flow
|
|
- [ ] Transaction creation on complete
|
|
|
|
### Phase 4: Translations (Files 9-12)
|
|
**Files:**
|
|
9-12. Update `i18n/messages/{en,sr,de,fr}.json`
|
|
|
|
**Deliverables:**
|
|
- [ ] All translation keys
|
|
- [ ] Serbian, English, German, French
|
|
|
|
### Phase 5: Testing
|
|
**Tasks:**
|
|
- [ ] Test COD flow end-to-end
|
|
- [ ] Verify transaction created in Saleor
|
|
- [ ] Test mobile responsiveness
|
|
- [ ] Test locale switching
|
|
|
|
---
|
|
|
|
## 5. CHECKOUT FLOW
|
|
|
|
```
|
|
1. User adds items to cart
|
|
↓
|
|
2. User proceeds to checkout
|
|
↓
|
|
3. Checkout page loads with:
|
|
- Contact form (email, phone)
|
|
- Shipping address form
|
|
- Billing address form (same as shipping default)
|
|
- Shipping method selector
|
|
- PAYMENT METHOD SELECTOR (NEW)
|
|
└─ COD selected by default
|
|
- Order summary
|
|
- Complete Order button
|
|
↓
|
|
4. User fills all required fields
|
|
↓
|
|
5. User clicks "Complete Order"
|
|
↓
|
|
6. System:
|
|
a. Validates all fields
|
|
b. Creates order via checkoutComplete
|
|
c. Creates COD Transaction on order
|
|
d. Redirects to order confirmation
|
|
↓
|
|
7. Order Confirmation page shows:
|
|
- Order number
|
|
- Total amount
|
|
- Payment method: "Cash on Delivery"
|
|
- Instructions: "Please prepare cash for delivery"
|
|
↓
|
|
8. Staff sees order in Dashboard:
|
|
- Status: UNFULFILLED
|
|
- Payment Status: NOT_CHARGED
|
|
- Transaction: "Cash on Delivery (COD-123)"
|
|
↓
|
|
9. On delivery:
|
|
- Delivery person collects cash
|
|
- Staff marks order as FULFILLED in Dashboard
|
|
- (Optional: Create CHARGE_SUCCESS transaction event)
|
|
```
|
|
|
|
---
|
|
|
|
## 6. SALESOR DASHBOARD VIEW
|
|
|
|
### Order Details:
|
|
```
|
|
Order #1234
|
|
├─ Status: UNFULFILLED
|
|
├─ Payment Status: NOT_CHARGED
|
|
├─ Transactions:
|
|
│ └─ Cash on Delivery (COD-1234-1743214567890)
|
|
│ ├─ Status: NOT_CHARGED
|
|
│ ├─ Amount: 3,200 RSD
|
|
│ └─ Available Actions: [CHARGE]
|
|
└─ Actions: [Fulfill] [Cancel]
|
|
```
|
|
|
|
### When Cash Collected:
|
|
```
|
|
Staff clicks [Fulfill]
|
|
↓
|
|
Order Status: FULFILLED
|
|
Payment Status: (still NOT_CHARGED, but order is complete)
|
|
```
|
|
|
|
---
|
|
|
|
## 7. TRANSLATION KEYS
|
|
|
|
### English (en.json):
|
|
```json
|
|
{
|
|
"Payment": {
|
|
"title": "Payment Method",
|
|
"cod": {
|
|
"name": "Cash on Delivery",
|
|
"description": "Pay when you receive your order",
|
|
"instructions": {
|
|
"title": "Payment Instructions",
|
|
"prepareCash": "Please prepare the exact amount in cash",
|
|
"inspectOrder": "You can inspect your order before paying",
|
|
"noFee": "No additional fee for cash on delivery"
|
|
}
|
|
},
|
|
"card": {
|
|
"name": "Credit Card",
|
|
"description": "Secure online payment",
|
|
"comingSoon": "Coming soon"
|
|
},
|
|
"selectMethod": "Select payment method",
|
|
"securePayment": "Secure payment processing"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Serbian (sr.json):
|
|
```json
|
|
{
|
|
"Payment": {
|
|
"title": "Način Plaćanja",
|
|
"cod": {
|
|
"name": "Plaćanje Pouzećem",
|
|
"description": "Platite kada primite porudžbinu",
|
|
"instructions": {
|
|
"title": "Uputstva za Plaćanje",
|
|
"prepareCash": "Pripremite tačan iznos u gotovini",
|
|
"inspectOrder": "Možete pregledati porudžbinu pre plaćanja",
|
|
"noFee": "Bez dodatne naknade za plaćanje pouzećem"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 8. TESTING CHECKLIST
|
|
|
|
### Functional Tests:
|
|
- [ ] COD radio button selected by default
|
|
- [ ] Payment section visible in checkout
|
|
- [ ] Order completes with COD selected
|
|
- [ ] Transaction created with correct details
|
|
- [ ] Transaction visible in Saleor Dashboard
|
|
- [ ] Order confirmation shows COD
|
|
- [ ] Translations work in all locales
|
|
|
|
### Edge Cases:
|
|
- [ ] Checkout validation fails - payment method preserved
|
|
- [ ] Network error during transaction creation
|
|
- [ ] User switches payment methods (when multiple available)
|
|
- [ ] Mobile viewport - payment section responsive
|
|
|
|
### Integration Tests:
|
|
- [ ] End-to-end COD flow
|
|
- [ ] Order appears in Dashboard
|
|
- [ ] Staff can fulfill COD order
|
|
- [ ] Multiple payment methods display correctly
|
|
|
|
---
|
|
|
|
## 9. FUTURE ENHANCEMENTS
|
|
|
|
### Phase 2 (Post-MVP):
|
|
- [ ] Add Bank Transfer payment method
|
|
- [ ] Payment method icons
|
|
- [ ] Save payment preference for logged-in users
|
|
|
|
### Phase 3 (Advanced):
|
|
- [ ] Bitcoin (manual) payment method
|
|
- [ ] Bitcoin (automated) via custom handler
|
|
- [ ] Payment Apps integration (Stripe, etc.)
|
|
|
|
---
|
|
|
|
## 10. NOTES
|
|
|
|
### Why No Metadata:
|
|
- Saleor has native Transaction objects
|
|
- Transactions are typed and validated
|
|
- Appear in Dashboard automatically
|
|
- Support proper lifecycle (NOT_CHARGED → CHARGED)
|
|
|
|
### Why Simple Type (Not App):
|
|
- COD doesn't need async processing
|
|
- No external API to integrate
|
|
- No PCI compliance requirements
|
|
- Manual verification by staff
|
|
|
|
### Compatibility:
|
|
- Current architecture supports Payment Apps later
|
|
- Can add Stripe/PayPal as `type: 'app'` without breaking COD
|
|
- Bitcoin can be added as `type: 'async'` when ready
|
|
|
|
---
|
|
|
|
**Last Updated:** March 29, 2026
|
|
**Next Review:** After Phase 1 completion |