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
← All changes | app/Http/Controllers/FrontendControllers/CustomerSubscriptionController.php +132 -3 1.5.1 → 1.6.5 View file →
@@ -53,8 +53,9 @@
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 55 $subscriptions = Subscription::query()
56 56 ->where('customer_id', $customer->id)
57 + ->with(['product'])
57 58 ->whereNotIn('status', [Status::SUBSCRIPTION_PENDING, Status::SUBSCRIPTION_INTENDED])
58 59 ->orderBy('id', 'desc')
59 60 ->paginate($perPage, ['*'], 'page', $page);
60 61
@@ -118,22 +119,34 @@
118 119 'bill_count' => $subscription->bill_count,
119 120 'variation_id' => $subscription->variation_id,
120 121 'product_id' => $subscription->product_id,
121 122 'config' => $subscription->config,
123 + 'collection_method' => $subscription->collection_method,
122 124 '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 : '',
125 + // item_name resolves to "<product> - <attributes>" (or the raw name),
126 + // so it carries the labeled combination on a single line.
127 + 'title' => $subscription->display_item_name,
128 + 'subtitle' => '',
125 129 'can_upgrade' => $subscription->canUpgrade(),
126 130 'can_switch_payment_method' => $subscription->canSwitchPaymentMethod(),
127 131 'switchable_payment_methods' => $subscription->switchablePaymentMethods(),
128 132 'can_update_payment_method' => $subscription->canUpdatePaymentMethod(),
133 + 'can_pause' => $subscription->canPause(),
134 + 'can_resume' => $subscription->canResume(),
129 135 'order' => [
130 136 'uuid' => $subscription->order ? $subscription->order->uuid : ''
131 137 ],
132 138 'billing_addresses' => $subscription->billing_addresses,
133 139 'recurring_amount' => $subscription->recurring_amount,
140 + 'currency' => $subscription->currency,
134 141 'can_early_pay' => EarlyPaymentFeature::canPay($subscription),
135 142 'remaining_installments' => max(0, $subscription->bill_times - $subscription->bill_count),
143 + 'card_update_url' => $subscription->url,
144 + // Auto-charged (system) subscriptions: the saved card is charged
145 + // automatically on each renewal date — the portal says so, and surfaces
146 + // the last failure so the customer knows to update the card.
147 + 'is_auto_charged' => $subscription->isSystem(),
148 + 'auto_charge_error' => Arr::get((array) $subscription->system_charge_state, 'last_error', ''),
136 149 ];
137 150
138 151
139 152 // Let's find all the transactions related to this order
@@ -150,9 +163,15 @@
150 163 ->orderBy('id', 'DESC')
151 164 ->get();
152 165
153 166 $formattedData['transactions'] = $transactions->map(function ($transaction) {
154 - return OrderService::transformTransaction($transaction);
167 + $transformedTransaction = OrderService::transformTransaction($transaction);
168 + if ($transaction->status === Status::TRANSACTION_PENDING
169 + && !empty($transformedTransaction['custom_checkout_url'])
170 + ) {
171 + $transformedTransaction['show_pay_now'] = true;
172 + }
173 + return $transformedTransaction;
155 174 });
156 175
157 176 $formattedData = apply_filters('fluent_cart/customer_portal/subscription_data', $formattedData, [
158 177 'subscription' => $subscription,
@@ -215,8 +234,13 @@
215 234 return $this->sendError([
216 235 'message' => $e->getMessage()
217 236 ]);
218 237 }
238 +
239 + return $this->sendSuccess([
240 + 'status' => 'success',
241 + 'message' => __('Payment method updated successfully', 'fluent-cart')
242 + ]);
219 243 }
220 244
221 245 return $this->sendError([
222 246 'message' => __('Could not update payment method', 'fluent-cart')
@@ -262,8 +286,13 @@
262 286 return $this->sendError([
263 287 'message' => $e->getMessage()
264 288 ]);
265 289 }
290 +
291 + return $this->sendSuccess([
292 + 'status' => 'success',
293 + 'message' => __('Plan created successfully', 'fluent-cart')
294 + ]);
266 295 }
267 296
268 297 return $this->sendError([
269 298 'message' => __('Could not get or create plan', 'fluent-cart')
@@ -302,8 +331,14 @@
302 331 'message' => __('Subscription not found', 'fluent-cart')
303 332 ]);
304 333 }
305 334
335 + if (!$subscription->canSwitchPaymentMethod()) {
336 + return $this->sendError([
337 + 'message' => __('This subscription cannot be moved to another payment gateway. Update the payment method on file instead.', 'fluent-cart')
338 + ]);
339 + }
340 +
306 341 if (App::gateway()->has($newPaymentMethod)) {
307 342 try {
308 343 App::gateway($newPaymentMethod)->subscriptions->switchPaymentMethod($data, $subscription->id);
309 344 } catch (\Exception $e) {
@@ -310,8 +345,13 @@
310 345 return $this->sendError([
311 346 'message' => $e->getMessage()
312 347 ]);
313 348 }
349 +
350 + return $this->sendSuccess([
351 + 'status' => 'success',
352 + 'message' => __('Payment method switched successfully', 'fluent-cart')
353 + ]);
314 354 }
315 355
316 356 return $this->sendError([
317 357 'message' => __('Could not switch payment method', 'fluent-cart')
@@ -352,8 +392,14 @@
352 392 'message' => __('Subscription not found', 'fluent-cart')
353 393 ]);
354 394 }
355 395
396 + if (!$subscription->canSwitchPaymentMethod()) {
397 + return $this->sendError([
398 + 'message' => __('This subscription cannot be moved to another payment gateway. Update the payment method on file instead.', 'fluent-cart')
399 + ]);
400 + }
401 +
356 402 if (APP::gateway()->has($method)) {
357 403 try {
358 404 APP::gateway($method)->subscriptions->confirmSubscriptionSwitch($data, $subscription->id);
359 405 } catch (\Exception $e) {
@@ -360,8 +406,13 @@
360 406 return $this->sendError([
361 407 'message' => $e->getMessage()
362 408 ]);
363 409 }
410 +
411 + return $this->sendSuccess([
412 + 'status' => 'success',
413 + 'message' => __('Subscription switch confirmed successfully', 'fluent-cart')
414 + ]);
364 415 }
365 416
366 417 return $this->sendError([
367 418 'message' => __('Could not confirm subscription switch', 'fluent-cart')
@@ -458,8 +509,86 @@
458 509 return App::isProActive()
459 510 && $subscription->bill_times > 0
460 511 && $subscription->bill_count < $subscription->bill_times
461 512 && in_array($subscription->status, [Status::SUBSCRIPTION_ACTIVE, Status::SUBSCRIPTION_TRIALING]);
513 + }
514 +
515 + public function pauseSubscription(Request $request, $subscription_uuid)
516 + {
517 + $errorResponse = $this->checkUserLoggedIn();
518 + if ($errorResponse !== null) {
519 + return $errorResponse;
520 + }
521 +
522 + $customer = CustomerResource::getCurrentCustomer();
523 + if (!$customer) {
524 + return $this->sendError([
525 + 'message' => __('Customer not found', 'fluent-cart')
526 + ]);
527 + }
528 +
529 + $subscription = Subscription::query()
530 + ->where('uuid', $subscription_uuid)
531 + ->where('customer_id', $customer->id)
532 + ->first();
533 +
534 + if (empty($subscription)) {
535 + return $this->sendError([
536 + 'message' => __('Subscription not found', 'fluent-cart')
537 + ]);
538 + }
539 +
540 + $reason = __('Paused by customer from customer portal', 'fluent-cart');
541 + $result = $subscription->pauseSubscription($reason);
542 +
543 + if (is_wp_error($result)) {
544 + return $this->sendError([
545 + 'message' => $result->get_error_message()
546 + ]);
547 + }
548 +
549 + return [
550 + 'message' => __('Your subscription has been successfully paused', 'fluent-cart')
551 + ];
552 + }
553 +
554 + public function resumeSubscription(Request $request, $subscription_uuid)
555 + {
556 + $errorResponse = $this->checkUserLoggedIn();
557 + if ($errorResponse !== null) {
558 + return $errorResponse;
559 + }
560 +
561 + $customer = CustomerResource::getCurrentCustomer();
562 + if (!$customer) {
563 + return $this->sendError([
564 + 'message' => __('Customer not found', 'fluent-cart')
565 + ]);
566 + }
567 +
568 + $subscription = Subscription::query()
569 + ->where('uuid', $subscription_uuid)
570 + ->where('customer_id', $customer->id)
571 + ->first();
572 +
573 + if (empty($subscription)) {
574 + return $this->sendError([
575 + 'message' => __('Subscription not found', 'fluent-cart')
576 + ]);
577 + }
578 +
579 + $reason = __('Resumed by customer from customer portal', 'fluent-cart');
580 + $result = $subscription->resumeSubscription($reason);
581 +
582 + if (is_wp_error($result)) {
583 + return $this->sendError([
584 + 'message' => $result->get_error_message()
585 + ]);
586 + }
587 +
588 + return [
589 + 'message' => __('Your subscription has been successfully resumed', 'fluent-cart')
590 + ];
462 591 }
463 592
464 593 public function getSetupIntentRemainingAttempts($subscription_uuid)
465 594 {