-
Notifications
You must be signed in to change notification settings - Fork 154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support sale
operation by Magento payment provider gateway
#9
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
## Overview | ||
[Magento payment provider gateway](https://devdocs.magento.com/guides/v2.2/payments-integrations/bk-payments-integrations.html) doesn't support `sale` payment operation out of the box like `authorize` or `capture` operations. | ||
|
||
This operation is available for the majority of payment methods. | ||
|
||
Now, each payment method should implement an own workaround for `sale` payment operation, because [Order\Payment](https://github.com/magento/magento2/blob/2.2-develop/app/code/Magento/Sales/Model/Order/Payment.php#L445) calls capture instead sale: | ||
|
||
**Magento\Sales\Model\Order\Payment** | ||
```php | ||
protected function processAction($action, Order $order) | ||
{ | ||
$totalDue = $order->getTotalDue(); | ||
$baseTotalDue = $order->getBaseTotalDue(); | ||
|
||
switch ($action) { | ||
............................................................................ | ||
case \Magento\Payment\Model\Method\AbstractMethod::ACTION_AUTHORIZE_CAPTURE: | ||
$this->setAmountAuthorized($totalDue); | ||
$this->setBaseAmountAuthorized($baseTotalDue); | ||
$this->capture(null); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
``` | ||
[This article](https://community.magento.com/t5/Magento-DevBlog/The-Magento-Sale-Payment-Operation/ba-p/67251) describes how to solve this problem in each particular case but doesn't solve the problem in general. | ||
|
||
All payment integrations implement boilerplate code for `sale` operation: | ||
![](sale_payment_operation_img/sale_operation_flow.png) | ||
|
||
## Theory of Operation | ||
For the current moment, we have next relations in order payment workflow. | ||
![](sale_payment_operation_img/order_payment_current.png) | ||
|
||
I propose to introduce `Magento\Payment\Model\SaleOperationInterface` and `Magento\Payment\Model\Method\Adapter` should implement this interface along with `Magento\Payment\Model\MethodInterface`. | ||
```php | ||
<?php | ||
namespace Magento\Payment\Model; | ||
|
||
/** | ||
* Responsible for support of `sale` payment operation via Magento payment provider gateway. | ||
* | ||
* @api | ||
*/ | ||
interface SaleOperationInterface | ||
{ | ||
/** | ||
* Checks `sale` payment operation availability. | ||
* | ||
* @return bool | ||
* | ||
*/ | ||
public function canSale(): bool; | ||
|
||
/** | ||
* Executes `sale` payment operation. | ||
* | ||
* @param InfoInterface $payment | ||
* @param float $amount | ||
* @return $this | ||
* | ||
*/ | ||
public function sale(InfoInterface $payment, float $amount); | ||
} | ||
``` | ||
|
||
|
||
`Magento\Sales\Model\Order\Payment\Operations\CaptureOperation` includes logic responsible for invoice creating and invoice processing. | ||
Logic responsible for invoice processing should be extracted from `CaptureOperation` into separate command `Magento\Sales\Model\Order\Payment\Operations\ProcessInvoiceOperation`. | ||
|
||
`SaleOperation` and `CaptureOperation` commands will use `ProcessInvoiceOperation` for invoice processing and calls to [Magento payment provider gateway](https://devdocs.magento.com/guides/v2.2/payments-integrations/bk-payments-integrations.html). | ||
![](sale_payment_operation_img/order_payment_new.png) | ||
|
||
`Order\Payment` will call `SaleOpertion` if `sale` operation is available for payment method. Otherway, `CaptureOperation` will be called for backward compatibility with existing payment integrations. | ||
|
||
**Magento\Sales\Model\Order\Payment** | ||
```php | ||
<?php | ||
protected function processAction($action, Order $order) | ||
{ | ||
$totalDue = $order->getTotalDue(); | ||
$baseTotalDue = $order->getBaseTotalDue(); | ||
|
||
switch ($action) { | ||
............................................................................ | ||
case \Magento\Payment\Model\Method\AbstractMethod::ACTION_AUTHORIZE_CAPTURE: | ||
$this->setAmountAuthorized($totalDue); | ||
$this->setBaseAmountAuthorized($baseTotalDue); | ||
if ($this->canSale()) { | ||
$this->saleOperation->sale($this); | ||
} else { | ||
$this->capture(null); | ||
} | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
/** | ||
* Check sale operation availability for payment method. | ||
* | ||
* @return bool | ||
*/ | ||
private function canSale(): bool | ||
{ | ||
$method = $this->getMethodInstance(); | ||
return $method instanceof SaleOperationInterface && $method->canSale(); | ||
} | ||
``` | ||
|
||
## Payment provider integration configuration | ||
Payment integration should be based on [Magento payment provider gateway](https://devdocs.magento.com/guides/v2.2/payments-integrations/bk-payments-integrations.html). | ||
|
||
Integrations based on deprecated `Magento\Payment\Model\Method\AbstractMethod` this solution doesn't support. | ||
|
||
In `config.xml` `can_sale` option should be defined: | ||
|
||
```xml | ||
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> | ||
<default> | ||
<payment> | ||
<braintree> | ||
...................... | ||
<can_sale>1</can_sale> | ||
...................... | ||
</braintree> | ||
</payment> | ||
</default> | ||
</config> | ||
``` | ||
In `di.xml` `sale` command should be defined in `CommandPool`: | ||
```xml | ||
<!-- Commands infrastructure --> | ||
<virtualType name="BraintreeCommandPool" type="Magento\Payment\Gateway\Command\CommandPool"> | ||
<arguments> | ||
<argument name="commands" xsi:type="array"> | ||
............................................................... | ||
<item name="sale" xsi:type="string">BraintreeSaleCommand</item> | ||
............................................................... | ||
</argument> | ||
</arguments> | ||
</virtualType> | ||
``` | ||
|
||
## Backward compatibility | ||
- New @api interface `SaleOperationInterface` should be introduced - **MINOR** change according to SemVer | ||
- Two public methods should be added in `Magento\Payment\Model\Method\Adapter` @api class - *sale()* and *canSale()* | ||
|
||
I suppose these changes can be made in the scope of **2.3 release** publication. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These methods will have implementation as far as I understand, if so - this will be minor change, otherwise it will be a major change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The base implementation of
sale()
andcanSale()
will be inMagento\Payment\Model\Method\Adapter
as it is the main extension point for payment integrations.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, they will