Payments SDK
Providers

eSewa

Signed ePay v2 form checkout, returns, and verification.

@payments-sdk/esewa implements eSewa ePay v2 signed form checkout, transaction verification, and signed browser returns.

Install and configure

npm install @payments-sdk/payments @payments-sdk/esewa
import { esewa } from '@payments-sdk/esewa';

const provider = esewa({
  productCode: process.env.ESEWA_PRODUCT_CODE!,
  secretKey: process.env.ESEWA_SECRET_KEY!,
  environment: 'sandbox',
});

Use environment: 'sandbox' with sandbox credentials and switch to 'production' only with production credentials and registered return URLs. The application supplies credentials; the package does not read environment variables automatically.

Form checkout

const result = await payments.checkout({
  provider: 'esewa',
  amount: 1500_00,
  currency: 'NPR',
  reference: 'order_123',
  providerOptions: {
    successUrl: 'https://merchant.example/returns/esewa',
    failureUrl: 'https://merchant.example/payments/failed',
    taxAmount: 0,
    productServiceCharge: 0,
    productDeliveryCharge: 0,
  },
});

if (result.action.type === 'form') {
  // Render a POST form using result.action.url and result.action.fields.
}

Amounts and optional charges are integer minor units. eSewa signs the formatted total_amount, transaction_uuid, and product_code fields. Persist the exact charged amount when the later verification call will need it.

Browser return

Pass the raw request from the application route:

export async function esewaReturn(request: Request) {
  const returned = await payments.returns.esewa(request);

  // Parse success is not settlement. Verify before fulfilling the order.
  return payments.verify({
    provider: 'esewa',
    reference: returned.reference!,
    providerOptions: { totalAmount: 1500_00 },
  });
}

The return handler decodes and validates eSewa's signed base64 data payload. It also accepts callback URLs where parameters are separated by a second ? and preserves literal + characters in base64 data for compatibility with malformed gateway callbacks.

Verification

Verification requires the exact total charged:

const result = await payments.verify({
  provider: 'esewa',
  reference: 'order_123',
  providerOptions: { totalAmount: 1500_00 },
});

Only eSewa's COMPLETE status becomes succeeded. PENDING remains pending, CANCELED remains cancelled, and NOT_FOUND becomes expired because eSewa uses it for terminated or expired sessions. AMBIGUOUS and unknown statuses remain unknown.

The verification result retains the raw eSewa response and exposes providerData.totalAmount, providerData.transactionUuid, and providerData.refId (eSewa's ref_id) so the application can validate the amount, transaction UUID, and provider reference before settlement. totalAmount preserves eSewa's returned string or number value.

Capabilities and security

eSewa implements checkout, verify, and returns. It does not implement webhooks, refunds, or cancellations. Keep secretKey server-side and treat the return as input to verification, even though its signature is validated.

On this page