PayBridge 2.0.0
dotnet add package PayBridge --version 2.0.0
NuGet\Install-Package PayBridge -Version 2.0.0
<PackageReference Include="PayBridge" Version="2.0.0" />
<PackageVersion Include="PayBridge" Version="2.0.0" />
<PackageReference Include="PayBridge" />
paket add PayBridge --version 2.0.0
#r "nuget: PayBridge, 2.0.0"
#:package PayBridge@2.0.0
#addin nuget:?package=PayBridge&version=2.0.0
#tool nuget:?package=PayBridge&version=2.0.0
PayBridge 💳
PayBridge is a lightweight, stateless, database-free .NET 8.0 payment SDK and middleware. It provides a single, unified API (IPayBridgeService) to seamlessly integrate and manage 12+ payment gateways in your SaaS applications, e-commerce stores, marketplaces, and multitenant platforms.
🌟 Why PayBridge?
- Unified Interface: Write payment logic once using
IPayBridgeServiceand execute across any supported payment gateway. - 100% Stateless & Database-Free: No database tables, ORM entities, or migrations required. Your application retains full control over store credentials, payment records, and idempotency.
- Dynamic Frontend Integration: Automatically builds normalized
PaymentFrontendConfigobjects (containing client secrets, SDK script URLs, flow types, and public keys) for checkout UIs. - Custom Metadata Forwarding: Pass custom tracking metadata (such as
tenant_idororder_id) during payment creation—PayBridge preserves and returns them in webhooks. - Built-in Webhook Processing & Security: Automated HMAC-SHA256 signature verification, normalized event parsing, and automated webhook registration where supported.
🚀 Quickstart
1. Installation
Install the latest version via NuGet Package Manager or .NET CLI:
dotnet add package PayBridge --version 2.0.0
2. Dependency Injection Setup
Register PayBridge in your Program.cs or Startup.cs:
using PayBridge.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Register PayBridge HTTP Clients, Providers, Factory, and IPayBridgeService
builder.Services.AddPayBridge();
3. Inject and Use
Inject IPayBridgeService into your controllers, minimal API routes, or application services:
using PayBridge;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/payments")]
public class PaymentController : ControllerBase
{
private readonly IPayBridgeService _payBridge;
public PaymentController(IPayBridgeService payBridge)
{
_payBridge = payBridge;
}
}
🔌 Supported Gateways & Configuration DTOs
PayBridge provides strongly-typed configuration classes for all 12 supported gateways:
| Gateway | ProviderCode | Configuration DTO Class | Required Credentials |
|---|---|---|---|
| Stripe | ProviderCode.Stripe |
StripeConfig |
SecretKey (optional: PublishableKey, AccountId, WebhookSecret) |
| PayPal | ProviderCode.PayPal |
PayPalConfig |
ClientId, ClientSecret (optional: UseSandbox, WebhookId) |
| Razorpay | ProviderCode.Razorpay |
RazorpayConfig |
KeyId, KeySecret (optional: WebhookSecret) |
| PayTabs | ProviderCode.PayTabs |
PayTabsConfig |
ProfileId, ServerKey (optional: ClientKey, CallbackUrl) |
| Telr | ProviderCode.Telr |
TelrConfig |
StoreId, AuthKey (optional: TestMode, CallbackUrl) |
| Checkout.com | ProviderCode.Checkout |
CheckoutConfig |
SecretKey (optional: PublicKey, ProcessingChannelId, TestMode) |
| Square | ProviderCode.Square |
SquareConfig |
LocationId, AccessToken (optional: Environment, WebhookSignatureKey) |
| Adyen | ProviderCode.Adyen |
AdyenConfig |
MerchantAccount, ApiKey (optional: ClientKey, Environment, HmacKey) |
| Mollie | ProviderCode.Mollie |
MollieConfig |
ApiKey (optional: ProfileId, RedirectUrl, WebhookUrl) |
| Worldpay | ProviderCode.Worldpay |
WorldpayConfig |
MerchantCode, InstallationId, XmlPassword (optional: MacSecret, Environment) |
| Cashfree | ProviderCode.Cashfree |
CashfreeConfig |
AppId, SecretKey (optional: Environment, WebhookSecret) |
| PayU India | ProviderCode.PayU |
PayUConfig |
MerchantKey, MerchantSalt (optional: Environment) |
📖 Complete API Reference & Step-by-Step Guide
Operation 1: Discover Gateway Metadata (GetAllGatewaysAsync)
Retrieves UI metadata schema for all supported gateways. Perfect for building admin configuration screens or merchant onboarding forms.
C# Usage
IEnumerable<GatewayInfo> gateways = await _payBridge.GetAllGatewaysAsync();
Response Object (IEnumerable<GatewayInfo>)
[
{
"providerCode": "Stripe",
"providerCodeInt": 1,
"displayName": "Stripe",
"flowType": "embedded",
"iconUrl": "http://pay-api.podstorefront.com/gateways/stripe.webp",
"supportedCurrencies": ["USD", "EUR", "GBP", "AUD", "CAD", "JPY"],
"requiredFields": ["accountId", "secretKeyRef", "publishableKey"],
"formFields": [
{
"name": "secretKeyRef",
"type": "password",
"label": "Secret Key",
"isRequired": true,
"defaultValue": null,
"options": null
}
],
"minimumAmountMinor": null,
"requiresManualWebhookRegistration": false,
"webhookRegistrationInstructions": "Webhook is automatically registered during configuration."
}
]
Operation 2: Validate Gateway Configuration (ValidateConfiguration)
Validates credential objects before initiating payment calls.
C# Usage
var config = new StripeConfig
{
SecretKey = "sk_test_...",
PublishableKey = "pk_test_..."
};
ValidationResult validation = _payBridge.ValidateConfiguration(config);
if (!validation.IsValid)
{
foreach (var error in validation.Errors)
{
Console.WriteLine($"Validation Error: {error}");
}
}
Response Object (ValidationResult)
{
"isValid": true,
"errors": []
}
Operation 3: Create Payment Intent (CreatePaymentIntentAsync)
Initiates a payment across any provider and returns unified payment details along with FrontendConfig for client SDK rendering.
Note:
AmountMinorrepresents amounts in minor units (e.g.5000= $50.00 USD or ₹50.00 INR).
C# Usage
var request = new CreatePaymentIntentRequest
{
PaymentId = "PAY-99102",
OrderId = "ORDER-10042",
AmountMinor = 5000,
Currency = "USD",
Description = "Payment for Order #10042",
ReturnUrl = "https://example.com/checkout/success",
CancelUrl = "https://example.com/checkout/cancel",
Metadata = new Dictionary<string, string>
{
["tenant_id"] = "tenant_abc123",
["internal_order_id"] = "ORDER-10042"
}
};
PaymentResponse response = await _payBridge.CreatePaymentIntentAsync(request, config);
Request Schema (CreatePaymentIntentRequest)
{
"paymentId": "PAY-99102",
"idempotencyKey": "IDEM-99102",
"orderId": "ORDER-10042",
"amountMinor": 5000,
"currency": "USD",
"providerCode": "Stripe",
"description": "Payment for Order #10042",
"returnUrl": "https://example.com/checkout/success",
"cancelUrl": "https://example.com/checkout/cancel",
"country": "US",
"metadata": {
"tenant_id": "tenant_abc123",
"internal_order_id": "ORDER-10042"
}
}
Response Schema (PaymentResponse)
{
"paymentId": "PAY-99102",
"orderId": "ORDER-10042",
"amountMinor": 5000,
"currency": "USD",
"providerCode": "Stripe",
"status": "Pending",
"providerPaymentId": "pi_3MtwB2LkdIwHu7ix28a3tCpD",
"clientSecret": "pi_3MtwB2LkdIwHu7ix28a3tCpD_secret_abc123",
"approvalUrl": null,
"description": "Payment for Order #10042",
"createdOn": "2026-08-05T18:00:00Z",
"modifiedOn": "2026-08-05T18:00:00Z",
"paymentMethod": null,
"paymentInfo": null,
"frontendConfig": {
"provider": "Stripe",
"flowType": "embedded",
"sdkScriptUrl": "https://js.stripe.com/v3/",
"publicKey": "pk_test_...",
"clientSecret": "pi_3MtwB2LkdIwHu7ix28a3tCpD_secret_abc123",
"approvalUrl": null,
"providerPaymentId": "pi_3MtwB2LkdIwHu7ix28a3tCpD",
"sdkOptions": null,
"requiresCapture": false
}
}
Operation 4: Confirm Payment (ConfirmPaymentAsync)
Confirms action-required payments or verifies payment status following browser redirects.
C# Usage
var confirmReq = new ConfirmPaymentRequest
{
ProviderPaymentId = "pi_3MtwB2LkdIwHu7ix28a3tCpD"
};
ConfirmPaymentResponse confirmed = await _payBridge.ConfirmPaymentAsync(confirmReq, config);
Request Schema (ConfirmPaymentRequest)
{
"providerPaymentId": "pi_3MtwB2LkdIwHu7ix28a3tCpD",
"providerSpecific": {
"return_url": "https://example.com/checkout/success"
}
}
Response Schema (ConfirmPaymentResponse)
{
"status": "Captured",
"rawResponse": "{\"id\":\"pi_3MtwB2LkdIwHu7ix28a3tCpD\",\"status\":\"succeeded\"}",
"providerCaptureId": "ch_3MtwB2LkdIwHu7ix28a3tCpD"
}
Operation 5: Capture Authorized Payment (CapturePaymentAsync)
Captures funds for authorized payments (for 2-step authorization and capture flows).
C# Usage
var captureReq = new CapturePaymentRequest
{
ProviderPaymentId = "pi_3MtwB2LkdIwHu7ix28a3tCpD",
AmountMinor = 5000
};
CapturePaymentResponse captured = await _payBridge.CapturePaymentAsync(captureReq, config);
Request Schema (CapturePaymentRequest)
{
"providerPaymentId": "pi_3MtwB2LkdIwHu7ix28a3tCpD",
"amountMinor": 5000,
"providerSpecific": null
}
Response Schema (CapturePaymentResponse)
{
"status": "Captured",
"rawResponse": "{\"id\":\"pi_3MtwB2LkdIwHu7ix28a3tCpD\",\"status\":\"succeeded\"}",
"captureId": "ch_3MtwB2LkdIwHu7ix28a3tCpD"
}
Operation 6: Refund Payment (RefundPaymentAsync)
Processes full or partial refunds.
C# Usage
var refundReq = new RefundPaymentRequest
{
ProviderPaymentId = "pi_3MtwB2LkdIwHu7ix28a3tCpD",
AmountMinor = 2500,
Currency = "USD",
Reason = "Customer return request",
IdempotencyKey = "REFUND-KEY-99120"
};
RefundPaymentResponse refundRes = await _payBridge.RefundPaymentAsync(refundReq, config);
Request Schema (RefundPaymentRequest)
{
"providerPaymentId": "pi_3MtwB2LkdIwHu7ix28a3tCpD",
"amountMinor": 2500,
"currency": "USD",
"reason": "Customer return request",
"idempotencyKey": "REFUND-KEY-99120",
"internalPaymentId": "PAY-99102"
}
Response Schema (RefundPaymentResponse)
{
"providerRefundId": "re_3MtwB2LkdIwHu7ix28a3tCpD",
"status": "Refunded",
"rawResponse": "{\"id\":\"re_3MtwB2LkdIwHu7ix28a3tCpD\",\"status\":\"succeeded\"}"
}
Operation 7: Verify Webhook Signature (VerifyWebhookAsync)
Verifies incoming HTTP webhook requests against cryptographic signatures.
C# Usage
[HttpPost("webhook/stripe")]
public async Task<IActionResult> StripeWebhook()
{
using var reader = new StreamReader(Request.Body);
var rawBody = await reader.ReadToEndAsync();
var headers = Request.Headers.ToDictionary(h => h.Key, h => h.Value.ToString());
WebhookValidationResult validation = await _payBridge.VerifyWebhookAsync(rawBody, headers, config);
if (!validation.IsValid)
{
return BadRequest("Invalid webhook signature.");
}
return Ok();
}
Response Schema (WebhookValidationResult)
{
"isValid": true,
"eventType": "payment_intent.succeeded",
"eventId": "evt_1MtwB2LkdIwHu7ix28a3tCpD",
"providerPaymentId": "pi_3MtwB2LkdIwHu7ix28a3tCpD",
"storeId": null,
"internalPaymentId": "PAY-99102",
"providerCaptureId": "ch_3MtwB2LkdIwHu7ix28a3tCpD",
"eventAmountMinor": 5000,
"metadata": {
"tenant_id": "tenant_abc123",
"internal_order_id": "ORDER-10042"
}
}
Operation 8: Process & Extract Webhook Event (HandleWebhookAsync)
Parses raw webhook payloads into normalized data objects including event status, payment method, metadata, and payment info.
C# Usage
ExtractedWebhookData eventData = await _payBridge.HandleWebhookAsync(rawBody, headers, config);
string tenantId = eventData.Metadata.GetValueOrDefault("tenant_id");
string paymentId = eventData.InternalPaymentId;
if (eventData.Status == "Captured")
{
// Mark order as paid in your system
}
Response Schema (ExtractedWebhookData)
{
"isValid": true,
"eventType": "payment_intent.succeeded",
"providerEventId": "evt_1MtwB2LkdIwHu7ix28a3tCpD",
"providerPaymentId": "pi_3MtwB2LkdIwHu7ix28a3tCpD",
"internalPaymentId": "PAY-99102",
"providerCaptureId": "ch_3MtwB2LkdIwHu7ix28a3tCpD",
"eventAmountMinor": 5000,
"status": "Captured",
"paymentMethod": "Card",
"paymentInfo": {
"brand": "Visa",
"last4": "4242"
},
"metadata": {
"tenant_id": "tenant_abc123",
"internal_order_id": "ORDER-10042"
},
"rawResponse": "{\"id\":\"evt_1MtwB2...\"}"
}
Operation 9: Register Webhook Endpoint (RegisterWebhookAsync)
Automates programmatic webhook endpoint registration for gateways that support API-based webhook creation.
C# Usage
WebhookRegistrationResponse regResponse = await _payBridge.RegisterWebhookAsync(
"https://api.yourdomain.com/api/webhooks/stripe", config);
if (regResponse.IsManual)
{
Console.WriteLine($"Manual Setup Required: {regResponse.Message}");
}
else
{
Console.WriteLine($"Webhook ID: {regResponse.WebhookId}");
Console.WriteLine($"Signing Secret: {regResponse.SigningSecret}");
}
Response Schema (WebhookRegistrationResponse)
{
"webhookId": "we_1MtwB2LkdIwHu7ix28a3tCpD",
"signingSecret": "whsec_abc123xyz...",
"rawResponse": "{\"id\":\"we_1MtwB2...\"}",
"isManual": false,
"message": "Webhook registered successfully."
}
⚠️ Exception & Error Handling
PayBridge throws strongly-typed PaymentException objects when errors occur during provider requests. You can inspect the ErrorCode enum to handle specific failure scenarios:
using PayBridge.Exceptions;
using PayBridge.Enums;
try
{
PaymentResponse response = await _payBridge.CreatePaymentIntentAsync(request, config);
}
catch (PaymentException ex)
{
Console.WriteLine($"Provider: {ex.Provider}");
Console.WriteLine($"Error Code: {ex.ErrorCode}");
Console.WriteLine($"Message: {ex.Message}");
switch (ex.ErrorCode)
{
case ErrorCode.CardDeclined:
// Handle declined card
break;
case ErrorCode.InsufficientFunds:
// Handle insufficient funds
break;
case ErrorCode.InvalidCard:
// Handle invalid card details
break;
case ErrorCode.RateLimited:
// Handle provider rate limiting
break;
default:
// Generic error handling
break;
}
}
Key Error Codes (ErrorCode Enum)
CardDeclined: Payment attempt was declined by bank/issuer.InsufficientFunds: Account has insufficient funds.ExpiredCard: Card has expired.InvalidCard: Invalid card number, CVV, or expiration date.AuthenticationFailed: Invalid API key or merchant credentials.GatewayNotConfigured: Missing or invalid configuration fields.InvalidAmount: Invalid amount specified for transaction.RateLimited: Too many requests sent to gateway API.ProviderUnavailable: Gateway service is offline or unreachable.ProcessingError: Unexpected provider processing error.
📜 License
PayBridge is distributed under the MIT License.
Copyright (c) 2026 Mohit Rao & BrothersTechJodhpur
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Http (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.