brazilianfriendsofsymfony/pagseguro-bundle
Installation:
composer require brazilianfriendsofsymfony/pagseguro-bundle
Add the bundle to config/bundles.php:
return [
// ...
BrazilianFriendsOfSymfony\PagSeguroBundle\BFOSPagSeguroBundle::class => ['all' => true],
];
Configuration: Publish the default config:
php bin/console bfos:pagseguro:install
Update config/packages/bfos_pagseguro.yaml with your PagSeguro credentials (email, token, environment).
First Use Case: Create a transaction via the CLI or controller:
use BrazilianFriendsOfSymfony\PagSeguroBundle\Service\PagSeguroService;
class PaymentController extends AbstractController
{
public function create(PagSeguroService $pagSeguroService)
{
$transaction = $pagSeguroService->createTransaction([
'amount' => 100.00,
'currency' => 'BRL',
'itemCode' => 'PROD-001',
'itemDescription' => 'Product Name',
'itemAmount' => 100.00,
'reference' => 'ORDER-123',
]);
return new Response($transaction->getCheckoutUrl());
}
}
Webhook Setup: Configure PagSeguro’s webhook URL in your PagSeguro account dashboard to point to:
/bfos/pagseguro/webhook
The bundle automatically validates and processes notifications.
Transaction Creation:
Use PagSeguroService to initiate transactions:
$pagSeguroService->createTransaction([
'amount' => $order->getTotal(),
'currency' => 'BRL',
'reference' => $order->getId(),
'sender' => [
'name' => $customer->getName(),
'email' => $customer->getEmail(),
],
'shipping' => [
'address' => $order->getShippingAddress(),
],
'items' => $order->getItems()->map(function ($item) {
return [
'id' => $item->getSku(),
'description' => $item->getName(),
'quantity' => $item->getQuantity(),
'amount' => $item->getPrice(),
];
}),
]);
Webhook Handling:
The bundle auto-validates and processes notifications via the NotificationHandler. Extend NotificationHandler to customize logic:
// config/packages/bfos_pagseguro.yaml
bfos_pagseguro:
notification_handler: App\Service\CustomNotificationHandler
Querying Transactions:
Use the TransactionRepository to fetch transactions:
$transactions = $transactionRepository->findBy(['reference' => 'ORDER-123']);
$transaction = $transactions->first();
Refunds/Cancellations:
$pagSeguroService->cancelTransaction($transaction->getCode());
// or
$pagSeguroService->refundTransaction($transaction->getCode(), 50.00);
Order State Machine:
Tie transaction states (CREATED, APPROVED, PENDING, REJECTED) to your order workflow:
// Example: Update order status on notification
public function onNotification(Notification $notification)
{
$order = $this->orderRepository->findOneBy(['reference' => $notification->getReference()]);
if ($notification->getType() === 'transaction' && $notification->getStatus() === 'approved') {
$order->setStatus('PAID');
$this->orderRepository->save($order);
}
}
Testing:
Use PagSeguro’s sandbox environment (configured via environment: sandbox in YAML). Mock the PagSeguroService in tests:
$this->mock(PagSeguroService::class)
->shouldReceive('createTransaction')
->andReturn(new Transaction(['checkoutUrl' => 'http://sandbox.pagseguro.com.br/checkout']));
Logging: Enable debug logging for transactions:
# config/packages/monolog.yaml
handlers:
bfos_pagseguro:
type: stream
path: "%kernel.logs_dir%/bfos_pagseguro.log"
level: debug
Custom Fields:
Pass additional PagSeguro fields via the customFields array:
$pagSeguroService->createTransaction([
'customFields' => [
'custom1' => 'value1',
'custom2' => 'value2',
],
]);
Webhook Validation:
Notification::getNotificationCode() to deduplicate processing:
public function onNotification(Notification $notification)
{
if ($this->processedNotifications->contains($notification->getNotificationCode())) {
return;
}
$this->processedNotifications->add($notification->getNotificationCode());
// Process logic...
}
Currency/Amount Precision:
number_format($amount, 2, '.', '') when passing amounts.Sandbox vs. Production:
environment in bfos_pagseguro.yaml:
environment: sandbox # For testing
# environment: production # For live
Transaction Timeouts:
$this->messageBus->dispatch(new ProcessPagSeguroTransaction($transactionData));
Enable Verbose Logging:
bfos_pagseguro:
debug: true
Logs will include raw PagSeguro responses/errors.
Check Database:
bfos_pagseguro_transaction and bfos_pagseguro_notification tables for missing records.php bin/console doctrine:schema:validate to check migrations.PagSeguro API Errors:
error field in the response:
try {
$transaction = $pagSeguroService->createTransaction($data);
} catch (\Exception $e) {
$error = json_decode($e->getMessage(), true);
// Handle PagSeguro-specific errors (e.g., $error['error']['code'] === 'invalid_amount')
}
Custom Notification Types:
Extend the NotificationHandler to handle non-standard notifications:
class CustomNotificationHandler extends NotificationHandler
{
protected function handleCustomNotification(Notification $notification)
{
// Logic for custom notification types
}
public function supports(Notification $notification)
{
return parent::supports($notification) || $notification->getType() === 'custom';
}
}
Pre/Post Transaction Hooks: Use Symfony’s event system to intercept transactions:
// src/EventListener/PagSeguroTransactionListener.php
class PagSeguroTransactionListener
{
public function onTransactionCreated(TransactionEvent $event)
{
$transaction = $event->getTransaction();
// Add custom logic (e.g., send email)
}
}
Register the listener in services.yaml:
services:
App\EventListener\PagSeguroTransactionListener:
tags:
- { name: kernel.event_listener, event: bfos_pagseguro.transaction.created }
Override Transaction Entity:
Extend BrazilianFriendsOfSymfony\PagSeguroBundle\Entity\Transaction to add custom fields:
#[ORM\Entity]
class CustomTransaction extends Transaction
{
#[ORM\Column(type: 'string', nullable: true)]
private $customField;
// Getters/setters...
}
Update bfos_pagseguro.yaml:
bfos_pagseguro:
transaction_class: App\Entity\CustomTransaction
PagSeguroClient:
bfos_pagseguro:
client:
class: App\
How can I help you explore Laravel packages today?