PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.2
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.2
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 / StripeGateway / API / API.php

API.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.6.2, at app/Modules/PaymentMethods/StripeGateway/API/API.php

253 lines 8.7 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\StripeGateway\API;
4
5 use FluentCart\App\Modules\PaymentMethods\StripeGateway\StripeSettingsBase;
6 use FluentCart\Framework\Support\Arr;
7
8 class API
9 {
10 private $createSessionUrl;
11
12 private $apiUrl = 'https://api.stripe.com/v1/';
13
14 public function makeRequest($path, $data = [], $apiKey = null, $method = 'GET')
15 {
16 if (!$apiKey) {
17 $apiKey = $this->getApiKey();
18 }
19
20 return $this->remoteRequest($path, $data, $apiKey, $method);
21 }
22
23 public function getStripeObject($path, $data = [], $mode = 'current')
24 {
25 $apiKey = (new StripeSettingsBase())->getApiKey($mode);
26
27 return $this->remoteRequest($path, $data, $apiKey, 'GET');
28 }
29
30 public function createStripeObject($path, $data = [], $mode = 'current', $headers = [])
31 {
32 $apiKey = (new StripeSettingsBase())->getApiKey($mode);
33 return $this->remoteRequest($path, $data, $apiKey, 'POST', $headers);
34 }
35
36 public function deleteStripeObject($path, $data = [], $mode = 'current')
37 {
38 $apiKey = (new StripeSettingsBase())->getApiKey($mode);
39 return $this->remoteRequest($path, $data, $apiKey, 'DELETE');
40 }
41
42 public function remoteRequest($path, $data, $apiKey, $method, $extraHeaders = [])
43 {
44 $stripeApiKey = $apiKey;
45
46 // Never fire a request with an empty Authorization header — Stripe replies
47 // with the cryptic "You did not provide an API key" error. This happens when
48 // the secret key for the requested mode is not configured (e.g. a store in
49 // test mode charging a live-mode order, or unconfigured keys). Fail early
50 // with an actionable message instead.
51 if (empty($stripeApiKey)) {
52 return new \WP_Error(
53 'stripe_missing_api_key',
54 __('Stripe API key is not configured for this payment mode. Please add your Stripe keys in Payment Settings.', 'fluent-cart')
55 );
56 }
57
58 $apiVersion = '2025-02-24.acacia';
59 $sessionHeaders = array(
60 'Authorization' => 'Bearer ' . $stripeApiKey,
61 'Content-Type' => 'application/x-www-form-urlencoded',
62 'Stripe-Version' => $apiVersion
63 );
64
65 // Per-request headers (e.g. Idempotency-Key for off-session renewal charges)
66 if ($extraHeaders && is_array($extraHeaders)) {
67 $sessionHeaders = array_merge($sessionHeaders, $extraHeaders);
68 }
69
70 $url = $this->apiUrl . $path;
71
72 if ($method === 'GET' && is_array($data) && !empty($data)) {
73 $url .= '?' . http_build_query($data);
74 $requestData = array(
75 'headers' => $sessionHeaders,
76 'method' => $method,
77 );
78 } else {
79 $requestData = array(
80 'headers' => $sessionHeaders,
81 'body' => is_array($data) ? http_build_query($data) : $data,
82 'method' => $method,
83 );
84 }
85
86 $sessionResponse = wp_remote_request($url, $requestData);
87
88 if (is_wp_error($sessionResponse)) {
89 return $sessionResponse;
90 }
91
92 $sessionResponseData = wp_remote_retrieve_body($sessionResponse);
93 $responseBodyArray = json_decode($sessionResponseData, true);
94
95 $statusCode = wp_remote_retrieve_response_code($sessionResponse);
96
97 if ($statusCode >= 300) {
98
99 $message = Arr::get($responseBodyArray, 'detail');
100 if (!$message) {
101 $message = Arr::get($responseBodyArray, 'error.message');
102 }
103 if (!$message) {
104 $message = __('Unknown Stripe API request error', 'fluent-cart');
105 }
106
107 return new \WP_Error('api_error', $message, $responseBodyArray);
108 }
109
110 return $responseBodyArray;
111 }
112
113 public function verifyIPN()
114 {
115 $rawPayload = @file_get_contents('php://input');
116
117 $data = $rawPayload ? json_decode($rawPayload) : null;
118
119 if (empty($data) && !empty($_POST)) {
120 $postArray = stripslashes_deep($_POST);
121 $data = json_decode(wp_json_encode($postArray));
122 }
123
124 if (!$data || empty($data->id)) {
125 return new \WP_Error('invalid_data', __('Invalid or empty payload received from Stripe', 'fluent-cart'));
126 }
127
128 return $data;
129 }
130
131 /**
132 * Event ids are namespaced per mode, so a live id is unfetchable with a test key
133 * and vice versa. The store's global mode toggle is not a reliable proxy — a
134 * renewal is billed by Stripe on its own schedule, whatever the store is set to.
135 *
136 * @param string $eventId
137 * @param bool|null $livemode Mode the event belongs to; null falls back to the store setting.
138 * @return object|null|\WP_Error Null when the response body is not decodable JSON.
139 */
140 public function getEvent($eventId, $livemode = null)
141 {
142 $mode = 'current';
143 if (!is_null($livemode)) {
144 $mode = $livemode ? 'live' : 'test';
145 }
146
147 $api = $this->getApi($mode);
148 return $api::request([], 'events/' . $eventId, 'GET');
149 }
150
151 public function getApi($mode = 'current')
152 {
153 $api = new ApiRequest();
154 $api::set_secret_key((new StripeSettingsBase())->getApiKey($mode));
155 return $api;
156 }
157
158 public function getApiKey($mode = 'current')
159 {
160 return (new StripeSettingsBase())->getApiKey($mode);
161 }
162
163 public function addWebhookEndpoint()
164 {
165 // get all the webhook endpoints first
166
167 }
168
169 public function getWebhookEndpoints()
170 {
171 return $this->getStripeObject('webhooks');
172 }
173
174 public function getActivatedPaymentMethodsConfigs($mode = 'live')
175 {
176 $apiKey = (new StripeSettingsBase())->getApiKey($mode);
177
178 if (!$apiKey) {
179 return [];
180 }
181
182 $clientId = 'ca_TDs9okG0Jy8gY5GWbwmsDWHmIpOlyIoc';
183 if ($mode == 'test') {
184 $clientId = 'ca_TDs9NGCHtEcklwK4EFKHe72TAxC2kQap';
185 }
186
187 $stripeGateways = (new \FluentCart\App\Modules\PaymentMethods\StripeGateway\API\API)->makeRequest('payment_method_configurations', [
188 'application' => $clientId,
189 ], $apiKey);
190
191 if (is_wp_error($stripeGateways) || empty($stripeGateways['data'])) {
192 return [];
193 }
194
195 $gateway = Arr::first($stripeGateways['data']);
196
197 $stripeGateways = [
198 'acss_debit' => 'ACSS Debit',
199 'affirm' => 'Affirm',
200 'afterpay_clearpay' => 'Afterpay / Clearpay',
201 'alipay' => 'Alipay',
202 'amazon_pay' => 'Amazon Pay',
203 'apple_pay' => 'Apple Pay',
204 'bacs_debit' => 'BACS Debit',
205 'bancontact' => 'Bancontact',
206 'blik' => 'BLIK',
207 'card' => 'Credit/Debit Card',
208 'cartes_bancaires' => 'Cartes Bancaires',
209 'cashapp' => 'Cash App',
210 'crypto' => 'Cryptocurrency',
211 'eps' => 'EPS',
212 'giropay' => 'Giropay',
213 'google_pay' => 'Google Pay',
214 'ideal' => 'iDEAL',
215 'kakao_pay' => 'Kakao Pay',
216 'klarna' => 'Klarna',
217 'kr_card' => 'Korea Card',
218 'link' => 'Link',
219 'mb_way' => 'MB Way',
220 'multibanco' => 'Multibanco',
221 'naver_pay' => 'Naver Pay',
222 'p24' => 'Przelewy24',
223 'payco' => 'Payco',
224 'pix' => 'Pix',
225 'samsung_pay' => 'Samsung Pay',
226 'sepa_debit' => 'SEPA Debit',
227 'sofort' => 'Sofort',
228 'us_bank_account' => 'US Bank Account',
229 'wechat_pay' => 'WeChat Pay',
230 'zip' => 'Zip'
231 ];
232
233 $allMethods = Arr::only($gateway, array_keys($stripeGateways));
234
235 $activatedMethods = array_filter($allMethods, function ($method) {
236 return !!Arr::get($method, 'available');
237 });
238
239 $stripeGateways = Arr::only($stripeGateways, array_keys($activatedMethods));
240 $settings = (new StripeSettingsBase())->settings;
241 $accountId = Arr::get($settings, $mode . '_account_id');
242
243 $liveMode = !!Arr::get($gateway, 'livemode');
244
245 return [
246 'id' => Arr::get($gateway, 'id'),
247 'activated_methods' => $stripeGateways,
248 'configure_url' => 'https://dashboard.stripe.com/' . $accountId . (!$liveMode ? '/test/' : '/') . 'settings/payment_methods/' . Arr::get($gateway, 'id'),
249 ];
250 }
251
252 }
253