Install the Package
composer require answear/payum-pay-u
Configure Payum and PayU
Add to config/services.php:
'payum' => [
'gateways' => [
'payu' => [
'factory' => 'payu',
'payum.action.capture' => \Answear\Payum\PayU\Action\CaptureAction::class,
'payum.action.refund' => \Answear\Payum\PayU\Action\RefundAction::class,
// ... other required actions (see README)
],
],
],
Register PayU Config
Create a config file (e.g., config/payu.php):
return [
'environment' => env('PAYU_ENVIRONMENT', 'sandbox'),
'configs' => [
'pos_1234' => [
'pos_id' => env('PAYU_POS_ID'),
'signature_key' => env('PAYU_SIGNATURE_KEY'),
'oauth_client_id' => env('PAYU_OAUTH_CLIENT_ID'),
'oauth_secret' => env('PAYU_OAUTH_SECRET'),
],
],
'logger' => \Monolog\Logger::class, // Optional
];
Bind Payum Services
In a service provider (e.g., AppServiceProvider):
use Payum\Core\PayumBuilder;
use Payum\Core\Payum;
public function register()
{
$this->app->singleton(Payum::class, function ($app) {
$config = $app['config']['payu'];
$builder = new PayumBuilder();
return $builder->addGateway('payu', [
'factory' => 'payu',
'config' => $config['configs']['pos_1234'],
'actions' => [
'Payum\Core\Action\CaptureAction' => $app->make(\Answear\Payum\PayU\Action\CaptureAction::class),
// ... other actions
],
])->getPayum();
});
}
First Use Case: Capture Payment
use Payum\Core\Request\Capture;
$payum = app(Payum::class);
$gateway = $payum->getGateway('payu');
$captureToken = uniqid();
$captureRequest = new Capture($captureToken);
$captureRequest->setModel($payment); // Your payment model
$captureRequest->setModel($payment->getDetails()); // Payment details
$gateway->execute($captureRequest);
Capture request with a token and payment details.ConvertPaymentAction).NotifyAction (webhook).$token = $payum->getTokenFactory()->createCaptureToken(
'payu',
$payment,
'https://your-app.com/payment/notify' // Notify URL
);
return $payum->getHttpClient()->getRedirectClient()->getRedirect($token);
notifyUrl after payment.completed, failed).public function handle(Request $request, Closure $next)
{
if ($request->isMethod('post') && $request->routeIs('payu.notify')) {
$payum = app(Payum::class);
$notifyRequest = new \Payum\Core\Request\Notify(
$request->input('token')
);
$payum->getGateway('payu')->execute($notifyRequest);
}
return $next($request);
}
Refund request with the payment token and amount.$refundRequest = new \Payum\Core\Request\Refund($token);
$refundRequest->setAmount(1000); // Amount in smallest currency unit (e.g., 1000 PLN = 10.00 PLN)
$gateway->execute($refundRequest);
Status action to fetch the latest payment status.$statusRequest = new \Payum\Core\Request\GetStatus($token);
$gateway->execute($statusRequest);
$status = $statusRequest->getStatus(); // 'pending', 'succeeded', 'failed', etc.
Token Management:
TokenFactory to generate unique tokens for each payment. Store these in your database to link payments to orders.$token = $payum->getTokenFactory()->createCaptureToken(
'payu',
$order,
'https://your-app.com/payment/notify'
);
Payment Details:
details array with PayU-specific fields (e.g., description, currency, buyer).$payment->setDetails([
'description' => 'Order #'.$order->id,
'currency' => 'PLN',
'buyer' => [
'email' => $user->email,
'ip' => $request->ip(),
],
'products' => [
[
'name' => 'Product 1',
'unitPrice' => 1000, // 10.00 PLN
'quantity' => 2,
],
],
]);
Multi-POS Configuration:
configs array in config/payu.php to switch between sandbox and production environments dynamically.$config = config('payu.configs.'.$this->app->environment() === 'production' ? 'pos_1234' : 'pos_5678');
Logging:
'logger' => \Monolog\Logger::class,
Error Handling:
PayuApiException).try {
$gateway->execute($captureRequest);
} catch (\Answear\Payum\PayU\Exception\PayuApiException $e) {
Log::error('PayU API Error: '.$e->getMessage());
throw new \RuntimeException('Payment failed. Please try again.');
}
Testing:
environment: sandbox) for development.Payum\Core\HttpClientInterface to test actions without hitting PayU’s API.$httpClient = $this->createMock(HttpClientInterface::class);
$httpClient->method('post')->willReturn(new Response(200, [], json_encode(['status' => 'succeeded'])));
$gateway->setHttpClient($httpClient);
Missing Features:
recurring payments, mcpData, and credit fields in OrderRequest. Workaround:
Answear\Payum\PayU\Api\OrderRequest class to include these fields.class ExtendedOrderRequest extends \Answear\Payum\PayU\Api\OrderRequest
{
public function setRecurring(bool $recurring): self
{
$this->parameters['recurring'] = $recurring;
return $this;
}
}
createOrder method to use your extended class.**Signature
How can I help you explore Laravel packages today?