[Architecture]: Payment provider plugin system for external gateway integrations
Los mantenedores suelen responder en 2 días
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 25/100
Línea de trabajo
Start by reading the existing plugin system in the plugin-system-fresh branch and the payment flow in Sales.php; the issue also points to locale_helper.php:243 and the proposed Payments/Webhook controller. The work spans payment abstractions, events, database migrations, webhooks, payment-type migration, and view hooks, so first establish which architecture decisions are accepted. Done would mean implementing the agreed phases and verifying compatibility with the existing sales workflow.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Overview
This issue proposes a Payment Provider Plugin System architecture to enable seamless integration with external payment gateways like SumUp and PayPal (Zettle). This builds on the existing plugin system in the plugin-system-fresh branch and addresses multiple feature requests for payment processing enhancements.
Related Issues
- #4346 - SumUp integration
- #4322 - PayPal In Store (POS/Zettle) Integration
- #3232 - Configurable payment types with custom options
- #3789 - Third-party integration standard architecture
- #3790 - Payment type stored as translated string breaks reports
- #2275 - Customer balance and payment tracking
Problem Statement
Currently, OSPOS has:
- Hardcoded payment types in
locale_helper.php:243(Cash, Debit, Credit, Due, Check, UPI) - No payment processing hooks - events fire after sale completion, not during payment
- No payment provider abstraction - no way to register external payment gateways
- No webhook infrastructure - no endpoints to receive payment callbacks
- Localized payment_type strings in DB - causes issues with multilingual installs (#3790)
Proposed Architecture
1. PaymentProviderInterface
A new interface that payment plugins implement:
interface PaymentProviderInterface
{
public function getProviderId(): string;
public function getProviderName(): string;
public function initiatePayment(float $amount, array $options): array;
public function processCallback(array $data): array;
public function getPaymentStatus(string $transactionId): string;
public function refund(string $transactionId, float $amount): bool;
public function getPaymentTypes(): array; // Returns payment type options
public function getIcon(): ?string;
public function getConfigView(): ?string;
}
2. PaymentPluginBase Class
Abstract class extending BasePlugin implementing common payment provider logic:
abstract class PaymentPluginBase extends BasePlugin implements PaymentProviderInterface
{
protected function logTransaction(string $transactionId, string $status, array $metadata = []): void;
protected function getTransaction(string $transactionId): ?array;
protected function validateCallbackSignature(array $data): bool;
}
3. New Events
Add payment-specific events in Sales.php:
| Event | Location | Purpose |
|---|---|---|
payment_options |
get_payment_options() |
Allow plugins to register dynamic payment types |
payment_initiated |
postAddPayment() |
Before payment is added to sale |
payment_completed |
After successful payment | After payment processed |
payment_failed |
On payment failure | Handle failed transactions |
sale_completed |
Sale finalization | After sale record saved |
4. Webhook Controller
New controller for external payment callbacks:
/app/Controllers/Payments/Webhook.php
Route: POST /payments/webhook/{provider_name}
5. Database Schema
Transaction tracking table:
CREATE TABLE ospos_payment_transactions (
id INT AUTO_INCREMENT PRIMARY KEY,
provider_id VARCHAR(50) NOT NULL,
sale_id INT NULL,
transaction_id VARCHAR(255) NOT NULL,
amount DECIMAL(15,2) NOT NULL,
currency VARCHAR(3) DEFAULT 'USD',
status ENUM('pending','authorized','completed','failed','refunded') DEFAULT 'pending',
metadata JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_provider (provider_id),
INDEX idx_sale (sale_id),
INDEX idx_transaction (transaction_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
6. Payment Type Refactor
Refactor payment_type storage (#3790) from translated strings to provider-prefixed constants:
| Current | Proposed |
|---|---|
lang('Sales.credit') → "Credit Card" |
provider:sumup:card |
lang('Sales.cash') → "Cash" |
builtin:cash |
lang('Sales.debit') → "Debit" |
builtin:debit |
7. View Hook Points
Standard injection points for payment plugins:
| Hook | Location | Purpose |
|---|---|---|
view:payment_buttons |
Register checkout UI | Payment method selection UI |
view:receipt_payment_details |
Receipt view | Show transaction details |
view:sale_complete_actions |
Post-sale screen | Refund/void buttons |
view:payment_provider_config |
Settings | Provider configuration UI |
Shared Components (SumUp & PayPal)
Both integrations would share:
| Component | Description |
|---|---|
PaymentProviderInterface |
Common contract |
| Transaction table | Shared tracking |
| Webhook controller | Unified callback handling |
| Settings storage | Via ospos_plugin_config |
| Icon system | Standardized payment icons |
| Status management | Common state machine |
| Receipt injection | Standard receipt format |
SumUp-Specific
- Card reader terminal integration via SumUp API
- Real-time transaction status polling
- Terminal display integration
- Refund processing
PayPal-Specific
- PayPal/Zettle card reader integration
- QR code payment display
- Invoicing integration
- Multi-currency support
Implementation Phases
Phase 1: Foundation
- Create
PaymentProviderInterfaceandPaymentPluginBase - Add payment events to
Sales.php - Modify
get_payment_options()to triggerpayment_optionsevent - Create
ospos_payment_transactionsmigration
Phase 2: Webhook Infrastructure
- Create
Payments/Webhookcontroller - Add routes for webhook endpoints
- Implement signature validation framework
Phase 3: Payment Type Refactor
- Migrate payment_type column to use provider-prefixed format
- Create migration to convert existing data
- Update all payment_type references
Phase 4: View System
- Add
plugin_content()hook points in views - Create payment button partials
- Add receipt injection helpers
Phase 5: Plugin Templates
- Create SumUp plugin stub
- Create PayPal plugin stub
- Documentation and examples
Benefits
- Extensibility: Any payment gateway can be integrated as a plugin
- Multilingual Support: Payment types no longer break across languages
- Separation of Concerns: Payment logic isolated from core
- Maintainability: Each provider maintains its own code
- Reusability: Shared infrastructure for all payment plugins
Technical Considerations
- Must work with existing sales workflow (suspended sales, returns, etc.)
- Need to handle offline/delayed payment scenarios
- Currency handling for international providers
- Security implications for payment data storage
- PCI compliance considerations (token-based, no card data storage)
Questions for Discussion
- Should payment provider plugins support both "pre-sale" (pay first, then complete sale) and "post-sale" (sale pending, pay via webhook) flows?
- How should we handle the transition from string-based payment types to the new format?
- Should we create a payment provider marketplace/registry?
Related to the plugin system in plugin-system-fresh branch.
- Lenguaje dominante
- PHP
- Estrellas
- 4.4k
- Forks
- 2.6k
- Merge medio
- 3 d 8 h
- PR fusionados (30 d)
- 29
Preparar el entorno
- Incluye un Dockerfile o un archivo de Docker Compose
- Sin plantilla de pull request
- Sin guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de opensourcepos/opensourcepos
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
opensourcepos/opensourcepos#4743 ·
Los mantenedores suelen responder en 2 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
opensourcepos/opensourcepos#4665 ·
Los mantenedores suelen responder en 2 días
-
enhancement needs owner question
Dificultad 2/5 1-3 horas Aptitud para principiantes 60/100
opensourcepos/opensourcepos#3565 · 5 comentarios ·
Los mantenedores suelen responder en 2 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 58/100
opensourcepos/opensourcepos#4754 ·
Los mantenedores suelen responder en 2 días
-
Move detailed documentation guides into docs/ and update links and release packagingPosiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 55/100
opensourcepos/opensourcepos#4751 ·
Los mantenedores suelen responder en 2 días
Todos los issues de opensourcepos/opensourcepos
Issues similares
-
Good first issue: add laravel-inertia stack budget preset (Laravel 11 + Inertia.js + PHP 8.3)Abiertoenhancement good first issue help wanted
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
-
backend gamification P0
Dificultad 2/5 1-3 horas Aptitud para principiantes 66/100
semanadeinformatica/website#461 ·
-
HttpRequestTrait fatals on WordPress 7.2: $blocked_http_requests clashes with WP_UnitTestCase_BaseAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 82/100