PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.33.0
GiveWP – Donation Plugin and Fundraising Platform v2.33.0
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 2 years ago PayPalOrder.php 4 years ago Settings.php 3 years ago Webhooks.php 2 years ago
PayPalAuth.php
293 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 2.9.0
137 *
138 * @return array|null
139 */
140 public function getSellerPartnerLink($returnUrl, $country)
141 {
142 $response = wp_remote_retrieve_body(
143 wp_remote_post(
144 sprintf(
145 $this->connectClient->getApiUrl('paypal?mode=%1$s&request=partner-link'),
146 $this->payPalClient->getMode()
147 ),
148 [
149 'body' => [
150 'return_url' => $returnUrl,
151 'country_code' => $country,
152 ],
153 ]
154 )
155 );
156
157 return empty($response) ? null : json_decode($response, true);
158 }
159
160 /**
161 * Get seller on-boarding details from seller.
162 *
163 * @since 2.9.0
164 *
165 * @param string $accessToken
166 *
167 * @param string $merchantId
168 *
169 * @return array
170 */
171 public function getSellerOnBoardingDetailsFromPayPal($merchantId, $accessToken)
172 {
173 $request = wp_remote_post(
174 $this->connectClient->getApiUrl(
175 sprintf(
176 'paypal?mode=%1$s&request=seller-status',
177 $this->payPalClient->getMode()
178 )
179 ),
180 [
181 'body' => [
182 'merchant_id' => $merchantId,
183 'token' => $accessToken,
184 ],
185 ]
186 );
187
188 return json_decode(wp_remote_retrieve_body($request), true);
189 }
190
191 /**
192 * Get seller rest API credentials
193 *
194 * @since 2.9.0
195 *
196 * @param string $accessToken
197 *
198 * @return array
199 */
200 public function getSellerRestAPICredentials($accessToken)
201 {
202 $request = wp_remote_post(
203 $this->connectClient->getApiUrl(
204 sprintf(
205 'paypal?mode=%1$s&request=seller-credentials',
206 $this->payPalClient->getMode()
207 )
208 ),
209 [
210 'body' => [
211 'token' => $accessToken,
212 ],
213 ]
214 );
215
216 return json_decode(wp_remote_retrieve_body($request), true);
217 }
218
219 /**
220 * Validate PayPal access token.
221 *
222 * Sample PayPal access token: https://developer.paypal.com/api/rest/authentication/#link-sampleresponse
223 *
224 * @since 2.25.0
225 *
226 * @param array $accessToken Access token response from PayPal.
227 *
228 * @return void
229 * @throws UnexpectedValueException
230 */
231 private function validateAccessToken(array $accessToken)
232 {
233 $requiredKeys = [
234 'scope',
235 'access_token',
236 'token_type',
237 'app_id',
238 'expires_in',
239 'nonce'
240 ];
241
242 if (array_diff($requiredKeys, array_keys($accessToken))) {
243 give(Log::class)->error(
244 'PayPal Commerce: Invalid access token',
245 [
246 'category' => 'Payment Gateway',
247 'source' => 'Paypal Commerce',
248 'response' => $accessToken,
249 ]
250 );
251
252 throw new UnexpectedValueException('PayPal Commerce: Error retrieving access token');
253 }
254 }
255
256 /**
257 * Validate PayPal seller access token.
258 *
259 * Sample PayPal access token: https://developer.paypal.com/docs/multiparty/seller-onboarding/build-onboarding/#link-sampleresponse
260 *
261 * @since 2.32.0
262 *
263 * @param array $sellerAccessToken Seller access token response from PayPal.
264 *
265 * @return void
266 * @throws UnexpectedValueException
267 */
268 private function validateSellerAccessToken(array $sellerAccessToken)
269 {
270 $requiredKeys = [
271 'scope',
272 'access_token',
273 'token_type',
274 'refresh_token',
275 'expires_in',
276 'nonce'
277 ];
278
279 if (array_diff($requiredKeys, array_keys($sellerAccessToken))) {
280 give(Log::class)->error(
281 'PayPal Commerce: Invalid seller access token',
282 [
283 'category' => 'Payment Gateway',
284 'source' => 'Paypal Commerce',
285 'response' => $sellerAccessToken,
286 ]
287 );
288
289 throw new UnexpectedValueException('PayPal Commerce: Error retrieving seller access token');
290 }
291 }
292 }
293