Create merchant commission calculator type plugins
Edit on GitHubThis document describes how to create and register a merchant commission calculator type plugin to provide custom calculation logic for merchant commissions.
Approximate time to complete: 1 hour.
Prerequisites
Install the Marketplace Merchant Commission feature.
1) Adjust transfer definitions
- To provide the required order item data, adjust the definition of the
MerchantCommissionCalculationRequestItem
transfer object.MerchantCommissionCalculationRequestItemTransfer
is populated with data from thespy_sales_order_item
database table. To provide the price to pay aggregation amount of the order item, add thesumPriceToPayAggregation
property to the transfer object.
src/Pyz/Shared/MerchantCommission/Transfer/merchant_commission.transfer.xml
<?xml version="1.0"?>
<transfers xmlns="spryker:transfer-01" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="spryker:transfer-01 http://static.spryker.com/transfer-01.xsd">
<transfer name="MerchantCommissionCalculationRequestItem" strict="true">
<property name="sumPriceToPayAggregation" type="int"/>
</transfer>
</transfers>
- Generate the transfer objects:
console transfer:generate
2) Implement the calculator business model
Implement a custom class to calculate merchant commission amount based on the order item’s sum price to pay aggregation value; this class implements the MerchantCommissionCalculatorTypeInterface
interface.
src/Pyz/Zed/MerchantCommission/Business/Calculator/SumPriceToPayPercentageMerchantCommissionCalculatorType.php
<?php
namespace Pyz\Zed\MerchantCommission\Business\Calculator;
use Generated\Shared\Transfer\MerchantCommissionCalculationRequestItemTransfer;
use Generated\Shared\Transfer\MerchantCommissionCalculationRequestTransfer;
use Generated\Shared\Transfer\MerchantCommissionTransfer;
use Spryker\Zed\MerchantCommission\Business\Calculator\MerchantCommissionCalculatorTypeInterface;
use Spryker\Zed\MerchantCommission\MerchantCommissionConfig;
class SumPriceToPayPercentageMerchantCommissionCalculatorType implements MerchantCommissionCalculatorTypeInterface
{
/**
* @var \Spryker\Zed\MerchantCommission\MerchantCommissionConfig
*/
protected MerchantCommissionConfig $merchantCommissionConfig;
/**
* @param \Spryker\Zed\MerchantCommission\MerchantCommissionConfig $merchantCommissionConfig
*/
public function __construct(MerchantCommissionConfig $merchantCommissionConfig)
{
$this->merchantCommissionConfig = $merchantCommissionConfig;
}
/**
* @param \Generated\Shared\Transfer\MerchantCommissionTransfer $merchantCommissionTransfer
* @param \Generated\Shared\Transfer\MerchantCommissionCalculationRequestItemTransfer $merchantCommissionCalculationRequestItemTransfer
* @param \Generated\Shared\Transfer\MerchantCommissionCalculationRequestTransfer $merchantCommissionCalculationRequestTransfer
*
* @return int
*/
public function calculateMerchantCommissionAmount(
MerchantCommissionTransfer $merchantCommissionTransfer,
MerchantCommissionCalculationRequestItemTransfer $merchantCommissionCalculationRequestItemTransfer,
MerchantCommissionCalculationRequestTransfer $merchantCommissionCalculationRequestTransfer
): int {
$merchantCommissionPercentAmount = $merchantCommissionTransfer->getAmountOrFail() / 100;
if ($merchantCommissionPercentAmount <= 0) {
return 0;
}
return $this->calculate(
$merchantCommissionCalculationRequestItemTransfer->getSumPriceToPayAggregationOrFail(),
$merchantCommissionPercentAmount,
);
}
/**
* @param int $sumPriceToPayAggregation
* @param float $merchantCommissionPercentAmount
*
* @return int
*/
protected function calculate(int $sumPriceToPayAggregation, float $merchantCommissionPercentAmount): int
{
$calculatedMerchantCommissionAmount = $sumPriceToPayAggregation * $merchantCommissionPercentAmount / 100;
return (int)round(
$calculatedMerchantCommissionAmount,
0,
$this->merchantCommissionConfig->getPercentageMerchantCommissionCalculationRoundMode(),
);
}
}
3) Introduce a facade method for the calculation logic
src/Pyz/Zed/MerchantCommission/Business/MerchantCommissionBusinessFactory.php
<?php
namespace Pyz\Zed\MerchantCommission\Business;
use Pyz\Zed\MerchantCommission\Business\Calculator\SumPriceToPayPercentageMerchantCommissionCalculatorType;
use Spryker\Zed\MerchantCommission\Business\Calculator\MerchantCommissionCalculatorTypeInterface;
use Spryker\Zed\MerchantCommission\Business\MerchantCommissionBusinessFactory as SprykerMerchantCommissionBusinessFactory;
/**
* @method \Spryker\Zed\MerchantCommission\Persistence\MerchantCommissionEntityManagerInterface getEntityManager()
* @method \Pyz\Zed\MerchantCommission\MerchantCommissionConfig getConfig()
* @method \Spryker\Zed\MerchantCommission\Persistence\MerchantCommissionRepositoryInterface getRepository()
*/
class MerchantCommissionBusinessFactory extends SprykerMerchantCommissionBusinessFactory
{
/**
* @return \Spryker\Zed\MerchantCommission\Business\Calculator\MerchantCommissionCalculatorTypeInterface
*/
public function createSumPriceToPayPercentageMerchantCommissionCalculatorType(): MerchantCommissionCalculatorTypeInterface
{
return new SumPriceToPayPercentageMerchantCommissionCalculatorType($this->getConfig());
}
}
src/Pyz/Zed/MerchantCommission/Business/MerchantCommissionFacadeInterface.php
<?php
namespace Pyz\Zed\MerchantCommission\Business;
use Generated\Shared\Transfer\MerchantCommissionCalculationRequestItemTransfer;
use Generated\Shared\Transfer\MerchantCommissionCalculationRequestTransfer;
use Generated\Shared\Transfer\MerchantCommissionTransfer;
use Spryker\Zed\MerchantCommission\Business\MerchantCommissionFacadeInterface as SprykerMerchantCommissionFacadeInterface;
interface MerchantCommissionFacadeInterface extends SprykerMerchantCommissionFacadeInterface
{
/**
* @param \Generated\Shared\Transfer\MerchantCommissionTransfer $merchantCommissionTransfer
* @param \Generated\Shared\Transfer\MerchantCommissionCalculationRequestItemTransfer $merchantCommissionCalculationRequestItemTransfer
* @param \Generated\Shared\Transfer\MerchantCommissionCalculationRequestTransfer $merchantCommissionCalculationRequestTransfer
*
* @return int
*/
public function calculateSumPriceToPayPercentageMerchantCommissionAmount(
MerchantCommissionTransfer $merchantCommissionTransfer,
MerchantCommissionCalculationRequestItemTransfer $merchantCommissionCalculationRequestItemTransfer,
MerchantCommissionCalculationRequestTransfer $merchantCommissionCalculationRequestTransfer
): int;
}
src/Pyz/Zed/MerchantCommission/Business/MerchantCommissionFacade.php
<?php
namespace Pyz\Zed\MerchantCommission\Business;
use Generated\Shared\Transfer\MerchantCommissionCalculationRequestItemTransfer;
use Generated\Shared\Transfer\MerchantCommissionCalculationRequestTransfer;
use Generated\Shared\Transfer\MerchantCommissionTransfer;
use Spryker\Zed\MerchantCommission\Business\MerchantCommissionFacade as SprykerMerchantCommissionFacade;
/**
* @method \Spryker\Zed\MerchantCommission\Persistence\MerchantCommissionEntityManagerInterface getEntityManager()
* @method \Spryker\Zed\MerchantCommission\Persistence\MerchantCommissionRepositoryInterface getRepository()
* @method \Pyz\Zed\MerchantCommission\Business\MerchantCommissionBusinessFactory getFactory()
*/
class MerchantCommissionFacade extends SprykerMerchantCommissionFacade implements MerchantCommissionFacadeInterface
{
/**
* @param \Generated\Shared\Transfer\MerchantCommissionTransfer $merchantCommissionTransfer
* @param \Generated\Shared\Transfer\MerchantCommissionCalculationRequestItemTransfer $merchantCommissionCalculationRequestItemTransfer
* @param \Generated\Shared\Transfer\MerchantCommissionCalculationRequestTransfer $merchantCommissionCalculationRequestTransfer
*
* @return int
*/
public function calculateSumPriceToPayPercentageMerchantCommissionAmount(
MerchantCommissionTransfer $merchantCommissionTransfer,
MerchantCommissionCalculationRequestItemTransfer $merchantCommissionCalculationRequestItemTransfer,
MerchantCommissionCalculationRequestTransfer $merchantCommissionCalculationRequestTransfer
): int {
return $this->getFactory()
->createSumPriceToPayPercentageMerchantCommissionCalculatorType()
->calculateMerchantCommissionAmount(
$merchantCommissionTransfer,
$merchantCommissionCalculationRequestItemTransfer,
$merchantCommissionCalculationRequestTransfer,
);
}
}
4) Implement the calculator plugin
Implement the plugin that provides the logic to calculate the merchant commission amount and correct persisting and reading the merchant commission amount; the plugin implements the MerchantCommissionCalculatorPluginInterface
interface and the following methods:
getCalculatorType()
Returns the type of the calculator because it will be stored in the spy_merchant_commission.calculator_plugin_type
database column.
transformAmountForPersistence()
Transforms merchant commission amount before persisting. To avoid floating point precision issues, we recommend persisting the amount multiplied by 100.
transformAmountFromPersistence()
Transforms the merchant commission amount after reading from the database.
formatMerchantCommissionAmount()
Formats the merchant commission amount for displaying in the Back Office on the Merchant Commission Detail page.
src/Pyz/Zed/MerchantCommission/Communication/Plugin/MerchantCommission/PriceToPayPercentageMerchantCommissionCalculatorPlugin.php
<?php
namespace Pyz\Zed\MerchantCommission\Communication\Plugin\MerchantCommission;
use Generated\Shared\Transfer\MerchantCommissionCalculationRequestItemTransfer;
use Generated\Shared\Transfer\MerchantCommissionCalculationRequestTransfer;
use Generated\Shared\Transfer\MerchantCommissionTransfer;
use Spryker\Zed\Kernel\Communication\AbstractPlugin;
use Spryker\Zed\MerchantCommissionExtension\Communication\Dependency\Plugin\MerchantCommissionCalculatorPluginInterface;
/**
* @method \Pyz\Zed\MerchantCommission\MerchantCommissionConfig getConfig()
* @method \Pyz\Zed\MerchantCommission\Business\MerchantCommissionFacadeInterface getFacade()
* @method \Spryker\Zed\MerchantCommission\Communication\MerchantCommissionCommunicationFactory getFactory()
*/
class SumPriceToPayPercentageMerchantCommissionCalculatorPlugin extends AbstractPlugin implements MerchantCommissionCalculatorPluginInterface
{
/**
* @var string
*/
protected const CALCULATOR_TYPE = 'sum-price-to-pay-percentage';
/**
* @return string
*/
public function getCalculatorType(): string
{
return static::CALCULATOR_TYPE;
}
/**
* @param \Generated\Shared\Transfer\MerchantCommissionTransfer $merchantCommissionTransfer
* @param \Generated\Shared\Transfer\MerchantCommissionCalculationRequestItemTransfer $merchantCommissionCalculationRequestItemTransfer
* @param \Generated\Shared\Transfer\MerchantCommissionCalculationRequestTransfer $merchantCommissionCalculationRequestTransfer
*
* @return int
*/
public function calculateMerchantCommission(
MerchantCommissionTransfer $merchantCommissionTransfer,
MerchantCommissionCalculationRequestItemTransfer $merchantCommissionCalculationRequestItemTransfer,
MerchantCommissionCalculationRequestTransfer $merchantCommissionCalculationRequestTransfer
): int {
return $this->getFacade()->calculateSumPriceToPayPercentageMerchantCommissionAmount(
$merchantCommissionTransfer,
$merchantCommissionCalculationRequestItemTransfer,
$merchantCommissionCalculationRequestTransfer,
);
}
/**
* @param float $merchantCommissionAmount
*
* @return int
*/
public function transformAmountForPersistence(float $merchantCommissionAmount): int
{
return (int)round($merchantCommissionAmount * 100);
}
/**
* @param int $merchantCommissionAmount
*
* @return float
*/
public function transformAmountFromPersistence(int $merchantCommissionAmount): float
{
return round($merchantCommissionAmount / 100, 2);
}
/**
* @param int $merchantCommissionAmount
* @param string|null $currencyIsoCode
*
* @return string
*/
public function formatMerchantCommissionAmount(int $merchantCommissionAmount, ?string $currencyIsoCode = null): string
{
return sprintf('%s %%', $this->transformAmountFromPersistence($merchantCommissionAmount));
}
}
5) Register the calculator plugin
To register the plugin, add it to the MerchantCommissionDependencyProvider::getMerchantCommissionCalculatorPlugins()
method.
src/Pyz/Zed/MerchantCommission/MerchantCommissionDependencyProvider.php
<?php
namespace Pyz\Zed\MerchantCommission;
use Pyz\Zed\MerchantCommission\Communication\Plugin\MerchantCommission\SumPriceToPayPercentageMerchantCommissionCalculatorPlugin;
use Spryker\Zed\MerchantCommission\MerchantCommissionDependencyProvider as SprykerMerchantCommissionDependencyProvider;
class MerchantCommissionDependencyProvider extends SprykerMerchantCommissionDependencyProvider
{
/**
* @return list<\Spryker\Zed\MerchantCommissionExtension\Communication\Dependency\Plugin\MerchantCommissionCalculatorPluginInterface>
*/
protected function getMerchantCommissionCalculatorPlugins(): array
{
return [
new SumPriceToPayPercentageMerchantCommissionCalculatorPlugin(),
];
}
}
Now you can import merchant commissions with the calculator type plugin sum-price-to-pay-percentage
and calculate commissions for items based on sum price to pay aggregation amount.
Thank you!
For submitting the form