1
|
|
|
<?php declare(strict_types=1); |
2
|
|
|
|
3
|
|
|
namespace Karser\PayumSaferpay\Action; |
4
|
|
|
|
5
|
|
|
use Karser\PayumSaferpay\Api; |
6
|
|
|
use Karser\PayumSaferpay\Constants; |
7
|
|
|
use Karser\PayumSaferpay\Request\Api\AssertPaymentPage; |
8
|
|
|
use Karser\PayumSaferpay\Request\Api\AuthorizeTransaction; |
9
|
|
|
use Karser\PayumSaferpay\Request\Api\CaptureTransaction; |
10
|
|
|
use Karser\PayumSaferpay\Request\Api\InitPaymentPage; |
11
|
|
|
use Karser\PayumSaferpay\Request\Api\InitTransaction; |
12
|
|
|
use League\Uri\Http as HttpUri; |
13
|
|
|
use League\Uri\Modifiers\MergeQuery; |
14
|
|
|
use Payum\Core\Action\ActionInterface; |
15
|
|
|
use Payum\Core\ApiAwareInterface; |
16
|
|
|
use Payum\Core\ApiAwareTrait; |
17
|
|
|
use Payum\Core\Bridge\Spl\ArrayObject; |
18
|
|
|
use Payum\Core\Exception\LogicException; |
19
|
|
|
use Payum\Core\GatewayAwareInterface; |
20
|
|
|
use Payum\Core\GatewayAwareTrait; |
21
|
|
|
use Payum\Core\Request\Capture; |
22
|
|
|
use Payum\Core\Exception\RequestNotSupportedException; |
23
|
|
|
use Payum\Core\Request\GetHttpRequest; |
24
|
|
|
use Payum\Core\Request\GetHumanStatus; |
25
|
|
|
use Payum\Core\Security\GenericTokenFactoryAwareInterface; |
26
|
|
|
use Payum\Core\Security\GenericTokenFactoryAwareTrait; |
27
|
|
|
use Payum\Core\Security\TokenInterface; |
28
|
|
|
|
29
|
|
|
final class CaptureAction implements ActionInterface, ApiAwareInterface, GatewayAwareInterface, GenericTokenFactoryAwareInterface |
30
|
|
|
{ |
31
|
|
|
use ApiAwareTrait; |
32
|
|
|
use GatewayAwareTrait; |
33
|
|
|
use GenericTokenFactoryAwareTrait; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @var Api |
37
|
|
|
*/ |
38
|
|
|
protected $api; |
39
|
|
|
|
40
|
35 |
|
public function __construct() |
41
|
|
|
{ |
42
|
35 |
|
$this->apiClass = Api::class; |
43
|
35 |
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* @param Capture $request |
47
|
|
|
*/ |
48
|
22 |
|
public function execute($request) |
49
|
|
|
{ |
50
|
22 |
|
RequestNotSupportedException::assertSupports($this, $request); |
51
|
|
|
|
52
|
16 |
|
$model = ArrayObject::ensureArrayObject($request->getModel()); |
53
|
|
|
|
54
|
16 |
|
$interface = $model['Interface'] ?? $this->api->getCaptureStrategy(); |
55
|
|
|
|
56
|
|
|
switch ($interface) { |
57
|
16 |
|
case Constants::INTERFACE_PAYMENT_PAGE: |
58
|
5 |
|
$this->handlePaymentPageInterface($request); |
59
|
5 |
|
break; |
60
|
11 |
|
case Constants::INTERFACE_TRANSACTION: |
61
|
11 |
|
$this->handleTransactionInterface($request); |
62
|
11 |
|
break; |
63
|
|
|
default: |
64
|
|
|
throw new LogicException(sprintf('Unknown interface "%s"', $interface)); |
65
|
|
|
} |
66
|
16 |
|
} |
67
|
|
|
|
68
|
5 |
|
private function handlePaymentPageInterface(Capture $request) |
69
|
|
|
{ |
70
|
5 |
|
$model = ArrayObject::ensureArrayObject($request->getModel()); |
71
|
|
|
|
72
|
5 |
|
if (empty($model['Token'])) { |
73
|
5 |
|
$token = $request->getToken(); |
74
|
5 |
|
if (empty($model['ReturnUrls'])) { |
75
|
5 |
|
$model['ReturnUrls'] = $this->composeReturnUrls($token->getTargetUrl()); |
76
|
|
|
} |
77
|
5 |
|
if (empty($model['Notification']['NotifyUrl'])) { |
78
|
5 |
|
$notifyToken = $this->tokenFactory->createNotifyToken($token->getGatewayName(), $token->getDetails()); |
79
|
5 |
|
$model['Notification'] = array_merge($model['Notification'] ?? [], [ |
80
|
5 |
|
'NotifyUrl' => $notifyToken->getTargetUrl(), |
81
|
|
|
]); |
82
|
|
|
} |
83
|
5 |
|
$this->gateway->execute(new InitPaymentPage($model)); //might throw redirect to iframe |
84
|
|
|
} |
85
|
|
|
|
86
|
5 |
|
$this->gateway->execute($httpRequest = new GetHttpRequest()); |
87
|
|
|
|
88
|
5 |
View Code Duplication |
if (isset($httpRequest->query['abort'])) { |
|
|
|
|
89
|
1 |
|
$model->replace(['Transaction' => array_merge($model['Transaction'], ['Status' => Constants::STATUS_ABORTED])]); |
90
|
1 |
|
return; |
91
|
|
|
} |
92
|
|
|
|
93
|
4 |
View Code Duplication |
if (isset($httpRequest->query['fail'])) { |
|
|
|
|
94
|
1 |
|
$model->replace(['Transaction' => array_merge($model['Transaction'], ['Status' => Constants::STATUS_FAILED])]); |
95
|
1 |
|
return; |
96
|
|
|
} |
97
|
3 |
|
$this->gateway->execute(new AssertPaymentPage($model)); |
98
|
|
|
|
99
|
3 |
|
$this->gateway->execute($status = new GetHumanStatus($model)); |
100
|
3 |
|
if ($status->isAuthorized()) { |
101
|
2 |
|
$this->gateway->execute(new CaptureTransaction($model)); |
102
|
|
|
} |
103
|
3 |
|
} |
104
|
|
|
|
105
|
11 |
|
private function handleTransactionInterface(Capture $request) |
106
|
|
|
{ |
107
|
11 |
|
$model = ArrayObject::ensureArrayObject($request->getModel()); |
108
|
|
|
|
109
|
11 |
|
if (empty($model['Token'])) { |
110
|
11 |
|
if (empty($model['ReturnUrls'])) { |
111
|
11 |
|
$token = $request->getToken(); |
112
|
11 |
|
$model['ReturnUrls'] = $this->composeReturnUrls($token->getTargetUrl()); |
113
|
|
|
} |
114
|
11 |
|
$this->gateway->execute(new InitTransaction($model)); //might throw redirect to iframe |
115
|
|
|
} |
116
|
|
|
|
117
|
11 |
|
$this->gateway->execute($httpRequest = new GetHttpRequest()); |
118
|
|
|
|
119
|
11 |
View Code Duplication |
if (isset($httpRequest->query['abort'])) { |
|
|
|
|
120
|
1 |
|
$model->replace(['Transaction' => array_merge($model['Transaction'], ['Status' => Constants::STATUS_ABORTED])]); |
121
|
1 |
|
return; |
122
|
|
|
} |
123
|
|
|
|
124
|
10 |
View Code Duplication |
if (isset($httpRequest->query['fail'])) { |
|
|
|
|
125
|
2 |
|
$model->replace(['Transaction' => array_merge($model['Transaction'], ['Status' => Constants::STATUS_FAILED])]); |
126
|
2 |
|
return; |
127
|
|
|
} |
128
|
8 |
|
$this->gateway->execute(new AuthorizeTransaction($model)); |
129
|
|
|
|
130
|
8 |
|
$this->gateway->execute($status = new GetHumanStatus($model)); |
131
|
8 |
|
if ($status->isAuthorized()) { |
132
|
7 |
|
$this->gateway->execute(new CaptureTransaction($model)); |
133
|
|
|
} |
134
|
8 |
|
} |
135
|
|
|
|
136
|
16 |
|
private function composeReturnUrls(string $url): array |
137
|
|
|
{ |
138
|
16 |
|
$successUrl = HttpUri::createFromString($url); |
139
|
16 |
|
$modifier = new MergeQuery('success=1'); |
140
|
16 |
|
$successUrl = $modifier->process($successUrl); |
141
|
|
|
|
142
|
16 |
|
$failedUrl = HttpUri::createFromString($url); |
143
|
16 |
|
$modifier = new MergeQuery('fail=1'); |
144
|
16 |
|
$failedUrl = $modifier->process($failedUrl); |
145
|
|
|
|
146
|
16 |
|
$cancelUri = HttpUri::createFromString($url); |
147
|
16 |
|
$modifier = new MergeQuery('abort=1'); |
148
|
16 |
|
$cancelUri = $modifier->process($cancelUri); |
149
|
|
|
|
150
|
|
|
return [ |
151
|
16 |
|
'Success' => (string) $successUrl, |
152
|
16 |
|
'Fail' => (string) $failedUrl, |
153
|
16 |
|
'Abort' => (string) $cancelUri, |
154
|
|
|
]; |
155
|
|
|
} |
156
|
|
|
|
157
|
32 |
|
public function supports($request): bool |
158
|
|
|
{ |
159
|
|
|
return |
160
|
32 |
|
$request instanceof Capture && |
161
|
32 |
|
$request->getModel() instanceof \ArrayAccess && |
162
|
32 |
|
$request->getToken() instanceof TokenInterface |
163
|
|
|
; |
164
|
|
|
} |
165
|
|
|
} |
166
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.