PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.5
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.5
1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk All 48 releases
fluent-cart / app / Modules / PaymentMethods / PayPalGateway / ConnectConfig.php

ConnectConfig.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.6.5, at app/Modules/PaymentMethods/PayPalGateway/ConnectConfig.php

261 lines 10.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Modules\PaymentMethods\PayPalGateway;
4
5 use FluentCart\App\App;
6 use FluentCart\App\Modules\PaymentMethods\PayPalGateway\API\API;
7 use FluentCart\App\Modules\PaymentMethods\PayPalGateway\API\PayPalPartner;
8 use FluentCart\App\Modules\PaymentMethods\PayPalGateway\API\PayPalPartnerRenderer;
9 use FluentCart\App\Modules\PaymentMethods\PayPalGateway\API\Webhook;
10 use FluentCart\App\Vite;
11 use FluentCart\Framework\Http\Request\Request;
12 use FluentCart\Framework\Support\Arr;
13
14 class ConnectConfig
15 {
16 public static function getConnectConfig()
17 {
18 $PaypalSettings = new PayPalSettingsBase();
19 $settings = $PaypalSettings->get();
20
21 $testAccountInfo = self::getAccountInfo($settings, 'test');
22 $liveAccountInfo = self::getAccountInfo($settings, 'live');
23
24 $testConnectRedirect = add_query_arg([
25 'fluent-cart' => 'paypal_connect',
26 'intent' => 'connect',
27 'mode' => 'test',
28 '_wpnonce' => wp_create_nonce('fluent_cart_paypal_connect_test'),
29 ], home_url());
30 $liveConnectRedirect = add_query_arg([
31 'fluent-cart' => 'paypal_connect',
32 'intent' => 'connect',
33 'mode' => 'live',
34 '_wpnonce' => wp_create_nonce('fluent_cart_paypal_connect_live'),
35 ], home_url());
36
37 return [
38 'connect_config' => [
39 'test_redirect' => $testConnectRedirect,
40 'live_redirect' => $liveConnectRedirect,
41 'image_url' => Vite::getAssetUrl('images/payment-methods/paypal-icon.svg'),
42 'disconnect_note' => __('Disconnecting your PayPal account will prevent you from offering PayPal services and products on your website. Do you wish to continue?', 'fluent-cart')
43 ],
44 'test_account' => $testAccountInfo,
45 'live_account' => $liveAccountInfo,
46 'settings' => $settings
47 ];
48 }
49
50 public static function handleConnect($data): void
51 {
52 $intent = Arr::get($data, 'intent');
53 if ($intent === 'return') {
54 self::parseConnectInfos($data);
55 return;
56 }
57
58 if ($intent !== 'connect') {
59 wp_die(esc_html__('Invalid PayPal connection request.', 'fluent-cart'), '', ['response' => 400]);
60 }
61
62 $mode = self::validateConnectRequest($data, 'connect');
63 // WebRoutes terminates the request after dispatching this action.
64 (new PayPalPartnerRenderer($mode))->template($data);
65 }
66
67 public static function parseConnectInfos($vendorData)
68 {
69 $mode = self::validateConnectRequest($vendorData, 'return');
70
71 if (!$vendorData || !Arr::get($vendorData, 'permissionsGranted')) {
72 echo '<div class="fct_message fct_message_error">' . esc_html(__('Invalid PayPal Request. Please try configuring paypal payment gateway again!', 'fluent-cart')) . '</div>';
73 die();
74 }
75
76 $settingsInstance = App::gateway('paypal')->settings;
77
78 /*
79 * @todo will verify later
80 * we need to verify merchant manually after they create account
81 *
82 // start verifications if merchant able to receive payments
83 $sellerAccessToken = fluent_cart_get_option('_paypal_partner_connect_access_token_' . Arr::get($vendorData, 'mode'));
84
85 $accountData = (new PayPalPartner($mode))->verifyMerchant(Arr::get($sellerAccessToken, 'access_token'), Arr::get($vendorData, 'merchantIdInPayPal'));
86
87 if (is_wp_error($accountData)) {
88 echo '<div class="fct_message fct_message_error">' . esc_html($accountData->get_error_message()) . '</div>';
89 }
90
91 if (!Arr::get($accountData, 'payments_receivable')) {
92 echo '<div class="fct_message fct_message_error">
93 <p style="color: #b94a48; background: #f2dede; padding: 12px 16px; border-radius: 4px; border: 1px solid #ebccd1; margin: 0; max-width: 460px; margin:0 auto; margin-top: 10%;">
94 Attention: You currently cannot receive payments due to restriction on your PayPal account. Please reach out to PayPal Customer Support or connect to <a href="https://www.paypal.com" style="color: #31708f; text-decoration: underline;">https://www.paypal.com</a> for more information.
95 </p>
96 </div>';
97 die();
98 }
99
100 if (!Arr::get($accountData, 'primary_email_confirmed')) {
101 echo '<div class="fct_message fct_message_error">
102 <p style="color: #b94a48; background: #f2dede; padding: 12px 16px; border-radius: 4px; border: 1px solid #ebccd1; margin: 0; max-width: 460px; margin:0 auto; margin-top: 10%;line-height: 1.7rem;">
103 Attention: Please confirm your email address on <a href="https://www.paypal.com/businessprofile/settings" style="color: #31708f; text-decoration: underline;">https://www.paypal.com/businessprofile/settings</a> in order to receive payments! You currently cannot receive payments.
104 </p>
105 </div>';
106 die();
107 }
108
109 *
110 */
111
112 // Store metadata only after authorizing the connection return.
113 $data = [
114 $mode . '_email_address' => sanitize_text_field(Arr::get($vendorData, 'merchantId')),
115 $mode . '_account_status' => sanitize_text_field(Arr::get($vendorData, 'accountStatus')),
116 ];
117 $settingsInstance->updateNonSensitiveData($data);
118
119 wp_redirect(admin_url('admin.php?page=fluent-cart#/settings/payments/paypal'));
120 }
121
122 public static function validateConnectRequest($data, string $intent): string
123 {
124 if (!current_user_can('manage_options')) {
125 wp_die(esc_html__('You do not have permission to configure PayPal.', 'fluent-cart'), '', ['response' => 403]);
126 }
127
128 $mode = Arr::get($data, 'mode');
129 if (!in_array($mode, ['live', 'test'], true)) {
130 wp_die(esc_html__('Invalid PayPal payment mode.', 'fluent-cart'), '', ['response' => 400]);
131 }
132
133 $nonce = Arr::get($data, '_wpnonce');
134 $action = $intent === 'return' ? 'fluent_cart_paypal_connect_return_' : 'fluent_cart_paypal_connect_';
135 if (!is_string($nonce) || !wp_verify_nonce(sanitize_text_field($nonce), $action . $mode)) {
136 wp_die(esc_html__('Security check failed. Please try connecting PayPal again.', 'fluent-cart'), '', ['response' => 403]);
137 }
138
139 return $mode;
140 }
141
142 public function getSellerAuthToken(Request $request)
143 {
144
145 $authCode = $request->getSafe('authCode', 'sanitize_text_field');
146 $clientId = $request->getSafe('sharedId', 'sanitize_text_field');
147 $mode = $request->getSafe('mode', 'sanitize_text_field');
148 $paypalConnect = new PayPalPartner($mode);
149
150 try {
151
152 $response = $paypalConnect->exchangeAuthCode($clientId, $authCode);
153
154 if (isset($response['access_token'])) {
155 $endpoint = "/v1/customer/partners/" . $paypalConnect->getPartnerId() . "/merchant-integrations/credentials/";
156
157 // retrieve the merchant client ID and client secret
158 $credentials = $paypalConnect->makeMerchantRequest($endpoint, $response['access_token']);
159
160 if (is_wp_error($credentials)) {
161 wp_send_json([
162 'message' => $credentials->get_error_message()
163 ], 422);
164 }
165 if (is_array($credentials)) {
166 static::prepareSettingToSave($credentials, $mode);
167 }
168 //update the existing access token for after redirect verification
169 fluent_cart_update_option('_paypal_partner_connect_access_token_' . $mode, $response);
170 }
171
172 if (isset($response['error'])) {
173 throw new \Exception($response['error_description']);
174 }
175 } catch (\Exception $exception) {
176 // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped
177 throw new \Exception($exception->getMessage());
178 }
179 }
180
181
182 public static function prepareSettingToSave($credentials, $mode = 'live')
183 {
184 $clientId = Arr::get($credentials, 'client_id');
185 $clientSecret = Arr::get($credentials, 'client_secret');
186
187 $data = [
188 $mode . '_client_id' => $clientId,
189 $mode . '_client_secret' => $clientSecret,
190 $mode . '_account_id' => Arr::get($credentials, 'payer_id'),
191 'provider' => 'connect',
192 'is_active' => 'yes',
193 'payment_mode' => $mode
194 ];
195
196 $payPalInstance = App::gateway('paypal');
197
198 $oldSettings = $payPalInstance->settings->get();
199 $settingsData = wp_parse_args($data, $oldSettings);
200 $payPalInstance->updateSettings($settingsData);
201
202 //create webhook and setup endpoints
203 (new Webhook())->registerWebhook($mode);
204 }
205
206 private static function getAccountInfo($settings, $mode)
207 {
208 if (Arr::get($settings, 'provider') !== 'connect') {
209 return false;
210 }
211 return API::retrieveAccount($settings, $mode);
212 }
213
214 public static function disconnect($mode, $sendResponse = true)
215 {
216 $payPalInstance = App::gateway('paypal');
217 $paypalSettings = $payPalInstance->settings->get();
218
219 if (empty($paypalSettings[$mode . '_account_id'])) {
220 if ($sendResponse) {
221 wp_send_json([
222 'message' => __('Selected Account does not exist', 'fluent-cart')
223 ], 422);
224 }
225 return false;
226 }
227
228 $paypalSettings[$mode . '_account_id'] = '';
229 $paypalSettings[$mode . '_publishable_key'] = '';
230 $paypalSettings[$mode . '_secret_key'] = '';
231 $paypalSettings[$mode . '_webhook_events'] = [];
232 $paypalSettings[$mode . '_webhook_id'] = '';
233 $paypalSettings[$mode . '_client_id'] = '';
234 $paypalSettings[$mode . '_client_secret'] = '';
235
236 if ($mode == 'live') {
237 $alternateMode = 'test';
238 } else {
239 $alternateMode = 'live';
240 }
241
242 if (empty($paypalSettings[$alternateMode . '_account_id'])) {
243 $paypalSettings['is_active'] = 'no';
244 $paypalSettings['payment_mode'] = 'test';
245 } else {
246 $paypalSettings['payment_mode'] = $alternateMode;
247 }
248
249 $sendResponse = $payPalInstance->updateSettings($paypalSettings);
250
251 if ($sendResponse) {
252 wp_send_json([
253 'message' => __('PayPal settings has been disconnected', 'fluent-cart'),
254 'settings' => $paypalSettings
255 ], 200);
256 }
257
258 return true;
259 }
260 }
261