This project is a complete implementation of SSLCommerz payment gateway integration using modern Next.js server architecture.
It includes:
- Checkout and order creation
- SSLCommerz session initiation
- Secure IPN verification and payment validation
- Order/payment persistence with PostgreSQL + Prisma
- Success / fail / cancel handling
- Framework: Next.js 16 (App Router)
- Language: TypeScript
- UI: React 19, Tailwind CSS 4, shadcn/ui
- Database: PostgreSQL
- ORM: Prisma 7 (generated client in
src/generated/prisma) - Payment Gateway: SSLCommerz (Sandbox + Live)
- Validation: Zod
- Runtime: Node.js (for payment APIs/IPN route)
src/
actions/
payment/
initiate-payment.ts # Creates order + starts SSL session
sslcommerz/
payments.ts # Gateway/validation API calls
ipn.ts # Signature verification + validation flow
app/
api/
payment/
ipn/route.ts # IPN endpoint (security + DB updates)
payment/
success/page.tsx
fail/page.tsx
cancel/page.tsx
lib/
prisma.ts # Shared Prisma singleton
global-config.ts # Env-based app/payment config
prisma/
schema.prisma # Full ecommerce + payment schema
seed.ts # Product seed script
Create a .env.local file in project root:
# App
NEXT_PUBLIC_APP_URL=http://localhost:3000
# Database
DATABASE_URL=postgresql://USER:PASSWORD@HOST:PORT/DB_NAME
# SSLCommerz
SSLCOMMERZ_STORE_ID=your_store_id
SSLCOMMERZ_STORE_PASSWORD=your_store_password
SSLCOMMERZ_ENV=sandbox
# Optional security hardening (comma-separated IP list)
SSLCOMMERZ_IPN_ALLOWLIST=
# Optional custom secret for your own transaction logic
SSLCOMMERZ_TRANSACTION_SECRET=For local development keep
SSLCOMMERZ_ENV=sandbox.
npm installGenerate Prisma client:
npm run prisma:generateRun migrations:
npm run prisma:migrateSeed sample products (optional but recommended):
npm run prisma:seedStart dev server:
npm run devOpen http://localhost:3000.
npm run dev- start development servernpm run build- production buildnpm run start- start production servernpm run lint- run ESLintnpm run prisma:generate- generate Prisma clientnpm run prisma:migrate- run Prisma migrations in devnpm run prisma:seed- seed product data
- User submits checkout form.
sslInitiatePayment(src/actions/payment/initiate-payment.ts):- Validates input with Zod
- Creates customer/address/order/order-items/payment rows in DB
- Calls SSLCommerz initiation API
- Stores
sessionkeyand updates order toPROCESSING - Returns
GatewayPageURL
- User completes payment on SSLCommerz hosted page.
- SSLCommerz calls IPN endpoint:
POST /api/payment/ipn. src/app/api/payment/ipn/route.ts:- Validates payload shape and size
- Optionally checks IP allowlist
- Verifies IPN signature (
verify_sign,verify_key) - Calls SSLCommerz validation API (
val_id) - Cross-checks amount/currency/transaction ID
- Upserts payment details and updates order status atomically
- User is redirected to success/fail/cancel pages.
Key models in prisma/schema.prisma:
Order- transaction-level order info and status lifecyclePayment- one order can have multiple payment attemptsRefund- tracks refund lifecycleCustomer,Address,OrderItem,Product,ProductVariant
Important enums:
OrderStatus:PENDING,PROCESSING,PAID,FAILED, etc.PaymentStatus:INITIATED,VALID,VALIDATED,FAILED, etc.RefundStatus:PENDING,PROCESSING,REFUNDED,FAILED
This project includes the following protections:
- Signature verification using SSLCommerz
verify_signflow - Validation API confirmation using
val_id - Amount/currency/tran_id cross-check before DB updates
- Optional IP allowlisting via
SSLCOMMERZ_IPN_ALLOWLIST - Basic idempotency guard in memory for duplicate IPN retries
In multi-instance production deployment, replace in-memory idempotency with Redis or a strict DB-level idempotency strategy.
SSLCommerz needs a publicly reachable ipn_url. For local testing, expose your app using a tunnel (for example, ngrok or Cloudflare Tunnel), then set:
NEXT_PUBLIC_APP_URLto your tunnel URL- SSLCommerz callback URLs (
success_url,fail_url,cancel_url,ipn_url) to that same base URL
Before go-live:
- Set
SSLCOMMERZ_ENV=live - Use live
SSLCOMMERZ_STORE_IDandSSLCOMMERZ_STORE_PASSWORD - Update domain and callback URLs to production HTTPS domain
- Configure real IP allowlist for IPN endpoint
- Monitor logs and payment/order status transitions
- Ensure
.env.localexists and includesDATABASE_URL.
- Verify store credentials and environment (
sandboxvslive). - Confirm your server can reach SSLCommerz endpoints.
- Use a public tunnel and update callback URLs.
- Check SSLCommerz merchant panel callback settings if needed.
- Check IPN logs and signature validation output.
- Confirm allowlist is not blocking SSLCommerz IP.
- Move idempotency from in-memory map to Redis/DB
- Add structured logging and alerting for failed validations
- Add retry-safe background reconciliation job for pending payments
- Enforce strict network/security policies on payment endpoints
- Add admin visibility for payment attempts and risk flags
Use this project as a learning reference for SSLCommerz integration. Add your own project license based on your distribution needs.

