Datatrans.Sdk 2.0.0

dotnet add package Datatrans.Sdk --version 2.0.0
                    
NuGet\Install-Package Datatrans.Sdk -Version 2.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="Datatrans.Sdk" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Datatrans.Sdk" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Datatrans.Sdk" />
                    
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 Datatrans.Sdk --version 2.0.0
                    
#r "nuget: Datatrans.Sdk, 2.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 Datatrans.Sdk@2.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=Datatrans.Sdk&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Datatrans.Sdk&version=2.0.0
                    
Install as a Cake Tool

Datatrans.Sdk — Datatrans .NET SDK

A strongly-typed, production-ready .NET SDK for the Datatrans Payment API, compatible with .NET 8, .NET 9, and .NET 10. It wraps every documented endpoint behind clean async interfaces, handles authentication, idempotency, and webhook signature validation, and uses System.Text.Json source-generation for zero-reflection serialization.

Both the v1 and v2 transactions APIs are supported behind a single version selector: v1 (DatatransClient.Transactions.V1) has full feature and payment-method coverage and is the recommended default; v2 (DatatransClient.Transactions.V2) is the next-generation API required for Mobile SDK 4.


Table of Contents


Features

  • Full API coverage — all Datatrans v1 endpoints: transactions, aliases, reconciliation, multi-currency, and health check
  • Transactions API v2 — UUID transaction IDs and attempt-based status, for Mobile SDK 4 scenarios
  • Dependency injection — one-line services.AddDatatrans(...) wiring
  • Idempotency support — pass an idempotency key to any mutating operation
  • Webhook security — HMAC-SHA256 validation with constant-time comparison
  • TLS 1.2/1.3 enforcedSocketsHttpHandler is configured at registration time
  • Zero reflection — System.Text.Json source generators throughout
  • Typed exceptionsDatatransAuthenticationException, DatatransValidationException, DatatransApiException
  • Sandbox / Production — switch environments with a single enum value

Requirements

Item Minimum
.NET SDK 8.0
Datatrans merchant account any

Installation

The SDK is referenced as a project reference in this repository. Once published to NuGet, add it with:

dotnet add package Datatrans.Sdk

Or reference the project directly:

<ProjectReference Include="..\src\DTSdk\DTSdk.csproj" />

Quick Start

1. Register in Program.cs

using Datatrans.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

// Register from appsettings.json "Datatrans" section
builder.Services.AddDatatrans(builder.Configuration);

// — OR — configure inline
builder.Services.AddDatatrans(options =>
{
    options.MerchantId  = "<YOUR_MERCHANT_ID>";
    options.Password    = "<YOUR_API_PASSWORD>";
    options.Environment = DatatransEnvironment.Sandbox;
    options.WebhookHmacKey = "your-hmac-hex-key";
});

2. Inject and use DatatransClient

public class PaymentService(DatatransClient datatrans)
{
    public async Task<string> CreatePaymentAsync(decimal amount, string currency, string refno)
    {
        var response = await datatrans.Transactions.V1.InitAsync(new InitTransactionRequest
        {
            Currency = currency,
            Refno    = refno,
            Amount   = (long)(amount * 100), // Datatrans uses minor units (CHF → Rappen)
            PaymentMethods = ["VIS", "ECA"],
            Redirect = new RedirectRequest
            {
                SuccessUrl = "https://yoursite.com/success",
                CancelUrl  = "https://yoursite.com/cancel",
                ErrorUrl   = "https://yoursite.com/error"
            }
        });

        return response.GetRedirectUrl(); // Redirect customer here
    }
}

3. Handle the result

After the customer completes payment and is redirected back, authorize the transaction:

var auth = await datatrans.Transactions.V1.AuthorizeSplitAsync(
    transactionId: 240110170459754479L,
    request: new AuthorizeSplitRequest
    {
        Refno      = refno,
        Amount     = 2000,
        AutoSettle = true
    });

Console.WriteLine($"Auth code: {auth.AcquirerAuthorizationCode}");

Configuration

Add a Datatrans section to appsettings.json:

{
  "Datatrans": {
        "MerchantId":    "<YOUR_MERCHANT_ID>",
        "Password":      "<YOUR_API_PASSWORD>",
        "Environment":   "Sandbox",
        "Timeout":       "00:00:30",
        "WebhookHmacKey":"your-hmac-key-hex-from-dashboard",
        "WebhookAllowedSkew": "00:05:00",
        "EnforceWebhookTimestampOnlyInProduction": false
  }
}
Key Type Default Description
MerchantId string required Your Datatrans merchant ID
Password string required API password from the dashboard
Environment Sandbox | Production Sandbox Target API environment
Timeout TimeSpan 00:00:30 Per-request HTTP timeout
WebhookHmacKey string null Hex HMAC key for webhook validation
WebhookAllowedSkew TimeSpan 00:05:00 Allowed clock skew for webhook timestamp validation. Set to 00:00:00 to disable enforcement.
EnforceWebhookTimestampOnlyInProduction bool false When true, timestamp validation is only enforced when Environment is Production.

Never commit credentials to source control. Use environment variables, Azure Key Vault, AWS Secrets Manager, or ASP.NET Core user secrets.

# Use environment variables
export Datatrans__MerchantId=<YOUR_MERCHANT_ID>
export Datatrans__Password=<YOUR_API_PASSWORD>

Services

All services are accessible through the DatatransClient facade injected via DI:

DatatransClient.Transactions     // ITransactionsApi      — version selector (.V1 / .V2)
DatatransClient.Transactions.V1  // ITransactionService   — 16 methods (v1, numeric IDs)
DatatransClient.Transactions.V2  // ITransactionService   —  9 methods (v2, UUID IDs)
DatatransClient.Aliases          // IAliasService         —  7 methods
DatatransClient.Reconciliations  // IReconciliationService —  2 methods
DatatransClient.MultiCurrency    // IMultiCurrencyService  —  1 method
DatatransClient.HealthCheck      // IHealthCheckService    —  1 method

See the docs/ folder for detailed per-service documentation:

Service Documentation
Transactions (v1) docs/transactions.md
Transactions (v2) docs/transactions-v2.md
Aliases docs/aliases.md
Reconciliation docs/reconciliation.md
Multi-Currency docs/multi-currency.md
Webhooks docs/webhooks.md

Webhook Validation

Datatrans sends POST notifications to your webhook endpoint with a Datatrans-Signature header. Validate it using the injected WebhookSignatureValidator:

[HttpPost("/webhook")]
public async Task<IActionResult> Receive(
    [FromServices] WebhookSignatureValidator validator,
    [FromServices] IOptions<DatatransOptions> options)
{
    Request.EnableBuffering();
    using var reader = new StreamReader(Request.Body, leaveOpen: true);
    var payload   = await reader.ReadToEndAsync();
    var signature = Request.Headers["Datatrans-Signature"].ToString();

    if (!validator.Validate(signature, payload, options.Value.WebhookHmacKey!))
        return Unauthorized();

    // Process payload ...
    return NoContent();
}

See docs/webhooks.md for full details.


Error Handling

All SDK methods throw typed exceptions derived from DatatransException:

DatatransException
└── DatatransApiException              (any non-2xx response)
    ├── DatatransAuthenticationException  (401 / 403)
    └── DatatransValidationException      (INVALID_PROPERTY, INVALID_JSON_PAYLOAD, …)
try
{
    var auth = await datatrans.Transactions.V1.AuthorizeAsync(request);
}
catch (DatatransValidationException ex)
{
    // 400 Bad Request — invalid field value
    Console.WriteLine($"Validation failed: {ex.Code} — {ex.Message}");
}
catch (DatatransAuthenticationException)
{
    // 401/403 — wrong credentials
}
catch (DatatransApiException ex)
{
    // Any other API error (declined, not found, server error…)
    Console.WriteLine($"API error {ex.HttpStatusCode}: {ex.Code}");
}

Every DatatransApiException exposes:

Property Type Description
Code string Datatrans error code (e.g. DECLINED)
Message string Human-readable error message
HttpStatusCode int Raw HTTP status code

Security

  • TLS 1.2 / 1.3 onlySocketsHttpHandler refuses older protocol versions
  • Basic Auth via DelegatingHandler — credentials are never stored in request bodies
  • Webhook HMAC-SHA256 with constant-time comparison — prevents timing attacks
  • No credential loggingDatatransOptions never serializes its Password field
  • Source-generated JSON — no JsonSerializer.Deserialize<object> anywhere

Testing

# Run all unit tests
dotnet test tests/Datatrans.Sdk.Tests/Datatrans.Sdk.Tests.csproj

# With coverage
dotnet test tests/Datatrans.Sdk.Tests/Datatrans.Sdk.Tests.csproj \
  --collect:"XPlat Code Coverage" \
  --results-directory ./coverage

# Run a specific test
dotnet test --filter "FullyQualifiedName~TransactionServiceTests"

The test suite contains 64 unit tests covering:

  • All 16 transaction operations (v1)
  • All 9 transaction operations (v2)
  • All 7 alias operations
  • Reconciliation (single & bulk)
  • Multi-currency rates
  • Health check (ok / non-ok / error)
  • Webhook signature validation (10 scenarios)
  • Full exception hierarchy (401, 403, 400, 422, 404, 500)

Project Structure

DTSdk/
├── src/Datatrans.Sdk/                        # SDK library
│   ├── DatatransClient.cs            # Facade: entry point for consumers
│   ├── DatatransOptions.cs           # Configuration options
│   ├── DatatransEnvironment.cs       # Sandbox / Production enum
│   ├── DependencyInjection/
│   │   └── ServiceCollectionExtensions.cs
│   ├── Http/
│   │   ├── DatatransHttpClient.cs    # Internal HTTP wrapper
│   │   ├── DatatransAuthHandler.cs   # Basic Auth delegating handler
│   │   ├── IdempotencyHandler.cs     # Idempotency-Key header injection
│   │   └── DatatransJsonContext.cs   # STJ source-generation context
│   ├── Services/
│   │   ├── Transactions/
│   │   │   ├── ITransactionsApi.cs / TransactionsApi.cs   # version selector (.V1 / .V2)
│   │   │   ├── V1/ITransactionService.cs / TransactionService.cs
│   │   │   └── V2/ITransactionService.cs / TransactionService.cs
│   │   ├── IAliasService.cs         / AliasService.cs
│   │   ├── IReconciliationService.cs / ReconciliationService.cs
│   │   ├── IMultiCurrencyService.cs  / MultiCurrencyService.cs
│   │   └── IHealthCheckService.cs   / HealthCheckService.cs
│   ├── Models/
│   │   ├── Common/                   # Shared types (Card, Address, detail, etc.)
│   │   ├── Transactions/             # Transaction DTOs: shared + V1/ + V2/
│   │   ├── Requests/                 # Alias / reconciliation request DTOs
│   │   └── Responses/                # Alias / reconciliation / multi-currency response DTOs
│   ├── Exceptions/
│   │   ├── DatatransException.cs
│   │   ├── DatatransApiException.cs
│   │   ├── DatatransAuthenticationException.cs
│   │   └── DatatransValidationException.cs
│   └── Webhooks/
│       └── WebhookSignatureValidator.cs
├── tests/Datatrans.Sdk.Tests/                # xUnit unit tests (64 tests)
│   ├── Helpers/MockHttpMessageHandler.cs
│   ├── TestBase.cs
│   └── Unit/
│       ├── TransactionServiceTests.cs
│       ├── TransactionV2ServiceTests.cs
│       ├── AliasServiceTests.cs
│       ├── ReconciliationServiceTests.cs
│       ├── MultiCurrencyServiceTests.cs
│       ├── HealthCheckServiceTests.cs
│       ├── WebhookSignatureValidatorTests.cs
│       └── ErrorHandlingTests.cs
├── samples/Datatrans.Sdk.Example/            # ASP.NET Core Web API sample
│   ├── Program.cs
│   ├── appsettings.json
│   └── Controllers/
│       ├── TransactionsController.cs
│       ├── TransactionsV2Controller.cs
│       ├── AliasController.cs
│       ├── ReconciliationController.cs
│       ├── MultiCurrencyController.cs
│       └── WebhookController.cs
└── docs/                             # Per-service documentation
    ├── transactions.md
    ├── transactions-v2.md
    ├── aliases.md
    ├── reconciliation.md
    ├── multi-currency.md
    └── webhooks.md

Releasing

Create a Git tag and push it to trigger the release workflow which builds, tests, packs and (optionally) publishes the NuGet package.

Run locally:

# create annotated tag
git tag -a v1.2.3 -m "Release v1.2.3"
# push the tag
git push origin --tags

From the GitHub UI you can also run the release workflow manually: Actions → Release → Run workflow.

To publish to NuGet.org automatically, add your API key to repository Secrets as NUGET_API_KEY (Settings → Secrets → Actions). The release workflow will fail early with a clear message if this secret is missing for non-manual (tag) runs.


CI fallback package version

When the release workflow runs without a tag-derived version (for example, a manual run or a branch-based run), the workflow will create a semver-compatible fallback package version so dotnet pack succeeds. The fallback version format is:

0.0.0-ci-<short-sha>

This is only used for producing build artifacts in CI; to publish a final NuGet package with a stable version, create and push a tag like v1.2.3.

Contributing

  1. Fork the repository and create a feature branch: git checkout -b feat/my-feature
  2. Write tests — all new behaviour must be covered by unit tests
  3. Build: dotnet build DTSdk.sln
  4. Test: dotnet test tests/DTSdk.Tests/
  5. Open a Pull Request against main

Coding conventions

  • Target net10.0; no multi-targeting unless strictly needed
  • Services are internal sealed class implementing a public interface
  • All public types use [JsonPropertyName] — no attribute-less serialization
  • Async methods must end in Async and accept a CancellationToken
  • No Console.WriteLine or logging in the SDK library itself

License

MIT © 2026

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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
2.0.0 129 6/25/2026
1.0.2 274 4/4/2026
1.0.1 109 4/4/2026
1.0.0 104 4/4/2026