Install the Bundle:
composer require alcalyn/payplug-bundle:1.x
Register in AppKernel.php:
new Alcalyn\PayplugBundle\AlcalynPayplugBundle(),
Configure Routing:
Add to app/config/routing.yml:
alcalyn_payplug:
resource: "@AlcalynPayplugBundle/Resources/config/routing.yml"
prefix: /
Set Up Payplug Account:
Configure app/config/parameters.yml with your Payplug credentials (use ~ for placeholders initially).
Run the autoconfig command:
php app/console payplug:account:update
(Enter your Payplug email/password when prompted.)
First Payment URL Generation:
In a controller, inject the payplug.payment service and generate a payment URL:
use Alcalyn\PayplugBundle\Model\Payment;
public function checkoutAction()
{
$payment = new Payment(1600, Payment::EUROS); // 16.00 EUR
$payplugPayment = $this->get('payplug.payment');
$paymentUrl = $payplugPayment->generateUrl($payment);
return $this->redirect($paymentUrl);
}
Frontend Integration:
$payplugPayment->generateUrl($payment).payment_id or reference in your DB to track the transaction.IPN Handling:
/payplug/ipn endpoint.event.payplug.ipn to process IPNs:
# services.yml
acme.payplug_listener:
class: Acme\Bundle\Listener\PayplugListener
tags:
- { name: kernel.event_listener, event: event.payplug.ipn, method: onIpn }
public function onIpn(PayplugIPNEvent $event)
{
$ipn = $event->getIPN();
switch ($ipn->getType()) {
case 'payment_succeeded':
$this->updateOrderStatus($ipn->getReference(), 'paid');
break;
case 'payment_canceled':
$this->updateOrderStatus($ipn->getReference(), 'canceled');
break;
// Handle refunds, disputes, etc.
}
}
Testing Payments:
config.yml):
alcalyn_payplug:
test_mode: true
php app/console payplug:simulate:ipn --type=payment_succeeded --reference=ORDER123
Payment Validation:
Check Payment::validate() before generating URLs to ensure amounts/currencies are supported.
if (!$payment->validate($payplugPayment->getAccount())) {
throw new \RuntimeException('Invalid payment parameters');
}
Webhook Security:
Verify IPN signatures using Payplug’s sign parameter (handled automatically by the bundle).
Retry Logic: Implement retries for failed IPNs (e.g., network issues) by storing unprocessed IPNs in a queue.
Missing Parameters:
payplug:account:update fails, manually copy parameters from Payplug’s autoconfig page.parameters.yml to version control (use .gitignore).IPN Processing:
processed_at timestamp in your DB to deduplicate./payplug/ipn.Test Mode Quirks:
https://sandbox.payplug.com). Verify generateUrl() outputs the correct endpoint.--no-prod flag with payplug:account:update to avoid overwriting production settings:
php app/console payplug:account:update --no-prod
Deprecated Features:
Log IPNs: Add a logger to your listener to inspect raw IPN data:
$this->logger->debug('Raw IPN data:', [$event->getIPN()->getData()]);
Command-Line Testing: Generate test URLs via CLI:
php app/console payplug:generate:url --amount=1000 --currency=EUR
Common Errors:
parameters.yml matches Payplug’s settings./payplug/ipn: Verify the route is enabled and the firewall allows access.Custom IPN Handling:
Extend the IPN class to add custom fields:
namespace Acme\Bundle\Model;
use Alcalyn\PayplugBundle\Model\IPN as BaseIPN;
class IPN extends BaseIPN
{
public function getCustomField()
{
return $this->getData()['custom_field'] ?? null;
}
}
Register the service to override the default:
services:
payplug.ipn:
class: Acme\Bundle\Model\IPN
parent: payplug.ipn.base
Pre/Post-Payment Actions: Use Symfony events to hook into the payment flow:
payplug.payment.generate (before URL generation).payplug.ipn.processed (after IPN handling).Webhook Retries:
Implement a PayplugIPNListener to queue failed IPNs for retry:
public function onIpn(PayplugIPNEvent $event)
{
try {
$this->processIpn($event->getIPN());
} catch (\Exception $e) {
$this->queue->push($event->getIPN());
}
}
cache:pool).
```markdown
---
How can I help you explore Laravel packages today?