Installing and configuring ratenkauf by easyCredit
Edit on GitHubInstallation
To install Easycredit, run the following command in console:
composer require spryker-eco/easycredit
After installation, run the propel:install
command or check the following migration:
CREATE SEQUENCE "spy_payment_easycredit_api_log_pk_seq";
CREATE TABLE "spy_payment_easycredit_api_log"
(
"id_payment_easycredit_api_log" INTEGER NOT NULL,
"type" VARCHAR NOT NULL,
"request" TEXT NOT NULL,
"response" TEXT NOT NULL,
"status_code" INT2,
"error_code" VARCHAR,
"error_message" VARCHAR,
"error_type" VARCHAR,
"created_at" TIMESTAMP,
"updated_at" TIMESTAMP,
PRIMARY KEY ("id_payment_easycredit_api_log")
);
CREATE SEQUENCE "spy_payment_easycredit_order_identifier_pk_seq";
CREATE TABLE "spy_payment_easycredit_order_identifier"
(
"id_payment_easycredit_order_identifier" INTEGER NOT NULL,
"fk_sales_order" INTEGER NOT NULL,
"identifier" VARCHAR NOT NULL,
"confirmed" BOOLEAN NOT NULL,
PRIMARY KEY ("id_payment_easycredit_order_identifier")
);
Configuration
Perform the initial configuration of Easycredit:
<?php
...
use SprykerEco\Shared\Easycredit\EasycreditConstants;
use Spryker\Shared\Oms\OmsConstants;
use Spryker\Shared\Sales\SalesConstants;
...
$config[OmsConstants::ACTIVE_PROCESSES] = [
...
'Easycredit01',
];
$config[SalesConstants::PAYMENT_METHOD_STATEMACHINE_MAPPING] = [
...
'easycredit' => 'Easycredit01',
];
...
$config[EasycreditConstants::SHOP_IDENTIFIER] = 'Your shop identifier';
$config[EasycreditConstants::SHOP_TOKEN] = 'Your shop token';
$config[EasycreditConstants::API_URL] = 'https://ratenkauf.easycredit.de/ratenkauf-ws/rest/v2';
$config[EasycreditConstants::SUCCESS_URL] = $config[ApplicationConstants::BASE_URL_YVES] . '/easycredit/payment/success';
$config[EasycreditConstants::CANCELLED_URL] = $config[ApplicationConstants::BASE_URL_YVES] . '/checkout/payment';
$config[EasycreditConstants::DENIED_URL] = $config[ApplicationConstants::BASE_URL_YVES] . '/checkout/payment';
Integration
To integrate Easycredit into your project, do the following:
- Update
CheckoutPageDependencyProvider
by adding a new payment subform and a payment method handler. To show the Easycredit payment method on the payment step, defineSubFormPlugin
andStepHandlerPlugin
.
CheckoutPageDependencyProvider.php
public const CLIENT_EASYCREDIT = 'CLIENT_EASYCREDIT';
...
/**
* @param \Spryker\Yves\Kernel\Container $container
*
* @return \Spryker\Yves\Kernel\Container
*/
public function provideDependencies(Container $container): Container
{
$container = parent::provideDependencies($container);
$container = $this->addEasycreditClient($container);
return $container;
}
/**
* @param \Spryker\Yves\Kernel\Container $container
*
* @return \Spryker\Yves\Kernel\Container
*/
protected function addSubFormPluginCollection(Container $container): Container
{
$container[static::PAYMENT_SUB_FORMS] = function () {
$subFormPluginCollection = new SubFormPluginCollection();
$subFormPluginCollection->add(new EasycreditSubFormPlugin());
return $subFormPluginCollection;
};
return $container;
}
/**
* @param \Spryker\Yves\Kernel\Container $container
*
* @return \Spryker\Yves\Kernel\Container
*/
protected function addPaymentMethodHandlerPluginCollection(Container $container): Container
{
$container[self::PAYMENT_METHOD_HANDLER] = function () {
$stepHandlerPluginCollection = new StepHandlerPluginCollection();
$stepHandlerPluginCollection->add(new EasycreditHandlerPlugin(), PaymentTransfer::EASYCREDIT);
return $stepHandlerPluginCollection;
};
return $container;
}
/**
* @param \Spryker\Yves\Kernel\Container $container
*
* @return \Spryker\Yves\Kernel\Container
*/
protected function addEasycreditClient(Container $container): Container
{
$container[static::CLIENT_EASYCREDIT] = function (Container $container) {
return $container->getLocator()->easycredit()->client();
};
return $container;
}
...
- The next dependency provider you should update is
OmsDependencyProvider
. To use commands and conditions for events in OMS, define them.
OmsDependencyProvider
...
$container->extend(self::CONDITION_PLUGINS, function (ConditionCollectionInterface $conditionCollection) {
$conditionCollection->add(new IsOrderConfirmedPlugin(), 'Easycredit/IsOrderConfirmed');
return $conditionCollection;
});
...
- And one more dependency provider to be updated is
CheckoutDependencyProvider
. To send requests to Easycredit, you need the technical order identifier value. After adding this plugin, the order identifier will be saved to the database in tablespy_payment_easycredit_order_identifier
.
CheckoutDependencyProvider
...
protected function getCheckoutOrderSavers(Container $container)
{
return [
...
new EasycreditOrderIdentifierPlugin(),
];
}
...
To use Easycredit requests during the checkout process, you have to create your own checkout steps. To implement the checkout steps, follow the guidelines below:
- Extend
StepFactory
.
CheckoutPageFactory
<?php
namespace Pyz\Yves\CheckoutPage;
use Pyz\Yves\CheckoutPage\Process\StepFactory;
use SprykerShop\Yves\CheckoutPage\CheckoutPageFactory as SprykerCheckoutPageFactory;
class CheckoutPageFactory extends SprykerCheckoutPageFactory
{
/**
* @return \SprykerShop\Yves\CheckoutPage\Process\StepFactory
*/
public function createStepFactory()
{
return new StepFactory();
}
}
- Implement
StepFactory
as shown in this example:
StepFactory
<?php
namespace Pyz\Yves\CheckoutPage\Process;
use Pyz\Yves\CheckoutPage\CheckoutPageDependencyProvider;
use Pyz\Yves\CheckoutPage\Plugin\Provider\CheckoutPageControllerProvider;
use Pyz\Yves\CheckoutPage\Process\Steps\EasycreditStep;
use Pyz\Yves\CheckoutPage\Process\Steps\ShipmentStep;
use Pyz\Yves\CheckoutPage\Process\Steps\SummaryStep;
use Spryker\Client\Messenger\MessengerClientInterface;
use Spryker\Yves\StepEngine\Dependency\Step\StepInterface;
use Spryker\Yves\StepEngine\Process\StepCollection;
use Spryker\Zed\Messenger\Business\MessengerFacadeInterface;
use SprykerEco\Client\Easycredit\EasycreditClient;
use SprykerShop\Yves\CheckoutPage\Process\StepFactory as SprykerStepFactory;
use SprykerShop\Yves\HomePage\Plugin\Provider\HomePageControllerProvider;
class StepFactory extends SprykerStepFactory
{
/**
* @return StepInterface
*/
public function createEasycreditStep(): StepInterface
{
return new EasycreditStep(
CheckoutPageControllerProvider::CHECKOUT_EASY_CREDIT,
HomePageControllerProvider::ROUTE_HOME,
$this->getEasycreditClient()
);
}
/**
* @return StepInterface
*/
public function createSummaryStep(): StepInterface
{
return new SprykerShopSummaryStep(
$this->getProductBundleClient(),
$this->getShipmentService(),
$this->getConfig(),
SprykerShopCheckoutPageControllerProvider::CHECKOUT_SUMMARY,
HomePageControllerProvider::ROUTE_HOME,
$this->getCheckoutClient()
);
}
/**
* @return StepInterface
*/
public function createShipmentStep(): StepInterface
{
return new ShipmentStep(
$this->getCalculationClient(),
$this->getShipmentPlugins(),
$this->createShipmentStepPostConditionChecker(),
$this->createGiftCardItemsChecker(),
SprykerShopCheckoutPageControllerProvider::CHECKOUT_SHIPMENT,
HomePageControllerProvider::ROUTE_HOME,
$this->getEasycreditClient()
);
}
/**
* @return \Spryker\Yves\StepEngine\Process\StepCollectionInterface
*/
public function createStepCollection(): StepCollectionInterface
{
$stepCollection = new StepCollection(
$this->getUrlGenerator(), {% if data.easycredit %}
{% include molecule('easycredit-summary', 'Easycredit') with {
data: {
interest: data.easycredit.interest,
url: data.easycredit.url,
text: data.easycredit.text
}
} only %}
{% endif %}
CheckoutPageControllerProvider::CHECKOUT_ERROR
);
$stepCollection
->addStep($this->createEntryStep())
->addStep($this->createCustomerStep())
->addStep($this->createAddressStep())
->addStep($this->createShipmentStep())
->addStep($this->createPaymentStep())
->addStep($this->createEasycreditStep())
->addStep($this->createSummaryStep())
->addStep($this->createPlaceOrderStep())
->addStep($this->createSuccessStep());
return $stepCollection;
}
/**
* @return EasycreditClientInterface
*/
protected function getEasycreditClient(): EasycreditClientInterface
{
return $this->getProvidedDependency(CheckoutPageDependencyProvider::CLIENT_EASYCREDIT);
}
}
- Now you can extend the basic steps on the project level and can create your Easycredit step that will be called when a user takes Easycredit as
PaymentMethod
. Examples of steps implementations:
EasycreditStep.php
<?php
namespace Pyz\Yves\CheckoutPage\Process\Steps;
use Spryker\Shared\Kernel\Transfer\AbstractTransfer;
use Spryker\Yves\StepEngine\Dependency\Step\AbstractBaseStep;
use Spryker\Yves\StepEngine\Dependency\Step\StepWithExternalRedirectInterface;
use SprykerEco\Client\Easycredit\EasycreditClient;
use SprykerEco\Shared\Easycredit\EasycreditConfig;
use Symfony\Component\HttpFoundation\Request;
class EasycreditStep extends AbstractBaseStep implements StepWithExternalRedirectInterface
{
protected const URL_EASYCREDIT_REDIRECT_URL = 'https://ratenkauf.easycredit.de/ratenkauf/content/intern/einstieg.jsf?vorgangskennung=';
/**
* @var string
*/
protected $redirectUrl = '';
/**
* @var \SprykerEco\Client\Easycredit\EasycreditClientInterface
*/
protected $easycreditClient;
/**
* @param string $stepRoute
* @param string $escapeRoute
* @param \SprykerEco\Client\Easycredit\EasycreditClientInterface $easycreditClient
*/
public function __construct(
$stepRoute,
$escapeRoute,
EasycreditClientInterface $easycreditClient
) {
parent::__construct($stepRoute, $escapeRoute);
$this->easycreditClient = $easycreditClient;
}
/**
* @param \Spryker\Shared\Kernel\Transfer\AbstractTransfer|\Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
*
* @return bool
*/
public function requireInput(AbstractTransfer $quoteTransfer)
{
return false;
}
/**
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Spryker\Shared\Kernel\Transfer\AbstractTransfer|\Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
*
* @return \Spryker\Shared\Kernel\Transfer\AbstractTransfer
*/
public function execute(Request $request, AbstractTransfer $quoteTransfer)
{
$payment = $quoteTransfer->getPayment();
if ($payment->getPaymentSelection() === 'easycredit') {
$responseTransfer = $this->easycreditClient->sendInitializePaymentRequest($quoteTransfer);
$this->redirectUrl = static::URL_EASYCREDIT_REDIRECT_URL . $responseTransfer->getPaymentIdentifier();
$quoteTransfer->getPayment()->getEasycredit()->setVorgangskennung($responseTransfer->getPaymentIdentifier());
}
return $quoteTransfer;
}
/**
* @param \Spryker\Shared\Kernel\Transfer\AbstractTransfer|\Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
*
* @return bool
*/
public function postCondition(AbstractTransfer $quoteTransfer)
{
return true;
}
/**
* Return external redirect url, when redirect occurs not within same application. Used after execute.
*
* @return string
*/
public function getExternalRedirectUrl()
{
return $this->redirectUrl;
}
/**
* Requirements for this step, return true when satisfied.
*
* @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
*
* @return bool
*/
public function preCondition(AbstractTransfer $quoteTransfer)
{
return true;
}
ShipmentStep.php
<?php
namespace Pyz\Yves\CheckoutPage\Process\Steps;
use Generated\Shared\Transfer\EasycreditLegalTextTransfer;
use Generated\Shared\Transfer\QuoteTransfer;
use Spryker\Shared\Kernel\Transfer\AbstractTransfer;
use Spryker\Yves\StepEngine\Dependency\Plugin\Handler\StepHandlerPluginCollection;
use SprykerEco\Client\Easycredit\EasycreditClient;
use SprykerEco\Shared\Easycredit\EasycreditConfig;
use SprykerShop\Yves\CheckoutPage\Dependency\Client\CheckoutPageToCalculationClientInterface;
use SprykerShop\Yves\CheckoutPage\Process\Steps\ShipmentStep as SprykerShipmentStep;
use Symfony\Component\HttpFoundation\Request;
class ShipmentStep extends SprykerShipmentStep
{
/**
* @var EasycreditClientInterface
*/
protected $easycreditClient;
public function __construct(
CheckoutPageToCalculationClientInterface $calculationClient,
StepHandlerPluginCollection $shipmentPlugins,
string $stepRoute,
string $escapeRoute,
EasycreditClientInterface $client
) {
parent::__construct($calculationClient, $shipmentPlugins, $stepRoute, $escapeRoute);
$this->easycreditClient = $client;
}
/**
* @param Request $request
* @param QuoteTransfer $quoteTransfer
* @return \Generated\Shared\Transfer\QuoteTransfer
*/
public function execute(Request $request, AbstractTransfer $quoteTransfer)
{
$easycreditLegalTextTransfer = new EasycreditLegalTextTransfer();
$easycreditLegalTextTransfer->setText($this->easycreditClient->sendApprovalTextRequest()->getText());
$quoteTransfer->setEasycreditLegalText($easycreditLegalTextTransfer);
return parent::execute($request, $quoteTransfer);
}
}
SummaryStep.php
<?php
namespace Pyz\Yves\CheckoutPage\Process\Steps;
use Spryker\Shared\Kernel\Transfer\AbstractTransfer;
use SprykerEco\Client\Easycredit\EasycreditClient;
use SprykerShop\Yves\CheckoutPage\Dependency\Client\CheckoutPageToProductBundleClientInterface;
use SprykerShop\Yves\CheckoutPage\Process\Steps\SummaryStep as SprykerSummaryStep;
use Symfony\Component\HttpFoundation\Request;
class SummaryStep extends SprykerSummaryStep
{
/**
* @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
*
* @return array
*/
public function getTemplateVariables(AbstractTransfer $quoteTransfer)
{
$easycreditData = [];
if ($quoteTransfer->getPayment() && $quoteTransfer->getPayment()->getEasycredit()) {
$easycreditData = [
'interest' => $quoteTransfer->getPayment()->getEasycredit()->getAnfallendeZinsen(),
'url' => $quoteTransfer->getPayment()->getEasycredit()->getUrlVorvertraglicheInformationen(),
'text' => $quoteTransfer->getPayment()->getEasycredit()->getTilgungsplanText(),
];
}
return [
'quoteTransfer' => $quoteTransfer,
'cartItems' => $this->productBundleClient->getGroupedBundleItems(
$quoteTransfer->getItems(),
$quoteTransfer->getBundleItems()
),
'easycredit' => $easycreditData,
];
}
}
- To run the step process for the new Easycredit step, extend the default
CheckoutController
with a new action for handling the Easycredit step.
\CheckoutController
<?php
namespace Pyz\Yves\CheckoutPage\Controller;
use SprykerShop\Yves\CheckoutPage\Controller\CheckoutController as SprykerCheckoutController;
use Symfony\Component\HttpFoundation\Request;
class CheckoutController extends SprykerCheckoutController
{
/**
* @param \Symfony\Component\HttpFoundation\Request $request
*
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function easyCreditAction(Request $request)
{
return $this->createStepProcess()->process($request);
}
}
- After creating a new action in the checkout controller, define a new route in
CheckoutPageRouteProviderPlugin
.
CheckoutPageRouteProviderPlugin.php
<?php
namespace Pyz\Yves\CheckoutPage\Plugin\Router;
use SprykerShop\Yves\CheckoutPage\Plugin\Router\CheckoutPageRouteProviderPlugin as SprykerCheckoutPageRouteProviderPlugin;
use Spryker\Yves\Router\Route\RouteCollection;
class CheckoutPageRouteProviderPlugin extends SprykerCheckoutPageRouteProviderPlugin
{
public const CHECKOUT_EASY_CREDIT = 'easy-credit';
protected const ROUTE_CART = 'cart';
/**
* Specification:
* - Adds Routes to the RouteCollection.
*
* @api
*
* @param \Spryker\Yves\Router\Route\RouteCollection $routeCollection
*
* @return \Spryker\Yves\Router\Route\RouteCollection
*/
public function addRoutes(RouteCollection $routeCollection): RouteCollection
{
$routeCollection = parent::addRoutes($routeCollection);
$routeCollection = $this->addEasycreditStepRoute($routeCollection);
return $routeCollection;
}
/**
* @param \Spryker\Yves\Router\Route\RouteCollection $routeCollection
*/
public function addEasycreditStepRoute($routeCollection)
{
$route = $this->buildRoute('/checkout/easycredit', 'CheckoutPage', 'Checkout', 'easyCredit');
$route = $route->setMethods(['GET', 'POST']);
$routeCollection->add(static::CHECKOUT_EASY_CREDIT, $route);
return $routeCollection;
}
}
- Also, the Easycredit bundle has its own
YvesController
for handling a success response from Easycredit, so you have to define a controller inRouterDependencyProvider
.
RouterDependencyProvider.php
<?php
namespace Pyz\Yves\Router;
...
use Pyz\Yves\CheckoutPage\Plugin\Router\CheckoutPageRouteProviderPlugin;
...
class RouterDependencyProvider extends SprykerRouterDependencyProvider
{
...
protected function getRouteProvider(): array
{
...
new CheckoutPageRouteProviderPlugin(),
...
}
...
}
Frontend Part
To show the Easycredit info on the Product Details page, at the Summary and Payment steps, you have to extend some views on the project level .
You can find some examples below in [
payment.twig](#payment-step)
, summary.twig
and pdp.twig
.
payment.twig
Payment step - src/Pyz/Yves/CheckoutPage/Theme/default/views/payment/payment.twig
{% extends template('page-layout-checkout', 'CheckoutPage') %}
{% define data = {
backUrl: _view.previousStepUrl,
forms: {
payment: _view.paymentForm
},
title: 'checkout.step.payment.title' | trans,
customForms: {
'Easycredit/easycredit': 1
}
} %}
{% block content %}
{% embed molecule('form') with {
class: 'box',
data: {
form: data.forms.payment,
options: {
attr: {
id: 'payment-form'
}
},
submit: {
enable: true,
text: 'checkout.step.summary' | trans
},
cancel: {
enable: true,
url: data.backUrl,
text: 'general.back.button' | trans
},
customForms: data.customForms
}
} only %}
{% block fieldset %}
{% for name, choices in data.form.paymentSelection.vars.choices %}
{% set paymentProviderIndex = loop.index0 %}
<h5>{{ ('checkout.payment.provider.' ~ name) | trans }}</h5>
<ul>
{% for key, choice in choices %}
<li class="list__item spacing-y clear">
{% embed molecule('form') with {
data: {
form: data.form[data.form.paymentSelection[key].vars.value],
enableStart: false,
enableEnd: false,
customForms: data.customForms
},
embed: {
index: loop.index ~ '-' ~ paymentProviderIndex,
toggler: data.form.paymentSelection[key]
}
} only %}
{% block fieldset %}
{{ form_row(embed.toggler, {
required: false,
component: molecule('toggler-radio'),
attributes: {
'target-selector': '.js-payment-method-' ~ embed.index,
'class-to-toggle': 'is-hidden'
}
}) }}
<div class="col col--sm-12 is-hidden js-payment-method-{{embed.index}}">
<div class="col col--sm-12 col--md-6">
{% if data.customForms[data.form.vars.template_path] is not defined %}
{{ parent() }}
{% else %}
{% include view('easycredit', 'Easycredit') with {
data: {
form: data.form,
legalText: data.form.vars.legalText
}
} only %}
{% endif %}
</div>
</div>
{% endblock %}
{% endembed %}
</li>
{% endfor %}
</ul>
{% endfor %}
{% endblock %}
{% endembed %}
{% endblock %}
summary.twig
Summary step - src/Pyz/Yves/CheckoutPage/Theme/default/views/summary/summary.twig
{% extends template('page-layout-checkout', 'CheckoutPage') %}
{% define data = {
backUrl: _view.previousStepUrl,
transfer: _view.quoteTransfer,
cartItems: _view.cartItems,
easycredit: _view.easycredit,
shippingAddress: _view.quoteTransfer.shippingAddress,
billingAddress: _view.quoteTransfer.billingAddress,
shipmentMethod: _view.quoteTransfer.shipment.method.name,
paymentMethod: _view.quoteTransfer.payment.paymentMethod,
forms: {
summary: _view.summaryForm
},
overview: {
shipmentMethod: _view.quoteTransfer.shipment.method.name,
expenses: _view.quoteTransfer.expenses,
voucherDiscounts: _view.quoteTransfer.voucherDiscounts,
cartRuleDiscounts: _view.quoteTransfer.cartRuleDiscounts,
prices: {
subTotal: _view.quoteTransfer.totals.subtotal,
storeCurrency: _view.quoteTransfer.shipment.method.storeCurrencyPrice,
grandTotal: _view.quoteTransfer.totals.grandtotal,
tax: _view.quoteTransfer.totals.taxtotal.amount,
discountTotal: _view.quoteTransfer.totals.discounttotal | default
}
},
title: 'checkout.step.summary.title' | trans
} %}
{% block content %}
<div class="grid">
<div class="col col--sm-12 col--lg-4">
<div class="box">
<span class="float-right">{{ 'checkout.step.summary.with_method' | trans }} <strong>{{data.paymentMethod}}</strong></span>
<h6>{{ 'checkout.step.summary.payment' | trans }}</h6>
<hr/>
{% include molecule('display-address') with {
class: 'text-small',
data: {
address: data.billingAddress
}
} only %}
</div>
<div class="box">
<span class="float-right">{{ 'checkout.step.summary.with_method' | trans }} <strong>{{ data.shipmentMethod }}</strong></span>
<h6>{{ 'checkout.step.summary.shipping' | trans }}</h6>
<hr/>
{% include molecule('display-address') with {
class: 'text-small',
data: {
address: data.shippingAddress
}
} only %}
</div>
</div>
<div class="col col--sm-12 col--lg-8">
<div class="box">
{% for item in data.cartItems %}
{% set item = item.bundleProduct is defined ? item.bundleProduct : item %}
{% embed molecule('summary-item', 'CheckoutPage') with {
data: {
name: item.name,
quantity: item.quantity,
price: item.sumPrice | money,
options: item.productOptions | default({}),
bundleItems: item.bundleItems | default([]),
quantitySalesUnit: item.quantitySalesUnit,
amountSalesUnit: item.amountSalesUnit,
amount: item.amount
},
embed: {
isLast: not loop.last,
item: item
}
} only %}
{% block body %}
{{parent()}}
{% if widgetExists('CartNoteQuoteItemNoteWidgetPlugin') %}
{% if embed.item.cartNote is not empty %}
{{ widget('CartNoteQuoteItemNoteWidgetPlugin', embed.item) }} {# @deprecated Use molecule('note-list', 'CartNoteWidget') instead. #}
{% endif %}
{% elseif embed.item.cartNote is not empty %}
{% include molecule('note-list', 'CartNoteWidget') ignore missing with {
data: {
label: 'cart_note.checkout_page.item_note',
note: embed.item.cartNote
}
} only %}
{% endif %}
{% if embed.isLast %}<hr/>{% endif %}
{% endblock %}
{% endembed %}
{% endfor %}
</div>
{% if data.transfer.cartNote is not empty %}
{% if widgetExists('CartNoteQuoteNoteWidgetPlugin') %}
<div class="box">
{{ widget('CartNoteQuoteNoteWidgetPlugin', data.transfer) }} {#@deprecated Use molecule('note-list', 'CartNoteWidget') instead.#}
</div>
{% else %}
<div class="box">
{% include molecule('note-list', 'CartNoteWidget') ignore missing with {
data: {
label: 'cart_note.checkout_page.quote_note',
note: data.transfer.cartNote
}
} only %}
</div>
{% endif %}
{% endif %}
<div class="box">
{% widget 'CheckoutVoucherFormWidget' args [data.transfer] only %}
{% elsewidget 'CheckoutVoucherFormWidgetPlugin' args [data.transfer] only %} {# @deprecated Use CheckoutVoucherFormWidget instead. #}
{% endwidget %}
</div>
% embed molecule('form') with {
class: 'box',
data: {
form: data.forms.summary,
submit: {
enable: can('SeeOrderPlaceSubmitPermissionPlugin'),
text: 'checkout.step.place.order' | trans
},
cancel: {
enable: true,
url: data.backUrl,
text: 'general.back.button' | trans
}
},
embed: {
overview: data.overview
}
} only %}
{% block body %}
{% include molecule('summary-overview', 'CheckoutPage') with {
data: embed.overview
} only %}
<hr />
{{parent()}}
{% endblock %}
{% endembed %}
{% if data.easycredit %}
{% include molecule('easycredit-summary', 'Easycredit') with {
data: {
interest: data.easycredit.interest,
url: data.easycredit.url,
text: data.easycredit.text
}
} only %}
{% endif %}
</div>
</div>
{% endblock %}
pdp.twig
PDP page - src/Pyz/Yves/ProductDetailPage/Theme/default/views/pdp/pdp.twig
{% extends template('page-layout-main') %}
{% define data = {
product: _view.product,
productUrl: _view.productUrl,
title: product.metaTitle | default(_view.product.name),
metaTitle: product.metaTitle | default(_view.product.name),
metaDescription: _view.product.metaDescription | default,
metaKeywords: _view.product.metaKeywords | default
} %}
{% block headScripts %}
{{ parent() }}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" type="text/javascript"></script>
{% endblock %}
{% block breadcrumbs %}
{% widget 'ProductBreadcrumbsWithCategoriesWidget' args [data.product] only %}
{% elsewidget 'ProductCategoryWidgetPlugin' args [data.product] only %} {# @deprecated Use ProductBreadcrumbsWithCategoriesWidget instead. #}
{% endwidget %}
{% endblock %}
{% block title %}
<h3 itemprop="name">{{ data.product.name }}</h3>
<link itemprop="url" href="{{ data.productUrl }}" />
{% endblock %}
{% block content %}
<div class="grid">
<div class="col col--sm-12 col--lg-7 col--xl-8">
{% include molecule('product-carousel', 'ProductDetailPage') with {
class: 'box',
data: {
product: data.product
}
} only %}
</div>
<div class="col col--sm-12 col--lg-5 col--xl-4">
{% include molecule('product-configurator', 'ProductDetailPage') with {
class: 'box',
data: {
product: data.product
}
} only %}
</div>
</div>
{% widget 'ProductAlternativeListWidget' args [data.product] only %}
{% elsewidget 'ProductAlternativeWidgetPlugin' args [data.product] only %} {# @deprecated Use ProductAlternativeListWidget instead. #}
{% endwidget %}
{% include molecule('product-detail', 'ProductDetailPage') with {
class: 'box',
data: {
description: data.product.description,
attributes: data.product.attributes
}
} only %}
{% widget 'ProductReplacementForListWidget' args [data.product.sku] only %}
{% elsewidget 'ProductReplacementForWidgetPlugin' args [data.product.sku] only %} {# @deprecated Use ProductReplacementForListWidget instead. #}
{% endwidget %}
{% widget 'ProductDetailPageReviewWidget' args [data.product.idProductAbstract] only %}
{% elsewidget 'ProductReviewWidgetPlugin' args [data.product.idProductAbstract] only %} {# @deprecated Use ProductDetailPageReviewWidget instead. #}
{% endwidget %}
{% widget 'SimilarProductsWidget' args [data.product] only %}
{% elsewidget 'SimilarProductsWidgetPlugin' args [data.product] only %} {# @deprecated Use SimilarProductsWidget instead. #}
{% endwidget %}
{% if widgetExists('ProductCmsBlockWidgetPlugin') %}
{{ widget('ProductCmsBlockWidgetPlugin', data.product) }} {# @deprecated Use molecule('product-cms-block', 'CmsBlockWidget') instead. #}
{% else %}
{% include molecule('product-cms-block', 'CmsBlockWidget') ignore missing with {
class: 'box',
data: {
idProductAbstract: data.product.idProductAbstract
}
} only %}
{% endif %}
{% endblock %}
You might want to configure the product detail page to add some validation and show the Easycredit badge in src/Pyz/Yves/ProductDetailPage/Theme/default/components/molecules/product-configurator/product-configurator.twig
product-configurator.twig
...
{% set easyCreditMinTreshold = 20000 %}
{% set easyCreditMaxTreshold = 500000 %}
{% if data.product.price > easyCreditMinTreshold and data.product.price < easyCreditMaxTreshold %}
{% include molecule('easycredit-badge', 'EasyCredit' ) with {
data: {
title: 'EasyCredit:',
id: 'easy-credit-id'
},
attributes: {
'easycredit-options': '{
"webshopId": "<Your shop identifier>",
"finanzierungsbetrag": "' ~ data.product.price / 100 ~ '" ,
"textVariante": "KURZ"
}'
}
} only %}
{% endif %}
...
Thank you!
For submitting the form