SDK-SPEC-CSHARP — C# SDK Specification¶
Status: Draft
Owner: Platform Engineering
Package: Simpaisa.SDK
Runtime: .NET 6+
Last Updated: 2026-04-03
1. Overview¶
Official C# SDK for the Simpaisa Payment Gateway. Provides async-first typed access to Pay-Ins, Pay-Outs, Remittances, and Cards across PK, BD, NP, and IQ corridors. Handles 270M+ annual transactions at $1B+ volume. Published to NuGet as Simpaisa.SDK.
2. NuGet Package¶
<PackageReference Include="Simpaisa.SDK" Version="1.*" />
CLI: dotnet add package Simpaisa.SDK
3. Namespace Structure¶
Simpaisa.SDK/
├── src/
│ ├── Simpaisa.SDK/
│ │ ├── SimPaisaClient.cs # Main client entry point
│ │ ├── SimPaisaOptions.cs # Configuration options
│ │ ├── PayIn/
│ │ │ ├── IPayInClient.cs # Interface
│ │ │ ├── PayInClient.cs # initiate, verify, status, list
│ │ │ ├── PayInRequest.cs
│ │ │ └── PayInResponse.cs
│ │ ├── PayOut/
│ │ │ ├── IPayOutClient.cs
│ │ │ ├── PayOutClient.cs # initiate, status, batch, cancel
│ │ │ ├── PayOutRequest.cs
│ │ │ └── PayOutResponse.cs
│ │ ├── Remittance/
│ │ │ ├── IRemittanceClient.cs
│ │ │ ├── RemittanceClient.cs # quote, initiate, status, beneficiaries
│ │ │ ├── RemittanceRequest.cs
│ │ │ └── RemittanceResponse.cs
│ │ ├── Cards/
│ │ │ ├── ICardsClient.cs
│ │ │ ├── CardsClient.cs # pay, capture, void, refund, tokenise
│ │ │ ├── CardPaymentRequest.cs
│ │ │ └── CardPaymentResponse.cs
│ │ ├── Webhook/
│ │ │ ├── WebhookVerifier.cs # HMAC-SHA256 verification
│ │ │ └── WebhookEvent.cs
│ │ ├── Auth/
│ │ │ ├── RSAAuthProvider.cs # RSA-SHA256 request signing
│ │ │ └── IAuthProvider.cs # Interface for custom auth
│ │ ├── Exceptions/
│ │ │ ├── SimPaisaException.cs # Base exception
│ │ │ ├── AuthenticationException.cs
│ │ │ ├── ValidationException.cs
│ │ │ ├── RateLimitException.cs
│ │ │ └── WebhookVerificationException.cs
│ │ ├── Retry/
│ │ │ └── RetryPolicyOptions.cs # Polly-based retry configuration
│ │ ├── Idempotency/
│ │ │ └── IdempotencyKeyGenerator.cs
│ │ └── Generated/
│ │ └── Models/ # OpenAPI-generated models
│ └── Simpaisa.SDK.csproj
├── tests/
│ └── Simpaisa.SDK.Tests/
├── Simpaisa.SDK.sln
└── Directory.Build.props
4. Authentication — RSAAuthProvider¶
- Load merchant private key from PEM file via
RSA.Create()+ImportFromPem() - Sign request body with RSA-SHA256 using
System.Security.Cryptography - Attach
X-Simpaisa-SignatureandX-Simpaisa-Merchant-Idheaders - No third-party crypto dependency required (.NET 6+ has native PEM support)
- Support key rotation via collection of key paths
var auth = new RSAAuthProvider(
merchantId: "MCH-001",
privateKeyPath: "./keys/merchant.pem"
);
5. Async/Await Throughout¶
- ALL public methods SHALL be async, returning
Task<T> - Follow TAP (Task-based Asynchronous Pattern)
- Accept
CancellationTokenon all async methods - No
.Resultor.Wait()calls internally - Synchronous wrappers NOT provided (async-only by design)
var result = await client.PayIn.InitiateAsync(request, cancellationToken);
6. WebhookVerifier¶
- Verify
X-Simpaisa-Webhook-SignatureusingHMACSHA256class bool Verify(ReadOnlySpan<byte> payload, string signature)- Constant-time comparison via
CryptographicOperations.FixedTimeEquals() - Replay protection: validate timestamp header within tolerance (default 300s)
- Throw
WebhookVerificationExceptionon failure
7. Retry (Polly)¶
- Exponential backoff with jitter via
Microsoft.Extensions.Http.Polly - Configurable max retries (default 3)
- Retry on: 429, 502, 503, 504,
HttpRequestException - Never retry: 400, 401, 403, 404, 409, 422
- Respect
Retry-Afterheader - Circuit breaker policy optional
OnRetryAsyncdelegate for observability
8. HttpClientFactory Integration¶
- Register via dependency injection:
services.AddSimpaisa(options =>
{
options.Environment = SimPaisaEnvironment.Sandbox;
options.MerchantId = "MCH-001";
options.PrivateKeyPath = "./keys/merchant.pem";
options.Timeout = TimeSpan.FromSeconds(30);
options.MaxRetries = 3;
});
- Uses
IHttpClientFactoryfor connection pooling and lifetime management - Named HttpClient:
"SimPaisaClient" - Polly policies attached via
AddPolicyHandler() - Supports
IOptions<SimPaisaOptions>pattern for configuration binding
9. Error Handling¶
SimPaisaException (base)
├── AuthenticationException — 401/403 responses
├── ValidationException — 400/422 with field-level details
├── RateLimitException — 429 with RetryAfter
├── TimeoutException — request/connection timeout
├── IdempotencyException — conflicting idempotency key
├── NetworkException — connection/DNS failures
└── WebhookVerificationException — signature mismatch
All exceptions include: ErrorCode, StatusCode, RequestId, IsRetryable.
10. Model Generation¶
- Models auto-generated from canonical OpenAPI 3.1 spec via NSwag or Kiota
- Generated into
Simpaisa.SDK.Generated.Modelsnamespace System.Text.Jsonserialisation (not Newtonsoft)- Immutable record types where appropriate
- Regenerated in CI on OpenAPI spec changes
11. Example Usage¶
using Simpaisa.SDK;
var client = new SimPaisaClient(new SimPaisaOptions
{
Environment = SimPaisaEnvironment.Sandbox,
MerchantId = "MCH-001",
PrivateKeyPath = "./keys/merchant.pem",
});
// Pay-In
var payIn = await client.PayIn.InitiateAsync(new PayInRequest
{
Amount = 5000m,
Currency = "PKR",
Channel = "EASYPAISA",
CustomerMsisdn = "03001234567",
CallbackUrl = "https://merchant.com/webhook",
});
// Webhook
var verifier = new WebhookVerifier(secret: "whsec_...");
bool valid = verifier.Verify(rawBody, signatureHeader);
12. Build and Publish¶
- Build:
dotnet build/ MSBuild - Test runner: xUnit + FluentAssertions + Moq
- Linting: .editorconfig + Roslyn analysers
- CI: Bitbucket Pipelines — lint → test → build → pack → push
- Publish: NuGet.org with API key
- Versioning: Semantic versioning via
Directory.Build.props - Target frameworks:
net6.0;net8.0;net9.0
13. Testing Requirements¶
- Unit tests for every public method (>90% coverage via Coverlet)
- Integration tests against sandbox environment
- Contract tests validating against OpenAPI spec
- Webhook verification round-trip tests
- Retry/circuit breaker tests with simulated failures
- DI registration tests
14. Documentation¶
- XML documentation comments on all public types and members
- README with quickstart, DI setup, and corridor-specific examples
- CHANGELOG following Keep a Changelog format
- IntelliSense-compatible (XML docs included in NuGet package)