Skip to content

Commit 6a27284

Browse files
committed
Release 2.0.8
1 parent cebe87f commit 6a27284

18 files changed

+278
-24
lines changed

Api/OrderRepositoryInterface.php

+8
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,12 @@ interface OrderRepositoryInterface
2727
* @return OrderInterface|null
2828
*/
2929
public function getOrderByIncrementId($incrementId);
30+
31+
/**
32+
* Get order by Id
33+
*
34+
* @param $id
35+
* @return OrderInterface|null
36+
*/
37+
public function getOrderById($id);
3038
}

Model/OrderRepository.php

+11
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,15 @@ public function getOrderByIncrementId($incrementId)
112112
}
113113
return $orderData;
114114
}
115+
116+
/**
117+
* Get Order data by Id
118+
*
119+
* @param $id
120+
* @return OrderInterface|null
121+
*/
122+
public function getOrderById($id)
123+
{
124+
return $this->orderRepository->get($id);
125+
}
115126
}

Model/Resolver/RestoreQuote.php

+224
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
<?php
2+
/**
3+
* PostFinance Checkout Magento 2
4+
*
5+
* This Magento 2 extension enables to process payments with PostFinance Checkout (https://postfinance.ch/en/business/products/e-commerce/postfinance-checkout-all-in-one.html/).
6+
*
7+
* @package PostFinanceCheckout_Payment
8+
* @author wallee AG (http://www.wallee.com/)
9+
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache Software License (ASL 2.0)
10+
*/
11+
namespace PostFinanceCheckout\Payment\Model\Resolver;
12+
13+
use Magento\Checkout\Model\Session as CheckoutSession;
14+
use Magento\CustomerGraphQl\Model\Customer\GetCustomer;
15+
use Magento\Framework\Event\ManagerInterface;
16+
use Magento\Framework\Exception\LocalizedException;
17+
use Magento\Framework\Exception\NoSuchEntityException;
18+
use Magento\Framework\GraphQl\Config\Element\Field;
19+
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;
20+
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
21+
use Magento\Framework\GraphQl\Query\ResolverInterface;
22+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
23+
use Magento\Customer\Model\Session;
24+
use Magento\GraphQl\Model\Query\ContextInterface;
25+
use Magento\Quote\Model\Quote;
26+
use Magento\Quote\Api\CartRepositoryInterface;
27+
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface;
28+
use Magento\Sales\Api\Data\OrderInterface;
29+
use Psr\Log\LoggerInterface;
30+
use PostFinanceCheckout\Payment\Api\OrderRepositoryInterface;
31+
32+
class RestoreQuote implements ResolverInterface
33+
{
34+
/**
35+
*
36+
* @var Session
37+
*/
38+
private $customerSession;
39+
40+
/**
41+
*
42+
* @var CheckoutSession
43+
*/
44+
private $checkoutSession;
45+
46+
/**
47+
*
48+
* @var GetCustomer
49+
*/
50+
private $getCustomer;
51+
52+
/**
53+
*
54+
* @var CartRepositoryInterface
55+
*/
56+
private $cartRepository;
57+
58+
/**
59+
*
60+
* @var OrderRepositoryInterface
61+
*/
62+
private $orderRepository;
63+
64+
/**
65+
*
66+
* @var MaskedQuoteIdToQuoteIdInterface
67+
*/
68+
private $maskedQuoteIdToQuoteIdService;
69+
70+
/**
71+
*
72+
* @var ManagerInterface
73+
*/
74+
private $eventManager;
75+
76+
/**
77+
*
78+
* @var LoggerInterface
79+
*/
80+
private $logger;
81+
82+
83+
public function __construct(
84+
Session $customerSession,
85+
CheckoutSession $checkoutSession,
86+
GetCustomer $getCustomer,
87+
CartRepositoryInterface $cartRepository,
88+
\Wallee\Payment\Api\OrderRepositoryInterface $orderRepository,
89+
MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteIdService,
90+
ManagerInterface $eventManager,
91+
LoggerInterface $logger
92+
) {
93+
$this->checkoutSession = $checkoutSession;
94+
$this->customerSession = $customerSession;
95+
$this->getCustomer = $getCustomer;
96+
$this->cartRepository = $cartRepository;
97+
$this->orderRepository = $orderRepository;
98+
$this->maskedQuoteIdToQuoteIdService = $maskedQuoteIdToQuoteIdService;
99+
$this->eventManager = $eventManager;
100+
$this->logger = $logger;
101+
}
102+
103+
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
104+
{
105+
$customerId = null;
106+
107+
//only perform validations if the user is anonymous.
108+
if ($this->checkoutSession->getQuote()->getCustomerId() || !$this->customerSession->getCustomer()->getId()) {
109+
/** @var ContextInterface $context */
110+
if (false === $context->getExtensionAttributes()->getIsCustomer()) {
111+
throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.'));
112+
}
113+
114+
$customer = $this->getCustomer->execute($context);
115+
$customerId = $customer->getId();
116+
117+
if (!empty($this->customerSession) && $customerId !== $this->customerSession->getCustomer()->getId()) {
118+
throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.'));
119+
}
120+
}
121+
122+
try {
123+
$cartIdMasked = $args['input']['cart_id'];
124+
return $this->restoreQuote($cartIdMasked, $customerId);
125+
} catch (NoSuchEntityException|\Exception $e) {
126+
$this->logger->critical($e);
127+
throw new GraphQlNoSuchEntityException(__($e->getMessage()));
128+
}
129+
}
130+
131+
/**
132+
* Restores a client's quote from a cart id
133+
*
134+
* @param string $cartIdMasked
135+
* @param string $customerId
136+
* @return array
137+
* @throws LocalizedException
138+
*/
139+
private function restoreQuote(string $cartIdMasked, string $customerId)
140+
{
141+
try {
142+
// Convert the masked ID to the real quote ID
143+
$quoteId = $this->maskedQuoteIdToQuoteIdService->execute($cartIdMasked);
144+
145+
// Get the quote using the actual ID
146+
/** @var Quote $quote */
147+
$quote = $this->cartRepository->get($quoteId);
148+
$order = $this->getOrderByQuote($quote);
149+
150+
//some validations
151+
$this->guardQuoteBelongsToCurrentCustomer($order, $customerId);
152+
$this->guardQuoteIsStillActive($quote);
153+
154+
//restore a customer's quote
155+
$quote
156+
->setIsActive(1)
157+
->setReservedOrderId(null);
158+
159+
$this->cartRepository->save($quote);
160+
161+
$this->checkoutSession
162+
->replaceQuote($quote)
163+
->unsLastRealOrderId();
164+
165+
$this->eventManager->dispatch('restore_quote', ['order' => $order, 'quote' => $quote]);
166+
$this->logger->debug("RESTORE-QUOTE-MUTATION::restoreQuote - Quote with id $cartIdMasked was restored");
167+
168+
return ['result' => 'OK'];
169+
} catch (NoSuchEntityException|\Exception $e) {
170+
return ['result' => 'KO. ' . $e->getMessage()];
171+
}
172+
}
173+
174+
/**
175+
* Get an order by quote
176+
*
177+
* @param Quote $quote
178+
* @return OrderInterface|null
179+
* @throws \Exception
180+
*/
181+
public function getOrderByQuote(Quote $quote)
182+
{
183+
$orderId = $quote->getReservedOrderId();
184+
185+
if (empty($orderId)) {
186+
throw new \Exception(__('The quote does not have an associated order'));
187+
}
188+
189+
return $this->orderRepository->getOrderById($orderId);
190+
}
191+
192+
/**
193+
* Check if quote belongs to the current customer
194+
*
195+
* @param OrderInterface $order
196+
* @param int $customerId
197+
* @return void
198+
* @throws \Exception
199+
*/
200+
private function guardQuoteBelongsToCurrentCustomer(OrderInterface $order, int $customerId)
201+
{
202+
$orderCustomerId = $order->getCustomerId();
203+
if ((int)$orderCustomerId !== $customerId) {
204+
$this->logger->debug("RESTORE-QUOTE-MUTATION::guardQuoteBelongsToCurrentCustomer - customer id '$customerId' doesn't match with order customer id '$orderCustomerId'");
205+
throw new \Exception(__('The current customer isn\'t authorized.'));
206+
}
207+
}
208+
209+
/**
210+
* Check if the quote is still active, only quotes that are not active will be activated
211+
*
212+
* @param Quote $quote
213+
* @return void
214+
* @throws \Exception
215+
*/
216+
private function guardQuoteIsStillActive(Quote $quote)
217+
{
218+
if ($quote->getIsActive()) {
219+
$this->logger->debug("RESTORE-QUOTE-MUTATION::guardQuoteIsStillActive - quote is still activated");
220+
221+
throw new \Exception(__('The quote is still active.'));
222+
}
223+
}
224+
}

Model/Service/Order/TransactionService.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ protected function buildUrl($route, Order $order, $extarnalUrl = false)
375375
}
376376

377377
if ($extarnalUrl) {
378-
return sprintf('%s/order_id/%d/token/%s/', $route, $order->getId(), $token);
378+
return sprintf('%s/order/%d/token/%s/', $route, $order->getId(), $token);
379379
}
380380

381381
return $order->getStore()->getUrl($route,

Model/TransactionInfoManagement.php

+6
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ public function setRedirectUrls(Transaction $transaction, $orderId, $successUrl,
104104
$transaction->getLinkedSpaceId(),
105105
$transaction->getId()
106106
);
107+
108+
//prevents a new transaction info from being created by duplicating the order id
109+
if ($info->getOrderId() != (int)$orderId) {
110+
$info = $this->transactionInfoRepository->getByOrderId($orderId);
111+
}
112+
107113
} catch (NoSuchEntityException $e) {
108114
$info = $this->transactionInfoFactory->create();
109115
}

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ This repository contains the Magento 2 extension that enables to process payment
1212

1313
## Documentation
1414

15-
* [Documentation](https://plugin-documentation.postfinance-checkout.ch/pfpayments/magento-2/2.0.7/docs/en/documentation.html)
15+
* [Documentation](https://plugin-documentation.postfinance-checkout.ch/pfpayments/magento-2/2.0.8/docs/en/documentation.html)
1616

1717

1818
## Support
@@ -30,4 +30,4 @@ We do provide special integrations for the following one step checkouts:
3030

3131
## License
3232

33-
Please see the [license file](https://github.com/pfpayments/magento-2/blob/2.0.7/LICENSE) for more information.
33+
Please see the [license file](https://github.com/pfpayments/magento-2/blob/2.0.8/LICENSE) for more information.

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
}
1717
],
1818
"type" : "magento2-module",
19-
"version" : "2.0.7",
19+
"version" : "2.0.8",
2020
"require" : {
2121
"php" : "~7.1.3||~7.2.0||~7.3.0||~7.4.0||~8.0||~8.1",
2222
"magento/framework" : "^102.0.0||^103.0.0",

docs/en/documentation.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ <h2>Documentation</h2> </div>
2222
</a>
2323
</li>
2424
<li>
25-
<a href="https://github.com/weareplanet/magento-2">
25+
<a href="https://github.com/pfpayments/magento-2/releases/tag/2.0.8/">
2626
Source
2727
</a>
2828
</li>

etc/adminhtml/system.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<resource>PostFinanceCheckout_Payment::config</resource>
1919
<group id="information" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
2020
<label>Information</label>
21-
<comment><![CDATA[If you need help setting up the PostFinance Checkout extension, check out the <a href="https://plugin-documentation.postfinance-checkout.ch/pfpayments/magento-2/2.0.7/docs/en/documentation.html" target="_blank">documentation</a>.]]></comment>
21+
<comment><![CDATA[If you need help setting up the PostFinance Checkout extension, check out the <a href="https://plugin-documentation.postfinance-checkout.ch/pfpayments/magento-2/2.0.8/docs/en/documentation.html" target="_blank">documentation</a>.]]></comment>
2222
<field id="version" translate="label" type="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
2323
<label>Module Version</label>
2424
</field>

etc/config.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<default>
1515
<postfinancecheckout_payment>
1616
<information>
17-
<version>2.0.7</version>
17+
<version>2.0.8</version>
1818
<sdk_version>3.2.0</sdk_version>
1919
</information>
2020
<general>

etc/module.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*/
1212
-->
1313
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
14-
<module name="PostFinanceCheckout_Payment" setup_version="2.0.7">
14+
<module name="PostFinanceCheckout_Payment" setup_version="2.0.8">
1515
<sequence>
1616
<module name="Magento_Sales"/>
1717
<module name="Magento_Payment"/>

etc/schema.graphqls

+15-10
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,22 @@ type Query {
22
customerOrderTransaction(
33
order_id: Int! @doc(description: "Specify the id of the order.")
44
integration_type: String! @doc(description: "Sort of integration: 'JAVASCRIPT', 'LIGHTBOX', 'PAYMENTPAGE'.")
5-
): customerOrderTransactionOutput
6-
@resolver( class: "\\Wallee\\Payment\\Model\\Resolver\\CustomerOrderTransactionSettings")
7-
@doc(description: "Customer order transaction's settings")
5+
): CustomerOrderTransactionOutput @resolver( class: "\\Wallee\\Payment\\Model\\Resolver\\CustomerOrderTransactionSettings") @doc(description: "Customer order transaction's settings") @cache(cacheable: false)
86
}
97

10-
type customerOrderTransactionOutput {
8+
type Mutation {
9+
updateTransactionUrls(input: UpdateTransactionUrlsInput!): UpdateTransactionUrlsOutput @resolver( class: "\\Wallee\\Payment\\Model\\Resolver\\UpdateTransactionUrls") @doc(description: "Update transaction urls to redirect the customer after placing the order")
10+
restoreQuote(input: RestoreQuoteInput!): RestoreQuoteOutput @resolver( class: "\\Wallee\\Payment\\Model\\Resolver\\RestoreQuote") @doc(description: "restores a quote if payment fails or is cancelled")
11+
}
12+
13+
type CustomerOrderTransactionOutput {
1114
order_id: Int @doc(description: "Order id")
1215
transaction_id: Int @doc(description: "WhiteLabelMachineName transaction id")
1316
transaction_state: String @doc(description: "WhiteLabelMachineName transaction state")
1417
payment_url: String @doc(description: "WhiteLabelMachineName payment url to integrate external payment")
1518
integration_type: String @doc(description: "Integration type")
1619
}
1720

18-
1921
input UpdateTransactionUrlsInput {
2022
cart_id: String!
2123
success_url: String @doc(description: "Success URL to redirect the customer after placing the order")
@@ -26,8 +28,11 @@ type UpdateTransactionUrlsOutput {
2628
result: String
2729
}
2830

29-
type Mutation {
30-
updateTransactionUrls(input: UpdateTransactionUrlsInput!): UpdateTransactionUrlsOutput
31-
@resolver( class: "\\Wallee\\Payment\\Model\\Resolver\\UpdateTransactionUrls")
32-
@doc(description: "Update transaction urls to redirect the customer after placing the order")
33-
}
31+
input RestoreQuoteInput {
32+
cart_id: String!
33+
}
34+
35+
type RestoreQuoteOutput {
36+
result: String!
37+
cart_id: String
38+
}

i18n/de_DE.csv

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
"Gift Wrap","Geschenkverpackung"
5151
"Hold Delivery","Lieferung halten"
5252
"ID required","ID erforderlich"
53-
"If you need help setting up the PostFinance Checkout extension, check out the <a href=""https://plugin-documentation.postfinance-checkout.ch/pfpayments/magento-2/2.0.7/docs/en/documentation.html"" target=""_blank"">documentation</a>.","Falls Sie Hilfe benötigen beim Einrichten der PostFinance Checkout-Erweiterung, sehen Sie sich die <a href=""https://plugin-documentation.postfinance-checkout.ch/pfpayments/magento-2/2.0.7/docs/en/documentation.html"" target=""_blank"">Dokumentation</a> an."
53+
"If you need help setting up the PostFinance Checkout extension, check out the <a href=""https://plugin-documentation.postfinance-checkout.ch/pfpayments/magento-2/2.0.8/docs/en/documentation.html"" target=""_blank"">documentation</a>.","Falls Sie Hilfe benötigen beim Einrichten der PostFinance Checkout-Erweiterung, sehen Sie sich die <a href=""https://plugin-documentation.postfinance-checkout.ch/pfpayments/magento-2/2.0.8/docs/en/documentation.html"" target=""_blank"">Dokumentation</a> an."
5454
"Inactive","Inaktiv"
5555
"Information","Informationen"
5656
"Invoice","Rechnung"

0 commit comments

Comments
 (0)