PayOne - Integration With Project
![](../../../../../resources/images/shoptype/demoshop.png)
- Objectives:
- Place order with PayPal express checkout.
- Be redirected to summary page of standard checkout.
- Have shipping a method selector on summary page.
First of all we need to provide a URL to Payone module, which will be used to redirect user when the quote is filled with data obtained from PayPal. To achieve this, make the following steps:
- Add custom controller action to
src/Pyz/Yves/Checkout/Controller/CheckoutController.php
: - Register a new controller action in controller provider:
- Create
ExpressCheckoutHandler
classsrc/Pyz/Yves/Checkout/Handler/ExpressCheckoutHandler.php
with corresponding interface: - Add
ExpressCheckoutHandler
related method insrc/Pyz/Yves/Checkout/CheckoutFactory.php
: - Extend
ShipmentForm
class to override a property_path option (createsrc/Pyz/Yves/Shipment/Form/ShipmentSubForm.php
): - Adjust summary form by adding a shipment subform in
src/Pyz/Yves/Checkout/Form/Steps/SummaryForm.php
: - Create shipment subform template for summary page in
src/Pyz/Yves/Checkout/Theme/default/checkout/partials/shipment.twig
: - Update summary twig template in
src/Pyz/Yves/Checkout/Theme/default/checkout/summary.twig
. Moveform_start
expression to the top of a content section andform_end
to the end: - Remove
{% include '@checkout/checkout/partials/voucher-form.twig' %}
include from summary template. Includecheckout/partials/shipment.twig
in your summary template: - {{ 'checkout.step.summary.shipping' | trans }} {% include '@checkout/checkout/partials/shipment.twig' %} ...
- Add shipment form data provider and remove voucher form from summary form collection(It is just an example, if you need voucher form, you need to adjust summary page on your own). In
src/Pyz/Yves/Checkout/Form/FormFactory.php
: - Handle shipment form data, when summary form is submitted. Inject two dependencies into
src/Pyz/Yves/Checkout/Process/Steps/SummaryStep.php
: - Extend
execute
method:
/**
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function paypalExpressCheckoutEntryPointAction()
{
$this->getFactory()
->createExpressCheckoutHandler()
->fulfillPostConditionsUntilSummaryStep();
return $this->redirectResponseInternal(CheckoutControllerProvider::CHECKOUT_SUMMARY);
}
...
const CHECKOUT_PAYPAL_EXPRESS_CHECKOUT_ENTRY_POINT = 'checkout-paypal-express-checkout-entry-point';
...
protected function defineControllers(Application $app)
{
...
$this->createController('/{checkout}/paypal-express-checkout-entry-point', self::CHECKOUT_PAYPAL_EXPRESS_CHECKOUT_ENTRY_POINT, 'Checkout', 'Checkout', 'paypalExpressCheckoutEntryPoint')
->assert('checkout', $allowedLocalesPattern . 'checkout|checkout')
->value('checkout', 'checkout')
->method('GET');
...
}
namespace Pyz\Yves\Checkout\Handler;
use Generated\Shared\Transfer\ExpenseTransfer;
use Spryker\Client\Cart\CartClientInterface;
use Spryker\Shared\Shipment\ShipmentConstants;
class ExpressCheckoutHandler implements ExpressCheckoutHandlerInterface
{
/**
* @var \Spryker\Client\Cart\CartClientInterface
*/
protected $cartClient;
/**
* @param \Spryker\Client\Cart\CartClientInterface $cartClient
*/
public function __construct(CartClientInterface $cartClient)
{
$this->cartClient = $cartClient;
}
/**
* @return void
*/
public function fulfillPostConditionsUntilSummaryStep()
{
$quoteTransfer = $this->cartClient->getQuote();
$quoteTransfer->addExpense(
(new ExpenseTransfer())->setType(ShipmentConstants::SHIPMENT_EXPENSE_TYPE)
);
}
}
/**
* @return \Pyz\Yves\Checkout\Handler\ExpressCheckoutHandler
*/
public function createExpressCheckoutHandler()
{
return new ExpressCheckoutHandler(
$this->getCartClient()
);
}
namespace Pyz\Yves\Shipment\Form;
class ShipmentSubForm extends ShipmentForm
{
/**
* @const string
*/
const SHIPMENT_SELECTION_PROPERTY_PATH = self::SHIPMENT_SELECTION;
}
class SummaryForm extends AbstractType
{
/**
* Builds the form.
*
* This method is called for each type in the hierarchy starting from the
* top most type. Type extensions can further modify the form.
*
* @see FormTypeExtensionInterface::buildForm()
*
* @param \Symfony\Component\Form\FormBuilderInterface $builder The form builder
* @param array $options The options
*
* @return void
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
'shipmentForm',
ShipmentSubForm::class,
array_merge(
$options,
[
'data_class' => ShipmentTransfer::class,
'property_path' => 'shipment',
]
)
);
}
/**
* @param \Symfony\Component\OptionsResolver\OptionsResolver $resolver
*
* @return void
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired('shipmentMethods');
$resolver->setDefaults([
'data_class' => QuoteTransfer::class,
]);
}
/**
* Returns the name of this type.
*
* @return string The name of this type
*/
public function getName()
{
return 'summaryForm';
}
}
<div class="row columns">
{% set shipmentForm = summaryForm.shipmentForm %}
<div class="callout">
<ul class="no-bullet">
{% for name, choices in shipmentForm.idShipmentMethod.vars.choices %}
<h4>{{ name }}</h4>
{% for key, choice in choices %}
<li>
<label>
{{ form_widget(shipmentForm.idShipmentMethod[key], {'attr': {'class': '__toggler'}}) }}
{{ shipmentForm.idShipmentMethod[key].vars.label | raw }}
</label>
</li>
{% endfor %}
{% endfor %}
</ul>
</div>
</div>
...
{% block content %}
{{ form_start(summaryForm, {'attr': {'class': 'row'}}) }}
...
...
...
{{ form_end(summaryForm) }}
{% endblock %}
...
/**
* @param \Generated\Shared\Transfer\QuoteTransfer
*
* @return \Spryker\Yves\StepEngine\Form\FormCollectionHandlerInterface
*/
public function createSummaryFormCollection()
{
return $this->createFormCollection($this->createSummaryFormTypes(), $this->getShipmentFormDataProviderPlugin());
}
....
/**
* @return \Symfony\Component\Form\FormTypeInterface[]
*/
protected function createSummaryFormTypes()
{
return [
$this->createSummaryForm(),
//$this->createVoucherFormType(),
];
}
/**
* @var \Spryker\Client\Calculation\CalculationClientInterface
*/
protected $calculationClient;
/**
* @var \Spryker\Yves\StepEngine\Dependency\Plugin\Handler\StepHandlerPluginCollection
*/
protected $shipmentPlugins;
/**
* @param \Spryker\Yves\ProductBundle\Grouper\ProductBundleGrouperInterface $productBundleGrouper
* @param \Spryker\Client\Cart\CartClientInterface $cartClient
* @param \Spryker\Client\Calculation\CalculationClientInterface $calculationClient
* @param \Spryker\Client\Calculation\CalculationClientInterface $shipmentPlugins
* @param string $stepRoute
* @param string $escapeRoute
*/
public function __construct(
ProductBundleGrouperInterface $productBundleGrouper,
CartClientInterface $cartClient,
CalculationClientInterface $calculationClient,
StepHandlerPluginCollection $shipmentPlugins,
$stepRoute,
$escapeRoute
) {
parent::__construct($stepRoute, $escapeRoute);
$this->productBundleGrouper = $productBundleGrouper;
$this->cartClient = $cartClient;
$this->calculationClient = $calculationClient;
$this->shipmentPlugins = $shipmentPlugins;
}
/**
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Spryker\Shared\Kernel\Transfer\AbstractTransfer|\Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
*
* @return \Generated\Shared\Transfer\QuoteTransfer
*/
public function execute(Request $request, AbstractTransfer $quoteTransfer)
{
$shipmentHandler = $this->shipmentPlugins->get(CheckoutDependencyProvider::PLUGIN_SHIPMENT_STEP_HANDLER);
$shipmentHandler->addToDataClass($request, $quoteTransfer);
$this->calculationClient->recalculate($quoteTransfer);
$this->markCheckoutConfirmed($request, $quoteTransfer);
return $quoteTransfer;
}
Now go to checkout and try placing an order with Paypal express checkout.
See also:
Last review date: Nov. 6th, 2017