online-payments/sdk-php
The Online Payments PHP SDK lets PHP applications communicate with the Online Payments Server API. It wraps API calls in convenient PHP request and response objects, handles authentication and required metadata automatically, and requires PHP 7.4 or above. Install it via Composer with online-payment...
App\Services\PaymentGateway) with clear interfaces for:
Http client to wrap SDK calls, enabling middleware for retries, logging, and rate limiting.PaymentProcessed, PaymentFailed) to trigger business logic (e.g., inventory updates, notifications).config/services/payment.php with environment-specific overrides (e.g., sandbox/live).PaymentController@charge() → PaymentGateway::create()).Payment::created() → store payment_id).ProcessRefundJob) to queues.MockPaymentGateway) and integration tests with sandbox environments.Http client or Guzzle, adding middleware for:
AddApiKeyMiddleware.RetryFailedRequests middleware.monolog or Laravel Debugbar.$client = app(HttpClient::class)->withOptions([
'base_uri' => config('services.payment.api_url'),
'headers' => ['Authorization' => 'Bearer ' . config('services.payment.key')],
]);
class Payment extends Model {
protected $casts = ['metadata' => 'array'];
public static function boot() {
static::created(fn ($payment) => PaymentGateway::create($payment));
}
}
POST /payment/webhook) with:
signed routes.PaymentWebhookReceived).IdempotenceException when a duplicate request is detected while the original is still in progress (previously this path did not raise reliably). Integrate this explicitly rather than treating it as an error:
IdempotenceException to a user-facing failure. Treat it as HTTP 409-like semantics and re-poll status or return a "processing" state.try/catch (IdempotenceException) inside the service layer, not in controllers.phpunit and pestphp using mocked SDK responses. Validate against Laravel’s LTS (e.g., 10.x) and PHP 8.1+.IdempotenceException for duplicate requests still in progress. This is a behavioral change to error surfaces — any retry middleware that previously swallowed or ignored this path will now receive an exception. Consumers on versions <= 11.2.0 were silently exposed to the in-flight gap; this release closes it.Cache::remember) or SDK-specific idempotency keys, and add explicit handling for IdempotenceException as a recoverable, non-terminal state. Add regression tests asserting the exception is caught and the request is not re-submitted blindly.failed_jobs table for retries and dead-letter queues.ProcessPaymentJob) with queue monitoring (e.g., Horizon).paymentPattern enum value in MultiplePaymentInformation can arrive on payloads your code does not recognize, producing ValueError/unhandled enum casts if you map SDK enums directly to Eloquent casts or DB enums.string and resolve lazily. Add a "unknown enum" fallback branch and cover it in contract tests before pinning the update.PaymentGatewayException with HTTP status codes)?Number package intervene?logs table or a custom payments table integrate with SDK events?IdempotenceException Contract (new): What is the documented retry/backoff guidance when this exception is raised? Does the SDK expose the original request key so we can correlate and poll status?paymentPattern Semantics (new): What does the new enum value represent, and is it emitted only for multi-payment information payloads? Does any existing match/switch in our code become non-exhaustive?$app->singleton(PaymentGateway::class, fn () => new OnlinePayments(
config('services.payment.key'),
config('services.payment.secret'),
config('services.payment.env')
));
Payment::charge()) while keeping core logic in a service class.Gate::define('create_payment')) to restrict access.Http client, adding middleware for:
LogRequests middleware.RetryFailedRequests middleware — configure this to exclude IdempotenceException from retry, since the SDK now surfaces it for in-flight duplicates; blind retry defeats the fix.ThrottleRequests middleware.$client = app(HttpClient::class)->withOptions([
'base_uri' => config('services.payment.api_url'),
'headers' => ['X-API-Key' => config('services.payment.key')],
]);
class Payment extends Model {
protected $dispatchesEvents = [
'created' => PaymentCharged::class,
'updated' => PaymentRefunded::class,
];
}
paymentPattern stored as a plain string column to absorb the 11.2.1 enum addition without a migration.Modules/Payments).amount in cents").IdempotenceException is surfaced (write a test that forces a duplicate in-flight request).catch/retry around SDK calls for the new exception type.paymentPattern usages for non-exhaustive match expressions; add default branches.^8.1) and Laravel (e.g., ^10.0) versions in composer.json.platform-check to resolve dependency conflicts (e.g., Guzzle, Symfony components).^11.2 constraint; treat the exception-raising change as a behavioral patch requiring code review even though the version is minor.| Environment | PHP | Laravel | SDK Version | Notes |
|---|---|---|---|---|
| Local (Docker) | 8.2 | 10.x | 11.2.1 | Use valet or laravel-sail |
| CI (GitHub Actions) | 8.1 | 9.x | 11.2.1 | Test oldest supported |
| Staging | 8.1 | 10.x | 11.2.1 | Mirror production; run duplicate-request test |
php artisan vendor:publish --tag=payment-config)..env with provider credentials.PaymentService class to wrap SDK methods.Payment::charge()).ProcessRefundJob).database or redis).POST /payment/webhook) with Laravel’s Route::post.PaymentWebhookHandled).monolog channel for payment events).laravel-metrics for success/failure rates).IdempotenceException handling and enum fallback ship — do not bundle the dependency bump with the error-handling change in a single deploy.config/services/payment.php with environment overrides.config:cache for runtime optimization.IdempotenceException semantics and paymentPattern enum growth; both are areas where our contract tests must stay ahead of the SDK.IdempotenceException — what the customer sees, when to re-poll, when to contact the provider. Frontline support must not treat it as a failed payment.paymentPattern values are a silent-support-ticket generator if unhandled.IdempotenceException handling encourages status-polling, which adds read volume; monitor provider rate limits under load.IdempotenceException: If not caught, in-flight duplicates surface as 500s in Laravel’s exception handler. Mitigation: dedicated exception handler mapping to a 202 Accepted/processing response.paymentPattern value hits a match without a default → UnhandledMatchError on multi-payment info flows. Mitigation: default branch + string storage + alerting on unknown values.paymentPattern) to the standard suite — small effort, high leverage.How can I help you explore Laravel packages today?