birim/laravel-payone
Laravel wrapper for the PAYONE payment gateway. Provides a Payone facade to send API requests (e.g., preauthorization, createaccess), publishable config for credentials and test/live mode, and helpers to override settings at runtime.
Installation:
composer require birim/laravel-payone
Publish the config file:
php artisan vendor:publish --provider="Birim\Payone\PayoneServiceProvider" --tag="config"
Add your PAYONE credentials to .env:
PAYONE_MERCHANT_ID=your_merchant_id
PAYONE_MERCHANT_PASSWORD=your_password
PAYONE_TEST_MODE=true # Set to false for live
First Use Case: Create a payment intent for a test transaction:
use Birim\Payone\Facades\Payone;
$payment = Payone::createPayment([
'amount' => 10.00,
'currency' => 'EUR',
'description' => 'Test Order #123',
'customer' => [
'email' => 'customer@example.com',
'ip' => request()->ip(),
],
'payment_methods' => ['creditcard'],
]);
return redirect()->to($payment->getRedirectUrl());
Where to Look First:
config/payone.php for configuration options.app/Http/Controllers/PaymentController.php (example controller in the package).Payment Creation & Redirection:
// Create a payment with dynamic data
$payment = Payone::createPayment([
'amount' => $order->total,
'currency' => $order->currency,
'description' => 'Order #'.$order->id,
'customer' => [
'email' => $order->email,
'ip' => request()->ip(),
'language' => app()->getLocale(),
],
'payment_methods' => ['creditcard', 'ideal', 'sepa'],
'additional_data' => ['order_id' => $order->id], // Store for callback
]);
// Redirect to PAYONE
return redirect()->to($payment->getRedirectUrl());
Handling Callbacks:
Register a route for PAYONE callbacks (e.g., POST /payone/callback):
Route::post('/payone/callback', [PaymentController::class, 'handleCallback']);
Process the callback in your controller:
public function handleCallback(Request $request)
{
$payment = Payone::verifyCallback($request->all());
if ($payment->isSuccessful()) {
// Update order status, send confirmation, etc.
$order = Order::find($payment->additional_data['order_id']);
$order->update(['status' => 'paid']);
}
return response()->json(['status' => 'success']);
}
Refunds & Cancellations:
// Refund a payment
$refund = Payone::createRefund($paymentId, [
'amount' => 5.00,
'currency' => 'EUR',
'description' => 'Partial refund for order #123',
]);
// Cancel a payment (if not yet settled)
$cancel = Payone::cancelPayment($paymentId);
payment_id and additional_data in your database to correlate callbacks with orders.PAYONE_WEBHOOK_URL in config).4111111111111111 for credit cards) in sandbox mode.language in the customer object to match PAYONE’s UI (e.g., 'de' for German).idempotency_key in createPayment() to avoid duplicate transactions.Callback Verification:
Payone::verifyCallback() to validate PAYONE’s signature. Skipping this exposes you to fraud.// ❌ UNSAFE: Trusting raw request data
$paymentStatus = $request->input('status');
// ✅ SAFE: Verified callback
$payment = Payone::verifyCallback($request->all());
$paymentStatus = $payment->status;
Test Mode Quirks:
PAYONE_TEST_MODE=true) does not use real payment methods. Use PAYONE’s test cards.authentication_failed) may not mirror live behavior. Refer to PAYONE’s test documentation.Currency & Amount:
10.00 EUR → 1000 cents). The package handles this, but ensure your database stores amounts consistently.USD) will fail silently. Check config/payone.php for allowed currencies.Redirect URLs:
PAYONE_SUCCESS_URL and PAYONE_FAILURE_URL in .env. These must be HTTPS in production.Rate Limits:
try {
$payment = Payone::createPayment(...);
} catch (\Birim\Payone\Exceptions\ApiException $e) {
if ($e->getCode() === 429) {
sleep(2); // Retry after 2 seconds
retry();
}
throw $e;
}
Enable Logging:
Add to config/payone.php:
'debug' => env('PAYONE_DEBUG', false),
Logs will appear in storage/logs/laravel.log.
API Response Inspection:
The package throws \Birim\Payone\Exceptions\ApiException with raw responses. Catch and log them:
try {
$payment = Payone::createPayment(...);
} catch (\Birim\Payone\Exceptions\ApiException $e) {
\Log::error('PAYONE API Error', ['response' => $e->getResponse()]);
throw $e;
}
Common Error Codes:
| Code | Meaning | Solution |
|---|---|---|
| 400 | Invalid request | Validate input data (e.g., currency). |
| 401 | Authentication failed | Check PAYONE_MERCHANT_ID/PAYONE_PASSWORD. |
| 402 | Insufficient funds | Notify customer or retry. |
| 403 | Payment method not allowed | Check payment_methods in config. |
| 500 | Server error | Contact PAYONE support. |
Custom Payment Methods:
Extend the package by adding new payment methods to config/payone.php:
'payment_methods' => [
'creditcard' => [
'name' => 'Credit Card',
'supported' => true,
],
'your_custom_method' => [
'name' => 'Custom Payment',
'supported' => true,
'config' => ['param1' => 'value1'],
],
];
Middleware for Authenticated Payments: Protect payment routes with Laravel middleware:
Route::post('/create-payment', function () {
// ...
})->middleware('auth');
Event Listeners:
Dispatch events for payment lifecycle hooks (e.g., payment.created, payment.succeeded):
// In EventServiceProvider
protected $listen = [
\Birim\Payone\Events\PaymentCreated::class => [
\App\Listeners\LogPaymentAttempt::class,
],
];
4. **Testing**:
Use Laravel’s HTTP tests to mock PAYONE responses:
```php
public function test_payment_creation()
{
Payone::shouldReceive('createPayment')
->once()
->andReturn(new \Birim\Payone\Models\Payment(['status' => 'success']));
$response = $this->post('/create-payment');
$response->assertRedirect();
}
How can I help you explore Laravel packages today?