Files
manoon-headless/docs/COD-IMPLEMENTATION-PLAN.md
Unchained ff481f18c3 feat: implement Cash on Delivery (COD) payment method
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
2026-03-29 06:02:51 +02:00

8.1 KiB

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

interface PaymentMethod {
  id: string;
  name: string;
  description: string;
  type: 'simple' | 'app';
  fee: number;
  available: boolean;
  availableInChannels: string[];
  icon?: string;
}

COD Transaction Structure

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):

{
  "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):

{
  "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