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 +144 -5 1.4.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,
@@ -158,11 +177,21 @@
158 177 'subscription' => $subscription,
159 178 'customer' => $customer
160 179 ]);
161 180
181 + $sectionParts = apply_filters('fluent_cart/customer/subscription_details_section_parts', [
182 + 'end_of_subscription' => ''
183 + ], [
184 + 'subscription' => $subscription,
185 + 'formattedData' => $formattedData
186 + ]);
187 +
188 + $sectionParts = array_map('wp_kses_post', $sectionParts);
189 +
162 190 return $this->sendSuccess([
163 - 'message' => __('Success', 'fluent-cart'),
164 - 'subscription' => $formattedData
191 + 'message' => __('Success', 'fluent-cart'),
192 + 'subscription' => $formattedData,
193 + 'section_parts' => $sectionParts
165 194 ]);
166 195 }
167 196
168 197 public function updatePaymentMethod(Request $request, $subscription_uuid)
@@ -205,8 +234,13 @@
205 234 return $this->sendError([
206 235 'message' => $e->getMessage()
207 236 ]);
208 237 }
238 +
239 + return $this->sendSuccess([
240 + 'status' => 'success',
241 + 'message' => __('Payment method updated successfully', 'fluent-cart')
242 + ]);
209 243 }
210 244
211 245 return $this->sendError([
212 246 'message' => __('Could not update payment method', 'fluent-cart')
@@ -252,8 +286,13 @@
252 286 return $this->sendError([
253 287 'message' => $e->getMessage()
254 288 ]);
255 289 }
290 +
291 + return $this->sendSuccess([
292 + 'status' => 'success',
293 + 'message' => __('Plan created successfully', 'fluent-cart')
294 + ]);
256 295 }
257 296
258 297 return $this->sendError([
259 298 'message' => __('Could not get or create plan', 'fluent-cart')
@@ -292,8 +331,14 @@
292 331 'message' => __('Subscription not found', 'fluent-cart')
293 332 ]);
294 333 }
295 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 +
296 341 if (App::gateway()->has($newPaymentMethod)) {
297 342 try {
298 343 App::gateway($newPaymentMethod)->subscriptions->switchPaymentMethod($data, $subscription->id);
299 344 } catch (\Exception $e) {
@@ -300,8 +345,13 @@
300 345 return $this->sendError([
301 346 'message' => $e->getMessage()
302 347 ]);
303 348 }
349 +
350 + return $this->sendSuccess([
351 + 'status' => 'success',
352 + 'message' => __('Payment method switched successfully', 'fluent-cart')
353 + ]);
304 354 }
305 355
306 356 return $this->sendError([
307 357 'message' => __('Could not switch payment method', 'fluent-cart')
@@ -342,8 +392,14 @@
342 392 'message' => __('Subscription not found', 'fluent-cart')
343 393 ]);
344 394 }
345 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 +
346 402 if (APP::gateway()->has($method)) {
347 403 try {
348 404 APP::gateway($method)->subscriptions->confirmSubscriptionSwitch($data, $subscription->id);
349 405 } catch (\Exception $e) {
@@ -350,8 +406,13 @@
350 406 return $this->sendError([
351 407 'message' => $e->getMessage()
352 408 ]);
353 409 }
410 +
411 + return $this->sendSuccess([
412 + 'status' => 'success',
413 + 'message' => __('Subscription switch confirmed successfully', 'fluent-cart')
414 + ]);
354 415 }
355 416
356 417 return $this->sendError([
357 418 'message' => __('Could not confirm subscription switch', 'fluent-cart')
@@ -448,8 +509,86 @@
448 509 return App::isProActive()
449 510 && $subscription->bill_times > 0
450 511 && $subscription->bill_count < $subscription->bill_times
451 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 + ];
452 591 }
453 592
454 593 public function getSetupIntentRemainingAttempts($subscription_uuid)
455 594 {