PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.16.3
GiveWP – Donation Plugin and Fundraising Platform v4.16.3
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 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / src / PaymentGateways / PayPalCommerce / Repositories / PayPalAuth.php
give / src / PaymentGateways / PayPalCommerce / Repositories Last commit date
Traits 2 years ago MerchantDetails.php 2 years ago PayPalAuth.php 1 year ago PayPalOrder.php 1 year ago Settings.php 2 years ago Webhooks.php 1 year ago
PayPalAuth.php
305 lines
1 <?php
2
3 namespace Give\PaymentGateways\PayPalCommerce\Repositories;
4
5 use Give\Framework\Http\ConnectServer\Client\ConnectClient;
6 use Give\Helpers\ArrayDataSet;
7 use Give\Log\Log;
8 use Give\PaymentGateways\PayPalCommerce\PayPalCheckoutSdk\Requests\GetAccessToken;
9 use Give\PaymentGateways\PayPalCommerce\PayPalClient;
10 use RuntimeException;
11 use UnexpectedValueException;
12
13 class PayPalAuth
14 {
15 /**
16 * @since 2.9.0
17 *
18 * @var PayPalClient
19 */
20 private $payPalClient;
21
22 /**
23 * @since 2.9.0
24 *
25 * @var ConnectClient
26 */
27 private $connectClient;
28
29 /**
30 * PayPalAuth constructor.
31 *
32 * @since 2.9.0
33 *
34 * @param PayPalClient $payPalClient
35 * @param ConnectClient $connectClient
36 */
37 public function __construct(PayPalClient $payPalClient, ConnectClient $connectClient)
38 {
39 $this->payPalClient = $payPalClient;
40 $this->connectClient = $connectClient;
41 }
42
43 /**
44 * Retrieves a token for the Client ID and Secret
45 *
46 * @since 2.32.0 Use PayPal client for rest api calls.
47 * @since 2.25.0 Validate paypal response.
48 * @since 2.9.0
49 *
50 * @param string $client_id
51 * @param string $client_secret
52 *
53 * @throws RuntimeException|\Exception
54 */
55 public function getTokenFromClientCredentials($client_id, $client_secret): array
56 {
57 $auth = base64_encode("$client_id:$client_secret");
58
59 $response = $this->payPalClient->getHttpClient()
60 ->execute(new GetAccessToken(
61 ['grant_type' => 'client_credentials'],
62 ['Authorization' => "Basic $auth"]
63 ));
64
65 if (200 !== $response->statusCode) {
66 give(Log::class)->http(
67 'PayPal Commerce: Error retrieving access token with client credentials',
68 [
69 'category' => 'Payment Gateway',
70 'source' => 'Paypal Commerce',
71 'response' => $response,
72 ]
73 );
74
75 throw new RuntimeException('PayPal Commerce: Error retrieving access token with client credentials');
76 }
77
78 $result = (array)$response->result;
79
80 $this->validateAccessToken($result);
81
82 return ArrayDataSet::camelCaseKeys($result);
83 }
84
85 /**
86 * Retrieves a token from the authorization code
87 *
88 * @since 2.32.0 Use PayPal client for rest api calls.
89 * @since 2.9.0
90 *
91 * @param string $authCode
92 * @param string $sharedId
93 * @param string $nonce
94 *
95 * @return array|null
96 * @throws RuntimeException|\Exception
97 */
98 public function getTokenFromAuthorizationCode($authCode, $sharedId, $nonce)
99 {
100 $auth = base64_encode($sharedId);
101
102 $response = $this->payPalClient->getHttpClient()
103 ->execute(new GetAccessToken(
104 [
105 'grant_type' => 'authorization_code',
106 'code' => $authCode,
107 'code_verifier' => $nonce, // Seller nonce.
108 ],
109 ['Authorization' => "Basic $auth"]
110 ));
111
112 if (200 !== $response->statusCode) {
113 give(Log::class)->http(
114 'PayPal Commerce: Error retrieving access token with authorization code',
115 [
116 'category' => 'Payment Gateway',
117 'source' => 'Paypal Commerce',
118 'response' => $response,
119 ]
120 );
121
122 throw new RuntimeException('PayPal Commerce: Error retrieving access token with authorization code');
123 }
124
125 $result = (array)$response->result;
126
127 $this->validateSellerAccessToken($result);
128
129 return ArrayDataSet::camelCaseKeys($result);
130 }
131
132 /**
133 * Retrieves a Partner Link for on-boarding
134 *
135 * @since 4.1.0 Add PayPal-Partner-Attribution-Id header
136 * @since 3.0.0 Implement $accountType. This parameter is required by GiveWP gateway server.
137 * @since 2.9.0
138 *
139 * @return array|null
140 */
141 public function getSellerPartnerLink($returnUrl, $accountType)
142 {
143 $response = wp_remote_retrieve_body(
144 wp_remote_post(
145 sprintf(
146 $this->connectClient->getApiUrl('paypal?mode=%1$s&request=partner-link'),
147 $this->payPalClient->getMode()
148 ),
149 [
150 'headers' => [
151 'PayPal-Partner-Attribution-Id' => give('PAYPAL_COMMERCE_ATTRIBUTION_ID'),
152 ],
153 'body' => [
154 'return_url' => $returnUrl,
155 'account_type' => $accountType,
156 ],
157 ]
158 )
159 );
160
161 return empty($response) ? null : json_decode($response, true);
162 }
163
164 /**
165 * Get seller on-boarding details from seller.
166 *
167 * @since 4.1.0 Add PayPal-Partner-Attribution-Id header
168 * @since 2.9.0
169 *
170 * @param string $accessToken
171 *
172 * @param string $merchantId
173 *
174 * @return array
175 */
176 public function getSellerOnBoardingDetailsFromPayPal($merchantId, $accessToken)
177 {
178 $request = wp_remote_post(
179 $this->connectClient->getApiUrl(
180 sprintf(
181 'paypal?mode=%1$s&request=seller-status',
182 $this->payPalClient->getMode()
183 )
184 ),
185 [
186 'headers' => [
187 'PayPal-Partner-Attribution-Id' => give('PAYPAL_COMMERCE_ATTRIBUTION_ID'),
188 ],
189 'body' => [
190 'merchant_id' => $merchantId,
191 'token' => $accessToken,
192 ],
193 ]
194 );
195
196 return json_decode(wp_remote_retrieve_body($request), true);
197 }
198
199 /**
200 * Get seller rest API credentials
201 *
202 * @since 4.1.0 Add PayPal-Partner-Attribution-Id header
203 * @since 2.9.0
204 *
205 * @param string $accessToken
206 *
207 * @return array
208 */
209 public function getSellerRestAPICredentials($accessToken)
210 {
211 $request = wp_remote_post(
212 $this->connectClient->getApiUrl(
213 sprintf(
214 'paypal?mode=%1$s&request=seller-credentials',
215 $this->payPalClient->getMode()
216 )
217 ),
218 [
219 'headers' => [
220 'PayPal-Partner-Attribution-Id' => give('PAYPAL_COMMERCE_ATTRIBUTION_ID'),
221 ],
222 'body' => [
223 'token' => $accessToken,
224 ],
225 ]
226 );
227
228 return json_decode(wp_remote_retrieve_body($request), true);
229 }
230
231 /**
232 * Validate PayPal access token.
233 *
234 * Sample PayPal access token: https://developer.paypal.com/api/rest/authentication/#link-sampleresponse
235 *
236 * @since 3.5.1 removed app_id from required keys as PayPal no longer supplies it
237 * @since 2.25.0
238 *
239 * @param array $accessToken Access token response from PayPal.
240 *
241 * @return void
242 * @throws UnexpectedValueException
243 */
244 private function validateAccessToken(array $accessToken)
245 {
246 $requiredKeys = [
247 'scope',
248 'access_token',
249 'token_type',
250 'expires_in',
251 'nonce'
252 ];
253
254 if (array_diff($requiredKeys, array_keys($accessToken))) {
255 give(Log::class)->error(
256 'PayPal Commerce: Invalid access token',
257 [
258 'category' => 'Payment Gateway',
259 'source' => 'Paypal Commerce',
260 'response' => $accessToken,
261 ]
262 );
263
264 throw new UnexpectedValueException('PayPal Commerce: Error retrieving access token');
265 }
266 }
267
268 /**
269 * Validate PayPal seller access token.
270 *
271 * Sample PayPal access token: https://developer.paypal.com/docs/multiparty/seller-onboarding/build-onboarding/#link-sampleresponse
272 *
273 * @since 2.32.0
274 *
275 * @param array $sellerAccessToken Seller access token response from PayPal.
276 *
277 * @return void
278 * @throws UnexpectedValueException
279 */
280 private function validateSellerAccessToken(array $sellerAccessToken)
281 {
282 $requiredKeys = [
283 'scope',
284 'access_token',
285 'token_type',
286 'refresh_token',
287 'expires_in',
288 'nonce'
289 ];
290
291 if (array_diff($requiredKeys, array_keys($sellerAccessToken))) {
292 give(Log::class)->error(
293 'PayPal Commerce: Invalid seller access token',
294 [
295 'category' => 'Payment Gateway',
296 'source' => 'Paypal Commerce',
297 'response' => $sellerAccessToken,
298 ]
299 );
300
301 throw new UnexpectedValueException('PayPal Commerce: Error retrieving seller access token');
302 }
303 }
304 }
305