Weave 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

Mvola Bundle Laravel Package

dahromy/mvola-bundle

Symfony bundle for integrating the MVola payment gateway. Provides MVola API authentication, services to initiate payments, check status and fetch transaction details, callback handling for notifications, plus configurable retries and token caching.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:
    composer require dahromy/mvola-bundle
    
  2. Configure (config/packages/mvola.yaml):
    mvola:
        environment: '%env(MVOLA_ENVIRONMENT)%'
        merchant_number: '%env(MVOLA_MERCHANT_NUMBER)%'
        consumer_key: '%env(MVOLA_CONSUMER_KEY)%'
        consumer_secret: '%env(MVOLA_CONSUMER_SECRET)%'
        auth_url: '%env(MVOLA_AUTH_URL)%'
    
  3. Environment Variables (.env):
    MVOLA_ENVIRONMENT=sandbox
    MVOLA_MERCHANT_NUMBER=your_merchant_number
    MVOLA_CONSUMER_KEY=your_key
    MVOLA_CONSUMER_SECRET=your_secret
    MVOLA_AUTH_URL=https://sandbox.mvola.mg/token
    

First Use Case: Initiate a Payment

// src/Controller/PaymentController.php
use DahRomy\MVola\Service\MVolaService;
use DahRomy\MVola\Model\TransactionRequest;

class PaymentController extends AbstractController
{
    public function __construct(private MVolaService $mvolaService) {}

    public function pay()
    {
        $request = new TransactionRequest();
        $request->setAmount(1000)
            ->setCurrency('Ar')
            ->setDescriptionText('Order #123')
            ->setDebitParty([['key' => 'msisdn', 'value' => '0343500003']])
            ->setCallbackData(['order_id' => '123']);

        $response = $this->mvolaService->initiateTransaction($request);
        return new JsonResponse($response);
    }
}

Verify Callback Endpoint

Ensure your server accepts PUT requests at /mvola/callback (default route). Test with:

curl -X PUT -H "Content-Type: application/json" -d '{"data": {...}}' http://your-app.test/mvola/callback

Implementation Patterns

Core Workflow: Payment Flow

  1. Initiate Payment:
    $transaction = $mvolaService->initiateTransaction($request);
    // Store $transaction->getServerCorrelationId() in DB
    
  2. Check Status (Polling):
    $status = $mvolaService->getTransactionStatus($serverCorrelationId);
    
  3. Handle Callback (Webhook):
    // In MVolaCallbackSubscriber
    public function onMVolaCallback(MVolaCallbackEvent $event) {
        $data = $event->getMVolaData();
        $callbackData = $event->getCallbackData(); // Your stored order_id
        // Update DB/order status
    }
    

Integration Tips

  • Database Sync: Store serverCorrelationId and originalTransactionReference to link callbacks to orders.
  • Retry Logic: Use max_retries and retry_delay in config for transient failures.
  • Testing: Use MVOLA_ENVIRONMENT=sandbox and mock the callback endpoint during development.

Common Patterns

Use Case Implementation Pattern
One-time payments initiateTransaction() + callback handling
Recurring payments Store originalTransactionReference and reuse
Refunds Use getTransactionDetails() to fetch transactionId
Webhook validation Verify signature in MVolaCallbackEvent

Gotchas and Tips

Pitfalls

  1. Callback Validation:

    • MVola sends callbacks with a signature header. Verify it matches:
      $signature = $request->headers->get('X-MVola-Signature');
      $expected = hash_hmac('sha256', $rawBody, $consumerSecret);
      if (!hash_equals($signature, $expected)) {
          throw new \RuntimeException('Invalid callback signature');
      }
      
    • Tip: Extend MVolaCallbackSubscriber to add validation.
  2. Rate Limiting:

    • MVola may throttle requests. Use max_retries and implement exponential backoff:
      $retryDelay = 1000 * (2 ** $attempt);
      sleep($retryDelay);
      
  3. Timeouts:

    • API calls may hang. Set a timeout in HttpClient (Symfony 5.3+):
      # config/packages/http_client.yaml
      framework:
          http_client:
              plugins:
                  - timeout: 30
      
  4. Sandbox vs. Production:

    • Always test in sandbox first. Use .env to switch:
      MVOLA_AUTH_URL=https://sandbox.mvola.mg/token  # Sandbox
      MVOLA_AUTH_URL=https://api.mvola.mg/token       # Production
      

Debugging

  • Enable Logging:
    # config/packages/mvola.yaml
    mvola:
        debug: true  # Logs raw API requests/responses
    
  • Check Exceptions: Catch specific exceptions (e.g., MVolaValidationException) for granular error handling.

Extension Points

  1. Custom Callback Logic:

    • Override the default callback route by binding a custom controller:
      # config/routes.yaml
      mvola.callback:
          path: /custom/mvola/callback
          controller: App\Controller\CustomMVolaCallbackController::handle
      
    • Update the bundle’s callback_url in TransactionRequest.
  2. Token Caching:

    • Extend MVolaAuthService to use a custom cache adapter (e.g., Redis):
      $cache = new RedisAdapter();
      $authService = new MVolaAuthService($cache, $config);
      
  3. Webhook Retries:

    • Implement a dead-letter queue for failed callbacks using Symfony Messenger:
      // In MVolaCallbackSubscriber
      $message = new MVolaCallbackMessage($data);
      $this->messageBus->dispatch($message);
      

Configuration Quirks

  • Environment Variables:
    • Prefix all MVOLA_* vars with APP_ if using Symfony’s default .env parser:
      APP_MVOLA_ENVIRONMENT=sandbox
      
  • Default Values:
    • cache_ttl defaults to 3600 (1 hour). Reduce for testing:
      mvola:
          cache_ttl: 60  # 1 minute
      
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.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table