Skip to main content

.NET SDK

The .NET SDK provides a comprehensive toolkit for integrating with Worldline Direct using C#. It supports all integration methods and handles authentication, request signing, and response parsing.

Features

  • Access to all RESTful API functionalities
  • Support for Hosted Checkout, Hosted Tokenization, and Server-to-Server
  • Full payment lifecycle: create, capture, refund, cancel
  • Webhook signature verification
  • Built-in logging and debugging

Requirements

RequirementVersion
.NET Framework4.6.1 or later
.NET Core2.0 or later
.NET 5/6/7/8Supported

Supported Platforms: Windows, Linux, macOS

Installation

Install via NuGet Package Manager:

dotnet add package OnlinePayments.Sdk

Or via Package Manager Console:

Install-Package OnlinePayments.Sdk

Quick Start

Initialize the Client

using OnlinePayments.Sdk;

var configuration = new CommunicatorConfiguration
{
ApiEndpoint = new Uri("https://payment.preprod.direct.worldline-solutions.com"),
ApiKeyId = "YOUR_API_KEY",
SecretApiKey = "YOUR_API_SECRET",
Integrator = "YourCompanyName"
};

var client = Factory.CreateClient(configuration);
var merchantClient = client.WithNewMerchant("YOUR_MERCHANT_ID");

Configuration Parameters

ParameterDescription
ApiEndpointEnvironment URL (test or production)
ApiKeyIdYour API key from the Merchant Portal
SecretApiKeyYour API secret from the Merchant Portal
IntegratorYour company name for request tracking

Environment URLs:

EnvironmentURL
Testhttps://payment.preprod.direct.worldline-solutions.com
Productionhttps://payment.direct.worldline-solutions.com

Creating Payments

Hosted Checkout

var request = new CreateHostedCheckoutRequest
{
Order = new Order
{
AmountOfMoney = new AmountOfMoney
{
Amount = 2980, // Amount in cents
CurrencyCode = "EUR"
},
Customer = new Customer
{
MerchantCustomerId = "customer-123",
BillingAddress = new Address
{
CountryCode = "NL"
}
}
},
HostedCheckoutSpecificInput = new HostedCheckoutSpecificInput
{
ReturnUrl = "https://yoursite.com/return",
Variant = "my-template"
}
};

var response = await merchantClient.HostedCheckout
.CreateHostedCheckoutAsync(request);

// Redirect customer to the payment page
string redirectUrl = response.RedirectUrl;
string hostedCheckoutId = response.HostedCheckoutId;

Server-to-Server Payment

var request = new CreatePaymentRequest
{
Order = new Order
{
AmountOfMoney = new AmountOfMoney
{
Amount = 2980,
CurrencyCode = "EUR"
},
References = new OrderReferences
{
MerchantReference = "order-12345"
}
},
CardPaymentMethodSpecificInput = new CardPaymentMethodSpecificInput
{
PaymentProductId = 1, // Visa
Card = new Card
{
CardholderName = "John Doe",
CardNumber = "4111111111111111",
Cvv = "123",
ExpiryDate = "1225"
},
ThreeDSecure = new ThreeDSecure
{
RedirectionData = new RedirectionData
{
ReturnUrl = "https://yoursite.com/return"
}
}
}
};

var response = await merchantClient.Payments
.CreatePaymentAsync(request);

Hosted Tokenization

var request = new CreateHostedTokenizationRequest
{
Variant = "my-tokenization-template.html"
};

var response = await merchantClient.HostedTokenization
.CreateHostedTokenizationAsync(request);

string hostedTokenizationUrl = response.PartialRedirectUrl;
string hostedTokenizationId = response.HostedTokenizationId;

Retrieving Payment Status

// Get payment details
var payment = await merchantClient.Payments
.GetPaymentDetailsAsync(paymentId);

int statusCode = payment.StatusOutput.StatusCode;
string status = payment.Status;

// Get hosted checkout status
var checkoutStatus = await merchantClient.HostedCheckout
.GetHostedCheckoutStatusAsync(hostedCheckoutId);

Maintenance Operations

Capture Payment

var request = new CapturePaymentRequest
{
Amount = 2980,
IsFinal = true
};

var capture = await merchantClient.Payments
.CapturePaymentAsync(paymentId, request);

Refund Payment

var request = new RefundRequest
{
AmountOfMoney = new AmountOfMoney
{
Amount = 2980,
CurrencyCode = "EUR"
}
};

var refund = await merchantClient.Payments
.RefundPaymentAsync(paymentId, request);

Cancel Payment

var result = await merchantClient.Payments
.CancelPaymentAsync(paymentId);

Exception Handling

Payment Exceptions

try
{
var response = await merchantClient.Payments
.CreatePaymentAsync(request);
}
catch (DeclinedPaymentException e)
{
// Payment was declined
var payment = e.CreatePaymentResponse.Payment;
Console.WriteLine($"Payment declined: {payment.StatusOutput.StatusCode}");

foreach (var error in e.Errors)
{
Console.WriteLine($"Error {error.Code}: {error.Message}");
}
}
catch (ValidationException e)
{
// Invalid request (400)
foreach (var error in e.Errors)
{
Console.WriteLine($"Validation error: {error.PropertyName} - {error.Message}");
}
}
catch (AuthorizationException e)
{
// Access denied (403)
Console.WriteLine("Authentication failed. Check your API credentials.");
}
catch (ReferenceException e)
{
// Resource not found (404/409/410)
Console.WriteLine($"Resource error: {e.Message}");
}
catch (PlatformException e)
{
// Server error (500/502/503)
Console.WriteLine($"Platform error: {e.Message}");
}

HTTP Exception Types

Status CodeException TypeDescription
400ValidationExceptionInput validation errors
403AuthorizationExceptionAccess denied
404/409/410ReferenceExceptionResource issues
409IdempotenceExceptionDuplicate request
500/502/503PlatformExceptionServer errors

Idempotent Requests

Prevent duplicate payments using idempotence keys:

string idempotenceKey = Guid.NewGuid().ToString();
var context = new CallContext().WithIdempotenceKey(idempotenceKey);

try
{
var response = await merchantClient.Payments
.CreatePaymentAsync(request, context);
}
catch (IdempotenceException e)
{
// Request was already processed
var existingResponse = e.IdempotenceRequestTimestamp;
}

Webhook Processing

// Store your webhook secret
InMemorySecretKeyStore.Instance.StoreSecretKey("webhookKeyId", "webhookSecret");

var helper = new WebhooksHelper(
DefaultMarshaller.Instance,
InMemorySecretKeyStore.Instance
);

// In your webhook endpoint
[HttpPost("webhook")]
public IActionResult HandleWebhook()
{
var body = new StreamReader(Request.Body).ReadToEnd();
var headers = Request.Headers
.Select(h => new RequestHeader(h.Key, h.Value.FirstOrDefault()))
.ToList();

try
{
var webhookEvent = helper.Unmarshal(body, headers);

// Process the event
var payment = webhookEvent.Payment;
var eventType = webhookEvent.Type;

return Ok();
}
catch (SignatureValidationException e)
{
return BadRequest("Invalid signature");
}
}

Advanced Configuration

Logging

Enable request/response logging for debugging:

// Enable logging
client.EnableLogging(new SystemConsoleCommunicatorLogger());

// Perform operations...

// Disable logging
client.DisableLogging();
Sensitive Data

The SDK automatically obfuscates sensitive data (card numbers, CVV) in logs.

Connection Pooling

Share connections across multiple clients:

var communicator = Factory.CreateCommunicator(configuration);

var client1 = Factory.CreateClient(communicator);
var client2 = Factory.CreateClient(communicator);

// Both clients share the same connection pool

Resource Management

// Using statement ensures proper disposal
using (var client = Factory.CreateClient(configuration))
{
var merchantClient = client.WithNewMerchant("MERCHANT_ID");
// Use merchantClient...
} // Connection automatically closed

// Or manually close idle connections
client.CloseIdleConnections(TimeSpan.FromMinutes(5));

Get Available Payment Methods

var queryParams = new GetPaymentProductsParams
{
CountryCode = "NL",
CurrencyCode = "EUR"
};

var products = await merchantClient.Products
.GetPaymentProductsAsync(queryParams);

foreach (var product in products.PaymentProducts)
{
Console.WriteLine($"{product.Id}: {product.DisplayHints.Label}");
}

Full Example

using OnlinePayments.Sdk;
using OnlinePayments.Sdk.Domain;

public class PaymentService
{
private readonly IClient _client;
private readonly IMerchantClient _merchantClient;

public PaymentService(string apiKey, string apiSecret, string merchantId)
{
var configuration = new CommunicatorConfiguration
{
ApiEndpoint = new Uri("https://payment.preprod.direct.worldline-solutions.com"),
ApiKeyId = apiKey,
SecretApiKey = apiSecret,
Integrator = "MyCompany"
};

_client = Factory.CreateClient(configuration);
_merchantClient = _client.WithNewMerchant(merchantId);
}

public async Task<CreateHostedCheckoutResponse> CreateCheckout(
long amountInCents,
string currency,
string returnUrl)
{
var request = new CreateHostedCheckoutRequest
{
Order = new Order
{
AmountOfMoney = new AmountOfMoney
{
Amount = amountInCents,
CurrencyCode = currency
}
},
HostedCheckoutSpecificInput = new HostedCheckoutSpecificInput
{
ReturnUrl = returnUrl
}
};

return await _merchantClient.HostedCheckout
.CreateHostedCheckoutAsync(request);
}

public async Task<PaymentResponse> GetPaymentStatus(string paymentId)
{
return await _merchantClient.Payments
.GetPaymentDetailsAsync(paymentId);
}

public void Dispose()
{
_client?.Dispose();
}
}

Resources

Next Steps