konekt/payum-otp-hungary

Custom Payum Gateway for SimplePay Hungary via Legacy OTP Bank integration

1.1.1 2021-01-26 12:00 UTC

This package is auto-updated.

Last update: 2024-12-26 20:24:33 UTC


README

Packagist Stable Version OTP SDK v5 SimplePay Compatible

The OTP based payment method has been deprecated by the bank, use SimplePay instead!

It works with OTP SDK v5 despite the names and references to v4.

Consists of a standard payum gateway library with which you can make online payments through OTP Bank Hungary. It also provides basic integration with Symfony and Sylius.

Disclaimer: the library for now provides only simple offsite (haromszereplos) payment for a single shop (no multishop support). Feel free to contribute or ask for support if you need further functionality.

Architecture

The library builds on top of OTP's official SDK. It hides some of the library's inconveniences, like having to edit a configuration file, no autoloading, messy warnings/notices and no support for PHP7. The official SDK's logging features work as they provide it.

You will have to download the SDK from OTP's site in order to be able to use the library.

SDK

After you downloaded the SDK (currently a ZIP file named Webshop_4.0) you will find the needed php library in the zip on the following path: kliensek/php/otpwebshop. This is the library that is used and you have to put it in a place accessible to your web server. From now on we will call the full path where you have the library SDK_DIR.

Because the SDK has no proper versioning, to check if it is the same code that this library is building on you will have to generate the checksum of the library like this (assuming you're on Unix):

find SDK_DIR/ -type f -name "*.php" -exec md5sum {} + | awk '{print $1}' | sort | md5sum1

The tested library has a checksum of 5a57d623e8da3541c8b8d6fd3848862c. If you have another one it means the SDK code has changed. If something is not working as expected this can be a reason for that.

Using the standalone library

You will have to implement actions as described in the Payum documentation. In the examples folder you will find working scripts which can help you.

Configuration

You will find the parameters you will have to configure in examples/params.dist.

  • sdk_dir: The full path to the SDK (as described above). Mandatory.
  • sandbox: Can be true or false, if it is true, you don't need to provide the secret_key and pos_id. Default: true.
  • pos_id: Your shop ID given to you by OTP. Mandatory when not in sandbox mode.
  • secret_key: The full path to the secret key file belonging to the shop id given to you by OTP. Mandatory when not in sandbox mode.
  • transactionid_prefix: For each payment the library generates a unique ID, you can specify any prefix to it here. It should be no more than 10 characters and should be alphanumeric.

In addition you can configure the log dirs where the SDK will log the transactions. You will find the details in the SDK official documentation about each directory.

Using the library with Sylius

You will have to register the action which converts the Sylius models into the gateway's data as a service.

app.payum.otp.action.convert:
    class: Konekt\PayumOtp\Bridge\Sylius\ConvertPaymentToOtpAction

You also can define another service where you can control the payment note (shopMegjegyzes) sent to OTP. If you do this you have to implement \Konekt\PayumOtp\Bridge\Sylius\PaymentNoteProviderInterface in your app and define it as a service, then inject it to the converter. In this case the above definition looks like:

app.payum.otp.note_provider:
    class: AppBundle\MyNoteProvider #this class implements \Konekt\PayumOtp\Bridge\Sylius\PaymentNoteProviderInterface
    public: false

app.payum.otp.action.convert:
    class: Konekt\PayumOtp\Bridge\Sylius\ConvertPaymentToOtpAction
    arguments:
        - @app.payum.otp.note_provider

To register the custom payum library into your app, you should add the following to your AppBundle:

$extension = $container->getExtension('payum');
$extension->addGatewayFactory(new Konekt\PayumOtp\Bridge\Symfony\OtpHungaryOffsiteGatewayFactory());

Then you will have to configure the payum bundle to know about the new custom library like this:

payum:
    gateways:
        otp_hungary_offsite:
            otp_hungary_offsite:
                sandbox: %payum.otp.is_sandbox%
                secret_key: %payum.otp.secret_key%
                sdk_dir: %payum.otp.sdk_dir%
                pos_id: %payum.otp.pos_id%
                transactionid_prefix: %payum.otp.transactionid_prefix%
                actions:
                    - app.payum.otp.action.convert
                extensions:
                    - app.payum.otp.extension.error_notifier

You can define the parameters in your parameters.yml (recommended). For the meaning of the parameters see the Configuration section above. Note: even if you are in sandbox mode you will have to provide a value for secret_key and pos_id, but in this case it doesn't matter what you provide there (this is a technical depth for now).

Error handling

You also have the possibility to handle the transaction errors in a decoupled way. For example you want to get an email if any transaction fails by reasons such as wrong amount sent or the private key was rejected etc. In this case you will have to register the library's event notifier extension class as a service:

app.payum.otp.extension.error_notifier:
    class:  Konekt\PayumOtp\Bridge\Symfony\ErrorNotifierExtension
    arguments:
        - @event_dispatcher

Then you will have to write a listener in your app and define it as a service. Implement MyOtpListener which sends an email if an error occurs:

<?php

namespace AppBundle;

use Konekt\PayumOtp\Bridge\Symfony\Event\TransactionError;

class MyOtpListener
{
    /**
     * @param \Konekt\PayumOtp\Bridge\Symfony\Event\TransactionError $event
     */
    public function handleTransactionErrors(TransactionError $event)
    {
        //var_dump($event->getErrors());
        //var_dump($event->getDetails());

        //TODO: implement here some notification logic: ie. send email to the support team
    }
}

Then register it as a service:

app.listener.otp_error:
    class: AppBundle\MyOtpListener
    tags:
        - { name: kernel.event_listener, event: payum.otp.transaction_error, method: handleTransactionErrors }

In the MyOtpListener::handleTransactionErrors method you will get a TransactionError event, which contains the array of occured errors and other details of the transaction. You can write your handling logic as you need.

FINAL NOTES

If you have any questions feel free to open an issue. Any improvements or further functionality is very welcomed, feel free to make a pull request.