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

Payone Symfony Bundle Laravel Package

andrepayone/payone-symfony-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle

    composer require andrepayone/payone-symfony-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        Andrepayone\PayoneBundle\PayoneBundle::class => ['all' => true],
    ];
    
  2. Configure PAYONE Add your credentials to config/packages/payone.yaml:

    payone:
        merchant_id: '%env(PAYONE_MERCHANT_ID)%'
        secret_key: '%env(PAYONE_SECRET_KEY)%'
        endpoint: '%env(PAYONE_ENDPOINT)%'  # e.g., 'https://payone.com/api/v1'
    
  3. First Use Case: Create a Payment Use the PayoneClient service to initiate a payment:

    use Andrepayone\PayoneBundle\Service\PayoneClient;
    
    class PaymentController extends AbstractController
    {
        public function createPayment(PayoneClient $payoneClient): Response
        {
            $payment = $payoneClient->createPayment([
                'amount' => 10.00,
                'currency' => 'EUR',
                'order_id' => 'order_123',
                'description' => 'Test payment',
                'success_url' => $this->generateUrl('payment_success'),
                'fail_url' => $this->generateUrl('payment_fail'),
            ]);
    
            return $this->redirect($payment->getRedirectUrl());
        }
    }
    
  4. Verify Callback Handling Ensure your payment_success and payment_fail routes handle the PAYONE callback parameters (e.g., payone_transaction_id, payone_status).


Implementation Patterns

Workflow: Payment Flow

  1. Initiate Payment Use PayoneClient::createPayment() to generate a payment request. The SDK returns a redirect URL for the customer.

  2. Handle Callback After payment, PAYONE redirects to your success_url or fail_url. Validate the callback using:

    $payoneClient->validateCallback($request);
    

    This ensures the request is legitimate (e.g., checks payone_signature).

  3. Process Asynchronous Notifications PAYONE sends webhook notifications for status updates. Create a route to handle these:

    # config/routes.yaml
    payone_webhook:
        path: /payone/webhook
        controller: App\Controller\PayoneWebhookController::handleWebhook
    

    Validate and process the notification:

    public function handleWebhook(Request $request, PayoneClient $payoneClient): Response
    {
        if ($payoneClient->validateWebhook($request)) {
            $notification = $payoneClient->processWebhook($request);
            // Update your database or trigger logic based on $notification.
        }
        return new Response('OK');
    }
    

Integration Tips

  • Laravel-Specific: Use Symfony’s HttpFoundation components via Laravel’s Symfony\Contracts\HttpClient or Guzzle for HTTP requests if needed.
  • Database Sync: Store payone_transaction_id in your orders table to link payments to orders.
  • Logging: Log webhook payloads for debugging:
    \Monolog\Logger::getInstance()->info('PAYONE Webhook', ['data' => $request->getContent()]);
    
  • Testing: Use PAYONE’s sandbox endpoint (endpoint: 'https://sandbox.payone.com/api/v1') and mock the PayoneClient in tests:
    $this->mock(PayoneClient::class)->shouldReceive('createPayment')->andReturn(new PaymentResponse('https://sandbox.payone.com/redirect'));
    

Gotchas and Tips

Pitfalls

  1. Callback Validation

    • Issue: Skipping validateCallback() or validateWebhook() exposes your app to fraudulent requests.
    • Fix: Always validate signatures and IP addresses (configured in PAYONE merchant settings).
  2. Idempotency

    • Issue: Webhook notifications may be retried. Process them idempotently (e.g., check if payone_transaction_id exists in your DB before acting).
    • Fix: Use a database check or a queue (e.g., Laravel Queues) to handle duplicates.
  3. Endpoint Configuration

    • Issue: Using the wrong endpoint (live vs. sandbox) can cause payments to fail silently.
    • Fix: Use environment variables and validate the endpoint in config:
      payone:
          endpoint: '%env(PAYONE_ENDPOINT)%'
      
      Ensure PAYONE_ENDPOINT is set correctly in .env.
  4. Currency/Amount Formatting

    • Issue: PAYONE expects amounts in minor units (e.g., 1000 for €10.00). Passing floats (e.g., 10.00) may fail.
    • Fix: Convert amounts to integers:
      $amount = 1000; // Not 10.00
      
  5. Timeouts

    • Issue: PAYONE API calls may time out if your server is slow.
    • Fix: Increase Symfony’s HTTP client timeout (if using Symfony’s client) or use Guzzle with retries:
      $client = new \GuzzleHttp\Client(['timeout' => 30]);
      

Debugging Tips

  • Enable SDK Logging: Configure the underlying payone-sdk to log requests/responses:
    payone:
        debug: true  # Adds logging to Symfony's logger
    
  • Check Headers: Ensure Content-Type: application/json is set for API calls.
  • Test with Postman: Manually test API endpoints using PAYONE’s sandbox credentials before integrating.

Extension Points

  1. Custom Payment Methods Extend the bundle by creating a custom service that wraps PayoneClient for your business logic:

    class CustomPayoneService
    {
        public function __construct(private PayoneClient $payoneClient) {}
    
        public function createSubscription(float $amount, string $customerId): PaymentResponse
        {
            return $this->payoneClient->createPayment([
                'amount' => $amount * 100,
                'currency' => 'EUR',
                'order_id' => "sub_$customerId",
                'subscription' => true,
                // ...
            ]);
        }
    }
    
  2. Event Dispatching Trigger Symfony events (e.g., kernel.event_dispatcher) after successful payments:

    $dispatcher->dispatch(new PaymentSucceededEvent($notification));
    

    Listen to events in your controllers or services.

  3. Queue Webhooks Offload webhook processing to a queue (e.g., Laravel Queues) to avoid timeouts:

    public function handleWebhook(Request $request): Response
    {
        if ($payoneClient->validateWebhook($request)) {
            ProcessWebhookJob::dispatch($request->getContent());
        }
        return new Response('OK');
    }
    
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.
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
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge