online-payments/sdk-php
PHP SDK for integrating Online Payments into your app. Create and manage hosted checkouts, process card and local payments, handle refunds and payouts, and verify webhooks. Built for Laravel/PHP projects with clean models, API clients, and examples.
Installation
composer require online-payments/sdk-php
Ensure the package is listed in composer.json under require.
Environment Configuration
Add to .env:
ONLINE_PAYMENTS_API_KEY=your_live_api_key
ONLINE_PAYMENTS_API_SECRET=your_live_secret
ONLINE_PAYMENTS_ENV=live # or 'sandbox' for testing
Service Provider Setup
Register the SDK in AppServiceProvider:
use OnlinePayments\SDK\OnlinePayments;
public function boot()
{
OnlinePayments::configure([
'api_key' => config('services.online_payments.key'),
'api_secret' => config('services.online_payments.secret'),
'environment' => config('services.online_payments.env'),
'timeout' => 30, // seconds
]);
}
First Integration: Charge a Payment
use OnlinePayments\SDK\Payment;
$payment = new Payment();
$payment->setAmount(100.00)
->setCurrency('USD')
->setDescription('Laravel Subscription')
->setCustomer([
'email' => 'user@example.com',
'name' => 'John Doe',
]);
try {
$response = $payment->charge();
// Handle success (e.g., save to DB, send confirmation)
} catch (\OnlinePayments\SDK\Exception\PaymentException $e) {
// Log error and handle failure
Log::error('Payment failed: ' . $e->getMessage());
}
Wrap the SDK in a Laravel service class for better testability and dependency injection:
// app/Services/PaymentService.php
namespace App\Services;
use OnlinePayments\SDK\Payment;
use OnlinePayments\SDK\OnlinePayments;
class PaymentService
{
public function __construct()
{
OnlinePayments::configure(config('services.online_payments'));
}
public function processPayment(array $data)
{
$payment = new Payment();
$payment->setAmount($data['amount'])
->setCurrency($data['currency'])
->setDescription($data['description'])
->setCustomer($data['customer']);
return $payment->charge();
}
}
Register in AppServiceProvider:
$this->app->bind(PaymentService::class, function ($app) {
return new PaymentService();
});
Use Laravel’s FormRequest to validate payment data before processing:
// app/Http/Requests/ProcessPaymentRequest.php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ProcessPaymentRequest extends FormRequest
{
public function rules()
{
return [
'amount' => 'required|numeric|min:0.50',
'currency' => 'required|string|size:3',
'description' => 'required|string|max:255',
'customer.email' => 'required|email',
];
}
}
Controller Usage:
use App\Http\Requests\ProcessPaymentRequest;
use App\Services\PaymentService;
public function pay(ProcessPaymentRequest $request, PaymentService $paymentService)
{
$response = $paymentService->processPayment($request->validated());
// ...
}
Offload payment processing to a queue job for async handling:
// app/Jobs/ProcessPaymentJob.php
namespace App\Jobs;
use App\Services\PaymentService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
class ProcessPaymentJob implements ShouldQueue
{
use Queueable;
protected $data;
public function __construct(array $data)
{
$this->data = $data;
}
public function handle(PaymentService $paymentService)
{
$paymentService->processPayment($this->data);
}
}
Dispatch from Controller:
ProcessPaymentJob::dispatch($request->validated());
Laravel routes + events for webhook processing:
// routes/web.php
Route::post('/payment/webhook', [PaymentWebhookController::class, 'handle']);
class PaymentWebhookController extends Controller
{
public function handle()
{
$payload = request()->all();
$signature = request()->header('X-Signature');
if (!OnlinePayments::validateWebhook($payload, $signature)) {
abort(403, 'Invalid signature');
}
event(new PaymentWebhookReceived($payload));
}
}
Event Listener:
// app/Listeners/HandlePaymentWebhook.php
namespace App\Listeners;
use App\Events\PaymentWebhookReceived;
class HandlePaymentWebhook
{
public function handle(PaymentWebhookReceived $event)
{
// Update DB, trigger notifications, etc.
}
}
Use Laravel middleware to retry failed payment requests:
// app/Http/Middleware/RetryPaymentRequests.php
namespace App\Http\Middleware;
use Closure;
use OnlinePayments\SDK\Exception\PaymentException;
class RetryPaymentRequests
{
public function handle($request, Closure $next, int $maxRetries = 3)
{
$attempts = 0;
while ($attempts < $maxRetries) {
try {
return $next($request);
} catch (PaymentException $e) {
$attempts++;
if ($attempts >= $maxRetries) {
throw $e;
}
sleep(2 ** $attempts); // Exponential backoff
}
}
}
}
Register Middleware:
// app/Http/Kernel.php
protected $routeMiddleware = [
'retry.payment' => \App\Http\Middleware\RetryPaymentRequests::class,
];
Apply to Route:
Route::post('/pay', [PaymentController::class, 'store'])
->middleware('retry.payment:3');
Mock the SDK in unit tests using Laravel’s MockHttpClient:
// tests/Unit/PaymentServiceTest.php
use OnlinePayments\SDK\OnlinePayments;
use OnlinePayments\SDK\Payment;
use Illuminate\Support\Facades\Http;
beforeEach(function () {
Http::fake();
});
it('processes a payment successfully', function () {
Http::fake([
'https://api.online-payments.com/v1/payments' => Http::response([
'success' => true,
'payment_id' => 'pay_123',
], 200),
]);
$service = new PaymentService();
$response = $service->processPayment([
'amount' => 100.00,
'currency' => 'USD',
'description' => 'Test',
'customer' => ['email' => 'test@example.com'],
]);
expect($response['payment_id'])->toBe('pay_123');
});
Environment Mismatches
sandbox and live environments.config('services.online_payments.env') and validate it in tests:
expect(config('services.online_payments.env'))->toBe('sandbox');
Idempotency Key Conflicts
$payment->setIdempotencyKey(strtolower(Uuid::generate()));
Webhook Signature Validation
if (!OnlinePayments::validateWebhook($payload, $signature)) {
abort(403);
}
Currency Formatting
100.00 vs. 100 for cents).10000 for $100.00):
$payment->setAmount((int) ($amount * 100));
Rate Limiting
throttle middleware:
Route::middleware(['throttle:10,1'])->group(function () {
// Payment routes
});
OnlinePayments::setLogger(function ($message)
How can I help you explore Laravel packages today?