PHPackages                             pimcore/payment-provider-unzer - 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. pimcore/payment-provider-unzer

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

pimcore/payment-provider-unzer
==============================

Pimcore Payment Provider - Unzer (Heidelpay)

v2.0.1(2y ago)024.3k↓50%7[2 PRs](https://github.com/pimcore/payment-provider-unzer/pulls)GPL-3.0+PHPCI passing

Since Feb 1Pushed 1mo ago6 watchersCompare

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

READMEChangelog (8)Dependencies (4)Versions (18)Used By (0)

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

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

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 Pimcore and Pimcore 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 Pimcore and unzer and if successful order is committed and user is redirected to success page.

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

[](#installation)

Install latest version with composer:

```
composer require pimcore/payment-provider-unzer
```

Enable bundle via console or extensions manager in Pimcore backend:

```
php bin/console pimcore:bundle:enable PimcorePaymentProviderUnzerBundle
php bin/console pimcore:bundle:install PimcorePaymentProviderUnzerBundle
```

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: Pimcore\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 Pimcore.

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

```
{% do pimcore_head_link().appendStylesheet('https://static.unzer.com/v1/unzer.css') %}
{% do pimcore_head_script().appendFile('https://static.unzer.com/v1/unzer.js') %}
{% do pimcore_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 \Pimcore\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

###  Health Score

47

—

FairBetter than 93% of packages

Maintenance68

Regular maintenance activity

Popularity28

Limited adoption so far

Community23

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor3

3 contributors hold 50%+ of commits

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 ~170 days

Total

12

Last Release

50d ago

Major Versions

v1.0.5 → v2.0.02024-04-05

2.1.x-dev → 2026.x-dev2026-03-20

### Community

Maintainers

![](https://www.gravatar.com/avatar/6e1692ffeae5f1a8303ef97a15b7cfb8bf9e1d810640b1be297e725030474ebd?d=identicon)[brusch](/maintainers/brusch)

![](https://www.gravatar.com/avatar/72f3c0cb1c22bda196b2f1112fbfc3c51baadc279ac5b4af74d038b17f44212d?d=identicon)[dvesh3](/maintainers/dvesh3)

---

Top Contributors

[![dvesh3](https://avatars.githubusercontent.com/u/5137917?v=4)](https://github.com/dvesh3 "dvesh3 (20 commits)")[![berfinyuksel](https://avatars.githubusercontent.com/u/99557970?v=4)](https://github.com/berfinyuksel "berfinyuksel (7 commits)")[![aashan10](https://avatars.githubusercontent.com/u/18713900?v=4)](https://github.com/aashan10 "aashan10 (5 commits)")[![fashxp](https://avatars.githubusercontent.com/u/8792145?v=4)](https://github.com/fashxp "fashxp (5 commits)")[![kingjia90](https://avatars.githubusercontent.com/u/6014195?v=4)](https://github.com/kingjia90 "kingjia90 (5 commits)")[![bluvulture](https://avatars.githubusercontent.com/u/7668379?v=4)](https://github.com/bluvulture "bluvulture (4 commits)")[![brusch](https://avatars.githubusercontent.com/u/142037?v=4)](https://github.com/brusch "brusch (4 commits)")[![markus-moser](https://avatars.githubusercontent.com/u/4639428?v=4)](https://github.com/markus-moser "markus-moser (2 commits)")[![aryaantony92](https://avatars.githubusercontent.com/u/97134765?v=4)](https://github.com/aryaantony92 "aryaantony92 (2 commits)")[![ITspirit](https://avatars.githubusercontent.com/u/2453696?v=4)](https://github.com/ITspirit "ITspirit (1 commits)")[![AlternateIf](https://avatars.githubusercontent.com/u/14984260?v=4)](https://github.com/AlternateIf "AlternateIf (1 commits)")[![pimcore-deployments](https://avatars.githubusercontent.com/u/71881008?v=4)](https://github.com/pimcore-deployments "pimcore-deployments (1 commits)")

---

Tags

payment-integrationpimcore

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

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

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

###  Alternatives

[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)[unzerdev/shopware6

Unzer payment integration for Shopware 6

1125.6k](/packages/unzerdev-shopware6)

PHPackages © 2026

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