An open API service indexing awesome lists of open source software.

https://github.com/pimcore/payment-provider-mpay24-seamless

MPay24 Seamless payment integration for Pimcore Ecommerce Framework (community bundle)
https://github.com/pimcore/payment-provider-mpay24-seamless

payment-integration pimcore

Last synced: 3 months ago
JSON representation

MPay24 Seamless payment integration for Pimcore Ecommerce Framework (community bundle)

Awesome Lists containing this project

README

          

# Pimcore E-Commerce Framework Payment Provider - MPay24 Seamless

### Official MPay24 Documentation
* [Documentation](https://docs.mpay24.com/docs)
* [Test Data](https://docs.mpay24.com/docs/test-data)

## Requirement
- mpay24/mpay24-php": "^4.2"

## Installation

Install latest version with Composer:
```bash
composer require pimcore/payment-provider-mpay24-seamless
```

Enable bundle via console or extensions manager in Pimcore backend:
```bash
php bin/console pimcore:bundle:enable PimcorePaymentProviderMpay24SeamlessBundle
php bin/console pimcore:bundle:install PimcorePaymentProviderMpay24SeamlessBundle
```

## Configuration
The Payment Manager is responsible for implementation
of different Payment Provider to integrate them into the framework.

For more information about Payment Manager, see
[Payment Manager Docs](../13_Checkout_Manager/07_Integrating_Payment.md).

Configure payment provider in the `pimcore_ecommerce_config.payment_manager` config section:
```yaml
pimcore_ecommerce_config:
payment_manager:
payment_manager_id: Pimcore\Bundle\EcommerceFrameworkBundle\PaymentManager\PaymentManager

providers:
mpay24:
provider_id: Pimcore\Bundle\EcommerceFrameworkBundle\PaymentManager\Payment\Mpay24Seamless
profile: testsystem
profiles:
_defaults:
#paypal_activate_item_level: true
partial: Shared/Includes/Shop/Payment/paymentMethods.html.php
payment_methods:
cc:
paypal:
sofort:
invoice:
testsystem:
merchant_id: 95387
password: 7&jcQ%v6RB
testSystem: true
debugMode: true
live:
merchant_id: todo
password: todo
testSystem: false
debugMode: false
```

## Implementation

CheckoutController.php (action, where the payment form will be rendered):
```
...
//important: if payment is active, then keep payment state and do not allow parallel payment!
if ($this->checkoutManager->hasActivePayment() && $this->cart->isCartReadOnly()) {
return $this->redirectToRoute('app_shop_cart_list');
}
$paymentInfo = $this->checkoutManager->startOrderPayment();
$payment = $this->checkoutManager->getPayment();
$paymentFormAsString =
$payment->initPayment(
$this->cart->getPriceCalculator()->getGrandTotal(),
[
'request' => $request,
'paymentInfo' => $paymentInfo
]
);
$order = $this->checkoutManager->getOrder();
$order->setOrderState("");//important to unlock order payment, as order can be locked
$order->save(['versionInfo' => 'Clear state, because payment is not locked yet.']);

$this->view->paymentFormAsString = $paymentFormAsString;
```

Somewhere in your order.html.php view:
```
...

Select Payment:


=$paymentFormAsString;?>

...
```

paymentMethods.html.php view (linked in ecommerce.yml):
```


foreach ($paymentMethods as $method => $methodConfig):?>



>

=$this->t('shop.payment.methods.'.$method);?>


if ($method == 'cc'): ?>





endforeach;?>

```

Example PaymentController.php (Responsiblity payment actions):
```
get(Service\Shop::class);
$checkoutManager = Factory::getInstance()->getCheckoutManager(
$serviceShop->getCart()
);
/** @var Mpay24Seamless $payment */
$payment = $checkoutManager->getPayment();
$paymentInfo = $checkoutManager->startOrderPayment();
$paymentType = $request->request->getString('type');

if ($request->isMethod('post')) {
if ($request->isMethod('post') && $paymentType == 'INVOICE') {
$factory = \Pimcore\Bundle\EcommerceFrameworkBundle\Factory::getInstance();
/** @var OrderManager $orderManager */
$orderManager = $factory->getOrderManager();
$order = $orderManager->getOrCreateOrderFromCart($serviceShop->getCart());
$factory->getCommitOrderProcessor()->commitOrder($order);
return $this->redirectToCheckoutSuccessPage($order);
} else {
$baseUrl = Tool::getHostUrl();
$paymentParams = [
'request' => $request,
'order' => $checkoutManager->getOrder(),
'paymentInfo' => $checkoutManager->getOrder()->getPaymentInfo()->get(0),
'successURL' => $baseUrl . $router->generate('app_shop_payment_response', ['type' => 'success', 'elementsclientauth'=>'disabled']),
'errorURL' => $baseUrl . $router->generate('app_shop_payment_response', ['type' => 'error', 'elementsclientauth'=>'disabled']),
'confirmationURL' => $baseUrl . $router->generate('app_shop_payment_response', ['type' => 'confirmation', 'elementsclientauth'=>'disabled']),
];
//either redirect to paypal, etc. or to internal (error) URL
list($redirectUrl, $errorText) = $payment->getInitPaymentRedirectUrl($paymentParams);
if ($errorText) {
$this->addFlash('error', [$errorText]);
//save note for debugging
$order = $checkoutManager->getOrder();
$note = new Note();
$note->setElement($order);
$note->setType("user_payment_denied");
$note->setTitle($errorText);
$note->setUser(0);
$note->save();

return $this->redirectToRoute('app_shop_checkout_start');
}
return new RedirectResponse($redirectUrl);
}
}
}

private function redirectToCheckoutSuccessPage(AbstractOrder $order) {
$factory = \Pimcore\Bundle\EcommerceFrameworkBundle\Factory::getInstance();
$orderManager = $factory->getOrderManager();
$encryptedOrderNumber = $orderManager->getEncryptedOrderNumber($order);
return $this->redirectToRoute('app_shop_checkout_success', ['o' => $encryptedOrderNumber]);
}

/**
* @Route("/{_prefix}/checkout/payment/mpay-response/{type}", requirements={"_prefix" = "\w\w\/?[\w\-]*"})
* @param Request $request
* @return RedirectResponse|\Symfony\Component\HttpFoundation\Response
* @throws \Exception
*/
public function responseAction(Request $request, Translator $translator)
{
$serviceShop = \Pimcore::getContainer()->get(Service\Shop::class);
$checkoutManager = Factory::getInstance()->getCheckoutManager(
$serviceShop->getCart()
);

$type = $request->request->getString('type');
if ($type == 'confirmation') {
//@see https://docs.mpay24.com/docs/backend2backend-integration
$this->getLogger()->info('Mpay24 called confirmation URL.');
$response = new Response();
$response->setContent("OK");
$response->headers->set('Content-Type', 'text/plain');
return $response;
}

//currently errors are also handled via commit processor and result in cancel-statements.
//Thus, the order remains uncommitted.

$commitOrderProcessor = Factory::getInstance()->getCommitOrderProcessor();

/** @var Mpay24Seamless $payment */
$payment = $checkoutManager->getPayment();

try {
$order = $commitOrderProcessor->handlePaymentResponseAndCommitOrderPayment(
$request->query->all(),$payment
);
if ($order->getOrderState() == AbstractOrder::ORDER_STATE_COMMITTED) {
return $this->redirectToCheckoutSuccessPage($order);
}
} catch (\Exception $e) {
$this->getLogger()->error(sprintf('Exception in payment Controller: %s', $e->getMessage()));
}

$this->addFlash('error', [$translator->trans('shop.payment.error-or-cancelled')]);
return $this->redirectToRoute('app_shop_checkout_start');
}
}
```