Home
PHP
Tech Tube
MySQL
Linux
CSS&HTML
JavaScript

Send payments via ePay.bg

The following class will enable you to send payments via ePay.bg. It also provides ability to decode and verify the payment notifications. To be able to do it you need MIN and SECRET that should be provided by ePay.bg You may register for a demo account here: https://demo.epay.bg Usage Example:
namespace Payments;

$ePaySettings = (object)[
    'PAYMENT_URL'   => 'https://demo.epay.bg/ezp/send.cgi',
    'MIN'           => '[The ePay account ID]',
    'SECRET'        => '[The ePay secret key]',
    'ENCODING'      => '[utf-8|CP1251]',
];

$paymentData = [
    'INVOICE'       => 123456,
    'AMOUNT'        => 22.10,
    'CURRENCY'      => 'BGN',
    'DESCR'         => 'Money Transfer',
    'ENCODING'      => 'utf-8',
    'RCPT_NAME'     => 'Samuil Banti',
    'RCPT_PID'      => 1111111110,
    'RCPT_ID_NO'    => 1111111111,
    'RCPT_ID_DATE'  => '14.02.2024',
    'RCPT_ADDRESS'  => 'Sofia, 109 Sunset Blvd.',
    'RCPT_PHONE'    => '359000000555',
];

$ePay = new ePay($ePaySettings);
$response = $ePay->sendPayment($paymentData);

// The encoding of the ePay responses is windows-1251
$response = iconv('windows-1251', 'utf-8', $response);
var_dump($response);
<?php
namespace Payments;

/**
 * This class is used to generate payments via ePay.bg and to process the payment notifications.
 * @package Sami's ePay class
 * @version $Id: ePay.php v.1.0 2019-03-25 16:06:00 $
 * @author Samuil Banti https://www.samiwell.eu/
 * @copyright (C) 2019 - Samuil Banti
 * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
**/
class ePay
{

    /**
    * @var - The ePay settings.
    */
    private $Settings;
    
    /**
    * @var - The URL for the cURL requests.
    */
    private $curlURL;
    
    /**
    * Set the ePay settings.
    * @param object $Settings - The ePay settings as described in the ePaySettings settings.
    */
    public function __construct(object $Settings)
    {
        $this->Settings = $Settings;
    }
    
    /**
    * Initiate a new payment.
    * @param array $paymentData - The data needed to do the payment. It's described in the ePay documentation.
    * @return string $responseData - The response provided by ePay.
    */
    public function sendPayment(array $paymentData)
    {
        $this->curlURL = $this->Settings->PAYMENT_URL;
        $responseData = $this->sendRequest($paymentData);
        return $responseData;
    }
    
    /**
    * Decode an ePay notification.
    * @param array $notification - The notification received by ePay. It should contain ENCODED and CHECKSUM parameters.
    * @return array $response - The data provided by ePay.
    */
    public function decodeNotification(array $notification)
    {
        if ( !isset($notification['ENCODED']) || !isset($notification['CHECKSUM']) ) {
            return $this->setError('The notification does NOT contain all data!');
        }
        $checksum = $this->calculateChecksum($notification['ENCODED']);
        if ($checksum != $notification['CHECKSUM']) {
            return $this->setError('The checksum does NOT match!');
        }
        
        $arguments = base64_decode($notification['ENCODED']);
        $arguments = preg_split('/\r\n|\r|\n/', $arguments);
        
        $response = [];
        foreach($arguments as $row) {
            list($key, $value) = explode('=', $row);
            $response[$key] = $value;
        }
        return $response;
    }
    
    /**
    * Send request to ePay.
    * @param array $arguments - The variables that will be encoded in the request.
    * @return string $responseData - The response provided by ePay.
    */
    private function sendRequest(array $arguments)
    {
        $encodedArguments = 'MIN=' . $this->Settings->MIN . PHP_EOL;
        foreach($arguments as $key => $value) {
            $encodedArguments .= $key . '=' . $value . PHP_EOL;
        }
        $encodedArguments = trim($encodedArguments, PHP_EOL);
        
        $encodedArguments = base64_encode($encodedArguments);
        $checksum = $this->calculateChecksum($encodedArguments);
        
        $curlArguments = http_build_query([
            'ENCODED' => $encodedArguments,
            'CHECKSUM' => $checksum,
        ]);
        
        $curlURL = rtrim($this->curlURL, '?') . '?' . $curlArguments;

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $curlURL);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Should be set to true in production
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $responseData = curl_exec($ch);
        
        if(curl_errno($ch)) {
            return curl_error($ch);
        }
        curl_close($ch);
        return $responseData;
    }
    
    /**
    * Calculate ePay checksum
    * @param string $encodedArguments - Base 64 encoded list of parameters.
    */
    private function calculateChecksum(string $encodedArguments)
    {
        $checksum = hash_hmac('sha1', $encodedArguments, $this->Settings->SECRET);
        return $checksum;
    }
    
    /**
    * Handle potential errors.
    * NOTE: The concept is to be overwriten by child class in case of need.
    * @param string $error - The triggered error.
    * @return NULL
    */
    protected function setError(string $error)
    {
        trigger_error($error);
        return;    
    }
    
}
Download...