xlabs/epochbundle

Epoch wrapper bundle

Installs: 724

Dependents: 1

Suggesters: 0

Security: 0

Type:symfony-bundle

2.0.8 2023-03-21 10:55 UTC

README

An EPOCH postback wrapper.

Installation

Install through composer:

php -d memory_limit=-1 composer.phar require xlabs/epochbundle

In your AppKernel

public function registerbundles()
{
    return [
    	...
    	...
    	new XLabs\EpochBundle\XLabsEpochBundle(),
    ];
}

In order for this bundle to work properly, EpochTransStats and MemberCancelStats need to be set to HTTPS method, not MYSQL method. You might need to contact Epoch support to enable this setting.

Routing

Append to main routing file:

# app/config/routing.yml
  
x_labs_epoch:
    resource: .
    type: xlabs_epoch_routing

Configuration sample

Default values are shown below:

# app/config/config.yml

x_labs_epoch:
    # postbacks will go to <url><postback_url>
    url: https://www.yourdomain.com
    postback_url: /your/epoch/postback/url (default '/epoch/postback')
    return_url: /your/epoch/response/url (default '/epoch/response')
    stats_url: /your/epoch/stats/url (default '/epoch/stats')
    logging:
        enabled: true
        location: '%kernel.logs_dir%/'
    allowed_ips: ['127.0.0.1', '192.168.1.10', '60.58.43.125', ...]
    api:
        url: 'https://wnu.com/secure/services/'
        reseller: 'a'
        epoch_digest_key: '<your_epoch_hmac_key>'
    mail_notifications:
        enabled: true|false
        subject: '' # descriptive prefix for the notifications subject
        from: '' # useful to apply a gmail label for the notifications
        destinataries: []

IMPORTANT

Make sure to create a daily cronjob to pull the Epoch IPs:

(0 8 * * *) php bin/console xlabs:epoch:update_ips

You can still use the config parameters "allowed_ips" to configure other allowed IPs.

Note: $_SERVER['SERVER_ADDR'] value is allowed by default, so no need to include it in the 'allowed_ips' array.

Also, make sure to ask support about the "S" transaction types, to avoid issues when the dataplys postbacks come after a CamCharge transaction. For CamCharge to work, we´ll also need to ask for the digest code.

Event listeners

The following events are fired based on the epoch postback:

SYNCHRONOUS (fired by flexpost):
    epoch.sync.join.event
SYNCHRONOUS (fired by memberplus):
    epoch.sync.join_channel.event
ASYNCHRONOUS (fired by dataplus):
    epoch.async.join.event
    epoch.async.join_channel.event
    epoch.async.rebill.event
    epoch.async.rebill_channel.event
    epoch.async.chargeback.event
    epoch.async.chargeback_channel.event
    epoch.async.refund.event
    epoch.async.refund_channel.event
    epoch.async.cancel.event
    epoch.async.purchase.event
SYNCHRONOUS (fired by camcharge):
    epoch.sync.purchase.event
SYNCHRONOUS (fired by unkown):
    epoch.async.reactivation.event

In both sync/async events, if transaction is declined, the following event is fired:

epoch.error.event

On epoch response, 2 events will be fired, depending on the response:

epoch.response_success.event
epoch.response_failed.event

You could use "epoch.response_success.event", for instance, to reload the user session to add his new purchase.

If you want to register an event listener for any of them:

# YourBundle/Resources/config/services.yml
    ...
    custom_listener_for_epoch_onPostback.event_listener:
        class:  YourBundle\EventListener\MyListener
        tags:
            - { name: kernel.event_listener, event: epoch.join.event, method: yourCustomMethod }
namespace YourBundle\EventListener;

use Symfony\Component\EventDispatcher\Event;

class MyListener extends Event
{
    public function yourCustomMethod(Event $event)
    {
        $params = $event->getParams(); // all params sent by epoch
        
        ...

        $event->setResponse('OK');
        /*
            OR
        */
        $event->setResponse('KO - <ERR MSG>');
    }
}

If no response is set in the listener, 'OK' will be the default output.

Return URL parameter

If you want to overwrite the "thank you / transaction denied" template, you can do it by overriding the following templates:

XLabsEpochBundle::response.html.twig
XLabsEpochBundle::success.html.twig
XLabsEpochBundle::error.html.twig

The following variables are sent to the template:

  • on successful transactions:
    status = "SUCCESS"
    message -> (empty string)
    
  • on failed transactions:
    status = "ERROR"
    message -> (string containing a descriptive error)
    

TO-DO

  1. Use needed dependencies (instead of the container) in twig extension: xlabs_epoch.twig_extension.
  2. Allow transactions only once, unless a custom querystring parameter comes set, in which case the transaction goes through.

Testing

Please use the following test card numbers to test Approval and Denial:

4121371122223333 / any valid expiration 5123456789012346 / any valid expiration

In order to simulate an approval, you will want to use '111' as the CVV2. In order to simulate a denial, you can use '567' as the CVV2.

You have to use the office proxy IP though, it's IP protected and that's the only one that's fully whitelisted by them.