Skip to main content

SSLCommerz

SSLCommerz Payment Gateway API v4 integration.

Installation

npm install @foxses/pay-sslcommerz

How It Works

SSLCommerz uses a session-based redirect flow:

  1. Init Session — POST credentials + order info → get GatewayPageURL
  2. Redirect user to GatewayPageURL to choose payment method and pay
  3. Callback — SSLCommerz redirects to success_url / fail_url / cancel_url with val_id
  4. Validate — GET request with val_id to confirm payment is genuine
  5. IPN — Server-to-server notification to ipn_url (optional but recommended)

Configuration

gateway.use("sslcommerz", {
storeId: "YOUR_STORE_ID", // required
storePassword: "YOUR_STORE_PASSWORD", // required
successUrl: "https://yoursite.com/payment/success", // required
failureUrl: "https://yoursite.com/payment/failure", // required
cancelUrl: "https://yoursite.com/payment/cancel", // required
callbackUrl: "https://yoursite.com/payment/ipn", // optional — IPN URL
sandbox: true, // optional, default: true
});
FieldTypeDescription
storeIdstringSSLCommerz store ID
storePasswordstringSSLCommerz store password
successUrlstringRedirect URL on successful payment
failureUrlstringRedirect URL on failed payment
cancelUrlstringRedirect URL when user cancels
callbackUrlstringIPN URL for server-to-server notification
sandboxbooleanUse sandbox environment

Create Payment

const payment = await gateway.createPayment("sslcommerz", {
amount: 500, // required
currency: "BDT", // required — BDT, USD, EUR, etc.
orderId: "ORDER-001", // required — unique (30 chars max)
customerName: "John Doe", // optional
customerEmail: "john@example.com", // optional
customerPhone: "01700000000", // optional
metadata: {
productName: "T-Shirt", // optional
productCategory: "clothing", // optional
productProfile: "physical-goods", // optional
value_a: "custom-data-1", // optional — echoed back in callback
value_b: "custom-data-2", // optional
},
});

Product Profile options: general, physical-goods, non-physical-goods, airline, travel-vertical, telecom-vertical

Response:

{
transactionId: "SESSION_KEY", // SSLCommerz session key
provider: "sslcommerz",
amount: 500,
currency: "BDT",
status: "pending",
checkoutUrl: "https://sandbox.sslcommerz.com/EasyCheckOut/...", // redirect here
}

Verify Payment

Call after SSLCommerz redirects to your successUrl with val_id in query params.

Always pass amount to detect response tampering.

const verified = await gateway.verifyPayment("sslcommerz", {
transactionId: val_id, // from query param: ?val_id=XXX
amount: 500, // recommended — validates amount matches
});

Security: SSLCommerz docs strongly recommend verifying the amount server-side. foxses-pay throws a ProviderError if amounts don't match.

Response:

{
transactionId: "BANK_TRX_ID", // bank_tran_id — save this for refunds
provider: "sslcommerz",
amount: 500,
currency: "BDT",
status: "completed",
}

Get Payment Status

Query status using your own orderId (tran_id):

const status = await gateway.getPaymentStatus("sslcommerz", "ORDER-001");

Refund Payment

Requires bank_tran_id from the verifyPayment response:

const refund = await gateway.refundPayment("sslcommerz", {
transactionId: bank_tran_id, // from verifyPayment response
amount: 500, // full or partial amount
reason: "Customer request",
});

Response:

{
refundId: "REFUND_REF_ID",
transactionId: "BANK_TRX_ID",
amount: 500,
status: "refunded",
}

Callback Handling

Success URL

SSLCommerz redirects to your successUrl with query params:

GET /payment/success?val_id=XXX&tran_id=ORDER-001&status=VALID&...
app.get("/payment/success", async (req, res) => {
const { val_id, tran_id, amount } = req.query;

const verified = await gateway.verifyPayment("sslcommerz", {
transactionId: val_id as string,
amount: parseFloat(amount as string),
});

if (verified.status === "completed") {
// update DB using tran_id
res.redirect("/order/confirmed");
}
});

IPN (Server-to-Server)

SSLCommerz also POSTs to your ipn_url:

app.post("/payment/ipn", async (req, res) => {
const { val_id, status, tran_id } = req.body;

if (status === "VALID" || status === "VALIDATED") {
const verified = await gateway.verifyPayment("sslcommerz", {
transactionId: val_id,
});
// update DB
}

res.sendStatus(200);
});

Sandbox Test Cards

Card TypeNumberExpiryCVV
VISA411111111111111112/26111
Mastercard511111111111111112/26111
Amex37111111111111112/26111

Mobile Banking OTP: 111111 or 123456

Whitelisted IPs (Production)

Add these IPs to your server firewall:

103.26.139.81
103.26.139.148
103.132.153.81
103.132.153.148

Production Endpoints

EnvironmentBase URL
Sandboxhttps://sandbox.sslcommerz.com
Productionhttps://securepay.sslcommerz.com

Credentials

Get from SSLCommerz Developer Portal