PHPackages                             open-dxp/payment-provider-unzer-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. [Payment Processing](/categories/payments)
4. /
5. open-dxp/payment-provider-unzer-bundle

ActiveOpendxp-bundle[Payment Processing](/categories/payments)

open-dxp/payment-provider-unzer-bundle
======================================

OpenDXP Payment Provider - Unzer (Heidelpay)

v1.0.0(3mo ago)00GPL-3.0+PHPCI passing

Since Feb 4Pushed 2mo agoCompare

[ Source](https://github.com/open-dxp/payment-provider-unzer-bundle)[ Packagist](https://packagist.org/packages/open-dxp/payment-provider-unzer-bundle)[ RSS](/packages/open-dxp-payment-provider-unzer-bundle/feed)WikiDiscussions 1.x Synced 1mo ago

READMEChangelog (1)Dependencies (7)Versions (3)Used By (0)

OpenDXP E-Commerce Framework Payment Provider - Unzer (former: Heidelpay)
=========================================================================

[](#opendxp-e-commerce-framework-payment-provider---unzer-former-heidelpay)

---

Disclaimer
----------

[](#disclaimer)

> OpenDXP is a community-driven fork based on the Pimcore® Community Edition (GPLv3).
> OpenDXP is independent and maintained by its community and contributors. It is not affiliated with, endorsed by, or sponsored by Pimcore GmbH.
> Original credits: [Pimcore GmbH](https://www.pimcore.com)

**OpenDXP E-Commerce Framework Payment Provider - Unzer is based on the Pimcore® Community Edition and remains licensed under GPLv3.**

---

Unzer Web Integration
---------------------

[](#unzer-web-integration)

To integrate Unzer web integration see [Unzer docs](https://docs.unzer.com/integrate/web-integration)and follow following steps.

The basic flow goes as following:

- Unzer gets initialized via java script and depending on activated payment methods additional form fields are injected to view template.
- User selects payment method and enters additional information if necessary (e.g. credit card information).
- Information is submitted to unzer, payment transaction is started and payment id is returned.
- Payment id is submitted back to OpenDxp and OpenDxp payment transaction is started.
- If necessary user is redirected to payment provider (e.g. Paypal).
- If user comes back from external payment site, payment state is checked server-to-server between OpenDxp and unzer and if successful order is committed and user is redirected to success page.

Installation
------------

[](#installation)

Install latest version with composer:

```
composer require open-dxp/payment-provider-unzer-bundle
```

Enable bundle via console:

```
php bin/console opendxp:bundle:enable OpenDxpPaymentProviderUnzerBundle
php bin/console opendxp:bundle:install OpenDxpPaymentProviderUnzerBundle
```

Configuration
-------------

[](#configuration)

Setup payment provider in e-commerce framework configuration. The access keys you find in Unzer documentation (or you will get them from Unzer for production integrations).

```
unzer:
    provider_id: OpenDxp\Bundle\EcommerceFrameworkBundle\PaymentManager\Payment\Unzer
    profile: sandbox
    profiles:
        sandbox:
            publicAccessKey: s-pub-2a10gsZJ2IeiiK80Wh68qrOzu4IZse6k
            privateAccessKey: s-priv-2a10BF2Cq2YvAo6ALSGHc3X7F42oWAIp
```

Payment Information: Order payment section "Payment Informations" stores information about every payment trial by Customer.

Add additional fields in "PaymentInfo" fieldcollection, so that Order Manager stores information in Order object: [![PaymentInfo Additional Data](./doc/img/unzer_paymentinfo.png)](./doc/img/unzer_paymentinfo.png)

**Create View Template**

Create view template for payment method selection. This view template

- needs to include a javascript and a css from Unzer.
- has a list of all provided payment methods and depending of the payment method additional form elements.
- includes a java script that handles data communication the data to Unzer.
- has an additional form that submits successful payment information (Unzer payment id) back to OpenDxp.

**Sample template with Creditcard, Paypal and Sofort**

```
{% do opendxp_head_link().appendStylesheet('https://static.unzer.com/v1/unzer.css') %}
{% do opendxp_head_script().appendFile('https://static.unzer.com/v1/unzer.js') %}
{% do opendxp_inline_script().appendFile(asset('static/js/payment.js')) %} {# custom payment js, see below #}

{{ 'checkout.payment' | trans }}

                    {{ 'checkout.creditcard' | trans }}

                        {{ 'general.creditcard.pay' | trans }}

                    {{ 'checkout.paypal' | trans }}

                    {{ 'general.paypal.pay' | trans }}

                    {{ 'checkout.sofort' | trans }}

                    {{ 'checkout.sofort.pay' | trans }}

```

**Sample Javascript (payment.js) with Creditcard, Paypal and Sofort**

```
$(document).ready(function() {

    let unzerInstance = new unzer(_config.accessKey, {locale: 'en-GB'});

    let $errorHolder = $('#error-holder');

    let Card = unzerInstance.Card();
    // Rendering input fields
    Card.create('number', {
        containerId: 'card-element-id-number',
        onlyIframe: false
    });
    Card.create('expiry', {
        containerId: 'card-element-id-expiry',
        onlyIframe: false
    });
    Card.create('cvc', {
        containerId: 'card-element-id-cvc',
        onlyIframe: false
    });

    let ccForm = document.getElementById('cc-form');
    let submitPaymentResultForm = document.getElementById('js-submit-payment-result');

    // General event handling
    let buttonDisabled = {};
    let submitButton = document.getElementById('submit-button');
    submitButton.disabled = true;

    let successHandler = function(data) {
        console.log('success');
        data.method = data.method ? data.method : 'card';
        $('.js-payment-method-hidden').val(data.method);
        $('.js-payment-id-hidden').val(data.id);

        submitPaymentResultForm.submit();
    };

    let errorHandler = function(error) {
        console.log('error');
        $errorHolder.html(error.message);
    };

    Card.addEventListener('change', function(e) {
        if (e.success) {
            buttonDisabled[e.type] = true;
            submitButton.disabled = false;
            $errorHolder.html('')
        } else {
            buttonDisabled[e.type] = false;
            submitButton.disabled = true;
            $errorHolder.html(e.error)
        }
        submitButton.disabled = !(buttonDisabled.number && buttonDisabled.expiry && buttonDisabled.cvc);

    });

    ccForm.addEventListener('submit', function(event) {
        event.preventDefault();
        console.log('creditcard form submit');
        Card.createResource()
            .then(successHandler)
            .catch(errorHandler)
    });

    $('#js-redirect-payment-method-paypal').on('click', function(e){
        e.preventDefault();

        var Paypal = unzerInstance.Paypal();

        Paypal.createResource()
            .then(successHandler)
            .catch(errorHandler)
    });

    $('#js-redirect-payment-method-paypal-sofort').on('click', function(e){
        e.preventDefault();

        var Sofort = unzerInstance.Sofort();

        Sofort.createResource()
            .then(successHandler)
            .catch(errorHandler)
    });

});
```

5. **Create Controller Action for Payment Selection**

The only special thing in this controller action is to get public access key out of payment provider and assign it to the template.

```
/**
 * @Route("/checkout-payment", name="shop-checkout-payment")
 *
 * @param Factory $factory
 * @return array
 */
public function checkoutPaymentAction(Factory $factory) {
    $cartManager = $factory->getCartManager();

    $cart = $cartManager->getOrCreateCartByName('cart');
    $checkoutManager = $factory->getCheckoutManager($cart);
    $paymentProvider = $checkoutManager->getPayment();

    $accessKey = '';
    if($paymentProvider instanceof Unzer) {
        $accessKey = $paymentProvider->getPublicAccessKey();
    }

    return [
        'cart' => $cart,
        'accessKey' => $accessKey
    ];
}
```

6. **Create Controller Action for Starting Payment**

To this action the paymentId of Unzer is submitted after payment transaction is started successfully on client side.

Additionally an error action is defined to extract the error messages from Unzer.

```
/**
 * @Route("/checkout-start-payment", name="shop-checkout-start-payment")
 *
 * @param Request $request
 * @param Factory $factory
 * @return RedirectResponse
 */
public function startPaymentAction(Request $request, Factory $factory, LoggerInterface $logger) {
    try {
        $cartManager = $factory->getCartManager();
        $cart = $cartManager->getOrCreateCartByName('cart');

        /** @var CheckoutManagerInterface $checkoutManager */
        $checkoutManager = $factory->getCheckoutManager($cart);

        $paymentInfo = $checkoutManager->initOrderPayment();

        /** @var OnlineShopOrder $order */
        $order = $paymentInfo->getObject();

        $paymentConfig = new UnzerRequest();
        $paymentConfig->setInternalPaymentId($paymentInfo->getInternalPaymentId());
        $paymentConfig->setPaymentReference($request->get('paymentId'));
        $paymentConfig->setReturnUrl($this->generateUrl('shop-commit-order', ['order' => $order->getOrdernumber()], UrlGeneratorInterface::ABSOLUTE_URL));
        $paymentConfig->setErrorUrl($this->generateUrl('shop-checkout-payment-error', [], UrlGeneratorInterface::ABSOLUTE_URL));

        $response = $checkoutManager->startOrderPaymentWithPaymentProvider($paymentConfig);

        if($response instanceof UrlResponse) {
            return new RedirectResponse($response->getUrl());
        }
    } catch (\Exception $e) {
        $this->addFlash('danger', $e->getMessage());
        $logger->error($e->getMessage());
        return $this->redirectToRoute('shop-checkout-payment');
    }

}

/**
 * @Route("/payment-error", name = "shop-checkout-payment-error" )
 */
public function paymentErrorAction(Request $request, LoggerInterface $logger)
{
    $logger->error('payment error: ' . $request->get('merchantMessage'));

    if($clientMessage = $request->get('clientMessage')) {
        $this->addFlash('danger', $clientMessage);
    }

    return $this->redirectToRoute('shop-checkout-payment');
}
```

7. **Create Controller Action for Commit Order**Finally commit order and redirect user to order success page.

```
/**
 * @Route("/payment-commit-order", name="shop-commit-order")
 *
 * @param Request $request
 * @param Factory $factory
 * @param LoggerInterface $logger
 * @param Translator $translator
 * @param SessionInterface $session
 * @return RedirectResponse
 * @throws \OpenDxp\Bundle\EcommerceFrameworkBundle\Exception\UnsupportedException
 */
public function commitOrderAction(Request $request, Factory $factory, LoggerInterface $logger, Translator $translator, SessionInterface $session) {
    $order = OnlineShopOrder::getByOrdernumber($request->query->get('order'), 1);

    $cartManager = $factory->getCartManager();
    $cart = $cartManager->getOrCreateCartByName('cart');

    /**
     * @var CheckoutManagerInterface $checkoutManager
     */
    $checkoutManager = $factory->getCheckoutManager($cart);

    try {
        $order = $checkoutManager->handlePaymentResponseAndCommitOrderPayment([
            'order' => $order
        ]);

    } catch(\Exception $e) {
        $logger->error($e->getMessage());
    }

    if(!$order || $order->getOrderState() !== AbstractOrder::ORDER_STATE_COMMITTED) {

        $this->addFlash('danger', $translator->trans('checkout.payment-failed'));
        return $this->redirectToRoute('shop-checkout-payment');
    }

    if (!$session->isStarted()) {
        $session->start();
    }

    $session->set("last_order_id", $order->getId());

    return $this->redirectToRoute('shop-checkout-completed');
}
```

Important Configuration
-----------------------

[](#important-configuration)

Please make sure that `serialize_precision` is set to a very high value, or even better to `-1` in order to prevent rounding issues with the unzer sdk. For details also see

---

Upstream Origin &amp; Version Transparency
------------------------------------------

[](#upstream-origin--version-transparency)

This project is a fork of the [Pimcore payment-provider-unzer (d76cca0 / v2.0.1)](https://github.com/pimcore/payment-provider-paypal-smart-payment-button/tree/d76cca089cd2c6a60b805409915a66b88918793c), which is © Pimcore GmbH and licensed under GPLv3.

License
-------

[](#license)

Licensed under the GNU General Public License v3.0 (GPLv3). For details, please see [LICENSE.md](LICENSE.md).

Copyright
---------

[](#copyright)

© Pimcore GmbH
© 2025 OpenDXP Contributors — GPLv3

Trademarks
----------

[](#trademarks)

Pimcore® is a registered [trademark](https://www.trademarkelite.com/europe/trademark/trademark-detail/009309841/PIMCORE) of Pimcore GmbH. Any use of the Pimcore® mark in this repository is purely descriptive to identify the original upstream project.

---

Contact
-------

[](#contact)

For inquiries, suggestions, or contributions, feel free to reach us at .

About
-----

[](#about)

OpenDXP is a community-driven project initiated by [DACHCOM.DIGITAL](https://www.dachcom.com/de-ch) (Rheineck, Switzerland) and maintained by its community and contributors. OpenDXP is independent and not affiliated with Pimcore GmbH.

The project’s purpose is to preserve and maintain a GPLv3‑licensed codebase for community use.

It is **not positioned as a competitor** to products or services of Pimcore GmbH and does **not** purport to replace or supersede any Pimcore offering.

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance83

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity35

Early-stage or recently created project

 Bus Factor1

Top contributor holds 80% 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 ~8 days

Total

2

Last Release

89d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/eac90c4e5116f383944994644316c1ce28ee109ddc1df43e3bfb6a8496e42538?d=identicon)[open-dxp](/maintainers/open-dxp)

---

Top Contributors

[![open-dxp-stack](https://avatars.githubusercontent.com/u/222377954?v=4)](https://github.com/open-dxp-stack "open-dxp-stack (8 commits)")[![scrummer](https://avatars.githubusercontent.com/u/15173170?v=4)](https://github.com/scrummer "scrummer (2 commits)")

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/open-dxp-payment-provider-unzer-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/open-dxp-payment-provider-unzer-bundle/health.svg)](https://phpackages.com/packages/open-dxp-payment-provider-unzer-bundle)
```

###  Alternatives

[omnipay/paypal

PayPal gateway for Omnipay payment processing library

3156.8M53](/packages/omnipay-paypal)[eduardokum/laravel-boleto

Biblioteca com boletos para o laravel

626351.9k2](/packages/eduardokum-laravel-boleto)[tbbc/money-bundle

This is a Symfony bundle that integrates moneyphp/money library (Fowler pattern): https://github.com/moneyphp/money.

1961.9M](/packages/tbbc-money-bundle)[2checkout/2checkout-php

2Checkout PHP Library

83740.3k2](/packages/2checkout-2checkout-php)[smhg/sepa-qr-data

Generate QR code data for SEPA payments

61717.2k5](/packages/smhg-sepa-qr-data)[omnipay/coinbase

Coinbase driver for the Omnipay payment processing library

18558.8k1](/packages/omnipay-coinbase)

PHPackages © 2026

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