npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

payload-sep-gateway-plugin

v2.0.0

Published

Payload CMS plugin for SEP (Saman Electronic Payment) gateway integration with correct REST API implementation

Readme

payload-sep-gateway-plugin

A comprehensive Payload CMS plugin for SEP (Saman Electronic Payment) gateway integration with correct REST API implementation. This plugin provides complete payment processing capabilities including collections, API handlers, and utilities for Iranian e-commerce applications.

⚠️ Important: Version 2.0 Breaking Changes

Version 2.0 includes major updates to align with the correct SEP Gateway documentation:

  • Fixed Token Creation: Now uses correct REST API endpoint (https://sep.shaparak.ir/onlinepg/onlinepg)
  • Fixed Payment URL: Updated to correct OnlinePG endpoint (https://sep.shaparak.ir/OnlinePG/OnlinePG)
  • Fixed Verification: Uses proper verification endpoint with correct parameters
  • Updated Parameters: Changed from MID to TerminalId throughout
  • Added Reverse Transactions: Complete refund/reversal functionality
  • Enhanced Security: Proper amount validation and double-spend prevention

Features

  • 🏪 E-Commerce Collections: Orders, Products, and Payment Transactions
  • 💳 Correct SEP Gateway Integration: Token-based payments with proper REST API
  • 🔐 Transaction Verification: Real-time payment verification with SEP
  • 🔄 Reverse Transactions: Complete refund/reversal functionality
  • 📊 Admin Dashboard: Full Payload CMS admin interface
  • 🧪 Test Mode: Built-in testing capabilities
  • 🌐 TypeScript Support: Full type safety and IntelliSense
  • 🔧 Highly Configurable: Customizable collections and fields
  • 🛡️ Security Features: Amount validation, double-spend prevention, IP whitelist support

Installation

npm install payload-sep-gateway-plugin@^2.0.0
# or
yarn add payload-sep-gateway-plugin@^2.0.0

Quick Start

1. Basic Setup

// payload.config.ts
import { buildConfig } from 'payload/config'
import { sepGatewayPlugin } from 'payload-sep-gateway-plugin'

export default buildConfig({
  // ... your existing config
  plugins: [
    sepGatewayPlugin({
      testMode: true, // Set to false for production
      sepConfig: {
        terminalId: 'your-terminal-id', // Changed from mid
        redirectUrl: 'https://yourdomain.com/api/sep/payment/callback',
      },
    }),
  ],
})

2. Environment Variables

# SEP Gateway Configuration (Updated)
SEP_TERMINAL_ID=your_terminal_id_here
SEP_REDIRECT_URL=https://yourdomain.com/api/sep/payment/callback

# Optional: Custom URLs (uses correct defaults)
SEP_PAYMENT_URL=https://sep.shaparak.ir/OnlinePG/OnlinePG
SEP_TOKEN_URL=https://sep.shaparak.ir/onlinepg/onlinepg
SEP_VERIFY_URL=https://sep.shaparak.ir/verifyTxnRandomSessionkey/ipg/VerifyTransaction
SEP_REVERSE_URL=https://sep.shaparak.ir/verifyTxnRandomSessionkey/ipg/ReverseTransaction

3. API Routes Setup

Create API routes in your Next.js app:

// app/api/sep/payment/initiate/route.ts
import { POST } from 'payload-sep-gateway-plugin/api-routes/initiate'
export { POST }

// app/api/sep/payment/token/route.ts
import { POST } from 'payload-sep-gateway-plugin/api-routes/token'
export { POST }

// app/api/sep/payment/callback/route.ts
import { POST } from 'payload-sep-gateway-plugin/api-routes/callback'
export { POST }

// app/api/sep/payment/verify/route.ts
import { POST } from 'payload-sep-gateway-plugin/api-routes/verify'
export { POST }

// app/api/sep/payment/reverse/route.ts
import { POST } from 'payload-sep-gateway-plugin/api-routes/reverse'
export { POST }

Configuration

Plugin Configuration Options

interface SEPPluginConfig {
  // Enable test mode for development
  testMode?: boolean
  
  // SEP Gateway Configuration (Updated)
  sepConfig?: {
    terminalId?: string        // Changed from mid
    redirectUrl?: string
    paymentUrl?: string
    tokenUrl?: string         // New
    verifyUrl?: string
    reverseUrl?: string       // New
  }
  
  // Custom collection slugs
  collections?: {
    orders?: string
    paymentTransactions?: string
    products?: string
  }
  
  // Custom field configurations
  fields?: {
    orders?: any[]
    paymentTransactions?: any[]
    products?: any[]
  }
  
  // API endpoints configuration
  api?: {
    prefix?: string
    endpoints?: {
      initiate?: boolean
      token?: boolean
      callback?: boolean
      verify?: boolean
      reverse?: boolean        // New
    }
  }
  
  // UI Configuration
  ui?: {
    showGatewayInfo?: boolean
    labels?: {
      orders?: string
      paymentTransactions?: string
      products?: string
    }
  }
}

Advanced Configuration Example

sepGatewayPlugin({
  testMode: process.env.NODE_ENV === 'development',
  sepConfig: {
    terminalId: process.env.SEP_TERMINAL_ID,
    redirectUrl: process.env.SEP_REDIRECT_URL,
  },
  collections: {
    orders: 'custom-orders',
    paymentTransactions: 'custom-transactions',
    products: 'custom-products',
  },
  fields: {
    orders: [
      {
        name: 'customField',
        type: 'text',
        admin: {
          description: 'Custom order field',
        },
      },
    ],
  },
  api: {
    prefix: '/api/custom-sep',
    endpoints: {
      initiate: true,
      token: true,
      callback: true,
      verify: true,
      reverse: true, // Enable reverse transactions
    },
  },
  ui: {
    showGatewayInfo: true,
    labels: {
      orders: 'سفارشات',
      paymentTransactions: 'تراکنش‌های پرداخت',
      products: 'محصولات',
    },
  },
})

Usage Examples

Correct SEP Payment Integration

// Correct token-based payment (Recommended)
const handlePayment = async (ev: React.FormEvent) => {
  ev.preventDefault()
  setLoading(true)
  setError('')

  const amount = 12000 // amount in Rials
  const resNum = 'order-12345' // your unique order id

  try {
    // 1) Ask your server to create token
    const response = await fetch('/api/sep/payment/token', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ 
        amount, 
        resNum,
        redirectUrl: `${window.location.origin}/api/sep/payment/callback`
      })
    })
    
    const data = await response.json()
    
    if (!response.ok) {
      throw new Error(data.error || data.errorDesc || 'Token request failed')
    }

    // 2) Build a form and submit to gateway (post token)
    const form = document.createElement('form')
    form.method = 'POST'
    form.action = 'https://sep.shaparak.ir/OnlinePG/OnlinePG'
    form.style.display = 'none'

    const tokenInput = document.createElement('input')
    tokenInput.name = 'Token'
    tokenInput.value = data.token
    form.appendChild(tokenInput)

    const getMethodInput = document.createElement('input')
    getMethodInput.name = 'GetMethod'
    getMethodInput.value = '' // or 'true' if you want GET behavior
    form.appendChild(getMethodInput)

    document.body.appendChild(form)
    form.submit()

  } catch (err) {
    setError(err instanceof Error ? err.message : 'Payment failed')
  } finally {
    setLoading(false)
  }
}

Payment Callback Handling

// Handle payment callback from SEP
const handlePaymentCallback = async () => {
  const urlParams = new URLSearchParams(window.location.search)
  
  const callbackData = {
    State: urlParams.get('State'),
    RefNum: urlParams.get('RefNum'),
    ResNum: urlParams.get('ResNum'),
    TraceNo: urlParams.get('TraceNo'),
    SecurePan: urlParams.get('SecurePan'),
  }

  const response = await fetch('/api/sep/payment/callback', {
    method: 'POST',
    body: new URLSearchParams(callbackData),
  })

  const result = await response.json()
  
  if (result.success) {
    // Payment processed successfully
    console.log('Payment processed:', result.message)
  } else {
    // Handle error
    console.error('Payment error:', result.error)
  }
}

Reverse Transaction (Refund)

// Reverse a transaction
const reverseTransaction = async (transactionId: string) => {
  const response = await fetch('/api/sep/payment/reverse', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ transactionId }),
  })

  const result = await response.json()
  
  if (result.success) {
    console.log('Transaction reversed:', result.data.message)
  } else {
    console.error('Reversal failed:', result.error)
  }
}

Collections

Orders Collection

The Orders collection manages customer orders with the following fields:

  • orderNumber: Auto-generated unique order number
  • customer: Customer information (name, email, phone, address)
  • items: Array of order items with product, quantity, and pricing
  • totalAmount: Total order amount in Rials
  • status: Order status (pending, processing, paid, failed, cancelled, refunded)
  • paymentTransaction: Reference to associated payment transaction
  • notes: Additional order notes

Payment Transactions Collection

The Payment Transactions collection tracks SEP gateway interactions:

  • order: Reference to associated order
  • referenceNumber: Unique transaction reference
  • reservationNumber: SEP reservation number
  • amount: Transaction amount in Rials
  • terminalId: SEP terminal ID (updated from merchantId)
  • status: Transaction status
  • sepResponse: SEP gateway response data
  • verificationResult: Verification result code
  • verificationStatus: Verification status
  • reverseResult: Reverse transaction result (new)
  • reverseStatus: Reverse transaction status (new)
  • errorMessage: Error message if transaction failed

Products Collection

The Products collection manages your product catalog:

  • name: Product name
  • description: Rich text product description
  • price: Product price in Rials
  • image: Main product image
  • images: Additional product images
  • category: Product category
  • sku: Stock Keeping Unit
  • stock: Available stock quantity
  • isActive: Whether product is active
  • isDigital: Whether product is digital
  • weight: Product weight in grams
  • dimensions: Product dimensions
  • tags: Product tags for search
  • meta: SEO metadata

Test Mode

The plugin includes comprehensive test mode capabilities:

sepGatewayPlugin({
  testMode: true, // Enable test mode
})

In test mode:

  • Mock responses are generated instead of real SEP calls
  • No real money is charged
  • All verification results are simulated
  • Test scenarios can be easily configured

API Reference

Payment Initiation

POST /api/sep/payment/initiate

// Request Body
{
  orderId: string
  amount: number
  redirectUrl: string
}

// Response
{
  success: boolean
  data?: {
    paymentTransactionId: string
    reservationNumber: string
    paymentFormData: Record<string, string>
    paymentUrl: string
  }
  error?: string
}

Token Payment (Recommended)

POST /api/sep/payment/token

// Request Body
{
  orderId: string
  amount: number
  redirectUrl: string
}

// Response
{
  success: boolean
  data?: {
    token: string
    paymentTransactionId: string
    reservationNumber: string
    paymentUrl: string
  }
  error?: string
}

Payment Callback

POST /api/sep/payment/callback

// Request Body (FormData)
{
  State: string
  RefNum: string
  ResNum: string
  TraceNo: string
  SecurePan?: string
  MID?: string
  Status?: string
  RRN?: string
  Amount?: number
  Wage?: number
  HashedCardNumber?: string
}

// Response
{
  success: boolean
  message?: string
  error?: string
}

Transaction Verification

POST /api/sep/payment/verify

// Request Body
{
  transactionId: string
}

// Response
{
  success: boolean
  data?: {
    verificationResult: number
    message: string
  }
  error?: string
}

Reverse Transaction (New)

POST /api/sep/payment/reverse

// Request Body
{
  transactionId: string
}

// Response
{
  success: boolean
  data?: {
    reverseResult: number
    message: string
  }
  error?: string
}

Security Features

IP Whitelist Support

  • Your server IP must be registered with SEP for token-based calls
  • Configure terminalId for proper IP whitelist validation

Amount Validation

  • Verifies transaction amounts match expected values
  • Prevents amount manipulation attacks

Double-Spend Prevention

  • Checks RefNum to prevent duplicate processing
  • Stores processed RefNums in database

Proper Verification

  • Always calls VerifyTransaction before marking payments as successful
  • Validates all transaction details server-to-server

Error Handling

The plugin provides comprehensive error handling with Persian error messages:

// SEP Error Codes
const errorMessages = {
  [0]: 'Success',
  [-1]: 'TP_ERROR - خطا در بررسی صحت رسید دیجیتالی',
  [-2]: 'ACCOUNTS_DONT_MATCH - خطا در تأیید رسید دیجیتالی',
  [-3]: 'BAD_INPUT - خطا در پردازش رسید دیجیتالی',
  // ... more error codes
}

// Transaction States
const stateMessages = {
  'OK': 'تراکنش موفق',
  'Canceled By User': 'تراکنش توسط خریدار کنسل شد',
  'No Sufficient Funds': 'موجودی ناکافی',
  // ... more states
}

Migration Guide (v1.x to v2.x)

Breaking Changes

  1. Parameter Names: Change mid to terminalId in configuration
  2. Environment Variables: Update SEP_MID to SEP_TERMINAL_ID
  3. API Endpoints: All endpoints now use correct SEP URLs
  4. Verification Response: Updated to handle new response format
  5. Dependencies: Removed axios and soap, now uses native fetch

Migration Steps

  1. Update package version:

    npm install payload-sep-gateway-plugin@^2.0.0
  2. Update environment variables:

    # Old
    SEP_MID=your-merchant-id
       
    # New
    SEP_TERMINAL_ID=your-terminal-id
  3. Update configuration:

    // Old
    sepConfig: {
      mid: process.env.SEP_MID,
    }
       
    // New
    sepConfig: {
      terminalId: process.env.SEP_TERMINAL_ID,
    }
  4. Update frontend code to use correct form submission (see examples above)

Contributing

Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.

License

MIT License - see LICENSE file for details.

Support

For support and questions:

Changelog

v2.0.0 (Breaking Changes)

  • Fixed Token Creation: Now uses correct REST API endpoint
  • Fixed Payment URL: Updated to correct OnlinePG endpoint
  • Fixed Verification: Uses proper verification endpoint
  • Updated Parameters: Changed from MID to TerminalId
  • Added Reverse Transactions: Complete refund/reversal functionality
  • Enhanced Security: Amount validation and double-spend prevention
  • Removed Dependencies: No longer requires axios or soap
  • Updated Examples: All examples now show correct implementation

v1.0.0

  • Initial release
  • Basic SEP gateway integration
  • E-commerce collections
  • Test mode support
  • TypeScript support