PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 3.16.4
GiveWP – Donation Plugin and Fundraising Platform v3.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 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 3 years ago MerchantDetails.php 3 years ago PayPalAuth.php 2 years ago PayPalOrder.php 2 years ago Settings.php 2 years ago Webhooks.php 2 years ago
PayPalAuth.php
294 lines
1 <?php
2
3 namespace Give\PaymentGateways\PayPalCommerce\Repositories;
4
5 use Give\Framework\Exceptions\Primitives\Exception;
6 use Give\Framework\Http\ConnectServer\Client\ConnectClient;
7 use Give\Helpers\ArrayDataSet;
8 use Give\Log\Log;
9 use Give\PaymentGateways\PayPalCommerce\PayPalCheckoutSdk\Requests\GetAccessToken;
10 use Give\PaymentGateways\PayPalCommerce\PayPalClient;
11 use RuntimeException;
12 use UnexpectedValueException;
13
14 class PayPalAuth
15 {
16 /**
17 * @since 2.9.0
18 *
19 * @var PayPalClient
20 */
21 private $payPalClient;
22
23 /**
24 * @since 2.9.0
25 *
26 * @var ConnectClient
27 */
28 private $connectClient;
29
30 /**
31 * PayPalAuth constructor.
32 *
33 * @since 2.9.0
34 *
35 * @param PayPalClient $payPalClient
36 * @param ConnectClient $connectClient
37 */
38 public function __construct(PayPalClient $payPalClient, ConnectClient $connectClient)
39 {
40 $this->payPalClient = $payPalClient;
41 $this->connectClient = $connectClient;
42 }
43
44 /**
45 * Retrieves a token for the Client ID and Secret
46 *
47 * @since 2.32.0 Use PayPal client for rest api calls.
48 * @since 2.25.0 Validate paypal response.
49 * @since 2.9.0
50 *
51 * @param string $client_id
52 * @param string $client_secret
53 *
54 * @throws RuntimeException|\Exception
55 */
56 public function getTokenFromClientCredentials($client_id, $client_secret): array
57 {
58 $auth = base64_encode("$client_id:$client_secret");
59
60 $response = $this->payPalClient->getHttpClient()
61 ->execute(new GetAccessToken(
62 ['grant_type' => 'client_credentials'],
63 ['Authorization' => "Basic $auth"]
64 ));
65
66 if (200 !== $response->statusCode) {
67 give(Log::class)->http(
68 'PayPal Commerce: Error retrieving access token with client credentials',
69 [
70 'category' => 'Payment Gateway',
71 'source' => 'Paypal Commerce',
72 'response' => $response,
73 ]
74 );
75
76 throw new RuntimeException('PayPal Commerce: Error retrieving access token with client credentials');
77 }
78
79 $result = (array)$response->result;
80
81 $this->validateAccessToken($result);
82
83 return ArrayDataSet::camelCaseKeys($result);
84 }
85
86 /**
87 * Retrieves a token from the authorization code
88 *
89 * @since 2.32.0 Use PayPal client for rest api calls.
90 * @since 2.9.0
91 *
92 * @param string $authCode
93 * @param string $sharedId
94 * @param string $nonce
95 *
96 * @return array|null
97 * @throws RuntimeException|\Exception
98 */
99 public function getTokenFromAuthorizationCode($authCode, $sharedId, $nonce)
100 {
101 $auth = base64_encode($sharedId);
102
103 $response = $this->payPalClient->getHttpClient()
104 ->execute(new GetAccessToken(
105 [
106 'grant_type' => 'authorization_code',
107 'code' => $authCode,
108 'code_verifier' => $nonce, // Seller nonce.
109 ],
110 ['Authorization' => "Basic $auth"]
111 ));
112
113 if (200 !== $response->statusCode) {
114 give(Log::class)->http(
115 'PayPal Commerce: Error retrieving access token with authorization code',
116 [
117 'category' => 'Payment Gateway',
118 'source' => 'Paypal Commerce',
119 'response' => $response,
120 ]
121 );
122
123 throw new RuntimeException('PayPal Commerce: Error retrieving access token with authorization code');
124 }
125
126 $result = (array)$response->result;
127
128 $this->validateSellerAccessToken($result);
129
130 return ArrayDataSet::camelCaseKeys($result);
131 }
132
133 /**
134 * Retrieves a Partner Link for on-boarding
135 *
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 'body' => [
151 'return_url' => $returnUrl,
152 'account_type' => $accountType,
153 ],
154 ]
155 )
156 );
157
158 return empty($response) ? null : json_decode($response, true);
159 }
160
161 /**
162 * Get seller on-boarding details from seller.
163 *
164 * @since 2.9.0
165 *
166 * @param string $accessToken
167 *
168 * @param string $merchantId
169 *
170 * @return array
171 */
172 public function getSellerOnBoardingDetailsFromPayPal($merchantId, $accessToken)
173 {
174 $request = wp_remote_post(
175 $this->connectClient->getApiUrl(
176 sprintf(
177 'paypal?mode=%1$s&request=seller-status',
178 $this->payPalClient->getMode()
179 )
180 ),
181 [
182 'body' => [
183 'merchant_id' => $merchantId,
184 'token' => $accessToken,
185 ],
186 ]
187 );
188
189 return json_decode(wp_remote_retrieve_body($request), true);
190 }
191
192 /**
193 * Get seller rest API credentials
194 *
195 * @since 2.9.0
196 *
197 * @param string $accessToken
198 *
199 * @return array
200 */
201 public function getSellerRestAPICredentials($accessToken)
202 {
203 $request = wp_remote_post(
204 $this->connectClient->getApiUrl(
205 sprintf(
206 'paypal?mode=%1$s&request=seller-credentials',
207 $this->payPalClient->getMode()
208 )
209 ),
210 [
211 'body' => [
212 'token' => $accessToken,
213 ],
214 ]
215 );
216
217 return json_decode(wp_remote_retrieve_body($request), true);
218 }
219
220 /**
221 * Validate PayPal access token.
222 *
223 * Sample PayPal access token: https://developer.paypal.com/api/rest/authentication/#link-sampleresponse
224 *
225 * @since 3.5.1 removed app_id from required keys as PayPal no longer supplies it
226 * @since 2.25.0
227 *
228 * @param array $accessToken Access token response from PayPal.
229 *
230 * @return void
231 * @throws UnexpectedValueException
232 */
233 private function validateAccessToken(array $accessToken)
234 {
235 $requiredKeys = [
236 'scope',
237 'access_token',
238 'token_type',
239 'expires_in',
240 'nonce'
241 ];
242
243 if (array_diff($requiredKeys, array_keys($accessToken))) {
244 give(Log::class)->error(
245 'PayPal Commerce: Invalid access token',
246 [
247 'category' => 'Payment Gateway',
248 'source' => 'Paypal Commerce',
249 'response' => $accessToken,
250 ]
251 );
252
253 throw new UnexpectedValueException('PayPal Commerce: Error retrieving access token');
254 }
255 }
256
257 /**
258 * Validate PayPal seller access token.
259 *
260 * Sample PayPal access token: https://developer.paypal.com/docs/multiparty/seller-onboarding/build-onboarding/#link-sampleresponse
261 *
262 * @since 2.32.0
263 *
264 * @param array $sellerAccessToken Seller access token response from PayPal.
265 *
266 * @return void
267 * @throws UnexpectedValueException
268 */
269 private function validateSellerAccessToken(array $sellerAccessToken)
270 {
271 $requiredKeys = [
272 'scope',
273 'access_token',
274 'token_type',
275 'refresh_token',
276 'expires_in',
277 'nonce'
278 ];
279
280 if (array_diff($requiredKeys, array_keys($sellerAccessToken))) {
281 give(Log::class)->error(
282 'PayPal Commerce: Invalid seller access token',
283 [
284 'category' => 'Payment Gateway',
285 'source' => 'Paypal Commerce',
286 'response' => $sellerAccessToken,
287 ]
288 );
289
290 throw new UnexpectedValueException('PayPal Commerce: Error retrieving seller access token');
291 }
292 }
293 }
294