.NET SDK (C#)
GitHub Repository: sunbay-nexus-sdk-net
Official SUNBAY Nexus .NET SDK, providing complete payment integration capabilities for .NET applications.
Features
- ✅ Support for .NET 6.0+
- ✅ Complete async API
- ✅ Strong type definitions
- ✅ Automatic authentication
- ✅ Automatic retry for GET requests
- ✅ Comprehensive exception handling
- ✅ Connection pool management
- ✅ Integration with Microsoft.Extensions.Logging
Installation
Package Manager
Install-Package SUNBAY.Nexus.SdkQuick Start
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using SUNBAY.Nexus.Sdk;
using SUNBAY.Nexus.Sdk.Models.Requests;
using SUNBAY.Nexus.Sdk.Models.Common;
using SUNBAY.Nexus.Sdk.Exceptions;
class Program
{
static async Task Main(string[] args)
{
// Get API key from environment variable or configuration
// Do not hardcode sensitive information in source code
var apiKey = Environment.GetEnvironmentVariable("SUNBAY_API_KEY")
?? throw new InvalidOperationException("SUNBAY_API_KEY environment variable is required");
// Initialize logger factory (optional, but recommended for debugging)
// Note: Passing ILoggerFactory is the mainstream C# SDK pattern (Azure SDK, AWS SDK, etc.)
using var loggerFactory = LoggerFactory.Create(builder =>
builder.AddConsole().SetMinimumLevel(LogLevel.Information));
var logger = loggerFactory.CreateLogger<Program>();
// Initialize client with logger factory
var client = new NexusClient(new NexusClientOptions
{
ApiKey = apiKey,
BaseUrl = "https://open.sunbay.us"
}, loggerFactory);
try
{
// Create payment request
var request = new SaleRequest
{
AppId = "app_123456",
MerchantId = "mch_789012",
ReferenceOrderId = $"ORDER{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}",
TransactionRequestId = Guid.NewGuid().ToString("N"),
Amount = new SaleAmount
{
OrderAmount = 10000L, // 100.00 USD, in cents (smallest currency unit)
PriceCurrency = "USD"
},
Description = "Product purchase",
TerminalSn = "T1234567890"
};
logger.LogInformation("Sending sale request - ReferenceOrderId: {ReferenceOrderId}, TransactionRequestId: {TransactionRequestId}",
request.ReferenceOrderId, request.TransactionRequestId);
// Execute transaction
// If code != "0", will throw SUNBAYBusinessException
var response = await client.SaleAsync(request);
logger.LogInformation("Transaction successful - TransactionId: {TransactionId}", response.TransactionId);
}
catch (SUNBAYNetworkException ex)
{
logger.LogError(ex, "Network error occurred - Message: {Message}, IsRetryable: {IsRetryable}", ex.Message, ex.IsRetryable);
}
catch (SUNBAYBusinessException ex)
{
logger.LogError("API error occurred - Code: {Code}, Message: {Message}, TraceId: {TraceId}", ex.Code, ex.Message, ex.TraceId);
}
catch (Exception ex)
{
logger.LogError(ex, "Unexpected error occurred - Message: {Message}", ex.Message);
}
finally
{
await client.DisposeAsync();
}
}
}Available API Methods
The SDK provides the following transaction methods:
Transaction APIs
SaleAsync(request)- Payment transactionAuthAsync(request)- Pre-authorizationForcedAuthAsync(request)- Forced authorizationIncrementalAuthAsync(request)- Incremental authorizationPostAuthAsync(request)- Post-authorization completionRefundAsync(request)- RefundVoidAsync(request)- Void transactionAbortAsync(request)- Abort transactionTipAdjustAsync(request)- Tip adjustment
Query APIs
QueryAsync(request)- Query transaction
Settlement APIs
BatchCloseAsync(request)- Batch settlement
Configuration Options
var client = new NexusClient(new NexusClientOptions
{
ApiKey = "sk_test_xxx", // Required
BaseUrl = "https://open.sunbay.us", // Optional, default: https://open.sunbay.us
Timeout = TimeSpan.FromSeconds(30), // Optional, default: 30 seconds
MaxRetries = 3, // Optional, default: 3 times
MaxTotalConnections = 200, // Optional, default: 200
MaxConnectionsPerEndpoint = 20 // Optional, default: 20
});Connection Pool Configuration
- MaxTotalConnections: Maximum total connections across all endpoints in the pool (default: 200)
- MaxConnectionsPerEndpoint: Maximum connections per endpoint (default: 20)
These settings help optimize performance in high-concurrency scenarios.
Logging
The SDK integrates with standard .NET logging abstractions (Microsoft.Extensions.Logging). Logging is optional and fully controlled by the application.
Using ILoggerFactory (Recommended)
This is the mainstream approach for C# SDKs, allowing the SDK to create category-specific loggers internally.
using Microsoft.Extensions.Logging;
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder
.AddConsole()
.SetMinimumLevel(LogLevel.Debug);
});
var client = new NexusClient(new NexusClientOptions
{
ApiKey = "sk_test_xxx"
}, loggerFactory);Using Dependency Injection (ASP.NET Core)
In dependency injection scenarios, you can inject ILoggerFactory from the DI container:
// Startup.cs or Program.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<NexusClient>(sp =>
{
var loggerFactory = sp.GetRequiredService<ILoggerFactory>();
return new NexusClient(new NexusClientOptions
{
ApiKey = Configuration["SUNBAY:ApiKey"]
}, loggerFactory);
});
}
// Use in controller
public class PaymentController : ControllerBase
{
private readonly NexusClient _nexusClient;
public PaymentController(NexusClient nexusClient)
{
_nexusClient = nexusClient;
}
[HttpPost]
public async Task<IActionResult> CreatePayment([FromBody] PaymentRequest request)
{
var response = await _nexusClient.SaleAsync(request);
return Ok(response);
}
}Without Logging
If you don’t pass a logger factory, logging will be disabled by default:
var client = new NexusClient(new NexusClientOptions
{
ApiKey = "sk_test_xxx"
});
// No logging will occurNote:
- Logging is optional - if you don’t need logging, simply don’t pass
ILoggerFactory - The SDK uses
ILoggerFactoryinstead ofILogger, which is the standard pattern for .NET SDKs - This allows the SDK to create appropriate category loggers for different components
Exception Handling
The SDK throws two types of exceptions:
SUNBAYNetworkException
Network-related errors (connection timeout, network errors, etc.)
Properties:
Message- Error messageIsRetryable- Whether the error can be retried
SUNBAYBusinessException
Business logic errors (parameter validation, API business errors, etc.)
Properties:
Code- Error codeMessage- Error messageTraceId- Trace ID (for debugging)
Example:
try
{
var response = await client.SaleAsync(request);
// Handle successful response
}
catch (SUNBAYNetworkException ex)
{
// Network error
Console.WriteLine($"Network error: {ex.Message}");
if (ex.IsRetryable)
{
// Can retry
Console.WriteLine("This error is retryable");
}
}
catch (SUNBAYBusinessException ex)
{
// Business error
Console.WriteLine($"API error: {ex.Code} - {ex.Message}");
if (!string.IsNullOrEmpty(ex.TraceId))
{
Console.WriteLine($"Trace ID: {ex.TraceId}");
}
// Handle based on error code
switch (ex.Code)
{
case "INSUFFICIENT_FUNDS":
// Handle insufficient funds
break;
case "INVALID_CARD":
// Handle invalid card
break;
default:
// Handle other errors
break;
}
}Complete Example
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using SUNBAY.Nexus.Sdk;
using SUNBAY.Nexus.Sdk.Models.Requests;
using SUNBAY.Nexus.Sdk.Models.Common;
using SUNBAY.Nexus.Sdk.Exceptions;
class PaymentExample
{
static async Task Main(string[] args)
{
// Configure logging
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder
.AddConsole()
.SetMinimumLevel(LogLevel.Information);
});
// Initialize client
var client = new NexusClient(new NexusClientOptions
{
ApiKey = Environment.GetEnvironmentVariable("SUNBAY_API_KEY"),
BaseUrl = "https://open.sunbay.us",
Timeout = TimeSpan.FromSeconds(30)
}, loggerFactory);
try
{
// Create payment request
var request = new SaleRequest
{
AppId = "app_123456",
MerchantId = "mch_789012",
ReferenceOrderId = $"ORDER{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}",
TransactionRequestId = Guid.NewGuid().ToString("N"),
Amount = new SaleAmount
{
OrderAmount = 10000L, // 100.00 USD = 10000 cents
PriceCurrency = "USD"
},
Description = "Product purchase",
TerminalSn = "T1234567890"
};
// Execute transaction
var response = await client.SaleAsync(request);
// Handle successful response
Console.WriteLine("Transaction successful!");
Console.WriteLine($"Transaction ID: {response.TransactionId}");
Console.WriteLine($"Reference Order ID: {response.ReferenceOrderId}");
Console.WriteLine($"Amount: ${response.Amount.OrderAmount / 100.0:F2}");
}
catch (SUNBAYNetworkException ex)
{
Console.WriteLine($"Network error: {ex.Message}");
Console.WriteLine($"Retryable: {ex.IsRetryable}");
}
catch (SUNBAYBusinessException ex)
{
Console.WriteLine($"Business error: {ex.Code} - {ex.Message}");
if (!string.IsNullOrEmpty(ex.TraceId))
{
Console.WriteLine($"Trace ID: {ex.TraceId}");
}
}
finally
{
await client.DisposeAsync();
}
}
}System Requirements
- .NET 6.0 or higher
- .NET Framework 4.6.2 or higher (if using .NET Framework)
Related Links
Support
If you encounter issues during usage:
- Check GitHub Issues
- Submit a new issue
- Contact our technical support team
License
MIT License. Copyright (c) 2025 SUNBAY