PHPackages                             otobul/epaybg-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. otobul/epaybg-bundle

ActiveSymfony-bundle

otobul/epaybg-bundle
====================

Symfony bundle for the ePay.bg communication package for merchants.

v2.0.0(2mo ago)192MITPHPPHP ^7.2.5 || ^8.0

Since Apr 12Pushed 2mo ago2 watchersCompare

[ Source](https://github.com/ggabrovski/epaybg-bundle)[ Packagist](https://packagist.org/packages/otobul/epaybg-bundle)[ RSS](/packages/otobul-epaybg-bundle/feed)WikiDiscussions master Synced today

READMEChangelog (6)Dependencies (8)Versions (11)Used By (0)

Symfony bundle for ePay.bg
==========================

[](#symfony-bundle-for-epaybg)

OtobulEpaybgBundle is symfony bundle to help working with ePay.bg communication package for merchants.

1. Installation
---------------

[](#1-installation)

Install the package with:

```
composer require otobul/epaybg-bundle
```

If you're *not* using Symfony Flex, you'll also need to enable the `Otobul\EpaybgBundle\OtobulEpaybgBundle`in your `config/bundles.php` file and configure the bundle.

2. Configuration
----------------

[](#2-configuration)

### 2.1 Configure the bundle

[](#21-configure-the-bundle)

Configure the bundle in **packages/otobul\_epaybg.yaml**

```
otobul_epaybg:
    # Identification number of the merchant
    min: '%env(OTOBUL_EPAYBG_MIN)%'

    # The secret word of the merchant
    secret: '%env(OTOBUL_EPAYBG_SECRET)%'

    # If true all requests will be sent to ePay.bg’s Demo System
    isDemo: '%env(bool:OTOBUL_EPAYBG_IS_DEMO)%'
```

The default values can be listed with:

```
php bin/console config:dump otobul_epaybg
```

To work properly you need also to configure dev env files. If you don`t have access to ePay.bg demo system you can visit and make registration to get demo merchant number and secret keys.

### 2.2 Configure webhook notification

[](#22-configure-webhook-notification)

To use webhook notification you need to add webhook notification route to your config. Configure the route in **config/routes/otobul\_epaybg.yaml**

```
otobul_epaybg:
    resource: '@OtobulEpaybgBundle/Resources/config/routes.yaml'
    prefix: /webhook/epaybg
    methods: ['POST']
```

The new notification URL will be something like: `https://your-domain.com/webhook/epaybg/`, add the notification URL in your ePay.bg account.

3. Usage
--------

[](#3-usage)

This bundle provides:

- controller to handle ePay.bg webhook notification;
- service that can be used in you console command or custom controller;
- template functions to generate "Pay" button and Easypay payment code directly in your template.

### 3.1 Template

[](#31-template)

#### 3.1.1 Generate "Pay" button for WEB\_LOGIN form

[](#311-generate-pay-button-for-web_login-form)

To generate simple **web\_login** "Pay" button in your template you can use `epayWebLoginForm` twig function. Example:

```
{% include '@OtobulEpaybg/Form/web_login.html.twig' with {
    form: epayWebLoginForm({invoice: 1, amount: 100})
} only %}
```

Required parameters:

- **invoice**: Your unique invoice number;
- **amount**: Total sum in BGN. This is the default currency.

Advanced configuration of **web\_login** "Pay" button allow you to configure other optional parameters:

```
{% include '@OtobulEpaybg/Form/web_login.html.twig' with {
    form: epayWebLoginForm({
        invoice: 1,
        amount: 100,
        returnUrl: url('your_payment_success_route'),
        cancelUrl: url('your_payment_cancel_route'),
        expDate: 'now'|date_modify('+7 day'),
        currency: 'EUR',
        description: 'Extra description max to 100 symbols',
        encoding: 'utf-8',
    }), button: 'Pay'
} only %}
```

Optional parameters:

- **returnUrl**: Your success route. ePay.bg will redirect the user after successful payment;
- **cancelUrl**: Your cancel route. ePay.bg will redirect the user after cancel payment;
- **expDate**: Expiration date. Variable need to be in \\DateTime. Default is +7 days;
- **currency**: ISO three-letter currency code. Accepted value are BGN|EUR|USD;
- **description**: Extra description max to 100 symbols;
- **encoding**: Accepted value are utf-8 or CP1251;
- **button**: Label of the pay button.

#### 3.1.2 Generate "Pay" button for CREDIT\_CARD form

[](#312-generate-pay-button-for-credit_card-form)

To generate simple **credit\_card** "Pay" button in your template you can use `epayCreditCardForm` twig function. Example:

```
{% include '@OtobulEpaybg/Form/web_login.html.twig' with {
    form: epayCreditCardForm({invoice: 1, amount: 100})
} only %}
```

For advanced configuration you can use the same optional parameter from above.

#### 3.1.3 Generate "Easypay code" in template

[](#313-generate-easypay-code-in-template)

To generate **Easypay code** in your template you can use `epayEasypayCode` twig function. Example:

```
{{ epayEasypayCode({invoice: 1, amount: 100}) }}
```

Please note that this will make HTTP request to Easypay server to retrieve the code. Use this careful! Recommended way is to generate the code in your controller and store it for later use.

### 3.2 Controller

[](#32-controller)

#### 3.2.1 Generate "Easypay code" in controller

[](#321-generate-easypay-code-in-controller)

Example usages of EpayManager service in controller to retrieve Easypay payment code.

```
// src/Controller/PaymentController.php

namespace App\Controller;

use Otobul\EpaybgBundle\Model\EpayPayloadData;
use Otobul\EpaybgBundle\Service\EpayManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class PaymentController extends AbstractController
{
    public function generateEasypayCode(EpayManagerInterface $epayManager)
    {
        $invoice = 1; // Generate your unique invoice number
        $amount = 100; // Total sum for payment

        $easypayCode = $epayManager->getEasypayCode(
            new EpayPayloadData($invoice, $amount)
        );

        return $this->render("payment/easypay_code.html.twig", [
            'invoice' => $invoice,
            'easypayCode' => $easypayCode,
        ]);
    }
}
```

#### 3.2.2 Generate "Pay" button for WEB\_LOGIN form in controller

[](#322-generate-pay-button-for-web_login-form-in-controller)

Example usages of EpayManager service in controller to generate "Pay" button form.

```
// src/Controller/PaymentController.php

namespace App\Controller;

use Otobul\EpaybgBundle\Model\EpayPayloadData;
use Otobul\EpaybgBundle\Service\EpayManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\RouterInterface;

class PaymentController extends AbstractController
{
    public function generateEasypayCode(EpayManagerInterface $epayManager, RouterInterface $router)
    {
        $payload = EpayPayloadData::createFromArray([
            'invoice' => 1,
            'amount' => 100,
        ]);
        $returnUrl = $this->router->generate('your_payment_success_route');
        $cancelUrl = $this->router->generate('your_payment_cancel_route');

        $form = $epayManager->createWebLoginForm($payload, $returnUrl, $cancelUrl);

        return $this->render("payment/easypay_code.html.twig", [
            'form' => $form->createView(),
        ]);
    }
}
```

To generate **CREDIT\_CARD** form use `createCreditCardForm` function.

### 3.3 Events

[](#33-events)

- **NOTIFICATION\_RECEIVED**: Called directly after the webhook notification is received. Listeners have the opportunity to get the raw content.
- **NOTIFICATION\_ERROR**: Called if webhook notification has not valid checksum or data. Listeners have the opportunity to get the error message.
- **NOTIFICATION\_RESPONSE**: Called directly before the webhook notification response to be sent. Listeners have the opportunity to get the raw response content.
- **INVOICE\_NOTIFICATION\_RECEIVED**: Called directly after the invoice notification is received. Listeners have the opportunity to process the invoice data.
- **EASYPAY\_CODE\_CREATED**: Called directly after the Easypay code is received. Listeners have the opportunity to get the code and payment data.

Example event subscriber for **INVOICE\_NOTIFICATION\_RECEIVED** this event is called directly after the invoice notification is received. Listeners have the opportunity to process the invoice data.

```
// src/EventSubscriber/EpayInvoiceNotificationSubscriber.php

namespace App\EventSubscriber;

use Doctrine\ORM\EntityManagerInterface;
use Otobul\EpaybgBundle\Event\OtobulEpaybgEvents;
use Otobul\EpaybgBundle\Event\InvoiceNotificationReceivedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class EpayInvoiceNotificationSubscriber implements EventSubscriberInterface
{
    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public static function getSubscribedEvents()
    {
        return [
            OtobulEpaybgEvents::INVOICE_NOTIFICATION_RECEIVED => 'epayInvoiceNotification',
        ];
    }

    public function epayInvoiceNotification(InvoiceNotificationReceivedEvent $event)
    {
        // Example logic to find some entity related to this invoice.
        $order = $this->entityManager->getRepository(Order::class)->find($event->getInvoice());
        if (!$order) {
            // If invoice cannot be found. Sending back NO, so ePay.bg system stops sending notification about the invoice.
            $event->setResponseStatusNo();
            return;
        }

        // process order state below
        if($event->isPaid()) {
            // process PAID order here
        }else {
            // process DENIED or EXPIRED order here
        }

        // Sending back OK, so ePay.bg system stops sending notification about the invoice.
        $event->setResponseStatusOk();
    }
}
```

Example for advanced event subscriber.

```
// src/EventSubscriber/EpayInvoiceNotificationSubscriber.php

namespace App\EventSubscriber;

use Otobul\EpaybgBundle\Event\EasypayCodeCreatedEvent;
use Otobul\EpaybgBundle\Event\NotificationErrorEvent;
use Otobul\EpaybgBundle\Event\NotificationReceivedEvent;
use Otobul\EpaybgBundle\Event\NotificationResponseEvent;
use Otobul\EpaybgBundle\Event\OtobulEpaybgEvents;
use Otobul\EpaybgBundle\Event\InvoiceNotificationReceivedEvent;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class EpayInvoiceNotificationSubscriber implements EventSubscriberInterface
{
    private $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public static function getSubscribedEvents()
    {
        return [
            OtobulEpaybgEvents::NOTIFICATION_RECEIVED => 'epayNotificationReceived',
            OtobulEpaybgEvents::NOTIFICATION_ERROR => 'epayNotificationError',
            OtobulEpaybgEvents::NOTIFICATION_RESPONSE => 'epayNotificationResponse',
            OtobulEpaybgEvents::INVOICE_NOTIFICATION_RECEIVED => 'epayInvoiceNotification',
            OtobulEpaybgEvents::EASYPAY_CODE_CREATED => 'epayEasypayCodeCreated',
        ];
    }

    public function epayNotificationReceived(NotificationReceivedEvent $event)
    {
        $this->logger->info('epayNotificationReceived: '. $event->getContent());
    }

    public function epayNotificationError(NotificationErrorEvent $event)
    {
        $this->logger->info('epayNotificationError: '. $event->getMessage());
    }

    public function epayNotificationResponse(NotificationResponseEvent $event)
    {
        $this->logger->info('epayNotificationResponse: '. $event->getContent());
    }

    public function epayEasypayCodeCreated(EasypayCodeCreatedEvent $event)
    {
        $this->logger->info('epayEasypayCodeCreated: code'. $event->getCode());
        $this->logger->info('epayEasypayCodeCreated: paymentData:'. print_r($event->getPaymentData()->toArray(), 1));
    }

    public function epayInvoiceNotification(InvoiceNotificationReceivedEvent $event)
    {
        $this->logger->info('epayInvoiceNotification: '. $event->getInvoice() .' isPaid: '. $event->isPaid());

        // Event object has access to invoice notification details

        /**
         * Invoice number
         * @var int $invoice
         */
        $invoice = $event->getInvoice();

        /**
         * Invoice status, can be PAID|DENIED|EXPIRED
         * @var string $status
         */
        $status = $event->getStatus();

        /**
         * Payment date
         * @var \DateTime $payDate
         */
        $payDate = $event->getPayDate();

        /**
         * Transaction number
         * @var int $stan
         */
        $stan = $event->getStan();

        /**
         * Authorization code
         * @var string $bcode
         */
        $bcode = $event->getBcode();

        /*
        // Your logic to find some entity related to this invoice. Example:

        $order = $this->orderRepository->find($invoice);
        if (!$order) {
            // If invoice cannot be found. Sending back NO, so ePay.bg system stops sending notification about the invoice.
            $event->setResponseStatusNo();
            return;
        }

        process order state below
        */

        if($event->isPaid()) {
            // process PAID order here
        }else {
            // process DENIED or EXPIRED order here
        }

        // Sending back OK, so ePay.bg system stops sending notification about the invoice.
        $event->setResponseStatusOk();
    }
}
```

###  Health Score

46

—

FairBetter than 93% of packages

Maintenance83

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity66

Established project with proven stability

 Bus Factor1

Top contributor holds 88.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~231 days

Recently: every ~321 days

Total

10

Last Release

88d ago

Major Versions

v1.0.8 → v2.0.02025-12-24

PHP version history (3 changes)v1.0.0PHP ^7.1.3

v1.0.1PHP ^7.2.5

v1.0.4PHP ^7.2.5 || ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/82e3e45fef4644a3f75e90e86142e1fe09fb03bd27d36f2379be325624924e6a?d=identicon)[ggabrovski](/maintainers/ggabrovski)

---

Top Contributors

[![ggabrovski](https://avatars.githubusercontent.com/u/24413349?v=4)](https://github.com/ggabrovski "ggabrovski (16 commits)")[![dtrifonoff](https://avatars.githubusercontent.com/u/50624492?v=4)](https://github.com/dtrifonoff "dtrifonoff (2 commits)")

### Embed Badge

![Health badge](/badges/otobul-epaybg-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/otobul-epaybg-bundle/health.svg)](https://phpackages.com/packages/otobul-epaybg-bundle)
```

###  Alternatives

[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k14.6k](/packages/prestashop-prestashop)[bolt/core

🧿 Bolt Core

585141.2k46](/packages/bolt-core)[contao/core-bundle

Contao Open Source CMS

1231.6M2.0k](/packages/contao-core-bundle)[novosga/novosga

Customer queue management system

26157.8k](/packages/novosga-novosga)[netgen/layouts-core

Netgen Layouts enables you to build and manage complex web pages in a simpler way and with less coding. This is the core of Netgen Layouts, its heart and soul.

3688.5k7](/packages/netgen-layouts-core)[forumify/forumify-platform

131.8k8](/packages/forumify-forumify-platform)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
