The Problem: Fragmented Payment APIs in South Africa
South Africa has a handful of dominant payment processors, including Paygate, PayFast, and DirectPay Online, but each one exposes a completely different API surface. Some use SOAP, others REST. Some require server-side checksums, others rely on redirect flows with callback URLs. For .NET developers, integrating even a single provider means writing boilerplate HTTP code, handling edge cases around 3D Secure, and managing secrets in a way that plays nicely with ASP.NET dependency injection.
When we needed to support all three providers across multiple client projects, copy-pasting integration code between repositories quickly became unsustainable. The answer was a set of clean, reusable .NET Standard libraries, one per provider, published as NuGet packages and open-sourced for the community.
Design Principles
Every wrapper follows the same architectural pattern. An interface (IPaygateService, IPayFastService, IDirectPayService) defines the contract so consumers can mock the payment gateway in unit tests. A concrete implementation handles HTTP communication, checksum generation, and response parsing. Configuration is injected through the standard IOptions pattern, and all libraries target .NET Standard 2.0 for maximum compatibility.
The interface-first approach turned out to be critical. Payment gateways are notoriously difficult to test because they involve real money, redirect flows, and asynchronous callbacks. By coding against an interface, developers can swap in a fake implementation during testing and only hit the live gateway in integration or staging environments.
Each library ships as a NuGet package with a single-line install, and registration with ASP.NET Core's service container is a one-liner as well. This lowers the barrier for any .NET developer in South Africa who needs to accept payments quickly.
IPaygateService: Redirect-Based Card Payments
Paygate is one of the oldest and most trusted payment processors in South Africa. Its API uses a redirect model: your server creates a transaction, receives a redirect URL, sends the customer to Paygate's hosted payment page, and then Paygate posts the result back to your callback endpoint.
The wrapper handles the full lifecycle. CreateTransaction builds the parameter set, generates the required MD5 checksum from your encryption key, and returns a redirect URL. QueryTransaction polls Paygate for the current status of a pending transaction. The checksum logic is the trickiest part: Paygate requires a specific field ordering and a shared secret. The library encapsulates this entirely, so consumers never have to think about it.
We also built in 3D Secure handling. When a card requires additional authentication, Paygate returns a specific status code and a URL for the 3D Secure challenge. The library detects this automatically and provides a clear API for the developer to redirect the customer appropriately.
IPayFastService and IDirectPayService
PayFast is arguably the most popular payment gateway for small and medium businesses in South Africa, offering both once-off and recurring payments. Our wrapper generates the signed payment form data, validates the ITN (Instant Transaction Notification) callbacks, and provides helpers for subscription management.
DirectPay Online supports a wider range of payment methods beyond cards, including mobile operator billing. The wrapper provides methods for CreateToken, ChargeTokenCreditCard, ChargeTokenMobile, and ChargeTokenAuth, covering the full spectrum of payment flows. It also supports the delayed-capture pattern where you authorise a card first and charge it later, which is common in hospitality and rental industries.
All three libraries share the same testing strategy: an xUnit project with mocked HTTP handlers that simulate the provider's responses. This means you can run the full test suite without any network calls or test credentials.
Lessons Learned and Community Impact
Publishing these as open-source NuGet packages taught us a few things. First, documentation matters more than code quality when it comes to adoption. We included step-by-step guides for both console applications and ASP.NET Core web apps, complete with dependency injection setup and example controllers.
Second, maintaining backward compatibility across .NET Standard, .NET Core, and .NET 5+ requires discipline. Targeting .NET Standard 2.0 was the right call because it maximises compatibility, but it means avoiding newer APIs that only exist in later runtimes.
The libraries now power payment processing across several production applications in South Africa, handling transactions for e-commerce stores, SaaS platforms, and service businesses. For any .NET developer in the region who needs to integrate with local payment processors, these open-source wrappers eliminate weeks of boilerplate work.