mirror of
https://github.com/opensourcepos/opensourcepos.git
synced 2026-04-02 22:36:21 -04:00
This commit introduces a comprehensive payment provider architecture to enable
seamless integration with external payment gateways like SumUp and PayPal/Zettle.
Architecture:
- PaymentProviderInterface: Contract for all payment providers
- PaymentProviderBase: Abstract base class with common functionality
- PaymentProviderRegistry: Singleton registry for provider management
- PaymentTransaction model: Transaction tracking and status management
Infrastructure:
- Webhook controller: Endpoint for external payment callbacks
- Payment events: payment_initiated, payment_completed, sale_completed
- payment_helper.php: Helper functions for payment provider content
- Migration for ospos_payment_transactions table
Core changes:
- Add Events::trigger('payment_options') in locale_helper.php
- Add Events::trigger('sale_completed') in Sales controller
- Add Events::trigger('payment_initiated') in postAddPayment()
- Add webhook routes for /payments/webhook/{provider}
Provider stubs:
- SumUpProvider: Card reader terminal integration
- PayPalProvider: Card reader and QR code payment integration
Related issues: #4346, #4322, #3232, #3789, #3790, #2275
71 lines
2.6 KiB
PHP
71 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Controllers\Payments;
|
|
|
|
use App\Controllers\BaseController;
|
|
use App\Libraries\Payments\PaymentProviderRegistry;
|
|
use CodeIgniter\HTTP\ResponseInterface;
|
|
|
|
class Webhook extends BaseController
|
|
{
|
|
public function handle(string $providerId): ResponseInterface
|
|
{
|
|
$provider = PaymentProviderRegistry::getInstance()->getProvider($providerId);
|
|
|
|
if ($provider === null) {
|
|
log_message('error', "Webhook received for unknown provider: {$providerId}");
|
|
return $this->response->setStatusCode(404)->setJSON([
|
|
'success' => false,
|
|
'error' => 'Provider not found'
|
|
]);
|
|
}
|
|
|
|
$rawInput = $this->request->getBody();
|
|
$data = json_decode($rawInput, true) ?? [];
|
|
|
|
if (empty($rawInput)) {
|
|
$data = $this->request->getPost();
|
|
}
|
|
|
|
try {
|
|
$result = $provider->processCallback($data);
|
|
|
|
if ($result['success'] ?? false) {
|
|
log_message('info', "Webhook processed successfully for provider: {$providerId}", $result);
|
|
return $this->response->setStatusCode(200)->setJSON($result);
|
|
}
|
|
|
|
log_message('warning', "Webhook processing failed for provider: {$providerId}", $result);
|
|
return $this->response->setStatusCode(400)->setJSON($result);
|
|
} catch (\Exception $e) {
|
|
log_message('error', "Webhook exception for provider {$providerId}: " . $e->getMessage());
|
|
return $this->response->setStatusCode(500)->setJSON([
|
|
'success' => false,
|
|
'error' => 'Internal server error'
|
|
]);
|
|
}
|
|
}
|
|
|
|
public function status(string $providerId, string $transactionId): ResponseInterface
|
|
{
|
|
$provider = PaymentProviderRegistry::getInstance()->getProvider($providerId);
|
|
|
|
if ($provider === null) {
|
|
return $this->response->setStatusCode(404)->setJSON([
|
|
'success' => false,
|
|
'error' => 'Provider not found'
|
|
]);
|
|
}
|
|
|
|
try {
|
|
$result = $provider->getPaymentStatus($transactionId);
|
|
return $this->response->setStatusCode(200)->setJSON($result);
|
|
} catch (\Exception $e) {
|
|
log_message('error', "Status check exception for provider {$providerId}: " . $e->getMessage());
|
|
return $this->response->setStatusCode(500)->setJSON([
|
|
'success' => false,
|
|
'error' => 'Internal server error'
|
|
]);
|
|
}
|
|
}
|
|
} |