Skip to content

Fix PayBridge gateway registration#56

Merged
teesofttech merged 1 commit into
masterfrom
codex/fix-paybridge-registration
Jul 17, 2026
Merged

Fix PayBridge gateway registration#56
teesofttech merged 1 commit into
masterfrom
codex/fix-paybridge-registration

Conversation

@teesofttech

@teesofttech teesofttech commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes PayBridge SDK registration so configuration binding, gateway DI visibility, and transaction lookup semantics match the behavior expected by the example app and payment service.

What changed

  • Bind PaymentGatewayConfig from PaymentGatewayConfig in configuration before applying code overrides.
  • Keep direct PaymentGatewayConfig injection and IOptions<PaymentGatewayConfig> backed by the same object.
  • Register enabled gateways consistently as both concrete gateway types and IPaymentGateway.
  • When EnabledGateways is empty, register only gateways with configured non-placeholder credentials.
  • Let GetByReferenceAsync return null when no transaction exists, matching existing service flow.
  • Add focused tests for config binding, options consistency, and gateway registration.

Validation

  • dotnet test PayBridge.SDK.sln passed: 90 passed, 2 skipped, 0 failed.

Summary by CodeRabbit

  • New Features

    • Added configuration-based setup support for the SDK initialization.
  • Bug Fixes

    • Improved error handling with validation for configured payment gateways.
    • Transaction lookup now returns null when no match is found instead of throwing an exception.
  • Tests

    • Added comprehensive unit tests for SDK dependency injection and gateway registration behavior.

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR refactors PayBridge SDK dependency injection to support configuration-based service registration alongside code-based customization, implements smart gateway selection that distinguishes between explicitly enabled and auto-detected gateways based on configured credentials, and adds supporting validation and null-safety improvements to the transaction and payment service layers.

Changes

DI Configuration Binding and Smart Gateway Selection

Layer / File(s) Summary
Configuration binding and core DI registration
PayBridge.SDK/Externsions/IServiceCollectionExtensions.cs, PayBridge.SDK.Example/Program.cs
New AddPayBridge(IConfiguration, configAction?) overload binds PaymentGatewayConfig from configuration, applies optional code overrides, and registers config as singleton and IOptions<PaymentGatewayConfig>. Existing AddPayBridge(configAction) now resolves IConfiguration from DI and delegates to shared core. Example updated to pass builder.Configuration.
Smart gateway registration with enabled/configured distinction
PayBridge.SDK/Externsions/IServiceCollectionExtensions.cs
Refactored gateway registration conditionally registers gateways: when EnabledGateways is empty, only gateways with valid configured credentials register (skipping YOUR_* placeholders); when non-empty, only explicitly enabled gateways register. New RegisterGateway switch, AddGatewayRegistration<TGateway> helper, and credential validators IsGatewayConfigured and HasValue.
Unit tests for DI registration behavior
PayBridge.SDK.Test/Unit/IServiceCollectionExtensionsTests.cs
Comprehensive test class verifying configuration binding with code overrides, explicit enabled gateway registration, and auto-detection of configured gateways when EnabledGateways is empty. Helper BuildConfiguration constructs in-memory test configuration.

Null-Safe Transaction Lookup and Empty Gateway Validation

Layer / File(s) Summary
Null-safe transaction lookup
PayBridge.SDK/Interfaces/ITransactionRepository.cs, PayBridge.SDK/Repositories/TransactionRepository.cs
GetByReferenceAsync return type changed to Task<PaymentTransaction?> to indicate "not found" results via null instead of exception. Implementation returns FirstOrDefaultAsync directly.
Empty gateway configuration guard
PayBridge.SDK/Services/PaymentService.cs
Early validation in CreatePaymentAsync throws PaymentGatewayException when gateway collection is empty, preventing subsequent selection attempts.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • teesofttech/PayBridge#31: Both modify AddPayBridge configuration binding and gateway-registration wiring in IServiceCollectionExtensions.cs.
  • teesofttech/PayBridge#26: Main PR's gateway registration refactor overlaps with PR #26's MonnifyGateway additions to the same enabled-gateways and registration paths.
  • teesofttech/PayBridge#35: Both touch gateway DI registration path and PaymentGatewayType.PeachPayments case in the same refactored registration logic.

Poem

🐰 Configuration flows like lettuce leaves,
Smart gateways know what they believe—
No placeholder strings to mislead,
Just valid paths where payments thread.
DI binds what's configured true,
And tests confirm the whole thing through!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix PayBridge gateway registration' directly relates to the main change—refactoring gateway registration logic in IServiceCollectionExtensions to properly bind configuration, apply overrides, and register gateways based on enabled list or configured credentials.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-paybridge-registration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@teesofttech teesofttech changed the title [codex] Fix PayBridge gateway registration Fix PayBridge gateway registration Jun 12, 2026
@teesofttech
teesofttech marked this pull request as ready for review June 12, 2026 08:51
Copilot AI review requested due to automatic review settings June 12, 2026 08:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
PayBridge.SDK.Example/Program.cs (1)

95-99: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the example comment to match the new auto-detection rule.

The SDK no longer enables every gateway whose section exists; it only enables gateways whose required credentials are populated with non-placeholder values. This example is the canonical setup guide, so the current wording will mislead anyone copying the sample config.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@PayBridge.SDK.Example/Program.cs` around lines 95 - 99, Update the example
comment to reflect the new auto-detection rule: explain that if EnabledGateways
is empty the SDK will only enable gateways whose configuration sections contain
real credentials (non-placeholder values), not merely those sections that exist;
mention the "PaymentGatewayConfig:EnabledGateways" key in appsettings.json
remains supported and that explicitly listing gateways is still recommended for
production to avoid accidental enabling when credentials are left as
placeholders.
🧹 Nitpick comments (1)
PayBridge.SDK.Test/Unit/IServiceCollectionExtensionsTests.cs (1)

44-64: ⚡ Quick win

Add one assertion for concrete-gateway resolution too.

This test proves IPaymentGateway registration, but the new contract also promises direct injection of the concrete gateway type. A GetRequiredService<PeachPaymentsGateway>() assertion here would pin that behavior and catch regressions in AddGatewayRegistration<TGateway>().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@PayBridge.SDK.Test/Unit/IServiceCollectionExtensionsTests.cs` around lines 44
- 64, Update the test AddPayBridge_RegistersEnabledGateway_AsIPaymentGateway to
also assert direct resolution of the concrete gateway type: after building the
provider call provider.GetRequiredService<PeachPaymentsGateway>() and assert it
is not null (or assert its GatewayType equals PaymentGatewayType.PeachPayments).
This verifies the AddGatewayRegistration<TGateway>() behavior and will catch
regressions where the concrete PeachPaymentsGateway is not registered for direct
injection.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@PayBridge.SDK/Externsions/IServiceCollectionExtensions.cs`:
- Around line 163-218: RegisterGateway currently ignores
PaymentGatewayType.Automatic (and any unknown enum values) causing silent no-op
registrations; update RegisterGateway to validate the incoming
PaymentGatewayType (from EnabledGateways) and throw an informative exception for
PaymentGatewayType.Automatic and any unsupported values instead of falling
through. Specifically, inside RegisterGateway (and before the switch or in a
default branch) detect PaymentGatewayType.Automatic and throw (or
ArgumentException) with a clear message referencing EnabledGateways and
PaymentGatewayType.Automatic, and ensure the switch has a default case that
throws for unknown enum values; keep using AddGatewayRegistration<TGateway> for
valid cases.

---

Outside diff comments:
In `@PayBridge.SDK.Example/Program.cs`:
- Around line 95-99: Update the example comment to reflect the new
auto-detection rule: explain that if EnabledGateways is empty the SDK will only
enable gateways whose configuration sections contain real credentials
(non-placeholder values), not merely those sections that exist; mention the
"PaymentGatewayConfig:EnabledGateways" key in appsettings.json remains supported
and that explicitly listing gateways is still recommended for production to
avoid accidental enabling when credentials are left as placeholders.

---

Nitpick comments:
In `@PayBridge.SDK.Test/Unit/IServiceCollectionExtensionsTests.cs`:
- Around line 44-64: Update the test
AddPayBridge_RegistersEnabledGateway_AsIPaymentGateway to also assert direct
resolution of the concrete gateway type: after building the provider call
provider.GetRequiredService<PeachPaymentsGateway>() and assert it is not null
(or assert its GatewayType equals PaymentGatewayType.PeachPayments). This
verifies the AddGatewayRegistration<TGateway>() behavior and will catch
regressions where the concrete PeachPaymentsGateway is not registered for direct
injection.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bbfc9ed3-5788-4162-9de6-fc1680970b64

📥 Commits

Reviewing files that changed from the base of the PR and between a17c810 and ff11cd6.

📒 Files selected for processing (6)
  • PayBridge.SDK.Example/Program.cs
  • PayBridge.SDK.Test/Unit/IServiceCollectionExtensionsTests.cs
  • PayBridge.SDK/Externsions/IServiceCollectionExtensions.cs
  • PayBridge.SDK/Interfaces/ITransactionRepository.cs
  • PayBridge.SDK/Repositories/TransactionRepository.cs
  • PayBridge.SDK/Services/PaymentService.cs

Comment on lines 163 to 218
foreach (var gateway in config.EnabledGateways)
{
switch (gateway)
{
case PaymentGatewayType.Stripe:
AddGatewayRegistration<StripeGateway>(services);
break;
case PaymentGatewayType.Paystack:
AddGatewayRegistration<PaystackGateway>(services);
break;
case PaymentGatewayType.Flutterwave:
AddGatewayRegistration<FlutterwaveGateway>(services);
break;
case PaymentGatewayType.Checkout:
AddGatewayRegistration<CheckoutGateway>(services);
break;
case PaymentGatewayType.BenefitPay:
AddGatewayRegistration<BenefitPayGateway>(services);
break;
case PaymentGatewayType.Knet:
AddGatewayRegistration<KnetGateway>(services);
break;
case PaymentGatewayType.Monnify:
AddGatewayRegistration<MonnifyGateway>(services);
break;
case PaymentGatewayType.Squad:
AddGatewayRegistration<SquadGateway>(services);
break;
case PaymentGatewayType.Korapay:
AddGatewayRegistration<KorapayGateway>(services);
break;
case PaymentGatewayType.Interswitch:
services.AddScoped<InterswitchGateway>();
services.AddScoped<IPaymentGateway>(sp => sp.GetRequiredService<InterswitchGateway>());
break;
case PaymentGatewayType.Remita:
services.AddScoped<RemitaGateway>();
break;
case PaymentGatewayType.Opay:
services.AddScoped<OpayGateway>();
break;
case PaymentGatewayType.DpoGroup:
AddGatewayRegistration<DpoGroupGateway>(services);
break;
case PaymentGatewayType.PawaPay:
services.AddScoped<PawaPayGateway>();
break;
case PaymentGatewayType.PeachPayments:
services.AddScoped<PeachPaymentsGateway>();
break;
}
RegisterGateway(services, gateway);
}
}

private static void RegisterGateway(IServiceCollection services, PaymentGatewayType gateway)
{
switch (gateway)
{
case PaymentGatewayType.Stripe:
AddGatewayRegistration<StripeGateway>(services);
break;
case PaymentGatewayType.Paystack:
AddGatewayRegistration<PaystackGateway>(services);
break;
case PaymentGatewayType.Flutterwave:
AddGatewayRegistration<FlutterwaveGateway>(services);
break;
case PaymentGatewayType.Checkout:
AddGatewayRegistration<CheckoutGateway>(services);
break;
case PaymentGatewayType.BenefitPay:
AddGatewayRegistration<BenefitPayGateway>(services);
break;
case PaymentGatewayType.Knet:
AddGatewayRegistration<KnetGateway>(services);
break;
case PaymentGatewayType.Monnify:
AddGatewayRegistration<MonnifyGateway>(services);
break;
case PaymentGatewayType.Squad:
AddGatewayRegistration<SquadGateway>(services);
break;
case PaymentGatewayType.Korapay:
AddGatewayRegistration<KorapayGateway>(services);
break;
case PaymentGatewayType.Interswitch:
AddGatewayRegistration<InterswitchGateway>(services);
break;
case PaymentGatewayType.Remita:
AddGatewayRegistration<RemitaGateway>(services);
break;
case PaymentGatewayType.Opay:
AddGatewayRegistration<OpayGateway>(services);
break;
case PaymentGatewayType.DpoGroup:
AddGatewayRegistration<DpoGroupGateway>(services);
break;
case PaymentGatewayType.PawaPay:
AddGatewayRegistration<PawaPayGateway>(services);
break;
case PaymentGatewayType.PeachPayments:
AddGatewayRegistration<PeachPaymentsGateway>(services);
break;
}

@coderabbitai coderabbitai Bot Jun 12, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail fast when EnabledGateways contains Automatic.

RegisterGateway has no Automatic branch, so an explicit EnabledGateways: ["Automatic"] configuration succeeds at startup but registers nothing. That misconfiguration only shows up later when a payment is attempted. Reject Automatic (and ideally any unsupported enum value) in the explicit-registration path so the error is immediate.

Possible guard
foreach (var gateway in config.EnabledGateways)
{
+    if (gateway == PaymentGatewayType.Automatic)
+    {
+        throw new ArgumentException(
+            "EnabledGateways cannot contain Automatic. List concrete gateway types instead.",
+            nameof(config));
+    }
+
     RegisterGateway(services, gateway);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@PayBridge.SDK/Externsions/IServiceCollectionExtensions.cs` around lines 163 -
218, RegisterGateway currently ignores PaymentGatewayType.Automatic (and any
unknown enum values) causing silent no-op registrations; update RegisterGateway
to validate the incoming PaymentGatewayType (from EnabledGateways) and throw an
informative exception for PaymentGatewayType.Automatic and any unsupported
values instead of falling through. Specifically, inside RegisterGateway (and
before the switch or in a default branch) detect PaymentGatewayType.Automatic
and throw (or ArgumentException) with a clear message referencing
EnabledGateways and PaymentGatewayType.Automatic, and ensure the switch has a
default case that throws for unknown enum values; keep using
AddGatewayRegistration<TGateway> for valid cases.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot What's the issue with this and can you fix it

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants