PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.7.0
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.7.0
1.7.0 1.6.6 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 All 50 releases
← All changes | app/Http/Controllers/FrontendControllers/CustomerSubscriptionController.php +192 -12 1.3.20 → 1.7.0 View file →
@@ -51,11 +51,11 @@
51 51
52 52 // Query the Subscription model to retrieve subscriptions for the logged-in customer
53 53 // Include associated order and product data using 'with' for eager loading
54 54 // Sort the results by 'id' in descending order and fetch the data
55 - $subscriptions = Subscription::query()
55 + $subscriptions = Subscription::visibleToCustomer()
56 56 ->where('customer_id', $customer->id)
57 - ->whereNotIn('status', [Status::SUBSCRIPTION_PENDING, Status::SUBSCRIPTION_INTENDED])
57 + ->with(['product'])
58 58 ->orderBy('id', 'desc')
59 59 ->paginate($perPage, ['*'], 'page', $page);
60 60
61 61
@@ -97,9 +97,9 @@
97 97 ->with(['product', 'variation', 'billing_addresses'])
98 98 ->where('uuid', $subscription_uuid)
99 99 ->first();
100 100
101 - if (!$subscription || in_array($subscription->status, [Status::SUBSCRIPTION_PENDING, Status::SUBSCRIPTION_INTENDED])) {
101 + if (!$subscription || !$subscription->isVisibleToCustomer()) {
102 102 return $this->sendError([
103 103 'message' => __('Subscription not found', 'fluent-cart')
104 104 ]);
105 105 }
@@ -118,22 +118,34 @@
118 118 'bill_count' => $subscription->bill_count,
119 119 'variation_id' => $subscription->variation_id,
120 120 'product_id' => $subscription->product_id,
121 121 'config' => $subscription->config,
122 + 'collection_method' => $subscription->collection_method,
122 123 'reactivate_url' => $subscription->getReactivateUrl(),
123 - 'title' => $subscription->product ? $subscription->product->post_title : $subscription->item_name,
124 - 'subtitle' => $subscription->variation && $subscription->product ? $subscription->variation->variation_title : '',
124 + // item_name resolves to "<product> - <attributes>" (or the raw name),
125 + // so it carries the labeled combination on a single line.
126 + 'title' => $subscription->display_item_name,
127 + 'subtitle' => '',
125 128 'can_upgrade' => $subscription->canUpgrade(),
126 129 'can_switch_payment_method' => $subscription->canSwitchPaymentMethod(),
127 130 'switchable_payment_methods' => $subscription->switchablePaymentMethods(),
128 131 'can_update_payment_method' => $subscription->canUpdatePaymentMethod(),
132 + 'can_pause' => $subscription->canPause(),
133 + 'can_resume' => $subscription->canResume(),
129 134 'order' => [
130 135 'uuid' => $subscription->order ? $subscription->order->uuid : ''
131 136 ],
132 137 'billing_addresses' => $subscription->billing_addresses,
133 138 'recurring_amount' => $subscription->recurring_amount,
139 + 'currency' => $subscription->currency,
134 140 'can_early_pay' => EarlyPaymentFeature::canPay($subscription),
135 141 'remaining_installments' => max(0, $subscription->bill_times - $subscription->bill_count),
142 + 'card_update_url' => $subscription->url,
143 + // Auto-charged (system) subscriptions: the saved card is charged
144 + // automatically on each renewal date — the portal says so, and surfaces
145 + // the last failure so the customer knows to update the card.
146 + 'is_auto_charged' => $subscription->isSystem(),
147 + 'auto_charge_error' => Arr::get((array) $subscription->system_charge_state, 'last_error', ''),
136 148 ];
137 149
138 150
139 151 // Let's find all the transactions related to this order
@@ -150,9 +162,15 @@
150 162 ->orderBy('id', 'DESC')
151 163 ->get();
152 164
153 165 $formattedData['transactions'] = $transactions->map(function ($transaction) {
154 - return OrderService::transformTransaction($transaction);
166 + $transformedTransaction = OrderService::transformTransaction($transaction);
167 + if ($transaction->status === Status::TRANSACTION_PENDING
168 + && !empty($transformedTransaction['custom_checkout_url'])
169 + ) {
170 + $transformedTransaction['show_pay_now'] = true;
171 + }
172 + return $transformedTransaction;
155 173 });
156 174
157 175 $formattedData = apply_filters('fluent_cart/customer_portal/subscription_data', $formattedData, [
158 176 'subscription' => $subscription,
@@ -158,16 +176,36 @@
158 176 'subscription' => $subscription,
159 177 'customer' => $customer
160 178 ]);
161 179
180 + $sectionParts = apply_filters('fluent_cart/customer/subscription_details_section_parts', [
181 + 'end_of_subscription' => ''
182 + ], [
183 + 'subscription' => $subscription,
184 + 'formattedData' => $formattedData
185 + ]);
186 +
187 + $sectionParts = array_map('wp_kses_post', $sectionParts);
188 +
162 189 return $this->sendSuccess([
163 - 'message' => __('Success', 'fluent-cart'),
164 - 'subscription' => $formattedData
190 + 'message' => __('Success', 'fluent-cart'),
191 + 'subscription' => $formattedData,
192 + 'section_parts' => $sectionParts
165 193 ]);
166 194 }
167 195
168 196 public function updatePaymentMethod(Request $request, $subscription_uuid)
169 197 {
198 + $errorResponse = $this->checkUserLoggedIn();
199 + if ($errorResponse !== null) {
200 + return $errorResponse;
201 + }
202 +
203 + $customer = CustomerResource::getCurrentCustomer();
204 + if (!$customer) {
205 + return $this->sendError(['message' => __('Customer not found', 'fluent-cart')]);
206 + }
207 +
170 208 $data = $request->input('data');
171 209 $method = $data['method'];
172 210 $subscriptionUuid = $subscription_uuid;
173 211
@@ -176,9 +214,12 @@
176 214 'message' => __('Method and Subscription Id required.', 'fluent-cart')
177 215 ]);
178 216 }
179 217
180 - $subscription = Subscription::query()->where('uuid', $subscriptionUuid)->first();
218 + $subscription = Subscription::query()
219 + ->where('uuid', $subscriptionUuid)
220 + ->where('customer_id', $customer->id)
221 + ->first();
181 222
182 223 if (empty($subscription)) {
183 224 return $this->sendError([
184 225 'message' => __('Subscription not found', 'fluent-cart')
@@ -192,8 +233,13 @@
192 233 return $this->sendError([
193 234 'message' => $e->getMessage()
194 235 ]);
195 236 }
237 +
238 + return $this->sendSuccess([
239 + 'status' => 'success',
240 + 'message' => __('Payment method updated successfully', 'fluent-cart')
241 + ]);
196 242 }
197 243
198 244 return $this->sendError([
199 245 'message' => __('Could not update payment method', 'fluent-cart')
@@ -201,8 +247,18 @@
201 247 }
202 248
203 249 public function getOrCreatePlan(Request $request, $subscription_uuid)
204 250 {
251 + $errorResponse = $this->checkUserLoggedIn();
252 + if ($errorResponse !== null) {
253 + return $errorResponse;
254 + }
255 +
256 + $customer = CustomerResource::getCurrentCustomer();
257 + if (!$customer) {
258 + return $this->sendError(['message' => __('Customer not found', 'fluent-cart')]);
259 + }
260 +
205 261 $data = $request->input('data');
206 262 $method = sanitize_text_field(Arr::get($data, 'method', ''));
207 263 $reason = sanitize_text_field(Arr::get($data, 'reason', ''));
208 264
@@ -211,9 +267,12 @@
211 267 'message' => __('Missing required parameters', 'fluent-cart')
212 268 ]);
213 269 }
214 270
215 - $subscription = Subscription::query()->where('uuid', $subscription_uuid)->first();
271 + $subscription = Subscription::query()
272 + ->where('uuid', $subscription_uuid)
273 + ->where('customer_id', $customer->id)
274 + ->first();
216 275 if (empty($subscription)) {
217 276 return $this->sendError([
218 277 'message' => __('Subscription not found', 'fluent-cart')
219 278 ]);
@@ -226,8 +285,13 @@
226 285 return $this->sendError([
227 286 'message' => $e->getMessage()
228 287 ]);
229 288 }
289 +
290 + return $this->sendSuccess([
291 + 'status' => 'success',
292 + 'message' => __('Plan created successfully', 'fluent-cart')
293 + ]);
230 294 }
231 295
232 296 return $this->sendError([
233 297 'message' => __('Could not get or create plan', 'fluent-cart')
@@ -245,8 +309,13 @@
245 309 $data = $request->input('data');
246 310 $newPaymentMethod = sanitize_text_field(Arr::get($data, 'newPaymentMethod', ''));
247 311 $currentPaymentMethod = sanitize_text_field(Arr::get($data, 'currentPaymentMethod', ''));
248 312
313 + $customer = CustomerResource::getCurrentCustomer();
314 + if (!$customer) {
315 + return $this->sendError(['message' => __('Customer not found', 'fluent-cart')]);
316 + }
317 +
249 318 if (!$newPaymentMethod || !$currentPaymentMethod || !$subscription_uuid) {
250 319 return $this->sendError([
251 320 'message' => __('Missing required parameters', 'fluent-cart')
252 321 ]);
@@ -251,9 +320,12 @@
251 320 'message' => __('Missing required parameters', 'fluent-cart')
252 321 ]);
253 322 }
254 323
255 - $subscription = Subscription::query()->where('uuid', $subscription_uuid)->first();
324 + $subscription = Subscription::query()
325 + ->where('uuid', $subscription_uuid)
326 + ->where('customer_id', $customer->id)
327 + ->first();
256 328 if (empty($subscription)) {
257 329 return $this->sendError([
258 330 'message' => __('Subscription not found', 'fluent-cart')
259 331 ]);
@@ -258,8 +330,14 @@
258 330 'message' => __('Subscription not found', 'fluent-cart')
259 331 ]);
260 332 }
261 333
334 + if (!$subscription->canSwitchPaymentMethod()) {
335 + return $this->sendError([
336 + 'message' => __('This subscription cannot be moved to another payment gateway. Update the payment method on file instead.', 'fluent-cart')
337 + ]);
338 + }
339 +
262 340 if (App::gateway()->has($newPaymentMethod)) {
263 341 try {
264 342 App::gateway($newPaymentMethod)->subscriptions->switchPaymentMethod($data, $subscription->id);
265 343 } catch (\Exception $e) {
@@ -266,8 +344,13 @@
266 344 return $this->sendError([
267 345 'message' => $e->getMessage()
268 346 ]);
269 347 }
348 +
349 + return $this->sendSuccess([
350 + 'status' => 'success',
351 + 'message' => __('Payment method switched successfully', 'fluent-cart')
352 + ]);
270 353 }
271 354
272 355 return $this->sendError([
273 356 'message' => __('Could not switch payment method', 'fluent-cart')
@@ -287,8 +370,13 @@
287 370 $data = $request->input('data');
288 371 $newVendorSubscriptionId = sanitize_text_field(Arr::get($data, 'newVendorSubscriptionId', ''));
289 372 $method = sanitize_text_field(Arr::get($data, 'method', ''));
290 373
374 + $customer = CustomerResource::getCurrentCustomer();
375 + if (!$customer) {
376 + return $this->sendError(['message' => __('Customer not found', 'fluent-cart')]);
377 + }
378 +
291 379 if (!$newVendorSubscriptionId || !$method || !$subscription_uuid) {
292 380 return $this->sendError([
293 381 'message' => __('Missing required parameters', 'fluent-cart')
294 382 ]);
@@ -293,9 +381,12 @@
293 381 'message' => __('Missing required parameters', 'fluent-cart')
294 382 ]);
295 383 }
296 384
297 - $subscription = Subscription::query()->where('uuid', $subscription_uuid)->first();
385 + $subscription = Subscription::query()
386 + ->where('uuid', $subscription_uuid)
387 + ->where('customer_id', $customer->id)
388 + ->first();
298 389 if (empty($subscription)) {
299 390 return $this->sendError([
300 391 'message' => __('Subscription not found', 'fluent-cart')
301 392 ]);
@@ -300,8 +391,14 @@
300 391 'message' => __('Subscription not found', 'fluent-cart')
301 392 ]);
302 393 }
303 394
395 + if (!$subscription->canSwitchPaymentMethod()) {
396 + return $this->sendError([
397 + 'message' => __('This subscription cannot be moved to another payment gateway. Update the payment method on file instead.', 'fluent-cart')
398 + ]);
399 + }
400 +
304 401 if (APP::gateway()->has($method)) {
305 402 try {
306 403 APP::gateway($method)->subscriptions->confirmSubscriptionSwitch($data, $subscription->id);
307 404 } catch (\Exception $e) {
@@ -308,8 +405,13 @@
308 405 return $this->sendError([
309 406 'message' => $e->getMessage()
310 407 ]);
311 408 }
409 +
410 + return $this->sendSuccess([
411 + 'status' => 'success',
412 + 'message' => __('Subscription switch confirmed successfully', 'fluent-cart')
413 + ]);
312 414 }
313 415
314 416 return $this->sendError([
315 417 'message' => __('Could not confirm subscription switch', 'fluent-cart')
@@ -406,8 +508,86 @@
406 508 return App::isProActive()
407 509 && $subscription->bill_times > 0
408 510 && $subscription->bill_count < $subscription->bill_times
409 511 && in_array($subscription->status, [Status::SUBSCRIPTION_ACTIVE, Status::SUBSCRIPTION_TRIALING]);
512 + }
513 +
514 + public function pauseSubscription(Request $request, $subscription_uuid)
515 + {
516 + $errorResponse = $this->checkUserLoggedIn();
517 + if ($errorResponse !== null) {
518 + return $errorResponse;
519 + }
520 +
521 + $customer = CustomerResource::getCurrentCustomer();
522 + if (!$customer) {
523 + return $this->sendError([
524 + 'message' => __('Customer not found', 'fluent-cart')
525 + ]);
526 + }
527 +
528 + $subscription = Subscription::query()
529 + ->where('uuid', $subscription_uuid)
530 + ->where('customer_id', $customer->id)
531 + ->first();
532 +
533 + if (empty($subscription)) {
534 + return $this->sendError([
535 + 'message' => __('Subscription not found', 'fluent-cart')
536 + ]);
537 + }
538 +
539 + $reason = __('Paused by customer from customer portal', 'fluent-cart');
540 + $result = $subscription->pauseSubscription($reason);
541 +
542 + if (is_wp_error($result)) {
543 + return $this->sendError([
544 + 'message' => $result->get_error_message()
545 + ]);
546 + }
547 +
548 + return [
549 + 'message' => __('Your subscription has been successfully paused', 'fluent-cart')
550 + ];
551 + }
552 +
553 + public function resumeSubscription(Request $request, $subscription_uuid)
554 + {
555 + $errorResponse = $this->checkUserLoggedIn();
556 + if ($errorResponse !== null) {
557 + return $errorResponse;
558 + }
559 +
560 + $customer = CustomerResource::getCurrentCustomer();
561 + if (!$customer) {
562 + return $this->sendError([
563 + 'message' => __('Customer not found', 'fluent-cart')
564 + ]);
565 + }
566 +
567 + $subscription = Subscription::query()
568 + ->where('uuid', $subscription_uuid)
569 + ->where('customer_id', $customer->id)
570 + ->first();
571 +
572 + if (empty($subscription)) {
573 + return $this->sendError([
574 + 'message' => __('Subscription not found', 'fluent-cart')
575 + ]);
576 + }
577 +
578 + $reason = __('Resumed by customer from customer portal', 'fluent-cart');
579 + $result = $subscription->resumeSubscription($reason);
580 +
581 + if (is_wp_error($result)) {
582 + return $this->sendError([
583 + 'message' => $result->get_error_message()
584 + ]);
585 + }
586 +
587 + return [
588 + 'message' => __('Your subscription has been successfully resumed', 'fluent-cart')
589 + ];
410 590 }
411 591
412 592 public function getSetupIntentRemainingAttempts($subscription_uuid)
413 593 {