Skip to content

Commit 8505252

Browse files
committed
Merge branch '1.2' into 1.3
* 1.2: Require 3D Secure and process its response correctly Change pay with PayPal form URL to use order token
2 parents 588459d + 814923c commit 8505252

File tree

8 files changed

+85
-20
lines changed

8 files changed

+85
-20
lines changed

UPGRADE.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
### UPGRADE FROM 1.3.0 to 1.3.1
2+
3+
1. `sylius_paypal_plugin_pay_with_paypal_form` route now operates on both payment ID and order token. URl then changed from
4+
`/pay-with-paypal/{id}` to `/pay-with-paypal/{orderToken}/{paymentId}`. If you use this route anywhere in your application, you
5+
need to change the URL attributes
6+
7+
### UPGRADE FROM 1.2.3 to 1.2.4
8+
9+
1. `sylius_paypal_plugin_pay_with_paypal_form` route now operates on both payment ID and order token. URl then changed from
10+
`/pay-with-paypal/{id}` to `/pay-with-paypal/{orderToken}/{paymentId}`. If you use this route anywhere in your application, you
11+
need to change the URL attributes
12+
113
### UPGRADE FROM 1.0.X TO 1.1.0
214

315
1. Upgrade your application to [Sylius 1.8](https://github.com/Sylius/Sylius/blob/master/UPGRADE-1.8.md).

phpstan.neon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ parameters:
1414
# Test dependencies
1515
- 'tests/Application/app/**.php'
1616
- 'tests/Application/src/**.php'
17+
18+
ignoreErrors:
19+
- '/Call to an undefined method Sylius\\Component\\Core\\Repository\\PaymentRepositoryInterface\:\:createQueryBuilder\(\)\./'

psalm.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<directory name="vendor" />
1313
<file name="src/DependencyInjection/Configuration.php" />
1414
<file name="src/UrlUtils.php" />
15+
<file name="src/Controller/PayWithPayPalFormAction.php" />
1516
</ignoreFiles>
1617
</projectFiles>
1718

spec/Payum/Action/ResolveNextRouteActionSpec.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ final class ResolveNextRouteActionSpec extends ObjectBehavior
1717
function it_executes_resolve_next_route_request_with_processing_payment(
1818
ResolveNextRoute $request,
1919
PaymentInterface $payment,
20+
OrderInterface $order,
2021
PaymentMethodInterface $paymentMethod,
2122
GatewayConfigInterface $gatewayConfig
2223
): void {
@@ -28,19 +29,24 @@ function it_executes_resolve_next_route_request_with_processing_payment(
2829
$paymentMethod->getGatewayConfig()->willReturn($gatewayConfig);
2930
$gatewayConfig->getFactoryName()->willReturn('sylius.pay_pal');
3031

32+
$payment->getOrder()->willReturn($order);
33+
$order->getTokenValue()->willReturn('123!@#asd');
34+
3135
$request->setRouteName('sylius_paypal_plugin_pay_with_paypal_form')->shouldBeCalled();
32-
$request->setRouteParameters(['id' => 12])->shouldBeCalled();
36+
$request->setRouteParameters(['orderToken' => '123!@#asd', 'paymentId' => 12])->shouldBeCalled();
3337

3438
$this->execute($request);
3539
}
3640

3741
function it_executes_resolve_next_route_request_with_completed_payment(
3842
ResolveNextRoute $request,
3943
PaymentInterface $payment,
44+
OrderInterface $order,
4045
PaymentMethodInterface $paymentMethod,
4146
GatewayConfigInterface $gatewayConfig
4247
): void {
4348
$request->getFirstModel()->willReturn($payment);
49+
$payment->getOrder()->willReturn($order);
4450

4551
$payment->getState()->willReturn(PaymentInterface::STATE_COMPLETED);
4652
$payment->getMethod()->willReturn($paymentMethod);

src/Controller/PayWithPayPalFormAction.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,11 @@ public function __construct(
4444

4545
public function __invoke(Request $request): Response
4646
{
47+
$paymentId = (string) $request->attributes->get('paymentId');
48+
$orderToken = (string) $request->attributes->get('orderToken');
49+
4750
/** @var PaymentInterface $payment */
48-
$payment = $this->paymentRepository->find($request->attributes->get('id'));
51+
$payment = $this->findOneByPaymentIdOrderToken($paymentId, $orderToken);
4952
/** @var PaymentMethodInterface $paymentMethod */
5053
$paymentMethod = $payment->getMethod();
5154

@@ -74,4 +77,22 @@ public function __invoke(Request $request): Response
7477
'partner_attribution_id' => $partnerAttributionId,
7578
]));
7679
}
80+
81+
/**
82+
* Need to be used due to support for Sylius 1.8.
83+
* After dropping it, we can switch to Sylius\Component\Core\Repository\PaymentRepositoryInterface::findOneByOrderToken
84+
*/
85+
private function findOneByPaymentIdOrderToken(string $paymentId, string $orderToken): ?PaymentInterface
86+
{
87+
return $this->paymentRepository
88+
->createQueryBuilder('p')
89+
->innerJoin('p.order', 'o')
90+
->andWhere('p.id = :paymentId')
91+
->andWhere('o.tokenValue = :orderToken')
92+
->setParameter('paymentId', $paymentId)
93+
->setParameter('orderToken', $orderToken)
94+
->getQuery()
95+
->getOneOrNullResult()
96+
;
97+
}
7798
}

src/Payum/Action/ResolveNextRouteAction.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,14 @@ public function execute($request): void
1919
/** @var PaymentInterface $payment */
2020
$payment = $request->getFirstModel();
2121

22+
/** @var OrderInterface $order */
23+
$order = $payment->getOrder();
24+
2225
if ($payment->getState() === PaymentInterface::STATE_NEW) {
2326
$request->setRouteName('sylius_paypal_plugin_pay_with_paypal_form');
24-
$request->setRouteParameters(['id' => $payment->getId()]);
27+
$request->setRouteParameters(
28+
['orderToken' => $order->getTokenValue(), 'paymentId' => $payment->getId()]
29+
);
2530

2631
return;
2732
}
@@ -32,9 +37,6 @@ public function execute($request): void
3237
return;
3338
}
3439

35-
/** @var OrderInterface $order */
36-
$order = $payment->getOrder();
37-
3840
$request->setRouteName('sylius_shop_order_show');
3941
$request->setRouteParameters(['tokenValue' => $order->getTokenValue()]);
4042
}

src/Resources/config/shop_routing.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
sylius_paypal_plugin_pay_with_paypal_form:
2-
path: /pay-with-paypal/{id}
2+
path: /pay-with-paypal/{orderToken}/{paymentId}
33
methods: [GET]
44
defaults:
55
_controller: Sylius\PayPalPlugin\Controller\PayWithPayPalFormAction

src/Resources/views/payWithPaypal.html.twig

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,8 @@
329329
});
330330
331331
if (paypal.HostedFields.isEligible() === true) {
332+
let processingOrderId;
333+
332334
paypal.HostedFields.render({
333335
createOrder: function(data, actions) {
334336
document.querySelector('#paypal-payment-container').classList.add('loading');
@@ -339,6 +341,8 @@
339341
}).then(function(res) {
340342
return res.json();
341343
}).then(function(data) {
344+
processingOrderId = data.orderID;
345+
342346
return data.orderID;
343347
});
344348
},
@@ -419,6 +423,7 @@
419423
420424
if (formValid) {
421425
hostedFields.submit({
426+
contingencies: ['SCA_ALWAYS'],
422427
cardholderName: document.getElementById('card-holder-name').value,
423428
billingAddress: {
424429
streetAddress: document.getElementById('card-billing-address-street').value,
@@ -428,20 +433,35 @@
428433
countryCodeAlpha2: document.getElementById('card-billing-address-country').value
429434
}
430435
}).then(payload => {
431-
return fetch(completePayPalOrderUrl, {
432-
method: 'post'
433-
}).then(function(res) {
434-
return res.json();
436+
if (payload.authenticationReason == 'SUCCESSFUL' && payload.authenticationStatus == 'YES') {
437+
return fetch(completePayPalOrderUrl, {
438+
method: 'post'
439+
}).then(function(res) {
440+
return res.json();
441+
}).then(function(data) {
442+
if (data.status == 'processing') {
443+
return fetch(cancelPayPalPaymentUrl, {
444+
method: 'post',
445+
headers: { 'content-type': 'application/json' },
446+
body: JSON.stringify({ payPalOrderId: data.orderID })
447+
}).then(window.location.reload());
448+
}
449+
450+
window.location.href = data.return_url;
451+
});
452+
}
453+
454+
455+
return fetch(errorPayPalPaymentUrl, {
456+
method: 'post',
457+
headers: { 'content-type': 'application/json' },
458+
body: JSON.stringify('Invalid 3D Secure authentication.')
435459
}).then(function(data) {
436-
if (data.status == 'processing') {
437-
return fetch(cancelPayPalPaymentUrl, {
438-
method: 'post',
439-
headers: { 'content-type': 'application/json' },
440-
body: JSON.stringify({ payPalOrderId: data.orderID })
441-
}).then(window.location.reload());
442-
}
443-
444-
window.location.href = data.return_url;
460+
return fetch(cancelPayPalPaymentUrl, {
461+
method: 'post',
462+
headers: { 'content-type': 'application/json' },
463+
body: JSON.stringify({ payPalOrderId: processingOrderId })
464+
}).then(window.location.reload());
445465
});
446466
});
447467
} else {

0 commit comments

Comments
 (0)