DevSkill.SSLCommerz 4.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package DevSkill.SSLCommerz --version 4.0.0
                    
NuGet\Install-Package DevSkill.SSLCommerz -Version 4.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="DevSkill.SSLCommerz" Version="4.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DevSkill.SSLCommerz" Version="4.0.0" />
                    
Directory.Packages.props
<PackageReference Include="DevSkill.SSLCommerz" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add DevSkill.SSLCommerz --version 4.0.0
                    
#r "nuget: DevSkill.SSLCommerz, 4.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package DevSkill.SSLCommerz@4.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=DevSkill.SSLCommerz&version=4.0.0
                    
Install as a Cake Addin
#tool nuget:?package=DevSkill.SSLCommerz&version=4.0.0
                    
Install as a Cake Tool

DevSkill.SSLCommerz

A .NET library for integrating with the SSLCommerz payment gateway: payment session requests, order validation, IPN verify_sign verification, and transaction search — fully async, typed, and testable.

Branch Status
main .NET 10
develop .NET 10

Requirements

  • .NET 10 SDK or later (the package targets net10.0)

Installation

dotnet add package DevSkill.SSLCommerz

Configuration

Bind SslCommerzSettings from configuration — this is the single credential source; the client stamps store_id/store_passwd onto every call at send time (credentials never appear on request models).

{
  "SSLCommerz": {
    "StoreId": "your_store_id",
    "StorePassword": "your_store_password",
    "Environment": "Sandbox",
    "SandboxBaseUrl": null,
    "LiveBaseUrl": null
  }
}
Setting Required Default Notes
StoreId yes Store identifier from the SSLCommerz dashboard
StorePassword yes Stamped at send time, never logged
Environment yes Sandbox or Live
SandboxBaseUrl no https://sandbox.sslcommerz.com Override for proxies/test fakes. Must be absolute HTTPS without a query string
LiveBaseUrl no https://securepay.sslcommerz.com Override, same rules

Registration

using DevSkill.SSLCommerz;
using DevSkill.SSLCommerz.Models;

builder.Services.Configure<SslCommerzSettings>(
    builder.Configuration.GetSection("SSLCommerz"));

builder.Services.AddSingleton<IGatewayClient, GatewayClient>();

To configure the underlying HttpClient (timeouts, proxies, resilience), register via the factory instead — the client accepts an injected HttpClient:

builder.Services.AddHttpClient<IGatewayClient, GatewayClient>();

Results and error handling

API calls never throw for transport, HTTP, or provider failures — they return SslCommerzResult<T>:

Member Meaning
Success true when the call succeeded and the payload deserialized
Value The parsed response. Also populated for ProviderFailed results, so the provider's failure payload (e.g. failedreason) stays reachable
RawJson The raw response body, whenever one arrived
Error Category + Message, plus HTTP StatusCode when applicable
SslCommerzErrorCategory Meaning
Transport Timeout or connection failure
HttpError Non-2xx HTTP status (e.g. a 500 HTML error page)
ProviderFailed HTTP 200 but provider status is FAILEDValue still populated
InvalidResponse HTTP 200 body failed to deserialize

Caller errors (null requests, models failing data-annotation validation) throw synchronously before any I/O.

Request a payment session

using DevSkill.SSLCommerz;
using DevSkill.SSLCommerz.Models;

public sealed class CheckoutService(IGatewayClient gateway)
{
    public async Task<string?> StartPaymentAsync(string transactionId, CancellationToken ct = default)
    {
        var request = new TransactionSessionRequestBuilder()
            .AddIntegrationRequiredParameter(new IntegrationRequiredParameter(
                totalAmount: 1750.50m,
                currency: "BDT",
                transactionId: transactionId,
                successUrl: "https://yourapp.com/payment/success",
                failUrl: "https://yourapp.com/payment/fail",
                cancelUrl: "https://yourapp.com/payment/cancel"))
            .AddCustomerInformation(new CustomerInformation(
                customerName: "Rahim Uddin",
                customerEmail: "rahim@example.com",
                customerAddress1: "12 Uttara Sector 4",
                customerCity: "Dhaka",
                customerPostcode: "1230",
                customerCountry: "Bangladesh",
                customerPhone: "+8801700000000"))
            .AddShipmentInformation(new ShipmentInformation(shippingMethod: "NO"))
            .AddProductInformation(new ProductInformation(
                productName: "Dev Skill Course",
                productCategory: "Education",
                productProfile: "general"))
            .Build();

        var result = await gateway.RequestSessionAsync(request, ct);

        return result.Success ? result.Value!.GatewayPageUrl : null;
    }
}

On success, redirect the customer to result.Value.GatewayPageUrl. Money fields serialize with invariant culture (1750.50), and optional numeric fields left unset (Vat, DiscountAmount, NumberOfItem, …) are simply not sent.

Validate a transaction (Order Validation)

The authoritative money-state check — run it on your success/cancel/IPN callbacks before fulfilling anything:

var result = await gateway.ValidateTransactionAsync(
    new ValidationRequest { ValidationId = valId }, ct);

if (result.Success
    && result.Value!.Status == "VALID"
    && result.Value.TransactionId == expectedTransactionId
    && result.Value.CurrencyType == "BDT"
    && result.Value.Amount == expectedAmount)
{
    // The payment is real and belongs to this order — fulfil it
}

Handle an IPN

Verify the verify_sign checksum over the raw posted fields (never over a re-serialized model), then parse:

using DevSkill.SSLCommerz;
using DevSkill.SSLCommerz.Models;
using Microsoft.Extensions.Options;

[ApiController]
public sealed class IpnController(
    IOptions<SslCommerzSettings> settings,
    IGatewayClient gateway) : ControllerBase
{
    [HttpPost("/ipn")]
    public async Task<IActionResult> Receive(CancellationToken ct)
    {
        var form = await Request.ReadFormAsync(ct);
        var fields = form.ToDictionary(kv => kv.Key, kv => kv.Value.ToString());

        // 1. Verify the checksum over the raw field dictionary (fail-closed)
        var verifier = new VerifySignVerifier(settings.Value);
        if (!verifier.Verify(fields))
        {
            return Unauthorized();
        }

        // 2. Parse the notification into a typed model
        var notification = PaymentNotificationParser.Parse(fields);

        // 3. A valid signature is necessary, NOT sufficient — re-check money
        //    state via Order Validation before acting on it
        var validation = await gateway.ValidateTransactionAsync(
            new ValidationRequest { ValidationId = notification.ValidationId! }, ct);

        return Ok();
    }
}

JSON-body notifications are also supported: PaymentNotificationParser.ParseJson(body).

Query transactions

Search by session key or transaction id — for pending-payment sweeps and late-completion hunts:

var result = await gateway.QueryTransactionAsync(
    new TransactionQuery { TransactionId = "DSAB12CD" }, ct);

if (result.Success)
{
    foreach (var element in result.Value!)
    {
        // element.Status (VALID / PENDING / CANCELLED / FAILED, ...) is
        // transaction data for your reconciliation logic to decide on
    }
}

Upgrading from 3.x

v4 is a breaking overhaul:

  • GatewayClient is now async behind IGatewayClient (RequestSessionAsync / ValidateTransactionAsync / QueryTransactionAsync) and returns SslCommerzResult<T> instead of tuples.
  • Credentials come from SslCommerzSettings only — the Credential type and the builder's credential argument are gone.
  • Environments.DevelopmentSslCommerzEnvironment.Sandbox.
  • Optional numeric request fields are nullable; unset fields are no longer sent as 0.
  • Transport/HTTP/provider failures return error results instead of throwing during deserialization.

License

See License.txt.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.0.1 222 8/19/2026
4.0.0 101 8/19/2026
2.0.105 556 1/11/2024
2.0.104 657 9/21/2023
2.0.103 260 9/21/2023
2.0.33 587 6/22/2023
2.0.31 2,131 3/2/2022
2.0.30 675 3/1/2022
2.0.29 1,120 1/17/2022
2.0.3 476 12/5/2022
1.0.39 571 11/18/2021
1.0.38 500 11/18/2021
1.0.37 502 11/18/2021
1.0.36 476 11/18/2021
1.0.26 543 12/12/2021
1.0.25 498 12/5/2021
1.0.23 498 12/5/2021
1.0.22 484 12/5/2021
1.0.21 506 12/5/2021
1.0.20 496 12/5/2021
Loading failed

v4.0.0 — breaking overhaul: async IGatewayClient with a typed SslCommerzResult result type (transport/HTTP/provider errors never throw); credentials stamped from SslCommerzSettings (single source); configurable sandbox/live base URLs; IPN verify_sign verifier and payment-notification parser; transaction query API; optional numeric request fields are nullable and unset fields are no longer sent; invariant-culture money formatting; SslCommerzEnvironment { Sandbox, Live } replaces Environments { Development, Live }.