PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.16.9
GiveWP – Donation Plugin and Fundraising Platform v4.16.9
4.17.0 4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 All 256 releases
give / src / Framework / PaymentGateways / Routes / GatewayRoute.php

GatewayRoute.php in GiveWP – Donation Plugin and Fundraising Platform 4.16.9, at src/Framework/PaymentGateways/Routes/GatewayRoute.php

180 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Give\Framework\PaymentGateways\Routes;
4
5 use Give\Framework\PaymentGateways\DataTransferObjects\GatewayRouteData;
6 use Give\Framework\PaymentGateways\Exceptions\PaymentGatewayException;
7 use Give\Framework\PaymentGateways\Log\PaymentGatewayLog;
8 use Give\Framework\PaymentGateways\PaymentGateway;
9 use Give\Framework\PaymentGateways\PaymentGatewayRegister;
10 use Give\Framework\PaymentGateways\Traits\HandleHttpResponses;
11
12 use function Give\Framework\Http\Response\response;
13
14 /**
15 * @since 2.18.0
16 */
17 class GatewayRoute
18 {
19 use HandleHttpResponses;
20
21 /**
22 * This is our entry point into the Gateway Routing system.
23 *
24 * @since 2.19.0 - validate secureRouteMethods
25 * @since 2.18.0
26 *
27 * @return void
28 *
29 * @throws PaymentGatewayException
30 */
31 public function __invoke()
32 {
33 if ($this->isValidListener()) {
34 /** @var PaymentGatewayRegister $paymentGatewaysRegister */
35 $paymentGatewaysRegister = give(PaymentGatewayRegister::class);
36
37 // get all registered gateways
38 $paymentGateways = $paymentGatewaysRegister->getPaymentGateways();
39
40 // get all registered gateway ids
41 $gatewayIds = array_keys($paymentGateways);
42
43 // make sure required params are valid
44 if (!$this->isValidRequest($gatewayIds)) {
45 throw new PaymentGatewayException('This route is not valid.');
46 }
47
48 // create DTO from GET request
49 $data = GatewayRouteData::fromRequest(give_clean($_GET));
50
51 /**
52 * Get the PaymentGateway instance
53 *
54 * @var PaymentGateway $gateway
55 */
56 $gateway = give($paymentGateways[$data->gatewayId]);
57
58 if (!$gateway->supportsMethodRoute($data->gatewayMethod)) {
59 throw new PaymentGatewayException('The gateway method does not exist.');
60 }
61
62 // If method is in secureRouteMethods then, validate signature
63 if (in_array($data->gatewayMethod, $gateway->secureRouteMethods, true)) {
64 $this->validateSignature($data->routeSignature, $data);
65 }
66
67 // Navigate to our payment gateway api to handle calling the gateway's method
68 $this->handleGatewayRouteMethod($gateway, $data->gatewayMethod, $data->queryParams);
69
70 exit;
71 }
72 }
73
74 /**
75 * Check if the request is valid
76 *
77 * @since 2.19.0 remove required check give-donation-id
78 *
79 * @since 2.18.0
80 *
81 * @param array $gatewayIds
82 *
83 * @return bool
84 *
85 * @example ?give-listener=give-gateway&give-gateway-id=test-gateway&give-donation-id=1&give-gateway-method=returnFromOffsiteRedirect
86 *
87 */
88 private function isValidRequest($gatewayIds)
89 {
90 $isset = isset($_GET['give-gateway-id'], $_GET['give-gateway-method']);
91 $idValid = in_array($_GET['give-gateway-id'], $gatewayIds, true);
92
93 return $isset && $idValid;
94 }
95
96 /**
97 * Check if the listener is valid
98 *
99 * @since 2.18.0
100 *
101 * @return bool
102 */
103 private function isValidListener()
104 {
105 return isset($_GET['give-listener']) && $_GET['give-listener'] === 'give-gateway';
106 }
107
108 /**
109 * Validate signature using nonces
110 *
111 * @since 4.16.8 verify the route's own query args against the signature
112 * @since 2.19.5 replace nonce with hash
113 * @since 2.19.4 replace RouteSignature args with unique donationId
114 * @since 2.19.0
115 *
116 * @param string $routeSignature
117 * @param GatewayRouteData $data
118 *
119 * @return void
120 */
121 private function validateSignature($routeSignature, GatewayRouteData $data)
122 {
123 $signature = RouteSignature::fromRouteData($data);
124
125 if (!$signature->isValid($routeSignature)) {
126 PaymentGatewayLog::error(
127 'Invalid Secure Route',
128 [
129 'routeSignature' => $routeSignature,
130 'signature' => $signature,
131 'signatureString' => $signature->toString(),
132 'signatureHash' => $signature->toHash(),
133 'signatureExpiration' => $signature->expiration,
134 'data' => $data
135 ]
136 );
137
138 wp_die('Forbidden', 403);
139 }
140 }
141
142 /**
143 * Handle gateway route method
144 *
145 * @since 2.18.0
146 *
147 * @since 2.19.0 - replace $donationId with $queryParams array
148 * @since 2.19.0 Record gateway id, callback method name and query params in log.
149 *
150 * @param PaymentGateway $gateway
151 * @param string $method
152 * @param array $queryParams
153 */
154 private function handleGatewayRouteMethod(PaymentGateway $gateway, $method, $queryParams)
155 {
156 try {
157 $this->handleResponse($gateway->callRouteMethod($method, $queryParams));
158 } catch (PaymentGatewayException $paymentGatewayException) {
159 $this->handleResponse(response()->json($paymentGatewayException->getMessage()));
160 } catch (\Exception $exception) {
161 PaymentGatewayLog::error(
162 $exception->getMessage(),
163 [
164 'Payment Gateway' => $gateway::id(),
165 'Payment Gateway Method' => $method,
166 'Query Params' => $queryParams
167 ]
168 );
169 $this->handleResponse(
170 response()->json(
171 __(
172 'An unexpected error occurred while processing your donation. Please try again or contact us to help resolve.',
173 'give'
174 )
175 )
176 );
177 }
178 }
179 }
180