Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions .github/workflows/docs-quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Docs Quality

on:
pull_request:
branches:
- master
paths:
- docs/**
- mkdocs.yml
- README.md
- README.nuget.md
- .github/workflows/docs-quality.yml
- .markdownlint-cli2.jsonc
- .lychee.toml
push:
branches:
- master
paths:
- docs/**
- mkdocs.yml
- README.md
- README.nuget.md
- .github/workflows/docs-quality.yml
- .markdownlint-cli2.jsonc
- .lychee.toml
workflow_dispatch:

permissions:
contents: read

jobs:
docs-quality:
name: Markdown lint, links, and strict docs build
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v7

- name: Markdown lint
uses: DavidAnson/markdownlint-cli2-action@v20
with:
config: .markdownlint-cli2.jsonc
globs: |
docs/**/*.md
README.md
README.nuget.md

- name: Link check
uses: lycheeverse/lychee-action@v2
with:
args: >-
--config .lychee.toml
docs/**/*.md
README.md
README.nuget.md
fail: true

- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.12'

- name: Install MkDocs Material
run: |
python -m pip install --upgrade pip
pip install mkdocs-material

- name: Build docs (strict)
run: mkdocs build --strict
14 changes: 14 additions & 0 deletions .lychee.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
verbose = true
exclude_loopback = true
exclude_private = true
max_retries = 2
retry_wait_time = 2
accept = [200, 206, 301, 302, 429]

exclude = [
"http://localhost",
"https://localhost",
"127.0.0.1",
"https://developer.flutterwave.com",
"https://dashboard.paystack.com/#/settings/developers"
]
9 changes: 9 additions & 0 deletions .markdownlint-cli2.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://raw.githubusercontent.com/DavidAnson/markdownlint-cli2/main/schema/markdownlint-cli2-config-schema.json",
"config": {
"default": true,
"MD013": false,
"MD033": false,
"MD041": false
}
}
92 changes: 92 additions & 0 deletions docs/api-cookbook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# API Cookbook

This cookbook gives practical, end-to-end integration patterns with production-oriented checklists.

## Flow 1: Create Payment -> Redirect -> Verify -> Fulfill

## Request (Create)

```json
{
"amount": 5000,
"currency": "NGN",
"description": "Order ORD-1042",
"customerEmail": "jane@example.com",
"customerName": "Jane Doe",
"customerPhone": "+2348012345678",
"redirectUrl": "https://merchant.example.com/pay/callback",
"webhookUrl": "https://merchant.example.com/api/webhook/Paystack",
"paymentMethodType": 0,
"gateway": 2
}
```

## Server workflow

1. Call CreatePaymentAsync with explicit gateway when possible.
2. Persist order as Pending with transaction reference.
3. Redirect user to checkoutUrl from SDK response.
4. On redirect or webhook, call VerifyPaymentAsync.
5. Fulfill only when provider verification confirms success and expected amount/currency.

## Production checklist

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Make repeated headings unique.

The docs-quality workflow fails MD024 because Pattern and Production checklist recur. Add flow-specific context to every occurrence so markdownlint passes and the generated navigation remains clear.

Proposed fix
-## Production checklist
+## Production checklist — Flow 1: Create Payment

-## Production checklist
+## Production checklist — Flow 2: Automatic Routing

-## Pattern
+## Pattern — Flow 3: Secure Webhooks

-## Production checklist
+## Production checklist — Flow 3: Secure Webhooks

-## Pattern
+## Pattern — Flow 4: Refund Request and Reconciliation

-## Production checklist
+## Production checklist — Flow 4: Refund Request and Reconciliation

Also applies to: 50-50, 58-58, 66-66, 74-74, 81-81

🤖 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 `@docs/api-cookbook.md` at line 32, Update every repeated “Production
checklist” heading in docs/api-cookbook.md to include flow-specific context, and
do the same for each repeated “Pattern” heading and the headings at the
referenced locations such as “50-50” and “58-58”. Keep the headings semantically
clear and uniquely named so MD024 passes and generated navigation remains
understandable.

Sources: Linters/SAST tools, Pipeline failures


- Never fulfill based only on redirect query or webhook payload body.
- Compare verified amount/currency/reference against original order.
- Use idempotency keys for create operations exposed to client retries.

## Flow 2: Automatic Routing with Fallback

## Goal

Route by currency while preserving deterministic behavior and safe fallback.

## Pattern

1. Keep gateway config explicit and validated on startup.
2. Set DefaultGateway only when it is compatible and configured.
3. Reject unsupported combinations before external provider calls.

## Production checklist

Check failure on line 50 in docs/api-cookbook.md

View workflow job for this annotation

GitHub Actions / Markdown lint, links, and strict docs build

Multiple headings with the same content

docs/api-cookbook.md:50 MD024/no-duplicate-heading Multiple headings with the same content [Context: "Production checklist"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md024.md

- Monitor selected gateway and routing reason in structured logs.
- Keep per-provider callback URLs aligned with actual selected provider.
- Validate startup configuration in CI/CD before deployment.

## Flow 3: Secure Webhooks

## Pattern

Check failure on line 58 in docs/api-cookbook.md

View workflow job for this annotation

GitHub Actions / Markdown lint, links, and strict docs build

Multiple headings with the same content

docs/api-cookbook.md:58 MD024/no-duplicate-heading Multiple headings with the same content [Context: "Pattern"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md024.md

1. Preserve raw request body bytes.
2. Verify provider signature before JSON parsing.
3. Reject missing/invalid signatures with no side effects.
4. Apply replay protection and idempotent processing.
5. Re-verify transaction with provider API before final state update.

## Production checklist

Check failure on line 66 in docs/api-cookbook.md

View workflow job for this annotation

GitHub Actions / Markdown lint, links, and strict docs build

Multiple headings with the same content

docs/api-cookbook.md:66 MD024/no-duplicate-heading Multiple headings with the same content [Context: "Production checklist"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md024.md

- Do not log full webhook payloads, signatures, or secrets.
- Keep webhook timestamp tolerance tight and clocks synchronized.
- Store replay receipt IDs with bounded retention.

## Flow 4: Refund Request and Reconciliation

## Pattern

Check failure on line 74 in docs/api-cookbook.md

View workflow job for this annotation

GitHub Actions / Markdown lint, links, and strict docs build

Multiple headings with the same content

docs/api-cookbook.md:74 MD024/no-duplicate-heading Multiple headings with the same content [Context: "Pattern"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md024.md

1. Accept refund request with explicit amount and reason.
2. Call RefundPaymentAsync.
3. Persist refund attempt with provider status and reference.
4. Reconcile pending refunds asynchronously until terminal state.

## Production checklist

Check failure on line 81 in docs/api-cookbook.md

View workflow job for this annotation

GitHub Actions / Markdown lint, links, and strict docs build

Multiple headings with the same content

docs/api-cookbook.md:81 MD024/no-duplicate-heading Multiple headings with the same content [Context: "Production checklist"] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md024.md

- Treat refund as asynchronous by default.
- Guard against duplicate refund submissions with idempotency keys.
- Reconcile uncertain provider outcomes using durable persistence jobs.

## Error-Handling Playbook

- 4xx request errors: map to actionable client messages.
- Timeout/transient network failures: retry only where idempotent.
- Provider failures: normalize status and preserve provider reference IDs for audit.
- Security failures: fail closed and return minimal error detail.
42 changes: 42 additions & 0 deletions docs/gateway-capability-matrix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Gateway Capability Matrix

This matrix documents implemented SDK capabilities at a feature-contract level.

Notes:

- Status reflects SDK adapter support, not merchant-account enablement.
- Provider dashboards and account permissions can still block runtime operations.
- For webhook handling, only providers with implemented signature contracts should use public webhook endpoints.

| Gateway | Create | Verify | Refund Adapter | Webhook Signature Contract | Auth Pattern | Primary Currencies |
|---|---|---|---|---|---|---|
| Paystack | Yes | Yes | Yes | Yes | Bearer secret key + HMAC-SHA512 webhook signature | NGN, GHS, ZAR, USD, KES |
| Flutterwave | Yes | Yes | Yes | Yes | Bearer secret key + Base64 HMAC webhook signature | NGN, GHS, KES, ZAR, UGX, USD, EUR, GBP |
| Stripe | Yes | Yes | Yes | Yes | Bearer secret key + signed timestamp webhook | USD, EUR, GBP, AUD, CAD, JPY |
| Checkout.com | Yes | Yes | Yes | Yes | Bearer secret key + webhook signature | USD, EUR, GBP, AED |
| BenefitPay | Yes | Yes | Yes | No | Merchant API key/secret | BHD |
| Knet | Yes | Yes | Yes | No | Transport credentials | KWD |
| Monnify | Yes | Yes | Yes | Yes | OAuth2-style secret flow + webhook signature | NGN |
| Squad | Yes | Yes | Yes | Yes | Bearer secret key + webhook signature | NGN |
| Korapay | Yes | Yes | Yes | Yes | Bearer secret key + data-field signature | NGN, GHS, KES |
| Interswitch | Yes | Yes | Yes | No | OAuth2 + HMAC request signing | NGN |
| Remita | Yes | Yes | Yes | No | Hash-based API credentials | NGN |
| OPay | Yes | Yes | Yes | No | HMAC request signing | NGN |
| DPO Group | Yes | Yes | Yes | No | XML API token model | KES, GHS, UGX, ZAR, USD |
| PawaPay | Yes | Yes | Yes | No (dedicated signature protocol not yet implemented) | Bearer token | GHS, TZS, UGX, RWF, ZMW |
| PeachPayments | Yes | Yes | Yes | Yes | Bearer AccessToken + signed webhook tuple | ZAR, KES, NGN, BWP, USD |

## Operational Guidance

## Use explicit provider webhooks when signature contracts exist

- Configure callback paths as /api/webhook/{gateway} and map each provider dashboard to its provider-specific route.

## Do not expose generic public webhooks for unsupported signature-contract providers

- Providers without implemented signature verification should rely on server-to-server verification workflows before state change.

## Refund behavior in production

- Adapter support means the SDK has a refund path.
- Provider-side final status can still be Pending or Failed based on asynchronous processing, entitlement, and transaction state.
6 changes: 6 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
### Start Here

- [Quick Start](quickstart.md): Configure, run, and process your first transaction flow.
- [API Cookbook](api-cookbook.md): End-to-end integration patterns and production checklists.
- [Automatic Routing](automatic-gateway-routing.md): Understand route selection and fallback behavior.
- [Payment Idempotency](payment-idempotency.md): Prevent duplicate effects across retries.

Expand All @@ -38,6 +39,11 @@
- [Refund Persistence](refund-persistence.md): Durable refund lifecycle handling.
- [Flutterwave Refunds](flutterwave-refunds.md): Known behavior and current implementation notes.

### Reference and Release

- [Gateway Capability Matrix](gateway-capability-matrix.md): Provider support for create/verify/refund/webhooks/auth/currencies.
- [Versioning Strategy & Release Notes](versioning-and-release-notes.md): SemVer policy, release gates, and versioned docs approach.

## Recommended Reading Order

1. Quick Start
Expand Down
75 changes: 75 additions & 0 deletions docs/versioning-and-release-notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Versioning Strategy & Release Notes

## Versioning Policy

PayBridge follows semantic versioning for package publication.

- MAJOR: breaking API or behavior changes.
- MINOR: backward-compatible features (new gateway, new optional capability).
- PATCH: backward-compatible fixes, security hardening, and documentation corrections.

## Release Triggers

- Tag pattern: v*.*.*
- NuGet publish workflow builds and pushes package from tagged commit.
- GitHub release is created from the same tag.

## Release Readiness Gate

Before tagging, confirm:

1. Unit tests pass in CI.
2. Integration gate passes with at least one real sandbox provider.
3. Security checks pass (secret scanning + dependency checks).
4. Docs build strict mode passes.
5. README, package metadata, and docs claims align with implementation.

## Versioned Docs Strategy

Current state:

- Primary docs are published at latest (master) on GitHub Pages.

Recommended expansion:

1. Keep latest docs at root (/).
2. Generate version snapshots per release tag under /v/{version}/.
3. Include a version selector in navigation.
4. Maintain migration guides for breaking changes.

## Minimal implementation approach

- On release tag workflow:
- Build docs for the tagged commit.
- Publish artifacts into /v/{version}/ in Pages artifact.
- Keep root pointing to latest stable.

## Release Notes

## Current line highlights

## v1.2.x

- PeachPayments gateway support and related operational/security hardening.
- Webhook security enforcement and replay-safety improvements.
- Startup configuration validation improvements for enabled/default gateways.
- Documentation portal redesign and quality gates.

## Template for next release

```markdown
## vX.Y.Z - Release title

### Added
- New capabilities

### Changed
- Behavior changes and compatibility notes

### Fixed
- Bug fixes and security remediations

### Operational Notes
- Required config changes
- Migration steps
```
5 changes: 5 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ nav:
- Overview: quickstart.md
- Automatic Routing: automatic-gateway-routing.md
- Payment Idempotency: payment-idempotency.md
- API Cookbook: api-cookbook.md
- Reference:
- Gateway Capability Matrix: gateway-capability-matrix.md
- Security:
- Webhook Security: webhook-security.md
- Webhook Replay Protection: webhook-replay-protection.md
Expand All @@ -61,3 +64,5 @@ nav:
- Integration Testing: integration-testing.md
- Refund Persistence: refund-persistence.md
- Flutterwave Refunds: flutterwave-refunds.md
- Release Management:
- Versioning Strategy & Release Notes: versioning-and-release-notes.md
Loading