A comprehensive example of integrating VNPay payment gateway with Next.js 15, featuring server actions, IPN handling, and a modern responsive UI built with Tailwind CSS.
- Next.js 15 with App Router and Server Actions
- Server-side VNPay Integration - All VNPay operations happen server-side
- Dual Payment Options for demo environments:
- π Direct Redirect: Production-ready flow to VNPay gateway
- ποΈ URL Preview: Generate and display payment URL for inspection, copying, or opening in new tab
- TypeScript for type safety and better development experience
- Tailwind CSS with modern responsive design
- Clean Architecture with organized component structure
- IPN (Instant Payment Notification) handling
- Payment verification and result display with print functionality
- Bank selection with dynamic bank list
- Responsive design optimized for all devices
- Vietnamese language support with proper SEO
- Resource Links with color-coded styling
- Error Boundary for robust error handling
- Reusable UI Components following best practices
- Next.js 15 - React framework with App Router
- TypeScript - Type safety
- Tailwind CSS - Utility-first CSS framework
- VNPay Package v2.4.2 - VNPay integration
- Heroicons - Beautiful SVG icons
- clsx - Conditional class names
- tailwind-merge - Merge Tailwind classes
- Production-ready payment flow
- Immediately redirects to VNPay gateway
- Best for live applications
- Perfect for development and testing
- Shows the generated payment URL
- Copy URL to clipboard functionality
- Open URL in new tab
- Inspect payment parameters
src/
βββ app/
β βββ actions/
β β βββ payment.ts # Server actions for VNPay operations
β βββ api/
β β βββ payment/
β β βββ ipn/
β β βββ route.ts # IPN webhook handler
β βββ payment/
β β βββ return/
β β βββ page.tsx # Payment result page
β βββ page.tsx # Main homepage with payment form
β βββ layout.tsx # Root layout with metadata
β βββ globals.css # Global styles
β βββ sitemap.ts # SEO sitemap generation
βββ components/
β βββ ui/
β β βββ Button.tsx # Reusable button component
β β βββ Input.tsx # Form input component
β β βββ Select.tsx # Select dropdown component
β β βββ Textarea.tsx # Textarea component
β β βββ PrintButton.tsx # Print functionality component
β β βββ index.ts # Barrel exports
β βββ layout/
β β βββ Header.tsx # App header with branding
β β βββ Footer.tsx # Footer with author info
β β βββ index.ts # Barrel exports
β βββ payment/
β β βββ PaymentForm.tsx # Main payment form
β β βββ PaymentResult.tsx # Payment result display
β β βββ InfoPanels.tsx # Information panels
β β βββ index.ts # Barrel exports
β βββ common/
β βββ ErrorBoundary.tsx # Error boundary component
βββ lib/
β βββ vnpay.ts # VNPay configuration and utilities
β βββ utils.ts # Utility functions (cn, etc.)
βββ types/
β βββ payment.ts # TypeScript type definitions
βββ public/ # Static assets and faviconsCreate a .env.local file in the project root:
# VNPay Configuration
VNPAY_TMN_CODE=your_tmn_code_here
VNPAY_SECURE_SECRET=your_secure_secret_here
VNPAY_RETURN_URL=http://localhost:3000/payment/return
VNPAY_IPN_URL=http://localhost:3000/api/payment/ipn
VNPAY_HOST=https://sandbox.vnpayment.vn
VNPAY_TEST_MODE=trueNote: For demo purposes, the app works with fallback values even without environment variables.
-
Clone the repository:
git clone https://github.com/lehuygiang28/vnpay-nextjs-fullstack-example.git cd vnpay-nextjs-fullstack-example -
Install dependencies:
npm install
-
Set up environment variables (optional for demo):
# Copy and edit with your VNPay credentials cp .env.example .env.local -
Run the development server:
npm run dev
-
Open your browser: Navigate to http://localhost:3000
-
Register with VNPay:
- Visit VNPay Merchant Portal
- Complete merchant registration
- Get your TMN Code and Secure Secret
-
Configure webhooks:
- Set IPN URL to:
your-domain.com/api/payment/ipn - Set Return URL to:
your-domain.com/payment/return
- Set IPN URL to:
createPaymentUrl()- Creates payment and redirects to VNPaygeneratePaymentUrlDemo()- Generates payment URL for inspectiongetBankListAction()- Fetches available banksgetProductCodeOptions()- Provides product categoriesgetLocaleOptions()- Language options
- Handles VNPay instant payment notifications
- Verifies payment authenticity using HMAC-SHA512
- Updates order status in your system
- Responds with appropriate status codes
- Verifies payment results from VNPay
- Displays comprehensive transaction details
- Handles success/failure/error states
- Print functionality for receipts
- Beautiful responsive UI with status indicators
- Server-side VNPay client configuration
- Utility functions for payment processing
- IP detection and amount formatting
- Error handling and validation
- UI Components: Reusable components with TypeScript interfaces
- Layout Components: Header, Footer with consistent styling
- Payment Components: Specialized components for payment flow
- Utility Functions: Helper functions for class merging and formatting
β Correct - Type-Only Imports:
// Single type import
import { type Bank } from "vnpay";
// Multiple type imports
import type { Bank, QueryDr, Refund } from "vnpay";
// Using in component
interface PaymentFormProps {
banks: Bank[];
onPayment: (data: QueryDr) => void;
}β Incorrect - Regular Imports:
// This will cause errors in browser
import { Bank, QueryDr } from "vnpay";Why? The VNPay package contains Node.js-specific code that cannot run in the browser. Type-only imports ensure you get TypeScript type checking without including the runtime code in your client bundle.
NEXT_REDIRECT error in the console. This is expected behavior - it's how Next.js handles redirect() in Server Actions, not an actual error.
// This is normal behavior in Server Actions
try {
await createPaymentUrl(formData);
} catch (error) {
// NEXT_REDIRECT errors are expected when redirect() is called
if (error.digest?.includes("NEXT_REDIRECT")) {
// This means the redirect is working correctly
return;
}
// Handle actual errors here
}- β Server-side only VNPay processing
- β HMAC-SHA512 signature verification
- β Route Handlers for secure API endpoints
- β Server Actions for form processing
- β IP address validation
- β Transaction amount verification
- β Order ID uniqueness
- β Input validation and sanitization
- β HTTPS enforcement for production
- β Secure environment variables
- π± Fully responsive design for all devices
- π― Modern gradient backgrounds and shadows
- π Interactive form elements with proper validation
- π Copy to clipboard functionality
- π Color-coded resource links (GitHub, NPM, VNPay, API Docs)
- β‘ Loading states and comprehensive error handling
- π Beautiful icons from Heroicons
- π¨ Professional styling with Tailwind CSS
- βΏ Accessibility features with ARIA labels
- π¨οΈ Print functionality for payment receipts
- π VNPay Node.js Package
- π¦ NPM Package
- π GitHub Repository
- π VNPay API Documentation
- β‘ Next.js 15 Documentation
- π¨ Tailwind CSS Documentation
The application includes comprehensive demo mode with sandbox environment:
- Test Environment: Uses VNPay sandbox for safe testing
- Sample Data: Pre-filled form with test values (50,000 VND)
- Test Cards: Use VNPay provided test card numbers
- URL Generation: Inspect payment URLs before redirecting
- IPN Testing: Webhook endpoints work in development
- Error Handling: Comprehensive error states and recovery
- π Vietnamese language optimization
- π Structured data for search engines
- πΌοΈ Open Graph and Twitter card meta tags
- π€ Sitemap generation for better indexing
- π± Mobile-first responsive design
- β‘ Optimized performance with Next.js 15
- π Proper internal linking structure
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License. See the LICENSE file for details.
- GitHub: @lehuygiang28
- Email: lehuygiang28@gmail.com
Made with β€οΈ for the Vietnamese developer community
- VNPay for providing the payment gateway services
- Next.js team for the amazing React framework
- Tailwind CSS for the utility-first CSS framework
- Heroicons for the beautiful icon set
- Vercel for Next.js hosting and deployment platform