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 +134 -6 1.5.1 → 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,
@@ -215,8 +233,13 @@
215 233 return $this->sendError([
216 234 'message' => $e->getMessage()
217 235 ]);
218 236 }
237 +
238 + return $this->sendSuccess([
239 + 'status' => 'success',
240 + 'message' => __('Payment method updated successfully', 'fluent-cart')
241 + ]);
219 242 }
220 243
221 244 return $this->sendError([
222 245 'message' => __('Could not update payment method', 'fluent-cart')
@@ -262,8 +285,13 @@
262 285 return $this->sendError([
263 286 'message' => $e->getMessage()
264 287 ]);
265 288 }
289 +
290 + return $this->sendSuccess([
291 + 'status' => 'success',
292 + 'message' => __('Plan created successfully', 'fluent-cart')
293 + ]);
266 294 }
267 295
268 296 return $this->sendError([
269 297 'message' => __('Could not get or create plan', 'fluent-cart')
@@ -302,8 +330,14 @@
302 330 'message' => __('Subscription not found', 'fluent-cart')
303 331 ]);
304 332 }
305 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 +
306 340 if (App::gateway()->has($newPaymentMethod)) {
307 341 try {
308 342 App::gateway($newPaymentMethod)->subscriptions->switchPaymentMethod($data, $subscription->id);
309 343 } catch (\Exception $e) {
@@ -310,8 +344,13 @@
310 344 return $this->sendError([
311 345 'message' => $e->getMessage()
312 346 ]);
313 347 }
348 +
349 + return $this->sendSuccess([
350 + 'status' => 'success',
351 + 'message' => __('Payment method switched successfully', 'fluent-cart')
352 + ]);
314 353 }
315 354
316 355 return $this->sendError([
317 356 'message' => __('Could not switch payment method', 'fluent-cart')
@@ -352,8 +391,14 @@
352 391 'message' => __('Subscription not found', 'fluent-cart')
353 392 ]);
354 393 }
355 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 +
356 401 if (APP::gateway()->has($method)) {
357 402 try {
358 403 APP::gateway($method)->subscriptions->confirmSubscriptionSwitch($data, $subscription->id);
359 404 } catch (\Exception $e) {
@@ -360,8 +405,13 @@
360 405 return $this->sendError([
361 406 'message' => $e->getMessage()
362 407 ]);
363 408 }
409 +
410 + return $this->sendSuccess([
411 + 'status' => 'success',
412 + 'message' => __('Subscription switch confirmed successfully', 'fluent-cart')
413 + ]);
364 414 }
365 415
366 416 return $this->sendError([
367 417 'message' => __('Could not confirm subscription switch', 'fluent-cart')
@@ -458,8 +508,86 @@
458 508 return App::isProActive()
459 509 && $subscription->bill_times > 0
460 510 && $subscription->bill_count < $subscription->bill_times
461 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 + ];
462 590 }
463 591
464 592 public function getSetupIntentRemainingAttempts($subscription_uuid)
465 593 {