Architecture¶
payments-hub is structured in two main layers: Core (gateway-agnostic business logic) and WooCommerce (integration layer). The Core layer must never depend on the WooCommerce layer.
Layer overview¶
src/
├── Config/ # Gateway config classes and factories
├── Core/
│ ├── Contracts/ # Interfaces for adapters, gateways, repos, loggers, requests, responses
│ ├── Controllers/ # REST-facing controllers (PaymentStatusController, WebhookController)
│ ├── Enums/ # GatewayProvider, PaymentStatus, AgreementStatus, …
│ ├── Exceptions/ # Domain exceptions
│ ├── Factories/ # Request factories (PaymentRequestFactory, AgreementRequestFactory)
│ ├── Gateways/ # Gateway implementations (Frisbii, MobilePay)
│ ├── Loggers/ # WooCommerce-backed loggers
│ ├── Migrations/ # Versioned DB migrations via Migrator
│ ├── Models/ # Request/response value objects
│ ├── Persistence/ # Entities (Agreement, Payment, Webhook, …) + repositories
│ ├── ServiceProviders/ # PaymentServiceProvider, WooCommerceIntegrationServiceProvider
│ ├── Services/ # Domain services (AgreementService, PaymentService, WebhookService, …)
│ └── Utilities/ # ArrayUtil, StringUtil, SubscriptionUtil
└── WooCommerce/
├── Admin/ # Meta boxes, order/subscription admin UI
├── API/REST/ # WooCommerce REST endpoint extensions
├── CLI/ # WP-CLI commands
├── Extensions/ # ApplicationStatus, BusinessCentral, GraphQL integrations
├── Frontend/ # Checkout, payment verification view
├── Gateways/ # WooCommerce gateway classes (Frisbii: CreditCard, ApplePay, GooglePay, …)
└── Services/ # Event handlers, subscription service, WooCommerce setup
Container wiring¶
Everything is wired via League Container inside PaymentServiceProvider.
Key shared services:
| Service | Implementation |
|---|---|
GatewayApiService | Routes operations to the active gateway |
AgreementService | Agreement lifecycle (create, update, cancel) |
PaymentService | Payment lifecycle (create, capture, refund, cancel) |
WebhookService | Routes incoming webhooks to the correct handler |
PaymentGatewayConfig | Built from env vars via PaymentConfigFactory |
AgreementRepositoryInterface | AgreementRepository |
PaymentRepositoryInterface | PaymentRepository |
Boot sequence¶
PaymentServiceProvider::boot()runs via League Container.Migrator::get_instance()applies any pending DB migrations.- Container inflectors inject
LoggerInterfaceinto allLoggerAwareInterfaceimplementations. - Webhook handlers receive state services and repositories via inflector.
Adding a new gateway¶
- Create
src/Core/Gateways/{Provider}/with a client, adapters, webhook handler, and a class implementingBasePaymentGatewayInterface. - Add the provider constant to
GatewayProvider. - Register it in
PaymentServiceProvider::register()(follow themaybeRegisterFrisbiipattern). - Add the provider to
GatewayApiServicewiring. - Create the WooCommerce gateway class(es) in
src/WooCommerce/Gateways/{Provider}/.