Skip to content

Commit e264454

Browse files
authored
Merge pull request #102 from swlodarski-sumoheavy/9.3.x
SP-1069 Add option to redirect to standard checkout success
2 parents 742c2fa + 6716b27 commit e264454

File tree

12 files changed

+161
-32
lines changed

12 files changed

+161
-32
lines changed

Model/BPCheckout.php

+10
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,14 @@ class BPCheckout extends AbstractMethod
2727
* @var bool
2828
*/
2929
protected $_isOffline = true;
30+
31+
/**
32+
* Get config payment action, do nothing if status is pending
33+
*
34+
* @return string|null
35+
*/
36+
public function getConfigPaymentAction()
37+
{
38+
return $this->getConfigData('order_status') == 'pending' ? null : parent::getConfigPaymentAction();
39+
}
3040
}

Model/BPRedirect.php

+49-15
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Magento\Framework\Controller\ResultFactory;
1414
use Magento\Framework\Controller\ResultInterface;
1515
use Magento\Sales\Model\OrderRepository;
16+
use Magento\Framework\Encryption\EncryptorInterface;
1617

1718
/**
1819
* @SuppressWarnings(PHPMD.TooManyFields)
@@ -34,6 +35,7 @@ class BPRedirect
3435
protected Client $client;
3536
protected OrderRepository $orderRepository;
3637
protected BitpayInvoiceRepository $bitpayInvoiceRepository;
38+
protected EncryptorInterface $encryptor;
3739

3840
/**
3941
* @param Session $checkoutSession
@@ -49,6 +51,7 @@ class BPRedirect
4951
* @param Client $client
5052
* @param OrderRepository $orderRepository
5153
* @param BitpayInvoiceRepository $bitpayInvoiceRepository
54+
* @param EncryptorInterface $encryptor
5255
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
5356
*/
5457
public function __construct(
@@ -64,7 +67,8 @@ public function __construct(
6467
ResultFactory $resultFactory,
6568
Client $client,
6669
OrderRepository $orderRepository,
67-
BitpayInvoiceRepository $bitpayInvoiceRepository
70+
BitpayInvoiceRepository $bitpayInvoiceRepository,
71+
EncryptorInterface $encryptor,
6872
) {
6973
$this->checkoutSession = $checkoutSession;
7074
$this->orderInterface = $orderInterface;
@@ -79,16 +83,19 @@ public function __construct(
7983
$this->client = $client;
8084
$this->orderRepository = $orderRepository;
8185
$this->bitpayInvoiceRepository = $bitpayInvoiceRepository;
86+
$this->encryptor = $encryptor;
8287
}
8388

8489
/**
8590
* Create bitpay invoice after order creation during redirect to success page
8691
*
92+
* @param ResultInterface $defaultResult
93+
* @param string|null $returnId
8794
* @return ResultInterface
8895
* @throws LocalizedException
8996
* @throws NoSuchEntityException|\Exception
9097
*/
91-
public function execute(): ResultInterface
98+
public function execute(ResultInterface $defaultResult, string $returnId = null): ResultInterface
9299
{
93100
$orderId = $this->checkoutSession->getData('last_order_id');
94101
if (!$orderId) {
@@ -102,17 +109,36 @@ public function execute(): ResultInterface
102109
return $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT)
103110
->setUrl($this->url->getUrl('checkout/cart'));
104111
}
105-
$baseUrl = $this->config->getBaseUrl();
106112
if ($order->getPayment()->getMethodInstance()->getCode() !== Config::BITPAY_PAYMENT_METHOD_NAME) {
107-
return $this->resultFactory->create(
108-
\Magento\Framework\Controller\ResultFactory::TYPE_PAGE
109-
);
113+
return $defaultResult;
114+
}
115+
116+
$isStandardCheckoutSuccess = $this->config->getBitpayCheckoutSuccess() === 'standard';
117+
$returnHash = $this->encryptor->hash("$incrementId:{$order->getCustomerEmail()}:{$order->getProtectCode()}");
118+
if ($isStandardCheckoutSuccess && $returnId) {
119+
if ($returnId !== $returnHash) {
120+
$this->checkoutSession->clearHelperData();
121+
122+
return $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT)
123+
->setUrl($this->url->getUrl('checkout/cart'));
124+
}
125+
126+
return $defaultResult;
110127
}
111128

112129
try {
130+
$baseUrl = $this->config->getBaseUrl();
113131
$order = $this->setToPendingAndOverrideMagentoStatus($order);
114132
$modal = $this->config->getBitpayUx() === 'modal';
115-
$redirectUrl = $baseUrl .'bitpay-invoice/?order_id='. $incrementId;
133+
$redirectUrl = $this->url->getUrl('bitpay-invoice', ['_query' => ['order_id' => $incrementId]]);
134+
if ($isStandardCheckoutSuccess) {
135+
$this->checkoutSession->setLastSuccessQuoteId($order->getQuoteId());
136+
if (!$modal) {
137+
$redirectUrl = $this->url->getUrl('checkout/onepage/success', [
138+
'_query' => ['return_id' => $returnHash]
139+
]);
140+
}
141+
}
116142
$params = $this->getParams($order, $incrementId, $modal, $redirectUrl, $baseUrl);
117143
$billingAddressData = $order->getBillingAddress()->getData();
118144
$this->setSessionCustomerData($billingAddressData, $order->getCustomerEmail(), $incrementId);
@@ -134,12 +160,20 @@ public function execute(): ResultInterface
134160
#set some info for guest checkout
135161
$this->setSessionCustomerData($billingAddressData, $order->getCustomerEmail(), $incrementId);
136162

137-
$redirectUrl = $this->url->getUrl('bitpay-invoice', ['_query' => ['invoiceID' => $invoiceID, 'order_id' => $incrementId, 'm' => 1]]);
163+
$redirectParams = [
164+
'invoiceID' => $invoiceID,
165+
'order_id' => $incrementId,
166+
'm' => 1,
167+
];
168+
if ($isStandardCheckoutSuccess) {
169+
$redirectParams['return_id'] = $returnHash;
170+
}
171+
$redirectUrl = $this->url->getUrl('bitpay-invoice', ['_query' => $redirectParams]);
138172

139173
return $this->resultFactory->create(
140-
\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT
141-
)
142-
->setUrl($redirectUrl);
174+
\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT
175+
)
176+
->setUrl($redirectUrl);
143177
case false:
144178
default:
145179
return $this->resultFactory->create(
@@ -234,16 +268,16 @@ private function getParams(
234268
*/
235269
private function deleteOrderAndRedirectToCart($exception, OrderInterface $order): ResultInterface
236270
{
271+
$this->checkoutSession->clearHelperData();
237272
$this->logger->error($exception->getMessage());
238273
$this->registry->register('isSecureArea', 'true');
239274
$order->delete();
240275
$this->registry->unregister('isSecureArea');
241276
$this->messageManager->addErrorMessage('We are unable to place your Order at this time');
242277

243278
return $this->resultFactory->create(
244-
\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT
245-
)
246-
->setUrl($this->url->getUrl('checkout/cart'));
247-
279+
\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT
280+
)
281+
->setUrl($this->url->getUrl('checkout/cart'));
248282
}
249283
}

Model/Config.php

+12-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class Config
1919
public const BITPAY_PAYMENT_ACTIVE = 'payment/bpcheckout/active';
2020
public const BPCHECKOUT_ORDER_STATUS = 'payment/bpcheckout/order_status';
2121
public const BITPAY_UX = 'payment/bpcheckout/bitpay_ux';
22+
public const BITPAY_CHECKOUT_SUCCESS = 'payment/bpcheckout/bitpay_checkout_success';
2223
public const BITPAY_MERCHANT_TOKEN_DATA = 'bitpay_merchant_facade/authenticate/token_data';
2324
public const BITPAY_MERCHANT_PRIVATE_KEY_PATH = 'bitpay_merchant_facade/authenticate/private_key_path';
2425
public const BITPAY_MERCHANT_PASSWORD = 'bitpay_merchant_facade/authenticate/password';
@@ -27,7 +28,7 @@ class Config
2728
public const BITPAY_PROD_TOKEN_URL = 'https://bitpay.com/tokens';
2829
public const API_HOST_DEV = 'test.bitpay.com';
2930
public const API_HOST_PROD = 'bitpay.com';
30-
public const EXTENSION_VERSION = 'Bitpay_BPCheckout_Magento2_9.2.2';
31+
public const EXTENSION_VERSION = 'Bitpay_BPCheckout_Magento2_9.3.0';
3132
public const BITPAY_PAYMENT_METHOD_NAME = 'bpcheckout';
3233
public const BITPAY_PAYMENT_ICON = 'Pay-with-BitPay-CardGroup.svg';
3334
public const BITPAY_PAYMENT_DIR_IMAGES = 'images';
@@ -109,6 +110,16 @@ public function getBitpayUx():? string
109110
return $this->scopeConfig->getValue(self::BITPAY_UX, ScopeInterface::SCOPE_STORE);
110111
}
111112

113+
/**
114+
* Get BitPay CheckoutSuccess
115+
*
116+
* @return string|null
117+
*/
118+
public function getBitpayCheckoutSuccess():? string
119+
{
120+
return $this->scopeConfig->getValue(self::BITPAY_CHECKOUT_SUCCESS, ScopeInterface::SCOPE_STORE);
121+
}
122+
112123
/**
113124
* Get token
114125
*
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Bitpay\BPCheckout\Model\Config\Source;
5+
6+
use Magento\Framework\Option\ArrayInterface;
7+
8+
/**
9+
* CheckoutSuccess Model
10+
*/
11+
class CheckoutSuccess implements ArrayInterface
12+
{
13+
/**
14+
* Return array of Checkout Success options
15+
*
16+
* @return string[]
17+
*/
18+
public function toOptionArray()
19+
{
20+
return [
21+
'module' => 'Module',
22+
'standard' => 'Standard',
23+
];
24+
}
25+
}

Plugin/Onepage/SuccessPlugin.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ public function afterExecute(
2828
\Magento\Checkout\Controller\Onepage\Success $subject,
2929
\Magento\Framework\Controller\ResultInterface $result
3030
) {
31-
return $this->bpRedirect->execute();
31+
return $this->bpRedirect->execute($result, $subject->getRequest()->getParam('return_id'));
3232
}
3333
}

Test/Unit/Model/BPRedirectTest.php

+38-10
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Magento\Sales\Api\Data\OrderInterface;
2121
use \Magento\Framework\Controller\Result\Redirect;
2222
use Magento\Framework\Controller\ResultFactory;
23+
use Magento\Framework\Encryption\EncryptorInterface;
2324
use Magento\Sales\Model\Order;
2425
use Magento\Payment\Model\MethodInterface;
2526
use Magento\Sales\Model\OrderRepository;
@@ -102,6 +103,11 @@ class BPRedirectTest extends TestCase
102103
*/
103104
private $resultFactory;
104105

106+
/**
107+
* @var EncryptorInterface|MockObject $encryptor
108+
*/
109+
private $encryptor;
110+
105111
public function setUp(): void
106112
{
107113
$this->checkoutSession = $this->getMock(Session::class);
@@ -112,11 +118,12 @@ public function setUp(): void
112118
$this->invoice = $this->getMock(Invoice::class);
113119
$this->messageManager = $this->getMock(Manager::class);
114120
$this->registry = $this->getMock(Registry::class);
115-
$this->url = $this->getMock(UrlInterface::class);
121+
$this->url = $this->getMockBuilder(UrlInterface::class)->getMock();
116122
$this->logger = $this->getMock(Logger::class);
117123
$this->resultFactory = $this->getMock(ResultFactory::class);
118124
$this->orderRepository = $this->getMock(OrderRepository::class);
119125
$this->bitpayInvoiceRepository = $this->getMock(BitpayInvoiceRepository::class);
126+
$this->encryptor = $this->getMock(EncryptorInterface::class);
120127
$this->bpRedirect = $this->getClass();
121128
}
122129

@@ -142,6 +149,14 @@ public function testExecute($ux): void
142149
->with('last_order_id')
143150
->willReturn($lastOrderId);
144151

152+
$this->url->expects(
153+
$this->any()
154+
)->method(
155+
'getUrl'
156+
)
157+
->withConsecutive(['bitpay-invoice', ['_query' => ['order_id' => $incrementId]]], ['checkout/cart'])
158+
->willReturnOnConsecutiveCalls('http://localhost/bitpay-invoice?order_id=' . $incrementId, 'http://localhost/checkout/cart');
159+
145160
$billingAddress->expects($this->once())->method('getData')
146161
->willReturn(['first_name' => 'test', 'last_name' => 'test1']);
147162
$billingAddress->expects($this->once())->method('getFirstName')->willReturn('test');
@@ -171,7 +186,9 @@ public function testExecute($ux): void
171186
$this->resultFactory->expects($this->once())->method('create')->willReturn($result);
172187
}
173188

174-
$this->bpRedirect->execute();
189+
$page = $this->getMock(\Magento\Framework\View\Result\Page::class);
190+
191+
$this->bpRedirect->execute($page);
175192
}
176193

177194
/**
@@ -195,7 +212,9 @@ public function testExecuteNoOrderId(): void
195212
$result->expects($this->once())->method('setUrl')->willReturnSelf();
196213
$this->resultFactory->expects($this->once())->method('create')->willReturn($result);
197214

198-
$this->bpRedirect->execute();
215+
$page = $this->getMock(\Magento\Framework\View\Result\Page::class);
216+
217+
$this->bpRedirect->execute($page);
199218
}
200219

201220
public function testExecuteNoBitpayPaymentMethod(): void
@@ -217,12 +236,10 @@ public function testExecuteNoBitpayPaymentMethod(): void
217236
$order->expects($this->once())->method('getIncrementId')->willReturn($incrementId);
218237
$order->expects($this->once())->method('getPayment')->willReturn($payment);
219238
$this->order->expects($this->once())->method('load')->with($lastOrderId)->willReturn($order);
220-
$this->config->expects($this->once())->method('getBaseUrl')->willReturn($baseUrl);
221-
222-
$result = $this->getMock(\Magento\Framework\Controller\Result\Redirect::class);
223-
$this->resultFactory->expects($this->once())->method('create')->willReturn($result);
224239

225-
$this->bpRedirect->execute();
240+
$page = $this->getMock(\Magento\Framework\View\Result\Page::class);
241+
242+
$this->assertSame($page, $this->bpRedirect->execute($page));
226243
}
227244

228245
/**
@@ -245,6 +262,14 @@ public function testExecuteException($exceptionType): void
245262
->with('last_order_id')
246263
->willReturn($lastOrderId);
247264

265+
$this->url->expects(
266+
$this->any()
267+
)->method(
268+
'getUrl'
269+
)
270+
->withConsecutive(['bitpay-invoice', ['_query' => ['order_id' => $incrementId]]], ['checkout/cart'])
271+
->willReturnOnConsecutiveCalls('http://localhost/bitpay-invoice?order_id=' . $incrementId, 'http://localhost/checkout/cart');
272+
248273
$billingAddress->expects($this->once())->method('getData')
249274
->willReturn(['first_name' => 'test', 'last_name' => 'test1']);
250275
$billingAddress->expects($this->once())->method('getFirstName')->willReturn('test');
@@ -263,7 +288,9 @@ public function testExecuteException($exceptionType): void
263288
->method('BPCCreateInvoice')
264289
->willThrowException(new $exceptionType('something went wrong'));
265290

266-
$this->bpRedirect->execute();
291+
$page = $this->getMock(\Magento\Framework\View\Result\Page::class);
292+
293+
$this->bpRedirect->execute($page);
267294
}
268295

269296
public function exceptionTypeDataProvider(): array
@@ -340,7 +367,8 @@ private function getClass(): BPRedirect
340367
$this->resultFactory,
341368
$this->client,
342369
$this->orderRepository,
343-
$this->bitpayInvoiceRepository
370+
$this->bitpayInvoiceRepository,
371+
$this->encryptor
344372
);
345373
}
346374

Test/Unit/Plugin/Onepage/SuccessPluginTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Bitpay\BPCheckout\Plugin\Onepage\SuccessPlugin;
66
use Bitpay\BPCheckout\Model\BPRedirect;
77
use Magento\Checkout\Controller\Onepage\Success;
8+
use Magento\Framework\App\RequestInterface;
89
use Magento\Framework\Controller\ResultInterface;
910
use PHPUnit\Framework\MockObject\MockObject;
1011
use PHPUnit\Framework\TestCase;
@@ -15,6 +16,10 @@ public function testAfterExecute(): void
1516
{
1617
$bpRedirect = $this->getMockBuilder(BPRedirect::class)->disableOriginalConstructor()->getMock();
1718
$subject = $this->getMockBuilder(Success::class)->disableOriginalConstructor()->getMock();
19+
$subject = $this->getMockBuilder(Success::class)->disableOriginalConstructor()->getMock();
20+
$request = $this->getMockBuilder(RequestInterface::class)->disableOriginalConstructor()->getMock();
21+
$request->expects($this->once())->method('getParam')->willReturn(null);
22+
$subject->expects($this->once())->method('getRequest')->willReturn($request);
1823
$result = $this->getMockBuilder(ResultInterface::class)->disableOriginalConstructor()->getMock();
1924
$testedClass = new SuccessPlugin($bpRedirect);
2025

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "",
44
"type": "magento2-module",
55
"license": "mit",
6-
"version":"9.2.2",
6+
"version":"9.3.0",
77
"authors": [
88
{
99
"email": "[email protected]",

etc/adminhtml/system.xml

+5
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@
128128
<source_model>Bitpay\BPCheckout\Model\Config\Source\Ux</source_model>
129129
</field>
130130

131+
<field id="bitpay_checkout_success" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
132+
<label>Checkout Success</label>
133+
<comment><![CDATA[Note: Using the standard checkout success page may require updates to your theme.]]></comment>
134+
<source_model>Bitpay\BPCheckout\Model\Config\Source\CheckoutSuccess</source_model>
135+
</field>
131136

132137
<field id="specificcountry" translate="label" type="multiselect" sortOrder="41" showInDefault="1"
133138
showInWebsite="1" showInStore="0">

etc/config.xml

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<model>Bitpay\BPCheckout\Model\BPCheckout</model>
2020
<group>offline</group>
2121
<send_order_email>0</send_order_email>
22+
<bitpay_checkout_success>module</bitpay_checkout_success>
2223
</bpcheckout>
2324
<!-- payment-config -->
2425
</payment>

0 commit comments

Comments
 (0)