1379 lines
40 KiB
Markdown
1379 lines
40 KiB
Markdown
# core-midtrans-cifo - Technical Specification
|
|
|
|
**Author:** BMad
|
|
**Date:** 2025-11-25
|
|
**Project Level:** Quick-Flow (2 Stories)
|
|
**Change Type:** UX Enhancement + Bug Fix
|
|
**Development Context:** Brownfield - Payment Flow Improvements
|
|
|
|
---
|
|
|
|
## Context
|
|
|
|
### Available Documents
|
|
|
|
**Loaded Documents:**
|
|
- ✅ **Problem-Solution Analysis** (`problem-solution-2025-11-25.md`) - Comprehensive problem analysis by Dr. Quinn identifying 3 interconnected payment flow issues with systematic root cause analysis and 15 evaluated solutions
|
|
- ✅ **Project Codebase** - Existing React + TypeScript + Midtrans integration
|
|
|
|
**Project Type:** Brownfield - Existing functional payment application
|
|
|
|
**Key Context:**
|
|
- Target users: Non-tech-savvy customers (ibu-ibu awam)
|
|
- Platform: Mobile-first web application
|
|
- Payment Gateway: Midtrans (1 VA per transaction constraint)
|
|
- Current Issues: Duplicate VA generation, poor post-payment UX, inadequate error handling
|
|
|
|
### Project Stack
|
|
|
|
**Frontend Stack:**
|
|
- **React** 19.1.1 - Latest React with modern hooks and concurrent features
|
|
- **TypeScript** 5.9.3 - Type-safe development
|
|
- **Vite** 7.1.7 - Fast build tool and dev server
|
|
- **React Router DOM** 7.9.5 - Client-side routing
|
|
- **TailwindCSS** 4.1.17 - Utility-first CSS framework
|
|
- **Framer Motion** 12.23.24 - Animation library
|
|
- **React Hook Form** 7.66.0 - Form state management
|
|
- **TanStack React Query** 5.90.7 - Server state management and data fetching
|
|
- **Axios** 1.13.2 - HTTP client
|
|
|
|
**Backend Stack:**
|
|
- **Express** 5.1.0 - Node.js web framework
|
|
- **Midtrans Client** 1.4.3 - Official Midtrans SDK for payment processing
|
|
- **CORS** 2.8.5 - Cross-origin resource sharing
|
|
- **dotenv** 17.2.3 - Environment variable management
|
|
|
|
**Development Tools:**
|
|
- **ESLint** 9.36.0 - Code linting
|
|
- **Prettier** 3.6.2 - Code formatting
|
|
- **TypeScript ESLint** 8.45.0 - TypeScript-specific linting rules
|
|
|
|
**Project Type:** Vite + React + TypeScript SPA with Express backend
|
|
|
|
### Existing Codebase Structure
|
|
|
|
**Directory Organization:**
|
|
```
|
|
src/
|
|
├── features/ (16 feature modules) - Feature-based architecture
|
|
├── pages/ (6 pages) - Route-level components
|
|
├── components/ (3 shared components) - Reusable UI components
|
|
├── services/ (API services) - Backend communication layer
|
|
├── lib/ (utilities) - Helper functions and utilities
|
|
└── app/ (app config) - Application configuration
|
|
```
|
|
|
|
**Architecture Pattern:** Feature-based modular architecture
|
|
- Each feature is self-contained with its own components, hooks, and logic
|
|
- Shared components in `/components` for cross-feature reusability
|
|
- Centralized API services in `/services`
|
|
- Utility functions in `/lib`
|
|
|
|
**Styling Approach:** TailwindCSS utility classes
|
|
- Responsive mobile-first design
|
|
- Custom design system via `tailwind.config.ts`
|
|
|
|
**State Management:**
|
|
- React Query for server state
|
|
- React Hook Form for form state
|
|
- React hooks (useState, useEffect) for local component state
|
|
|
|
---
|
|
|
|
## The Change
|
|
|
|
### Problem Statement
|
|
|
|
**Core Problem:** Mobile-first payment application untuk non-tech-savvy users (ibu-ibu awam) mengalami critical UX failures dan poor state management yang menyebabkan:
|
|
|
|
1. **Duplicate VA Generation** - Users click generate VA button multiple times during 3-5 second delay, triggering HTTP 409 errors with technical error messages
|
|
2. **Post-Payment Confusion** - After successful payment, users are redirected to status page with no clear next steps, causing them to press back button which triggers invalid transaction states
|
|
3. **Poor Error Handling** - HTTP errors (409, 404) displayed as technical messages; invalid states show "Rp 0" instead of helpful recovery options
|
|
|
|
**Business Impact:**
|
|
- Abandoned transactions → lost revenue
|
|
- High support ticket volume
|
|
- User frustration and distrust
|
|
- Poor mobile UX for primary user demographic
|
|
|
|
**Root Causes Identified:**
|
|
1. Lack of defensive UX design patterns (no loading states, no button disable)
|
|
2. Poor React lifecycle management (useEffect re-triggering on navigation)
|
|
3. Missing error handling framework (no user-friendly messages, no recovery paths)
|
|
|
|
### Proposed Solution
|
|
|
|
**Phase 1: Quick Wins Bundle** - Implement 5 high-impact, low-risk solutions organized into 2 user stories:
|
|
|
|
**Story 1: Prevent Duplicate VA Generation & Improve Feedback**
|
|
- Solution #1: Button State Management - Disable button during processing
|
|
- Solution #2: Request Debouncing - 500ms debounce on VA generation
|
|
- Solution #3: User-Friendly Error Messages - Map HTTP codes to bahasa Indonesia
|
|
- Solution #4: Loading Overlay - Full-screen overlay with clear messaging
|
|
|
|
**Story 2: Improve Post-Payment UX**
|
|
- Solution #5: Auto-Redirect After Success - 5-second countdown with clear CTA
|
|
|
|
**Expected Impact:** Solves 70-80% of payment flow issues with minimal risk
|
|
|
|
### Scope
|
|
|
|
**In Scope:**
|
|
|
|
✅ **Story 1: Prevent Duplicate VA Generation & Improve Feedback**
|
|
1. Implement button disable/enable logic on VA generation button
|
|
2. Add loading spinner to button during processing
|
|
3. Implement 500ms debounce on VA generation function
|
|
4. Create full-screen loading overlay component
|
|
5. Map HTTP 409 → "Kode pembayaran Anda sudah dibuat! Klik di sini untuk melihat"
|
|
6. Map HTTP 404 → "Terjadi kesalahan. Silakan coba lagi"
|
|
7. Add "Coba Lagi" recovery button on error states
|
|
8. Add "Lihat Kode Pembayaran" button on 409 errors
|
|
|
|
✅ **Story 2: Improve Post-Payment UX**
|
|
1. Implement 5-second countdown timer on payment success page
|
|
2. Add "Anda akan diarahkan ke dashboard dalam X detik..." message
|
|
3. Add "Kembali Sekarang" button for impatient users
|
|
4. Implement auto-redirect logic to dashboard/home after countdown
|
|
|
|
✅ **Cross-Story Requirements**
|
|
1. Mobile-first responsive design (primary focus)
|
|
2. Bahasa Indonesia for all user-facing text
|
|
3. Consistent with existing TailwindCSS design system
|
|
4. Accessible (keyboard navigation, screen reader friendly)
|
|
|
|
**Out of Scope:**
|
|
|
|
❌ **Phase 2 Solutions** (future work):
|
|
- Navigation guards (useEffect cleanup)
|
|
- Modal-based success page
|
|
- Progressive loading states
|
|
- Transaction state machine
|
|
- Idempotency key implementation
|
|
|
|
❌ **Backend Changes:**
|
|
- Midtrans API modifications
|
|
- Database schema changes
|
|
- Backend validation logic
|
|
|
|
❌ **Complete Redesign:**
|
|
- Single-page payment flow
|
|
- Optimistic UI patterns
|
|
- Guided tour/onboarding
|
|
|
|
---
|
|
|
|
## Implementation Details
|
|
|
|
### Source Tree Changes
|
|
|
|
**Files to CREATE:**
|
|
|
|
1. **`src/components/LoadingOverlay.tsx`** - NEW
|
|
- Full-screen loading overlay component
|
|
- Props: `isLoading: boolean`, `message: string`
|
|
- Semi-transparent backdrop with centered spinner and message
|
|
|
|
2. **`src/components/CountdownRedirect.tsx`** - NEW
|
|
- Countdown timer component for auto-redirect
|
|
- Props: `seconds: number`, `onComplete: () => void`, `destination: string`
|
|
- Display countdown with "Kembali Sekarang" button
|
|
|
|
3. **`src/lib/errorMessages.ts`** - NEW
|
|
- Error message mapping utility
|
|
- Function: `mapErrorToUserMessage(error: AxiosError): string`
|
|
- Maps HTTP status codes to user-friendly Indonesian messages
|
|
|
|
4. **`src/lib/debounce.ts`** - NEW
|
|
- Debounce utility function
|
|
- Function: `debounce<T>(func: T, delay: number): T`
|
|
- Generic debounce implementation for click handlers
|
|
|
|
**Files to MODIFY:**
|
|
|
|
1. **`src/features/payment/components/PaymentMethodSelector.tsx`** (or equivalent)
|
|
- ADD: Button disable logic (disabled state during VA generation)
|
|
- ADD: Loading spinner on button
|
|
- ADD: Debounce wrapper on generateVA handler
|
|
- ADD: LoadingOverlay integration
|
|
- MODIFY: Error handling to use mapErrorToUserMessage
|
|
|
|
2. **`src/features/payment/pages/PaymentSuccessPage.tsx`** (or equivalent)
|
|
- ADD: CountdownRedirect component
|
|
- ADD: Auto-redirect logic after 5 seconds
|
|
- MODIFY: Layout to include countdown timer and CTA button
|
|
|
|
3. **`src/features/payment/hooks/useGenerateVA.ts`** (or create if doesn't exist)
|
|
- ADD: Loading state management
|
|
- ADD: Error state with user-friendly messages
|
|
- ADD: Button disable logic
|
|
- MODIFY: Error handling to use mapErrorToUserMessage
|
|
|
|
**Files to ADD TESTS:**
|
|
|
|
1. **`src/components/__tests__/LoadingOverlay.test.tsx`** - CREATE
|
|
2. **`src/components/__tests__/CountdownRedirect.test.tsx`** - CREATE
|
|
3. **`src/lib/__tests__/errorMessages.test.ts`** - CREATE
|
|
4. **`src/lib/__tests__/debounce.test.ts`** - CREATE
|
|
|
|
### Technical Approach
|
|
|
|
**1. Button State Management (Solution #1)**
|
|
|
|
**Approach:** Use React state to track loading status and disable button during API call
|
|
|
|
```typescript
|
|
const [isGenerating, setIsGenerating] = useState(false);
|
|
|
|
const handleGenerateVA = async () => {
|
|
setIsGenerating(true);
|
|
try {
|
|
await generateVAAPI();
|
|
} finally {
|
|
setIsGenerating(false);
|
|
}
|
|
};
|
|
|
|
<button disabled={isGenerating}>
|
|
{isGenerating ? <Spinner /> : 'Generate VA'}
|
|
</button>
|
|
```
|
|
|
|
**Why:** Simple, effective, uses existing React patterns
|
|
|
|
---
|
|
|
|
**2. Request Debouncing (Solution #2)**
|
|
|
|
**Approach:** Wrap VA generation handler with debounce utility (500ms delay)
|
|
|
|
```typescript
|
|
import { debounce } from '@/lib/debounce';
|
|
|
|
const debouncedGenerateVA = useMemo(
|
|
() => debounce(handleGenerateVA, 500),
|
|
[]
|
|
);
|
|
```
|
|
|
|
**Why:** Prevents rapid successive clicks, complements button disable
|
|
|
|
---
|
|
|
|
**3. User-Friendly Error Messages (Solution #3)**
|
|
|
|
**Approach:** Create error mapping utility that translates HTTP codes to Indonesian
|
|
|
|
```typescript
|
|
// src/lib/errorMessages.ts
|
|
export const mapErrorToUserMessage = (error: AxiosError): string => {
|
|
if (error.response?.status === 409) {
|
|
return "Kode pembayaran Anda sudah dibuat! Klik di sini untuk melihat";
|
|
}
|
|
if (error.response?.status === 404) {
|
|
return "Terjadi kesalahan. Silakan coba lagi";
|
|
}
|
|
return "Terjadi kesalahan. Silakan coba lagi";
|
|
};
|
|
```
|
|
|
|
**Why:** Centralized error handling, easy to maintain and extend
|
|
|
|
---
|
|
|
|
**4. Loading Overlay (Solution #4)**
|
|
|
|
**Approach:** Create reusable LoadingOverlay component with Framer Motion animations
|
|
|
|
```typescript
|
|
// src/components/LoadingOverlay.tsx
|
|
export const LoadingOverlay = ({ isLoading, message }) => {
|
|
if (!isLoading) return null;
|
|
|
|
return (
|
|
<motion.div
|
|
initial={{ opacity: 0 }}
|
|
animate={{ opacity: 1 }}
|
|
className="fixed inset-0 bg-black/50 flex items-center justify-center z-50"
|
|
>
|
|
<div className="bg-white p-6 rounded-lg">
|
|
<Spinner />
|
|
<p>{message}</p>
|
|
</div>
|
|
</motion.div>
|
|
);
|
|
};
|
|
```
|
|
|
|
**Why:** Prevents interaction during processing, clear visual feedback
|
|
|
|
---
|
|
|
|
**5. Auto-Redirect After Success (Solution #5)**
|
|
|
|
**Approach:** Use countdown timer with useEffect and setTimeout
|
|
|
|
```typescript
|
|
// src/components/CountdownRedirect.tsx
|
|
export const CountdownRedirect = ({ seconds, onComplete, destination }) => {
|
|
const [countdown, setCountdown] = useState(seconds);
|
|
|
|
useEffect(() => {
|
|
if (countdown === 0) {
|
|
onComplete();
|
|
return;
|
|
}
|
|
|
|
const timer = setTimeout(() => {
|
|
setCountdown(c => c - 1);
|
|
}, 1000);
|
|
|
|
return () => clearTimeout(timer);
|
|
}, [countdown, onComplete]);
|
|
|
|
return (
|
|
<div>
|
|
<p>Anda akan diarahkan ke {destination} dalam {countdown} detik...</p>
|
|
<button onClick={onComplete}>Kembali Sekarang</button>
|
|
</div>
|
|
);
|
|
};
|
|
```
|
|
|
|
**Why:** Clear user guidance, option for impatient users, prevents back button confusion
|
|
|
|
### Existing Patterns to Follow
|
|
|
|
**React Patterns:**
|
|
- Functional components with hooks (no class components)
|
|
- Custom hooks for reusable logic (e.g., `useGenerateVA`)
|
|
- TypeScript for type safety
|
|
- Props interfaces defined with `interface` keyword
|
|
|
|
**Styling Patterns:**
|
|
- TailwindCSS utility classes
|
|
- Responsive design with mobile-first breakpoints (`sm:`, `md:`, `lg:`)
|
|
- Custom colors and spacing from `tailwind.config.ts`
|
|
- Framer Motion for animations (already in use)
|
|
|
|
**State Management Patterns:**
|
|
- React Query for API calls and server state
|
|
- React Hook Form for form state
|
|
- Local useState for component-specific state
|
|
|
|
**Error Handling Patterns:**
|
|
- Try-catch blocks for async operations
|
|
- Error states in components
|
|
- User-friendly error messages (to be improved by this change)
|
|
|
|
**File Naming Conventions:**
|
|
- PascalCase for components: `LoadingOverlay.tsx`
|
|
- camelCase for utilities: `errorMessages.ts`
|
|
- Test files: `ComponentName.test.tsx`
|
|
|
|
### Integration Points
|
|
|
|
**1. Midtrans API Integration**
|
|
- **Location:** `src/services/midtrans.ts` (or similar)
|
|
- **Integration:** VA generation API call
|
|
- **Changes:** Wrap with loading state, error handling, debounce
|
|
|
|
**2. React Query Integration**
|
|
- **Usage:** Manage VA generation API state
|
|
- **Pattern:** Use `useMutation` for VA generation
|
|
- **Changes:** Add onMutate (loading), onError (error messages), onSuccess (redirect)
|
|
|
|
**3. React Router Integration**
|
|
- **Usage:** Navigate to success page, auto-redirect after payment
|
|
- **Pattern:** Use `useNavigate` hook
|
|
- **Changes:** Implement programmatic navigation in CountdownRedirect
|
|
|
|
**4. TailwindCSS Design System**
|
|
- **Integration:** All new components use Tailwind classes
|
|
- **Consistency:** Match existing color scheme, spacing, typography
|
|
- **Responsive:** Mobile-first breakpoints
|
|
|
|
**5. Framer Motion Animations**
|
|
- **Usage:** LoadingOverlay fade-in animation
|
|
- **Pattern:** `motion.div` with initial/animate props
|
|
- **Consistency:** Match existing animation timing and easing
|
|
|
|
---
|
|
|
|
## Development Context
|
|
|
|
### Relevant Existing Code
|
|
|
|
**Payment Feature Module:**
|
|
- **Location:** `src/features/payment/` (assumed based on feature-based architecture)
|
|
- **Components:** PaymentMethodSelector, PaymentSuccessPage (names may vary)
|
|
- **Hooks:** Likely has custom hooks for payment logic
|
|
- **Services:** API calls to Midtrans via backend
|
|
|
|
**Reference Patterns:**
|
|
- Check existing components in `src/components/` for styling patterns
|
|
- Review existing API calls in `src/services/` for error handling patterns
|
|
- Look at existing hooks for state management patterns
|
|
|
|
**Key Files to Review Before Implementation:**
|
|
1. Payment method selection component (where VA generation button lives)
|
|
2. Payment success/status page component
|
|
3. Existing API service layer for Midtrans calls
|
|
4. Existing error handling utilities (if any)
|
|
|
|
### Dependencies
|
|
|
|
**Framework/Libraries:**
|
|
|
|
**Production Dependencies (Already Installed):**
|
|
- `react@19.1.1` - Core React library
|
|
- `react-dom@19.1.1` - React DOM rendering
|
|
- `react-router-dom@7.9.5` - Routing
|
|
- `@tanstack/react-query@5.90.7` - Server state management
|
|
- `axios@1.13.2` - HTTP client
|
|
- `framer-motion@12.23.24` - Animations
|
|
- `tailwindcss@4.1.17` - Styling
|
|
- `clsx@2.1.1` - Conditional class names
|
|
- `tailwind-merge@3.3.1` - Merge Tailwind classes
|
|
|
|
**Development Dependencies (Already Installed):**
|
|
- `typescript@5.9.3` - TypeScript compiler
|
|
- `vite@7.1.7` - Build tool
|
|
- `eslint@9.36.0` - Linting
|
|
- `prettier@3.6.2` - Code formatting
|
|
|
|
**No New Dependencies Required** - All solutions use existing stack
|
|
|
|
### Internal Modules
|
|
|
|
**Modules to Create:**
|
|
- `@/components/LoadingOverlay` - Loading overlay component
|
|
- `@/components/CountdownRedirect` - Countdown redirect component
|
|
- `@/lib/errorMessages` - Error message mapping utility
|
|
- `@/lib/debounce` - Debounce utility function
|
|
|
|
**Modules to Import:**
|
|
- `@/services/midtrans` (or equivalent) - Midtrans API service
|
|
- `react-router-dom` - useNavigate hook
|
|
- `@tanstack/react-query` - useMutation hook
|
|
- `framer-motion` - motion components
|
|
- `clsx` or `tailwind-merge` - Conditional styling
|
|
|
|
### Configuration Changes
|
|
|
|
**No Configuration Changes Required**
|
|
|
|
All solutions work within existing configuration:
|
|
- ✅ No new environment variables
|
|
- ✅ No Vite config changes
|
|
- ✅ No TailwindCSS config changes
|
|
- ✅ No ESLint/Prettier config changes
|
|
- ✅ No package.json changes (no new dependencies)
|
|
|
|
### Existing Conventions (Brownfield)
|
|
|
|
**Code Style:**
|
|
- **TypeScript:** Strict mode enabled
|
|
- **Quotes:** Single quotes (based on Prettier config)
|
|
- **Semicolons:** Yes (TypeScript default)
|
|
- **Indentation:** 2 spaces
|
|
- **Line Length:** 80-100 characters (Prettier default)
|
|
|
|
**Component Patterns:**
|
|
- Functional components with TypeScript interfaces for props
|
|
- Named exports preferred
|
|
- Props interface named `ComponentNameProps`
|
|
|
|
**Import Organization:**
|
|
- React imports first
|
|
- Third-party libraries second
|
|
- Internal imports last
|
|
- Absolute imports using `@/` alias
|
|
|
|
**Error Handling:**
|
|
- Try-catch for async operations
|
|
- Error boundaries for component errors (if implemented)
|
|
- User-friendly error messages (to be improved)
|
|
|
|
**Testing:**
|
|
- Test files co-located with components in `__tests__/` folder
|
|
- File naming: `ComponentName.test.tsx`
|
|
- Framework: Likely Vitest (Vite's test framework) or Jest
|
|
|
|
### Test Framework & Standards
|
|
|
|
**Test Framework:** Vitest (recommended for Vite projects) or Jest
|
|
|
|
**Test File Patterns:**
|
|
- Location: `src/components/__tests__/` or `src/lib/__tests__/`
|
|
- Naming: `ComponentName.test.tsx` or `utilityName.test.ts`
|
|
- Structure: Describe blocks for component/function, it blocks for test cases
|
|
|
|
**Testing Strategy:**
|
|
- Unit tests for utilities (`debounce`, `errorMessages`)
|
|
- Component tests for UI components (`LoadingOverlay`, `CountdownRedirect`)
|
|
- Integration tests for payment flow (optional, recommended)
|
|
|
|
**Coverage Requirements:**
|
|
- Aim for 80%+ coverage on new code
|
|
- All utility functions must have tests
|
|
- All new components must have basic render tests
|
|
|
|
---
|
|
|
|
## Implementation Stack
|
|
|
|
**Runtime Environment:**
|
|
- Node.js 20.x (recommended for Express 5.x)
|
|
- Browser: Modern browsers with ES2020+ support
|
|
|
|
**Frontend Stack:**
|
|
- React 19.1.1
|
|
- TypeScript 5.9.3
|
|
- Vite 7.1.7
|
|
- TailwindCSS 4.1.17
|
|
- Framer Motion 12.23.24
|
|
- React Router DOM 7.9.5
|
|
- TanStack React Query 5.90.7
|
|
- Axios 1.13.2
|
|
|
|
**Backend Stack:**
|
|
- Express 5.1.0
|
|
- Midtrans Client 1.4.3
|
|
|
|
**Development Tools:**
|
|
- ESLint 9.36.0
|
|
- Prettier 3.6.2
|
|
- TypeScript ESLint 8.45.0
|
|
|
|
**Testing:**
|
|
- Vitest (recommended) or Jest
|
|
- React Testing Library (for component tests)
|
|
|
|
---
|
|
|
|
## Technical Details
|
|
|
|
### Story 1: Prevent Duplicate VA Generation & Improve Feedback
|
|
|
|
**Technical Implementation Details:**
|
|
|
|
**1. Button Disable Logic**
|
|
- State variable: `isGenerating: boolean`
|
|
- Set to `true` on button click, `false` on API response (success or error)
|
|
- Button `disabled` attribute bound to `isGenerating`
|
|
- Visual feedback: Show spinner when `isGenerating === true`
|
|
|
|
**2. Debounce Implementation**
|
|
- Debounce delay: 500ms
|
|
- Implementation: Custom debounce utility using setTimeout
|
|
- Applied to: VA generation click handler
|
|
- Edge case: Clear timeout on component unmount
|
|
|
|
**3. Error Message Mapping**
|
|
- HTTP 409 → "Kode pembayaran Anda sudah dibuat! Klik di sini untuk melihat"
|
|
- HTTP 404 → "Terjadi kesalahan. Silakan coba lagi"
|
|
- HTTP 500 → "Terjadi kesalahan server. Silakan coba lagi nanti"
|
|
- Network error → "Tidak dapat terhubung ke server. Periksa koneksi internet Anda"
|
|
- Default → "Terjadi kesalahan. Silakan coba lagi"
|
|
|
|
**4. Loading Overlay**
|
|
- Z-index: 50 (above all content)
|
|
- Backdrop: Semi-transparent black (`bg-black/50`)
|
|
- Content: White card with spinner and message
|
|
- Animation: Fade in (200ms) using Framer Motion
|
|
- Message: "Sedang membuat kode pembayaran..."
|
|
- Accessibility: Focus trap, ESC key to cancel (optional)
|
|
|
|
**5. Recovery Buttons**
|
|
- "Coba Lagi" button on all errors → Retry VA generation
|
|
- "Lihat Kode Pembayaran" button on 409 error → Navigate to existing VA view
|
|
- "Kembali" button on errors → Navigate back to payment method selection
|
|
|
|
### Story 2: Improve Post-Payment UX
|
|
|
|
**Technical Implementation Details:**
|
|
|
|
**1. Countdown Timer**
|
|
- Initial value: 5 seconds
|
|
- Update interval: 1 second (1000ms)
|
|
- Implementation: useEffect with setTimeout
|
|
- Cleanup: Clear timeout on unmount
|
|
- Display format: "Anda akan diarahkan ke dashboard dalam {X} detik..."
|
|
|
|
**2. Auto-Redirect**
|
|
- Trigger: When countdown reaches 0
|
|
- Destination: Dashboard or home page (configurable)
|
|
- Method: `useNavigate()` from react-router-dom
|
|
- Fallback: Manual "Kembali Sekarang" button
|
|
|
|
**3. Manual Redirect Button**
|
|
- Label: "Kembali Sekarang"
|
|
- Action: Immediately navigate to destination (skip countdown)
|
|
- Styling: Primary button style (prominent, easy to find)
|
|
- Position: Below countdown message
|
|
|
|
**Performance Considerations:**
|
|
- Debounce prevents excessive API calls
|
|
- Loading overlay prevents UI interaction during processing
|
|
- Countdown timer uses single setTimeout (not setInterval) for better performance
|
|
|
|
**Security Considerations:**
|
|
- No sensitive data in error messages
|
|
- Error messages don't reveal system internals
|
|
- Rate limiting handled by backend (out of scope)
|
|
|
|
**Accessibility Considerations:**
|
|
- Loading overlay has proper ARIA labels
|
|
- Countdown timer announced by screen readers
|
|
- Buttons have clear labels and keyboard navigation
|
|
- Focus management during loading states
|
|
|
|
---
|
|
|
|
## Development Setup
|
|
|
|
**Prerequisites:**
|
|
- Node.js 20.x installed
|
|
- npm or yarn package manager
|
|
- Git for version control
|
|
|
|
**Initial Setup (if not already done):**
|
|
|
|
```bash
|
|
# 1. Clone repository (if not already cloned)
|
|
git clone <repository-url>
|
|
cd core-midtrans-cifo
|
|
|
|
# 2. Install dependencies
|
|
npm install
|
|
|
|
# 3. Set up environment variables
|
|
cp .env.example .env
|
|
# Edit .env with your Midtrans credentials
|
|
|
|
# 4. Start development server
|
|
npm run dev
|
|
|
|
# 5. Start backend server (in separate terminal)
|
|
npm run server
|
|
```
|
|
|
|
**Development Workflow:**
|
|
|
|
```bash
|
|
# Start Vite dev server (frontend)
|
|
npm run dev
|
|
# Access at http://localhost:5173
|
|
|
|
# Start Express server (backend)
|
|
npm run server
|
|
# Access at http://localhost:3000 (or configured port)
|
|
|
|
# Run linter
|
|
npm run lint
|
|
|
|
# Run tests (when implemented)
|
|
npm test
|
|
|
|
# Build for production
|
|
npm run build
|
|
|
|
# Preview production build
|
|
npm run preview
|
|
```
|
|
|
|
**Environment Variables Required:**
|
|
- `VITE_MIDTRANS_CLIENT_KEY` - Midtrans client key
|
|
- `MIDTRANS_SERVER_KEY` - Midtrans server key (backend)
|
|
- `MIDTRANS_IS_PRODUCTION` - true/false for sandbox vs production
|
|
|
|
---
|
|
|
|
## Implementation Guide
|
|
|
|
### Setup Steps
|
|
|
|
**Pre-Implementation Checklist:**
|
|
|
|
1. ✅ Create feature branch
|
|
```bash
|
|
git checkout -b feature/payment-ux-improvements
|
|
```
|
|
|
|
2. ✅ Verify development environment running
|
|
- Frontend dev server: `npm run dev`
|
|
- Backend server: `npm run server`
|
|
- Both running without errors
|
|
|
|
3. ✅ Review existing payment flow code
|
|
- Locate payment method selection component
|
|
- Locate payment success page component
|
|
- Locate Midtrans API service layer
|
|
- Understand current error handling
|
|
|
|
4. ✅ Set up test environment (if not already)
|
|
- Install Vitest or Jest
|
|
- Configure test runner
|
|
- Create test file structure
|
|
|
|
### Implementation Steps
|
|
|
|
**Story 1: Prevent Duplicate VA Generation & Improve Feedback**
|
|
|
|
**Phase 1: Create Utility Functions (30 minutes)**
|
|
|
|
1. Create `src/lib/debounce.ts`
|
|
- Implement generic debounce function
|
|
- Add TypeScript types
|
|
- Write unit tests
|
|
|
|
2. Create `src/lib/errorMessages.ts`
|
|
- Implement error mapping function
|
|
- Map all HTTP status codes
|
|
- Add recovery action suggestions
|
|
- Write unit tests
|
|
|
|
**Phase 2: Create UI Components (1 hour)**
|
|
|
|
3. Create `src/components/LoadingOverlay.tsx`
|
|
- Implement overlay with backdrop
|
|
- Add Framer Motion animations
|
|
- Add spinner and message
|
|
- Make responsive for mobile
|
|
- Write component tests
|
|
|
|
**Phase 3: Modify Payment Method Component (1.5 hours)**
|
|
|
|
4. Locate and modify payment method selection component
|
|
- Add `isGenerating` state
|
|
- Wrap VA generation handler with debounce
|
|
- Add button disable logic
|
|
- Add loading spinner to button
|
|
- Integrate LoadingOverlay
|
|
- Update error handling to use `mapErrorToUserMessage`
|
|
- Add recovery buttons based on error type
|
|
|
|
**Phase 4: Testing & Refinement (1 hour)**
|
|
|
|
5. Manual testing
|
|
- Test duplicate click prevention
|
|
- Test loading overlay display
|
|
- Test error messages for different error types
|
|
- Test recovery buttons
|
|
- Test on mobile devices
|
|
|
|
6. Fix any issues found during testing
|
|
|
|
**Story 2: Improve Post-Payment UX**
|
|
|
|
**Phase 1: Create Countdown Component (45 minutes)**
|
|
|
|
1. Create `src/components/CountdownRedirect.tsx`
|
|
- Implement countdown timer with useEffect
|
|
- Add auto-redirect logic
|
|
- Add manual redirect button
|
|
- Make responsive for mobile
|
|
- Write component tests
|
|
|
|
**Phase 2: Modify Payment Success Page (45 minutes)**
|
|
|
|
2. Locate and modify payment success page component
|
|
- Integrate CountdownRedirect component
|
|
- Configure redirect destination
|
|
- Update layout for mobile-first
|
|
- Add clear success messaging
|
|
|
|
**Phase 3: Testing & Refinement (30 minutes)**
|
|
|
|
3. Manual testing
|
|
- Test countdown timer accuracy
|
|
- Test auto-redirect functionality
|
|
- Test manual redirect button
|
|
- Test on mobile devices
|
|
- Verify no back button issues
|
|
|
|
4. Fix any issues found during testing
|
|
|
|
### Testing Strategy
|
|
|
|
**Unit Tests:**
|
|
|
|
1. **`debounce.test.ts`**
|
|
- Test debounce delays function execution
|
|
- Test multiple rapid calls only execute once
|
|
- Test cleanup on unmount
|
|
|
|
2. **`errorMessages.test.ts`**
|
|
- Test HTTP 409 maps to correct message
|
|
- Test HTTP 404 maps to correct message
|
|
- Test default error message
|
|
- Test network error message
|
|
|
|
**Component Tests:**
|
|
|
|
3. **`LoadingOverlay.test.tsx`**
|
|
- Test renders when isLoading=true
|
|
- Test doesn't render when isLoading=false
|
|
- Test displays correct message
|
|
- Test animation
|
|
|
|
4. **`CountdownRedirect.test.tsx`**
|
|
- Test countdown decrements every second
|
|
- Test onComplete called when countdown reaches 0
|
|
- Test manual redirect button works
|
|
- Test cleanup on unmount
|
|
|
|
**Integration Tests (Recommended):**
|
|
|
|
5. **Payment Flow Integration Test**
|
|
- Test full VA generation flow with loading states
|
|
- Test error handling and recovery
|
|
- Test success flow with auto-redirect
|
|
|
|
**Manual Testing Checklist:**
|
|
|
|
- [ ] Click VA generation button multiple times rapidly → Only one request sent
|
|
- [ ] Loading overlay appears during VA generation
|
|
- [ ] Error 409 shows user-friendly message with "Lihat Kode" button
|
|
- [ ] Error 404 shows user-friendly message with "Coba Lagi" button
|
|
- [ ] Payment success page shows countdown timer
|
|
- [ ] Auto-redirect works after 5 seconds
|
|
- [ ] Manual "Kembali Sekarang" button works immediately
|
|
- [ ] All flows work on mobile devices (Chrome, Safari)
|
|
- [ ] All text is in Bahasa Indonesia
|
|
- [ ] Keyboard navigation works
|
|
- [ ] Screen reader announces loading states and countdown
|
|
|
|
### Acceptance Criteria
|
|
|
|
**Story 1: Prevent Duplicate VA Generation & Improve Feedback**
|
|
|
|
**AC1: Button Disable During Processing**
|
|
- GIVEN user clicks "Generate VA" button
|
|
- WHEN API request is in progress
|
|
- THEN button is disabled and shows loading spinner
|
|
- AND user cannot click button again
|
|
- AND loading overlay appears with message "Sedang membuat kode pembayaran..."
|
|
|
|
**AC2: Debounce Prevents Rapid Clicks**
|
|
- GIVEN user clicks "Generate VA" button multiple times within 500ms
|
|
- WHEN debounce is active
|
|
- THEN only one API request is sent
|
|
- AND subsequent clicks within 500ms are ignored
|
|
|
|
**AC3: User-Friendly Error Messages**
|
|
- GIVEN VA generation fails with HTTP 409
|
|
- WHEN error is displayed to user
|
|
- THEN message shows "Kode pembayaran Anda sudah dibuat! Klik di sini untuk melihat"
|
|
- AND "Lihat Kode Pembayaran" button is displayed
|
|
- AND clicking button navigates to existing VA view
|
|
|
|
**AC4: Error Recovery Options**
|
|
- GIVEN VA generation fails with any error
|
|
- WHEN error is displayed to user
|
|
- THEN "Coba Lagi" button is displayed
|
|
- AND clicking button retries VA generation
|
|
- AND "Kembali" button is displayed
|
|
- AND clicking button returns to payment method selection
|
|
|
|
**AC5: Loading Overlay Prevents Interaction**
|
|
- GIVEN VA generation is in progress
|
|
- WHEN loading overlay is displayed
|
|
- THEN user cannot interact with page content
|
|
- AND overlay shows clear message in Bahasa Indonesia
|
|
- AND overlay is responsive on mobile devices
|
|
|
|
**Story 2: Improve Post-Payment UX**
|
|
|
|
**AC6: Countdown Timer Display**
|
|
- GIVEN user completes payment successfully
|
|
- WHEN payment success page loads
|
|
- THEN countdown timer shows "Anda akan diarahkan ke dashboard dalam 5 detik..."
|
|
- AND countdown decrements every second (5, 4, 3, 2, 1)
|
|
- AND timer is visible and readable on mobile devices
|
|
|
|
**AC7: Auto-Redirect After Countdown**
|
|
- GIVEN countdown timer reaches 0
|
|
- WHEN timer completes
|
|
- THEN user is automatically redirected to dashboard/home page
|
|
- AND redirect happens smoothly without errors
|
|
|
|
**AC8: Manual Redirect Button**
|
|
- GIVEN countdown timer is active
|
|
- WHEN user clicks "Kembali Sekarang" button
|
|
- THEN user is immediately redirected to dashboard/home page
|
|
- AND countdown is cancelled
|
|
|
|
**AC9: Mobile-First Responsive Design**
|
|
- GIVEN user accesses payment flow on mobile device
|
|
- WHEN any new UI element is displayed
|
|
- THEN all elements are properly sized and positioned for mobile
|
|
- AND all text is readable without zooming
|
|
- AND all buttons are easily tappable (minimum 44x44px)
|
|
|
|
**AC10: Bahasa Indonesia Throughout**
|
|
- GIVEN user interacts with any new UI element
|
|
- WHEN text is displayed
|
|
- THEN all text is in Bahasa Indonesia
|
|
- AND language is appropriate for non-tech-savvy users (ibu-ibu awam)
|
|
- AND no technical jargon is used
|
|
|
|
---
|
|
|
|
## Developer Resources
|
|
|
|
### File Paths Reference
|
|
|
|
**New Files to Create:**
|
|
- `src/components/LoadingOverlay.tsx`
|
|
- `src/components/CountdownRedirect.tsx`
|
|
- `src/lib/errorMessages.ts`
|
|
- `src/lib/debounce.ts`
|
|
- `src/components/__tests__/LoadingOverlay.test.tsx`
|
|
- `src/components/__tests__/CountdownRedirect.test.tsx`
|
|
- `src/lib/__tests__/errorMessages.test.ts`
|
|
- `src/lib/__tests__/debounce.test.ts`
|
|
|
|
**Existing Files to Modify:**
|
|
- `src/features/payment/components/PaymentMethodSelector.tsx` (or equivalent)
|
|
- `src/features/payment/pages/PaymentSuccessPage.tsx` (or equivalent)
|
|
- `src/features/payment/hooks/useGenerateVA.ts` (or create if doesn't exist)
|
|
|
|
**Configuration Files (No Changes):**
|
|
- `package.json` - No new dependencies
|
|
- `vite.config.ts` - No changes
|
|
- `tailwind.config.ts` - No changes
|
|
- `tsconfig.json` - No changes
|
|
|
|
### Key Code Locations
|
|
|
|
**Payment Feature Module:**
|
|
- **Location:** `src/features/payment/` (assumed)
|
|
- **Key Components:**
|
|
- Payment method selection component (contains VA generation button)
|
|
- Payment success/status page component
|
|
- **Key Hooks:**
|
|
- VA generation hook (may need to create)
|
|
- **Key Services:**
|
|
- Midtrans API service (`src/services/midtrans.ts` or similar)
|
|
|
|
**Shared Components:**
|
|
- **Location:** `src/components/`
|
|
- **New Components:**
|
|
- LoadingOverlay
|
|
- CountdownRedirect
|
|
|
|
**Utilities:**
|
|
- **Location:** `src/lib/`
|
|
- **New Utilities:**
|
|
- errorMessages
|
|
- debounce
|
|
|
|
**Important Functions to Locate:**
|
|
1. VA generation API call function
|
|
2. Payment success navigation logic
|
|
3. Error handling in payment flow
|
|
4. Existing loading state management (if any)
|
|
|
|
### Testing Locations
|
|
|
|
**Unit Tests:**
|
|
- `src/lib/__tests__/` - Utility function tests
|
|
- `debounce.test.ts`
|
|
- `errorMessages.test.ts`
|
|
|
|
**Component Tests:**
|
|
- `src/components/__tests__/` - Component tests
|
|
- `LoadingOverlay.test.tsx`
|
|
- `CountdownRedirect.test.tsx`
|
|
|
|
**Integration Tests (Recommended):**
|
|
- `src/features/payment/__tests__/` - Payment flow integration tests
|
|
- `PaymentFlow.integration.test.tsx`
|
|
|
|
**Test Configuration:**
|
|
- `vitest.config.ts` or `jest.config.js` (if exists)
|
|
- Test setup file (if exists)
|
|
|
|
### Documentation to Update
|
|
|
|
**Code Documentation:**
|
|
- [ ] Add JSDoc comments to all new functions and components
|
|
- [ ] Add inline comments for complex logic (debounce, countdown timer)
|
|
- [ ] Add TypeScript interfaces with descriptions
|
|
|
|
**Project Documentation:**
|
|
- [ ] Update `README.md` with new features (optional)
|
|
- [ ] Update API documentation if error responses changed (unlikely)
|
|
- [ ] Add this tech-spec to `docs/` folder for future reference
|
|
|
|
**User Documentation (Optional):**
|
|
- [ ] Update user guide with new payment flow behavior
|
|
- [ ] Update FAQ with error message explanations
|
|
- [ ] Create internal documentation for support team
|
|
|
|
---
|
|
|
|
## UX/UI Considerations
|
|
|
|
**UI Components Affected:**
|
|
|
|
**Story 1:**
|
|
1. **VA Generation Button**
|
|
- MODIFY: Add disabled state styling
|
|
- MODIFY: Add loading spinner
|
|
- ENSURE: Button remains accessible (keyboard, screen reader)
|
|
|
|
2. **Loading Overlay** (NEW)
|
|
- CREATE: Full-screen overlay component
|
|
- DESIGN: Semi-transparent backdrop, centered content
|
|
- ANIMATION: Fade in/out with Framer Motion
|
|
- MOBILE: Full viewport coverage, readable text
|
|
|
|
3. **Error Display** (MODIFY)
|
|
- MODIFY: Replace technical errors with user-friendly messages
|
|
- ADD: Recovery action buttons
|
|
- DESIGN: Clear, non-threatening, helpful tone
|
|
|
|
**Story 2:**
|
|
1. **Payment Success Page**
|
|
- ADD: Countdown timer component
|
|
- ADD: Manual redirect button
|
|
- MODIFY: Layout to accommodate new elements
|
|
- MOBILE: Ensure all elements visible without scrolling
|
|
|
|
**UX Flow Changes:**
|
|
|
|
**Current Flow:**
|
|
1. User selects payment method
|
|
2. User clicks "Generate VA"
|
|
3. (3-5 second delay with no feedback)
|
|
4. VA displayed OR error shown
|
|
5. After payment: Success page with no clear next step
|
|
6. User presses back → Invalid state
|
|
|
|
**New Flow:**
|
|
1. User selects payment method
|
|
2. User clicks "Generate VA"
|
|
3. **Button disables, loading overlay appears**
|
|
4. **"Sedang membuat kode pembayaran..." message shown**
|
|
5. VA displayed OR **user-friendly error with recovery options**
|
|
6. After payment: Success page with **countdown timer**
|
|
7. **Auto-redirect after 5 seconds** OR **user clicks "Kembali Sekarang"**
|
|
8. User lands on dashboard (no back button confusion)
|
|
|
|
**Visual/Interaction Patterns:**
|
|
|
|
**Loading States:**
|
|
- Spinner: Use existing spinner component or create simple CSS spinner
|
|
- Color: Match primary brand color
|
|
- Size: Appropriate for mobile (not too small)
|
|
- Animation: Smooth, not distracting
|
|
|
|
**Error States:**
|
|
- Color: Warning yellow or soft red (not harsh)
|
|
- Icon: Information icon (not scary error icon)
|
|
- Tone: Helpful, not blaming user
|
|
- Actions: Clear buttons with action verbs
|
|
|
|
**Success States:**
|
|
- Color: Success green
|
|
- Icon: Checkmark
|
|
- Tone: Positive, reassuring
|
|
- Actions: Clear next step
|
|
|
|
**Responsive Design:**
|
|
- Mobile-first: Design for 320px width minimum
|
|
- Breakpoints: Use TailwindCSS defaults (sm: 640px, md: 768px, lg: 1024px)
|
|
- Touch targets: Minimum 44x44px for buttons
|
|
- Text size: Minimum 16px for body text (prevents zoom on iOS)
|
|
|
|
**Accessibility:**
|
|
|
|
**Keyboard Navigation:**
|
|
- All interactive elements focusable
|
|
- Logical tab order
|
|
- Visible focus indicators
|
|
- ESC key to dismiss overlay (optional)
|
|
|
|
**Screen Reader:**
|
|
- ARIA labels for loading states
|
|
- ARIA live regions for countdown timer
|
|
- Descriptive button labels
|
|
- Alt text for icons
|
|
|
|
**Color Contrast:**
|
|
- WCAG AA compliance minimum
|
|
- Text on overlay readable
|
|
- Error messages high contrast
|
|
|
|
**User Feedback:**
|
|
|
|
**Loading Feedback:**
|
|
- Visual: Spinner + overlay
|
|
- Text: Clear message in Bahasa Indonesia
|
|
- Duration: Show immediately, hide on response
|
|
|
|
**Error Feedback:**
|
|
- Visual: Error message + icon
|
|
- Text: User-friendly explanation + recovery action
|
|
- Persistence: Stay until user takes action
|
|
|
|
**Success Feedback:**
|
|
- Visual: Success message + checkmark
|
|
- Text: Countdown timer with destination
|
|
- Action: Auto-redirect + manual option
|
|
|
|
---
|
|
|
|
## Testing Approach
|
|
|
|
**Test Framework:** Vitest (recommended for Vite) or Jest
|
|
|
|
**Testing Pyramid:**
|
|
- 70% Unit Tests (utilities, hooks)
|
|
- 20% Component Tests (UI components)
|
|
- 10% Integration Tests (full flows)
|
|
|
|
**Unit Tests:**
|
|
|
|
1. **`debounce.test.ts`**
|
|
```typescript
|
|
describe('debounce', () => {
|
|
it('delays function execution', () => {
|
|
// Test implementation
|
|
});
|
|
|
|
it('only executes once for multiple rapid calls', () => {
|
|
// Test implementation
|
|
});
|
|
|
|
it('clears timeout on cleanup', () => {
|
|
// Test implementation
|
|
});
|
|
});
|
|
```
|
|
|
|
2. **`errorMessages.test.ts`**
|
|
```typescript
|
|
describe('mapErrorToUserMessage', () => {
|
|
it('maps HTTP 409 to user-friendly message', () => {
|
|
// Test implementation
|
|
});
|
|
|
|
it('maps HTTP 404 to user-friendly message', () => {
|
|
// Test implementation
|
|
});
|
|
|
|
it('returns default message for unknown errors', () => {
|
|
// Test implementation
|
|
});
|
|
});
|
|
```
|
|
|
|
**Component Tests:**
|
|
|
|
3. **`LoadingOverlay.test.tsx`**
|
|
```typescript
|
|
describe('LoadingOverlay', () => {
|
|
it('renders when isLoading is true', () => {
|
|
// Test implementation
|
|
});
|
|
|
|
it('does not render when isLoading is false', () => {
|
|
// Test implementation
|
|
});
|
|
|
|
it('displays the provided message', () => {
|
|
// Test implementation
|
|
});
|
|
});
|
|
```
|
|
|
|
4. **`CountdownRedirect.test.tsx`**
|
|
```typescript
|
|
describe('CountdownRedirect', () => {
|
|
it('decrements countdown every second', () => {
|
|
// Test implementation with fake timers
|
|
});
|
|
|
|
it('calls onComplete when countdown reaches 0', () => {
|
|
// Test implementation
|
|
});
|
|
|
|
it('redirects immediately when button clicked', () => {
|
|
// Test implementation
|
|
});
|
|
});
|
|
```
|
|
|
|
**Integration Tests (Recommended):**
|
|
|
|
5. **Payment Flow Integration Test**
|
|
```typescript
|
|
describe('Payment Flow', () => {
|
|
it('prevents duplicate VA generation', () => {
|
|
// Test full flow with multiple clicks
|
|
});
|
|
|
|
it('shows user-friendly error on 409', () => {
|
|
// Test error handling
|
|
});
|
|
|
|
it('auto-redirects after payment success', () => {
|
|
// Test success flow
|
|
});
|
|
});
|
|
```
|
|
|
|
**Coverage Goals:**
|
|
- Overall: 80%+
|
|
- New utilities: 100%
|
|
- New components: 90%+
|
|
- Modified components: 80%+
|
|
|
|
**Manual Testing Checklist:**
|
|
- [ ] Desktop Chrome
|
|
- [ ] Desktop Firefox
|
|
- [ ] Desktop Safari
|
|
- [ ] Mobile Chrome (Android)
|
|
- [ ] Mobile Safari (iOS)
|
|
- [ ] Tablet (iPad)
|
|
- [ ] Slow 3G network simulation
|
|
- [ ] Offline scenario
|
|
- [ ] Keyboard-only navigation
|
|
- [ ] Screen reader (NVDA/JAWS/VoiceOver)
|
|
|
|
---
|
|
|
|
## Deployment Strategy
|
|
|
|
### Deployment Steps
|
|
|
|
**Pre-Deployment:**
|
|
|
|
1. **Code Review**
|
|
- Create pull request from feature branch
|
|
- Request review from team lead
|
|
- Address all review comments
|
|
- Ensure all tests pass
|
|
|
|
2. **QA Testing**
|
|
- Deploy to staging environment
|
|
- QA team tests all acceptance criteria
|
|
- Fix any bugs found
|
|
- Re-test until all criteria pass
|
|
|
|
3. **Merge to Main**
|
|
```bash
|
|
git checkout main
|
|
git merge feature/payment-ux-improvements
|
|
git push origin main
|
|
```
|
|
|
|
**Deployment to Production:**
|
|
|
|
4. **Build Production Bundle**
|
|
```bash
|
|
npm run build
|
|
```
|
|
|
|
5. **Deploy Frontend**
|
|
- Upload `dist/` folder to hosting (Vercel, Netlify, or custom server)
|
|
- Verify environment variables are set
|
|
- Test production build locally with `npm run preview`
|
|
|
|
6. **Deploy Backend (if changes)**
|
|
- No backend changes in Phase 1
|
|
- Backend deployment not required
|
|
|
|
7. **Verify Deployment**
|
|
- Test VA generation on production
|
|
- Test error scenarios
|
|
- Test payment success flow
|
|
- Monitor for errors
|
|
|
|
**Post-Deployment:**
|
|
|
|
8. **Monitor**
|
|
- Watch error logs for 24 hours
|
|
- Monitor user behavior analytics
|
|
- Check support ticket volume
|
|
- Gather user feedback
|
|
|
|
9. **Iterate**
|
|
- Address any issues found
|
|
- Plan Phase 2 improvements based on data
|
|
|
|
### Rollback Plan
|
|
|
|
**If Critical Issues Found:**
|
|
|
|
1. **Immediate Rollback**
|
|
```bash
|
|
# Revert to previous commit
|
|
git revert HEAD
|
|
git push origin main
|
|
|
|
# Rebuild and redeploy
|
|
npm run build
|
|
# Deploy dist/ folder
|
|
```
|
|
|
|
2. **Verify Rollback**
|
|
- Test that old behavior is restored
|
|
- Confirm no errors in logs
|
|
- Notify users if necessary
|
|
|
|
3. **Post-Mortem**
|
|
- Identify what went wrong
|
|
- Fix issues in feature branch
|
|
- Re-test thoroughly
|
|
- Re-deploy when ready
|
|
|
|
**Rollback Triggers:**
|
|
- Critical bug preventing payments
|
|
- Widespread errors (>5% of transactions)
|
|
- Security vulnerability discovered
|
|
- Performance degradation (>2s load time increase)
|
|
|
|
### Monitoring
|
|
|
|
**Metrics to Monitor:**
|
|
|
|
**User Behavior:**
|
|
- VA generation success rate (target: >95%)
|
|
- Error rate (target: <5%)
|
|
- Payment completion rate (target: increase by 10%+)
|
|
- Time on payment success page (target: decrease by 50%)
|
|
- Back button usage after payment (target: decrease by 80%)
|
|
|
|
**Technical Metrics:**
|
|
- API response time (target: <3 seconds)
|
|
- Frontend load time (target: <2 seconds)
|
|
- Error logs (target: <1% error rate)
|
|
- 409 error frequency (target: near zero)
|
|
|
|
**Business Metrics:**
|
|
- Abandoned transaction rate (target: decrease by 20%+)
|
|
- Support ticket volume (target: decrease by 30%+)
|
|
- User satisfaction score (target: increase)
|
|
|
|
**Monitoring Tools:**
|
|
- Google Analytics for user behavior
|
|
- Sentry or similar for error tracking
|
|
- Server logs for API monitoring
|
|
- User feedback surveys
|
|
|
|
**Alert Thresholds:**
|
|
- Error rate >10% → Immediate alert
|
|
- API response time >5s → Warning alert
|
|
- Payment success rate <90% → Critical alert
|
|
|
|
---
|
|
|
|
**End of Technical Specification**
|
|
|
|
This tech-spec provides a comprehensive guide for implementing Phase 1 Quick Wins Bundle (2 stories, 5 solutions) to improve payment flow UX for non-tech-savvy users in a brownfield Midtrans payment application.
|