Install Dependencies
composer require payum/payum payum/sips ekyna/payum-sips
Ensure payum/payum-bundle is installed if using Laravel’s PayumBundle.
Configure Payum
Add the SIPS gateway to your Payum configuration (e.g., in config/payum.php):
'gateways' => [
'sips' => [
'factory' => 'ekyna_payum_sips',
'config' => [
'username' => env('SIPS_USERNAME'),
'password' => env('SIPS_PASSWORD'),
'test_mode' => env('SIPS_TEST_MODE', true), // Use sandbox first
'url' => env('SIPS_URL', 'https://sips.atos.net'),
],
],
],
First Use Case: Initiate a Payment
Create a service to handle payments (e.g., app/Services/PaymentService.php):
use Payum\Core\Payum;
use Payum\Core\Request\Capture;
class PaymentService {
protected $payum;
public function __construct(Payum $payum) {
$this->payum = $payum;
}
public function capturePayment(float $amount, array $details) {
$gateway = $this->payum->getGateway('sips');
$request = new Capture([
'amount' => $amount,
'currency' => 'EUR',
'details' => $details,
]);
$gateway->execute($request);
return $request->getModel();
}
}
Register the Service
Bind the service in AppServiceProvider:
public function register() {
$this->app->bind(PaymentService::class, function ($app) {
return new PaymentService($app->make(Payum::class));
});
}
Trigger a Payment in a Controller
use App\Services\PaymentService;
class CheckoutController extends Controller {
public function checkout(PaymentService $paymentService) {
$result = $paymentService->capturePayment(100.00, [
'orderId' => 'ORD-123',
'customerEmail' => 'user@example.com',
]);
return redirect()->route('payment.success')->with('payment', $result);
}
}
Payment Capture with Redirect
Use Authorize for payments requiring redirect (e.g., 3D Secure):
$authorizeRequest = new Authorize([
'amount' => 100.00,
'currency' => 'EUR',
'details' => ['orderId' => 'ORD-123'],
'redirectUrl' => route('payment.redirect'),
]);
$gateway->execute($authorizeRequest);
return $authorizeRequest->getRedirectUrl();
Handling Redirect Responses Create a route to process the redirect:
Route::post('/payment/redirect', function (Request $request) {
$payum = app(Payum::class);
$gateway = $payum->getGateway('sips');
$statusRequest = new GetHumanStatus();
$statusRequest->setToken($request->input('token'));
$gateway->execute($statusRequest);
return view('payment.status', ['status' => $statusRequest->getStatus()]);
});
Refunds and Cancellations
Use Refund or Cancel requests:
$refundRequest = new Refund([
'reference' => 'SIPS_REF_123', // SIPS transaction ID
'amount' => 50.00,
]);
$gateway->execute($refundRequest);
Webhook Integration Implement a controller to handle SIPS webhooks:
class SipsWebhookController extends Controller {
public function handleWebhook(Request $request) {
$payum = app(Payum::class);
$gateway = $payum->getGateway('sips');
$notifyRequest = new Notify([
'request' => $request->all(),
]);
$gateway->execute($notifyRequest);
return response()->json(['status' => 'success']);
}
}
Add the route:
Route::post('/payum/sips/webhook', [SipsWebhookController::class, 'handleWebhook']);
Async Processing with Queues Dispatch payment events to queues for async handling:
use Illuminate\Support\Facades\Queue;
$paymentService->capturePayment(100.00, $details);
Queue::push(new ProcessPayment($details));
Laravel Events Dispatch custom events for payment status changes:
event(new PaymentProcessed($result));
Listen to events in EventServiceProvider:
protected $listen = [
PaymentProcessed::class => [
SendPaymentConfirmation::class,
UpdateOrderStatus::class,
],
];
Database Storage
Store payment results in a payments table:
$payment = Payment::create([
'gateway' => 'sips',
'reference' => $result['reference'],
'amount' => $amount,
'status' => $result['status'],
'metadata' => $result,
]);
Testing Use Payum’s test utilities or mock the SIPS API:
$this->mock(SipsGateway::class)->shouldReceive('execute')->once();
Webhook Signature Validation SIPS webhooks require HMAC signature validation. Implement this in your controller:
public function handleWebhook(Request $request) {
$expectedSignature = hash_hmac('sha256', $request->getContent(), env('SIPS_WEBHOOK_SECRET'));
if (!hash_equals($expectedSignature, $request->header('X-Sips-Signature'))) {
abort(403, 'Invalid signature');
}
// Process webhook
}
Idempotency SIPS may reject duplicate requests. Use idempotency keys:
$captureRequest->setIdempotencyKey(Str::uuid());
Test Mode Quirks
Ensure test_mode is set to true in sandbox environments. Some SIPS test endpoints may behave differently.
Timeouts SIPS API calls may timeout. Configure Payum’s HTTP client:
'http_client' => [
'timeout' => 30, // seconds
],
Currency and Amount Formatting
SIPS expects amounts in minor units (e.g., 100.00 as 10000 for EUR). Validate this:
$amountInMinorUnits = (int) ($amount * 100);
Enable Payum Debug Mode
Payum::setDebug(true);
Logs will appear in storage/logs/payum.log.
Log Raw Responses Extend the gateway to log requests/responses:
$gateway->getHttpClient()->setOption('debug', true);
SIPS Sandbox Testing Use Atos’s SIPS sandbox for testing. Common test credentials:
testtesthttps://sips-test.atos.netEnvironment Variables
Store sensitive SIPS credentials in .env:
SIPS_USERNAME=your_username
SIPS_PASSWORD=your_password
SIPS_WEBHOOK_SECRET=your_webhook_secret
SIPS_TEST_MODE=true
Gateway Factory Ensure the factory is correctly registered in Payum’s configuration. Example:
'gateways' => [
'sips' => [
'factory' => 'ekyna_payum_sips',
'config' => [...],
],
],
Custom Storage
If using Payum’s storage (e.g., for tokens), configure it in config/payum.php:
'storage' => [
'orm' => [
'db_options' => [
'driver' => 'mysql',
'host' => env('DB_HOST'),
'dbname' => env('DB_DATABASE'),
'user' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
],
],
],
class CustomSipsRequest extends Request {
public
How can I help you explore Laravel packages today?