Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Przelewy24 Bundle Laravel Package

arturwwl/przelewy24-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require arturwwl/przelewy24-bundle
    

    Register the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 3.x):

    return [
        // ...
        Arturwwl\Przelewy24Bundle\ArturwwlPrzelewy24Bundle::class => ['all' => true],
    ];
    
  2. Routing: Add to config/routes.yaml:

    arturwwl_przelewy24:
        resource: "@ArturwwlPrzelewy24Bundle/Resources/config/routing.xml"
    
  3. Configuration: Add to config/packages/arturwwl_przelewy24.yaml:

    arturwwl_przelewy24:
        sandbox: true  # Set to false for production
        merchant_id: "%env(PRZELEWY24_MERCHANT_ID)%"
        crc_key: "%env(PRZELEWY24_CRC_KEY)%"
    

First Use Case: Redirect to Payment Gateway

use Arturwwl\Przelewy24Bundle\Factory\ProcessFactory;
use Arturwwl\Przelewy24Bundle\Model\Payment;

class PaymentController extends AbstractController
{
    public function initiatePayment(ProcessFactory $processFactory): Response
    {
        $payment = (new Payment())
            ->setCurrency('PLN')
            ->setSessionId(uniqid()) // Unique order identifier
            ->setAmount(100.00)
            ->setDescription('Test payment')
            ->setEmail('customer@example.com')
            ->setStatusUrl($this->generateUrl('payment_status'))
            ->setReturnUrl($this->generateUrl('payment_return', [], UrlGeneratorInterface::ABSOLUTE_URL));

        $processFactory->setPayment($payment);
        $url = $processFactory->createAndGetUrl(
            $this->getParameter('arturwwl_przelewy24.merchant_id'),
            $this->getParameter('arturwwl_przelewy24.crc_key')
        );

        return $this->redirect($url);
    }
}

Implementation Patterns

Core Workflow: Payment Processing

  1. Initiate Payment:

    • Use ProcessFactory to create a Payment object.
    • Set required fields (sessionId, amount, currency, returnUrl, statusUrl).
    • Redirect to Przelewy24 using createAndGetUrl().
  2. Handle Callbacks:

    • Success: Listen to przelewy24.event.payment_success (via Symfony Events).
    • Status: Implement a controller for statusUrl to verify payments:
      public function paymentStatus(ProcessFactory $processFactory, Request $request): Response
      {
          $response = $processFactory->verifyPayment(
              $request->query->get('sessionId'),
              $request->query->get('amount'),
              $request->query->get('currency'),
              $request->query->get('signature')
          );
      
          if ($response->isSuccess()) {
              // Dispatch event or update order status
          }
          return new Response('OK');
      }
      
  3. Event-Driven Logic:

    • Register listeners for events:
      # config/services.yaml
      App\EventListener\Przelewy24SuccessListener:
          tags:
              - { name: kernel.event_listener, event: przelewy24.event.payment_success, method: onPaymentSuccess }
      

Integration Tips

  • Order Management: Store sessionId in your database to link payments to orders. Use it to fetch order details in event listeners.

    $order = $this->orderRepository->findOneBy(['token' => $event->getPayment()->getSessionId()]);
    
  • Testing: Use the built-in test tools (/p24-test) to simulate payments in development. Trigger fake success with /p24-fake-success/{sessionId}.

  • Customization: Extend the Payment model or override services via dependency injection:

    # config/services.yaml
    services:
        Arturwwl\Przelewy24Bundle\Model\Payment:
            arguments:
                $customField: '%some_value%'
    

Gotchas and Tips

Pitfalls

  1. Session ID Uniqueness:

    • sessionId must be unique and persistent (e.g., a database-generated token). Reusing IDs can corrupt payment tracking.
  2. URL Validation:

    • returnUrl and statusUrl must be absolute URLs (use UrlGeneratorInterface::ABSOLUTE_URL).
    • Przelewy24 rejects relative URLs, causing silent failures.
  3. Sandbox vs. Production:

    • Always test in sandbox mode (sandbox: true) before switching to production.
    • Sandbox uses test credentials; production requires live Przelewy24 keys.
  4. Event Dispatching:

    • Events are not dispatched automatically for all responses. Verify payments via the statusUrl endpoint to ensure events fire.
  5. CRC Key Sensitivity:

    • The crc_key must match exactly (case-sensitive) between your config and Przelewy24’s merchant settings.

Debugging

  • Verify Payments Manually: Use the test tool (/p24-test) to check if your statusUrl endpoint is reachable and correctly processes Przelewy24’s callbacks.

  • Log Events: Add logging to event listeners to debug:

    public function onPaymentSuccess(PaymentEventInterface $event)
    {
        $this->logger->info('Payment success', [
            'sessionId' => $event->getPayment()->getSessionId(),
            'amount' => $event->getPayment()->getAmount(),
        ]);
    }
    
  • Check Guzzle Responses: If payments fail silently, enable Guzzle logging:

    $processFactory->setClient($this->createClientWithLogging());
    

Extension Points

  1. Custom Payment Data: Extend the Payment model to add fields:

    class CustomPayment extends Payment
    {
        private $customField;
    
        public function setCustomField($value): self
        {
            $this->customField = $value;
            return $this;
        }
    }
    

    Override the service in config/services.yaml:

    services:
        Arturwwl\Przelewy24Bundle\Model\Payment: '@App\Model\CustomPayment'
    
  2. Override ProcessFactory: Create a decorator to modify behavior:

    class CustomProcessFactoryDecorator implements ProcessFactoryInterface
    {
        private $decorated;
    
        public function __construct(ProcessFactory $decorated)
        {
            $this->decorated = $decorated;
        }
    
        public function createAndGetUrl($merchantId, $crcKey)
        {
            // Add custom logic (e.g., logging)
            return $this->decorated->createAndGetUrl($merchantId, $crcKey);
        }
    }
    

    Register it as a replacement in config/services.yaml.

  3. Add New Events: Extend the bundle’s event system by creating custom events and dispatching them in listeners:

    class PaymentProcessedEvent extends Event
    {
        // ...
    }
    

    Dispatch in a listener:

    $eventDispatcher->dispatch(new PaymentProcessedEvent($payment));
    

Configuration Quirks

  • Environment Variables: Use Symfony’s %env() syntax for sensitive data (e.g., merchant_id and crc_key). Example in .env:

    PRZELEWY24_MERCHANT_ID=your_merchant_id
    PRZELEWY24_CRC_KEY=your_crc_key
    
  • Bundle Parameters: Access config via:

    $merchantId = $this->getParameter('arturwwl_przelewy24.merchant_id');
    

    Or inject the config directly:

    public function __construct(array $config)
    {
        $this->merchantId = $config['merchant_id'];
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle