.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
| Requirement | Version |
|---|---|
| .NET Framework | 4.6.1 or later |
| .NET Core | 2.0 or later |
| .NET 5/6/7/8 | Supported |
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
| Parameter | Description |
|---|---|
ApiEndpoint | Environment URL (test or production) |
ApiKeyId | Your API key from the Merchant Portal |
SecretApiKey | Your API secret from the Merchant Portal |
Integrator | Your company name for request tracking |
Environment URLs:
| Environment | URL |
|---|---|
| Test | https://payment.preprod.direct.worldline-solutions.com |
| Production | https://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 Code | Exception Type | Description |
|---|---|---|
| 400 | ValidationException | Input validation errors |
| 403 | AuthorizationException | Access denied |
| 404/409/410 | ReferenceException | Resource issues |
| 409 | IdempotenceException | Duplicate request |
| 500/502/503 | PlatformException | Server 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();
}
}