PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.4.2
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.4.2
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 1.3.19 All 49 releases
fluent-cart / app / Services / Renderer / Receipt / ThankYouRender.php

ThankYouRender.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.4.2, at app/Services/Renderer/Receipt/ThankYouRender.php

1,329 lines 56.1 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\Services\Renderer\Receipt;
4
5 use FluentCart\Api\StoreSettings;
6 use FluentCart\App\App;
7 use FluentCart\App\Helpers\Helper;
8 use FluentCart\App\Modules\Tax\TaxModule;
9 use FluentCart\App\Modules\Templating\AssetLoader;
10 use FluentCart\App\Vite;
11 use FluentCart\Framework\Support\Arr;
12 use FluentCart\App\Modules\PaymentMethods\Core\GatewayManager;
13
14 class ThankYouRender
15 {
16
17 protected $config = null;
18
19 protected $settings = null;
20
21 protected $is_first_time = false;
22
23 protected $order_operation = null;
24
25
26 public function __construct($config)
27 {
28 $this->config = $config;
29
30 $this->is_first_time = Arr::get($this->config, 'is_first_time', false);
31 $this->order_operation = Arr::get($this->config, 'order_operation', false);
32
33 $this->settings = new StoreSettings();
34 AssetLoader::enqueueThankYouPageAssets();
35
36 }
37
38 public function renderWrapperStart()
39 {
40 ?>
41 <div class="fct-thank-you-page">
42 <div class="fct-thank-you-page-inner">
43 <div class="fct-thank-you-page-content email-template-content">
44 <?php
45 }
46
47 public function renderWrapperEnd()
48 {
49 ?>
50 </div>
51 </div>
52 </div>
53 <?php
54 }
55
56 public function render($hide_wrapper = false)
57 {
58 $order = Arr::get($this->config, 'order', null);
59
60 if (!$order) {
61 return;
62 }
63 ?>
64 <?php if (!$hide_wrapper) {
65 $this->renderWrapperStart();
66 } ?>
67 <?php do_action('fluent_cart/receipt/thank_you/before_header', $this->config); ?>
68 <?php $this->renderHeader(); ?>
69 <?php do_action('fluent_cart/receipt/thank_you/after_header', $this->config); ?>
70
71 <?php do_action('fluent_cart/receipt/thank_you/before_body', $this->config); ?>
72 <?php $this->renderBody(); ?>
73 <?php do_action('fluent_cart/receipt/thank_you/after_body', $this->config); ?>
74 <?php if (!$hide_wrapper) {
75 $this->renderWrapperEnd();
76 } ?>
77
78 <?php
79
80 $this->renderFooter();
81
82 do_action('fluent_cart/after_receipt', [
83 'order' => $order,
84 'is_first_time' => $this->is_first_time ?? false,
85 'order_operation' => $this->order_operation ?? null
86 ]);
87
88 if (!empty($this->is_first_time)) {
89 do_action('fluent_cart/after_receipt_first_time', [
90 'order' => $order,
91 'order_operation' => $this->order_operation ?? null
92 ]);
93 }
94 }
95
96 public function renderHeader()
97 {
98 $bgColor = '#d4edda';
99 $titleColor = '#155724';
100 $iconBg = '#155724bd';
101
102 $order = Arr::get($this->config, 'order', null);
103
104 if ($order->payment_status !== 'paid') {
105 $bgColor = '#fff3cd';
106 $titleColor = '#856404';
107 $iconBg = '#856404bd';
108 }
109 ?>
110 <div class="fct-thank-you-page-header" style="background: <?php echo esc_attr($bgColor); ?>;">
111 <?php if ($order->payment_status !== 'paid') : ?>
112 <div class="fct-thank-you-page-header-icon" style="background: <?php echo esc_attr($iconBg); ?>;">
113 <svg class="w-64 h-64" xmlns="http://www.w3.org/2000/svg"
114 viewBox="0 0 1024 1024" fill="currentColor">
115 <path
116 d="M480 674V192c0-18 14-32 32-32s32 14 32 32v482h-64zm0 63h64v60h-64v-60zM0 512C0 229 229 0 512 0s512 229 512 512-229 512-512 512S0 795 0 512zm961 0c0-247-202-448-449-448S64 265 64 512s201 448 448 448 449-201 449-448z"></path>
117 </svg>
118 </div>
119 <h1 class="fct-thank-you-page-header-title" style="color:<?php echo esc_attr($titleColor); ?>">
120 <?php echo esc_html__('Payment Pending!', 'fluent-cart'); ?>
121 </h1>
122
123 <?php else: ?>
124 <div class="fct-thank-you-page-header-icon" style="background: <?php echo esc_attr($iconBg); ?>;">
125 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"
126 stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
127 <polyline points="20,6 9,17 4,12"></polyline>
128 </svg>
129 </div>
130 <h1 class="fct-thank-you-page-header-title" style="color:<?php echo esc_attr($titleColor); ?>;">
131 <?php echo esc_html__('Purchase Successful!', 'fluent-cart'); ?>
132 </h1>
133 <?php endif; ?>
134
135 <?php do_action('fluent_cart/receipt/thank_you/after_header_title', $this->config); ?>
136
137 </div>
138
139 <?php
140 }
141
142 public function renderBody()
143 {
144 $order = Arr::get($this->config, 'order', null);
145
146 if (!$order) {
147 return;
148 }
149 ?>
150 <div class="fct-thank-you-page-body">
151 <div class="fct-thank-you-page-body-inner">
152 <div class="fct-thank-you-page-body-content">
153 <div class="fct-thank-you-page-body-content-inner">
154 <?php do_action('fluent_cart/receipt/thank_you/before_order_header', $this->config); ?>
155 <?php $this->renderOrderHeader(); ?>
156 <?php do_action('fluent_cart/receipt/thank_you/after_order_header', $this->config); ?>
157
158 <?php $this->renderStoreTaxInformation(); ?>
159
160 <?php do_action('fluent_cart/receipt/thank_you/before_order_items', $this->config); ?>
161 <?php $this->renderOrderItems(); ?>
162 <?php do_action('fluent_cart/receipt/thank_you/after_order_items', $this->config); ?>
163
164 <?php $this->renderSubscriptionItems(); ?>
165
166 <?php $this->renderDownloads(); ?>
167
168 <?php $this->renderLicenses(); ?>
169
170 <?php $this->renderAddress(); ?>
171
172 <?php $this->renderThankYouPageInstructions(); ?>
173
174 </div>
175 </div>
176 </div>
177 </div>
178
179 <?php
180 }
181
182 public function renderOrderHeader()
183 {
184 $order = Arr::get($this->config, 'order', null);
185 $profilePage = $this->settings->getCustomerProfilePage();
186 ?>
187 <div class="no-print">
188 <div class="no-print-title">
189 <?php
190 echo sprintf(
191 /* translators: %s is the customer's full name */
192 esc_html__('Hello %s!', 'fluent-cart'),
193 esc_html($order->customer->full_name)
194 );
195 ?>
196 </div>
197 <?php if ($order->payment_status === 'paid') : ?>
198 <p>
199 <?php
200 printf(
201 '%s<strong style="color: #007bff;"><a href="%s">#%s</a></strong>%s',
202 esc_html__('Your order ', 'fluent-cart'),
203 esc_url($profilePage . 'order/' . $order->uuid),
204 esc_html($order->invoice_no),
205 esc_html__(' has been placed successfully.', 'fluent-cart')
206 );
207 ?>
208 </p>
209 <?php else: ?>
210 <p>
211
212 <?php
213 printf(
214 '<strong style="color: #007bff;"><a href="%s">%s</a></strong> %s <a style="color: #007bff;" target="_blank" href="%s">%s</a>.',
215 esc_url($profilePage . 'order/' . $order->uuid),
216 esc_html__('Your order', 'fluent-cart'),
217 esc_html__('has payment due. You can pay from', 'fluent-cart'),
218 esc_url(\FluentCart\App\Services\Payments\PaymentHelper::getCustomPaymentLink($order->uuid)),
219 esc_html__('here', 'fluent-cart')
220 );
221 ?>
222
223 </p>
224 <?php endif; ?>
225
226 </div>
227
228 <?php
229 }
230
231 public function renderStoreTaxInformation()
232 {
233 $order = Arr::get($this->config, 'order', null);
234
235 $orderTaxRates = $order->getPrimaryOrderTaxRate();
236 if ($order->tax_total > 0 || $orderTaxRates): ?>
237 <div class="fct_invoice_tax_content">
238 <?php
239 if ($orderTaxRates) {
240 $storeVatNumber = Arr::get($orderTaxRates->meta, 'store_vat_number', '');
241 $taxcountry = Arr::get($orderTaxRates->meta ?? [], 'tax_country', '');
242 if ($storeVatNumber !== '') {
243 echo '<p>' . esc_html(TaxModule::getCountryTaxTitle($taxcountry)) . ': ' . esc_html($storeVatNumber) . '</p>';
244 }
245 }
246 ?>
247 </div>
248 <?php endif;
249 }
250
251 public function renderOrderItems()
252 {
253 $order = Arr::get($this->config, 'order', null);
254
255 if ($order->order_items) : ?>
256 <div class="fct-thank-you-page-order-items">
257 <?php $this->renderOrderItemsHeader(); ?>
258
259 <?php $this->renderOrderItemsBody(); ?>
260 </div>
261 <?php endif;
262 }
263
264 public function renderOrderItemsHeader()
265 {
266 ?>
267 <div class="fct-thank-you-page-order-items-header">
268 <div class="fct-thank-you-page-order-items-header-row">
269 <?php echo esc_html__('Item', 'fluent-cart'); ?>
270 </div>
271 <div class="fct-thank-you-page-order-items-header-row">
272 <?php echo esc_html__('Total', 'fluent-cart'); ?>
273 </div>
274 </div>
275 <?php
276 }
277
278 public function renderOrderItemsBody()
279 {
280 $order = Arr::get($this->config, 'order', null);
281 ?>
282 <div class="fct-thank-you-page-order-items-body">
283 <?php
284 $order->loadMissing(['order_items']);
285 $orderItems = $order->getProductItems()->toArray();
286 $orderItems = $this->buildBundleItemsTree($orderItems);
287
288 foreach ($orderItems as $item) :
289
290 ?>
291 <div class="fct-thank-you-page-order-items-list">
292 <div class="fct-thank-you-page-order-items-list-title">
293 <p class="fct-thank-you-page-order-items-list-quantity">
294 <?php echo esc_html($item['post_title']); ?>
295 <?php if ($item['quantity'] > 1): ?>
296 <span>x <?php echo esc_html(Helper::translateNumber($item['quantity'])); ?></span>
297 <?php endif; ?>
298 </p>
299 <p class="fct-thank-you-page-order-items-list-variant-title">
300 - <?php echo esc_html($item['title']); ?>
301 </p>
302 <?php if ($item['payment_type'] === 'subscription' && !empty($item['payment_info'])): ?>
303 <p class="fct-thank-you-page-order-items-list-payment-info">
304 <?php echo wp_kses_post($item['payment_info']) ?>
305 </p>
306 <?php endif; ?>
307 <?php $this->renderBundleProducts($item); ?>
308 </div>
309 <div class="fct-thank-you-page-order-items-list-price">
310 <div class="fct-thank-you-page-order-items-list-price-inner">
311 <?php echo esc_html($item['formatted_total']); ?>
312 </div>
313 </div>
314 </div>
315
316 <div class="fct-thank-you-page-order-items-tax-info">
317 <?php $this->renderItemTaxPill($item, $order); ?>
318 <?php if (!empty($item['setup_info'])): ?>
319 <div class="fct-thank-you-page-order-items-setup-fee">
320 <div class="setup-fee">
321 <?php echo esc_html(Arr::get($item, 'other_info.signup_fee_name', '')); ?>
322 </div>
323
324 <div class="setup-fee-amount">
325 <?php echo esc_html(Helper::toDecimal(Arr::get($item, 'other_info.signup_fee', ''))); ?>
326 </div>
327 </div>
328 <?php endif; ?>
329 <?php $this->renderItemSetupFeeTaxPills($item, $order); ?>
330 </div>
331 <?php endforeach; ?>
332
333 <?php $this->renderOrderTotal(); ?>
334
335 <!-- tax note -->
336 <?php $this->renderTaxNote(); ?>
337
338 </div>
339 <?php
340 }
341
342 public function renderThankYouPageInstructions()
343 {
344 $order = Arr::get($this->config, 'order', null);
345 if (!$order) {
346 return;
347 }
348 $transaction = $order->getLatestTransaction();
349 $methodSlug = '';
350 $thankYouPageInstructions = '';
351 if ($transaction && !empty($transaction->payment_method)) {
352 $methodSlug = $transaction->payment_method;
353 }
354 if (GatewayManager::has($methodSlug)) {
355 $gatewayInstance = GatewayManager::getInstance($methodSlug);
356 if ($gatewayInstance && isset($gatewayInstance->settings)) {
357 $gatewaySettings = (array) $gatewayInstance->settings->get();
358 $thankYouPageInstructions = Arr::get($gatewaySettings, 'thank_you_page_instructions', '');
359 }
360 }
361
362 if (!empty($thankYouPageInstructions)) : ?>
363
364 <div style="max-width: 620px; margin: 15px auto 0; font-family: Arial, Helvetica, sans-serif;">
365 <div style="font-size: 14px; color: #2F3448; padding: 12px 0; border-top: 1px solid #e7eaee;">
366 <?php echo wp_kses_post($thankYouPageInstructions); ?>
367 </div>
368 </div>
369 <?php endif;
370 }
371
372 public function renderOrderTotal()
373 {
374 ?>
375 <div class="fct-thank-you-page-order-items-total">
376 <?php $this->renderSubtotal(); ?>
377 <?php $this->renderDiscount(); ?>
378 <?php $this->renderShipping(); ?>
379 <?php $this->renderFees(); ?>
380 <?php $this->renderTaxSummaryBox(); ?>
381
382 <?php $this->renderProrateCredit(); ?>
383 <?php $this->renderRefund(); ?>
384 <?php $this->renderTotal(); ?>
385 <?php $this->renderPaymentMethod(); ?>
386 </div>
387 <?php
388 }
389
390 public function renderTaxNote()
391 {
392 $order = Arr::get($this->config, 'order', null);
393 if ($order->isReverseChargeTaxOrder()): ?>
394 <div style="text-align: right; font-size: 14px; margin-top: 10px;">
395 <?php echo '*' . esc_html__('Tax to be paid on reverse charge basis', 'fluent-cart') ?>
396 </div>
397 <?php
398 endif;
399 }
400
401 public function renderSubtotal()
402 {
403 $order = Arr::get($this->config, 'order', null);
404 if ($order->subtotal != $order->total_amount || $order->tax_total > 0): ?>
405 <div class="fct-meta-line fct-thank-you-page-order-items-total-subtotal">
406 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
407 <?php echo esc_html__('Subtotal', 'fluent-cart'); ?>
408 </div>
409 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value"><?php echo esc_html(Helper::toDecimal($order->subtotal)); ?></div>
410 </div>
411 <?php endif;
412 }
413
414 public function renderDiscount()
415 {
416 $order = Arr::get($this->config, 'order', null);
417 $prorateCredit = (int) Arr::get($order->config, 'prorate_credit', 0);
418 $upgradeDiscount = $order->manual_discount_total - $prorateCredit;
419 // When the prorate credit IS the whole discount, label the row directly
420 // instead of showing "Discount" with a single redundant breakdown row.
421 $onlyProrateCredit = $prorateCredit > 0 && $upgradeDiscount <= 0 && $order->coupon_discount_total <= 0;
422
423 if ($order->manual_discount_total + $order->coupon_discount_total > 0): ?>
424 <div class="fct-meta-line fct-thank-you-page-order-items-total-discount">
425 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
426 <?php echo $onlyProrateCredit ? esc_html__('Prorate Credit', 'fluent-cart') : esc_html__('Discount', 'fluent-cart'); ?>
427 </div>
428 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
429 - <?php echo esc_html(Helper::toDecimal($order->manual_discount_total + $order->coupon_discount_total)); ?>
430 </div>
431 </div>
432 <?php if ($prorateCredit > 0 && $upgradeDiscount > 0): ?>
433 <div class="fct-meta-line" style="padding-left:12px;">
434 <div class="fct-meta-line-label" style="font-size:12px;color:rgb(107,114,128);">
435 <?php echo esc_html__('Upgrade Discount', 'fluent-cart'); ?>
436 </div>
437 <div class="fct-meta-line-value" style="font-size:12px;color:rgb(107,114,128);">
438 <?php echo esc_html(Helper::toDecimal($upgradeDiscount)); ?>
439 </div>
440 </div>
441 <?php endif; ?>
442 <?php if ($prorateCredit > 0 && !$onlyProrateCredit): ?>
443 <div class="fct-meta-line" style="padding-left:12px;">
444 <div class="fct-meta-line-label" style="font-size:12px;color:rgb(107,114,128);">
445 <?php echo esc_html__('Prorate Credit', 'fluent-cart'); ?>
446 </div>
447 <div class="fct-meta-line-value" style="font-size:12px;color:rgb(107,114,128);">
448 <?php echo esc_html(Helper::toDecimal($prorateCredit)); ?>
449 </div>
450 </div>
451 <?php endif; ?>
452 <?php endif;
453 }
454
455 public function renderProrateCredit()
456 {
457 // Rendered as a sub-row inside renderDiscount.
458 }
459
460 public function renderShipping()
461 {
462 $order = Arr::get($this->config, 'order', null);
463
464 if ($order->shipping_total <= 0) {
465 return;
466 }
467 $displayShipping = (int) $order->shipping_total;
468 if ($order->isReverseChargeTaxOrder()) {
469 $rcAdj = (int) Arr::get(TaxSummaryHelper::computeTaxSummary($order), 'rcShippingAdjustment', 0);
470 if ($rcAdj > 0) {
471 $displayShipping = max(0, $displayShipping - $rcAdj);
472 }
473 }
474 ?>
475 <div class="fct-meta-line fct-thank-you-page-order-items-total-shipping">
476 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
477 <?php echo esc_html__('Shipping', 'fluent-cart'); ?>
478 </div>
479 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value"><?php echo esc_html(Helper::toDecimal($displayShipping)); ?></div>
480 </div>
481 <?php
482 }
483
484 public function renderFees()
485 {
486 $order = Arr::get($this->config, 'order', null);
487 if (!$order || $order->fee_total <= 0) {
488 return;
489 }
490 $feeItems = $order->feeItems()->get();
491 foreach ($feeItems as $feeItem): ?>
492 <div class="fct-meta-line fct-thank-you-page-order-items-total-fee">
493 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
494 <?php echo esc_html($feeItem->title); ?>
495 </div>
496 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
497 <?php echo esc_html(Helper::toDecimal($feeItem->subtotal)); ?>
498 </div>
499 </div>
500 <?php endforeach;
501 }
502
503 public function renderTaxTotal()
504 {
505 $order = Arr::get($this->config, 'order', null);
506
507 if ($order->isReverseChargeTaxOrder()): ?>
508 <?php
509 $rcReversedTotal = $order->getReversedTaxTotal();
510 $rcChargeLabel = $rcReversedTotal > 0
511 ? sprintf(
512 /* translators: %1$s: formatted reversed tax amount */
513 __('Tax reversed: %1$s', 'fluent-cart'),
514 Helper::toDecimal($rcReversedTotal)
515 )
516 : __('Charge reversed', 'fluent-cart');
517 ?>
518 <div class="fct-meta-line fct-thank-you-page-order-items-total-tax">
519 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
520 <?php echo esc_html__('Tax', 'fluent-cart'); ?>
521 </div>
522 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
523 <?php echo esc_html($rcChargeLabel); ?>
524 </div>
525 </div>
526 <?php elseif ($order->tax_total > 0): ?>
527 <div class="fct-meta-line fct-thank-you-page-order-items-total-tax">
528 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
529 <?php echo esc_html__('Total Tax', 'fluent-cart'); ?>
530 <?php echo \FluentCart\App\Helpers\Helper::getOrderTaxLabel($order); ?>
531 </div>
532 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
533 <?php echo esc_html(Helper::toDecimal($order->tax_total)); ?>
534 </div>
535 </div>
536 <?php endif;
537 }
538
539 public function renderShippingTax()
540 {
541 $order = Arr::get($this->config, 'order', null);
542
543 if ($order->shipping_tax <= 0) {
544 return;
545 }
546 ?>
547 <div class="fct-meta-line fct-thank-you-page-order-items-total-shipping-tax">
548 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
549 <?php echo esc_html__('Shipping Tax', 'fluent-cart'); ?>
550 <?php echo \FluentCart\App\Helpers\Helper::getOrderTaxLabel($order); ?>
551 </div>
552 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
553 <?php echo esc_html(Helper::toDecimal($order->shipping_tax)); ?>
554 </div>
555 </div>
556 <?php
557 }
558
559 public function renderRefund()
560 {
561 $order = Arr::get($this->config, 'order', null);
562
563 if ($order->total_refund > 0): ?>
564 <div class="fct-meta-line fct-thank-you-page-order-items-total-refund">
565 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
566 <?php echo esc_html__('Refund', 'fluent-cart'); ?>
567 </div>
568 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
569 - <?php echo esc_html(Helper::toDecimal($order->total_refund)); ?>
570 </div>
571 </div>
572 <?php endif;
573 }
574
575 public function renderTotal()
576 {
577 $order = Arr::get($this->config, 'order', null);
578 $displayTotal = (int) $order->total_amount - (int) $order->total_refund;
579 if ($order->isReverseChargeTaxOrder()) {
580 $rcAdj = (int) Arr::get(TaxSummaryHelper::computeTaxSummary($order), 'rcTotalAdjustment', 0);
581 if ($rcAdj > 0) {
582 $displayTotal = max(0, $displayTotal - $rcAdj);
583 }
584 }
585 ?>
586 <div class="fct-meta-line fct-thank-you-page-order-items-total-total">
587 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
588 <?php echo esc_html__('Total', 'fluent-cart'); ?>
589 </div>
590 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
591 <?php echo esc_html(Helper::toDecimal($displayTotal)); ?>
592 </div>
593 </div>
594 <?php
595 }
596
597 public function renderPaymentMethod()
598 {
599 $order = Arr::get($this->config, 'order', null);
600 $transaction = $order->getLatestTransaction();
601 ?>
602 <div class="fct-meta-line fct-thank-you-page-order-items-total-payment-method">
603 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
604 <?php echo esc_html__('Payment Method', 'fluent-cart'); ?>
605 </div>
606 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
607 <?php if ($transaction->card_last_4) :
608 echo esc_html($transaction->card_brand) . ' ' . esc_html($transaction->card_last_4);
609 else:
610 $title = $transaction->payment_method;
611 $gateway = GatewayManager::getInstance($transaction->payment_method);
612 $title = $gateway ? $gateway->getMeta('title') : $title;
613 echo esc_html($title);
614 endif; ?>
615 </div>
616 </div>
617 <?php
618 }
619
620 public function renderSubscriptionItems()
621 {
622 $order = Arr::get($this->config, 'order', null);
623 $subscriptions = $order->subscriptions;
624
625 if ($subscriptions->count() == 0) {
626 return;
627 }
628 ?>
629 <div class="fct-thank-you-page-order-items-subscriptions">
630 <p class="fct-thank-you-page-order-items-subscriptions-heading">
631 <?php echo esc_html__('Subscription Details', 'fluent-cart'); ?>
632 </p>
633
634 <table class="fct-thank-you-page-order-items-subscriptions-table" role="presentation">
635 <tbody>
636 <?php foreach ($subscriptions as $subs): ?>
637 <tr>
638 <td class="fct-thank-you-page-order-items-subscriptions-table-file">
639 <p>
640 <?php echo esc_html($subs->item_name); ?>
641 </p>
642 </td>
643
644 <td class="fct-thank-you-page-order-items-subscriptions-billing-infos">
645 <div>
646 <?php if (!empty($subs->payment_info)) : ?>
647 <span>
648 <?php echo $subs->payment_info; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
649 </span>
650 <?php endif; ?>
651
652 <?php if (!empty($subs->next_billing_date)) : ?>
653 <p class="fct-thank-you-page-order-items-subscriptions-billing-infos-next-billing"><?php
654 echo sprintf(
655 /* translators: 1: Next billing date */
656 esc_html__('- Auto renews on %1$s', 'fluent-cart'),
657 esc_html(
658 \FluentCart\App\Services\DateTime\DateTime::gmtToTimezone($subs->next_billing_date)->format('M d, Y h:i A')
659 )
660 );
661 ?>
662 </p>
663 <?php endif; ?>
664 </div>
665 </td>
666 </tr>
667 <?php endforeach; ?>
668 </tbody>
669 </table>
670 </div>
671
672
673 <?php
674 // App::make('view')->render('invoice.parts.subscription_items', [
675 // 'subscriptions' => $order->subscriptions,
676 // 'order' => $order
677 // ]);
678 }
679
680 public function renderDownloads()
681 {
682 $order = Arr::get($this->config, 'order', null);
683 $downloads = $order->getDownloads();
684 if (!$downloads) {
685 return;
686 }
687 ?>
688 <div class="fct-thank-you-page-order-items-downloads">
689 <p class="fct-thank-you-page-order-items-downloads-heading">
690 <?php echo esc_html__('Downloads', 'fluent-cart'); ?>
691 </p>
692
693 <table class="fct-thank-you-page-order-items-downloads-table"
694 role="presentation">
695 <tbody>
696 <tr>
697 <td>
698 <table role="presentation" width="100%">
699 <tbody>
700 <?php foreach ($downloads as $downloadItem): ?>
701 <tr>
702 <td>
703 <?php if ($downloadItem['downloads']): ?>
704
705 <table role="presentation" width="100%">
706 <tbody>
707 <?php foreach ($downloadItem['downloads'] as $download): ?>
708 <tr>
709 <td class="fct-thank-you-page-order-items-downloads-table-file">
710 <p>
711 <?php echo esc_html($download['title']); ?>
712 <?php if ($download['file_size']): ?>
713 <span>(<?php echo esc_html(Helper::readableFileSize($download['file_size'])); ?>)</span>
714 <?php endif; ?>
715 </p>
716 </td>
717 <td class="fct-thank-you-page-order-items-downloads-button">
718 <a href="<?php echo esc_url($download['download_url'] ?? ''); ?>">
719 <?php echo esc_html__('Download', 'fluent-cart'); ?>
720 </a>
721 </td>
722 </tr>
723 <?php endforeach; ?>
724 </tbody>
725 </table>
726
727 <?php endif; ?>
728
729 </td>
730 </tr>
731 <?php endforeach; ?>
732 </tbody>
733 </table>
734 </td>
735 </tr>
736 </tbody>
737 </table>
738 </div>
739
740 <?php $this->renderDownloadsNotice(); ?>
741
742 <?php
743 }
744
745 public function renderDownloadsNotice($show_notice = false)
746 {
747 $showNotice = $show_notice ?? true;
748 ?>
749 <?php if (!$showNotice) {
750 return;
751 } ?>
752 <table
753 class="fct-thank-you-page-order-items-downloads-notice"
754 role="presentation">
755 <tbody>
756 <tr>
757 <td>
758 <p class="fct-thank-you-page-order-items-downloads-notice-title">
759 <?php echo esc_html__('Important', 'fluent-cart'); ?>
760 </p>
761 <p class="fct-thank-you-page-order-items-downloads-notice-content">
762 <?php echo esc_html__('This download link is valid for 7 days. After that, you can download the files again from your account
763 on our website.', 'fluent-cart'); ?>
764 </p>
765 </td>
766 </tr>
767 </tbody>
768 </table>
769 <?php
770 }
771
772 public function renderLicenseNotice($show_notice = false)
773 {
774 $showNotice = $show_notice ?? true;
775 ?>
776 <?php if (!$showNotice) {
777 return;
778 } ?>
779 <table
780 class="fct-thank-you-page-order-items-downloads-notice"
781 role="presentation">
782 <tbody>
783 <tr>
784 <td>
785 <p class="fct-thank-you-page-order-items-downloads-notice-title">
786 <?php echo esc_html__('Important', 'fluent-cart'); ?>
787 </p>
788 <p class="fct-thank-you-page-order-items-downloads-notice-content">
789 <?php echo esc_html__('This download link is valid for 7 days. After that, you can download the files again from your account on our website.', 'fluent-cart'); ?>
790 </p>
791 </td>
792 </tr>
793 </tbody>
794 </table>
795 <?php
796 }
797
798 public function renderLicenses()
799 {
800 $order = Arr::get($this->config, 'order', null);
801 $licenses = $order->getLicenses();
802 if (!$licenses || $licenses->count() == 0) {
803 return;
804 }
805 ?>
806 <div class="fct-thank-you-page-order-items-licenses">
807 <p class="fct-thank-you-page-order-items-licenses-heading">
808 <?php echo esc_html__('Licenses', 'fluent-cart'); ?>
809 </p>
810 <table class="fct-thank-you-page-order-items-licenses-table" role="presentation">
811 <tbody>
812 <tr>
813 <td>
814 <table role="presentation">
815 <tbody>
816
817 <?php foreach ($licenses as $license): ?>
818 <tr>
819 <td class="fct-thank-you-page-order-items-licenses-table-file">
820 <p>
821 <?php echo esc_html($license->productVariant->variation_title); ?>:
822 <?php echo esc_html($license->license_key); ?>
823 </p>
824 </td>
825 </tr>
826 <?php endforeach; ?>
827 </tbody>
828 </table>
829 </td>
830 </tr>
831 </tbody>
832 </table>
833 </div>
834
835 <?php $this->renderLicenseNotice(); ?>
836 <?php
837 }
838
839 public function renderAddress()
840 {
841 $order = Arr::get($this->config, 'order', null);
842 ?>
843 <div class="fct-thank-you-page-order-items-addresses">
844 <?php $this->renderBillToAddress(); ?>
845 <?php if ($order->fulfillment_type === 'physical') : ?>
846 <?php $this->renderShipToAddress(); ?>
847 <?php endif; ?>
848 </div>
849 <?php
850 }
851
852 public function renderBillToAddress()
853 {
854 $order = Arr::get($this->config, 'order', null);
855 ?>
856 <div class="fct-thank-you-page-order-items-addresses-bill-to">
857 <h5>
858 <?php echo esc_html__('Bill To', 'fluent-cart'); ?>
859 </h5>
860 <?php
861 if (!empty($order->billing_address)) :
862 ?>
863 <div class="fct-thank-you-page-order-items-addresses-bill-to-address">
864 <?php echo esc_html($order->billing_address->getAddressAsText()); ?>
865 </div>
866
867 <div class="fct-thank-you-page-order-items-addresses-bill-to-email">
868 <?php echo esc_html($order->customer->email); ?>
869 </div>
870 <?php else: ?>
871 <div class="fct-thank-you-page-order-items-addresses-bill-to-name">
872 <?php echo esc_html($order->customer->full_name); ?>
873 </div>
874 <div class="fct-thank-you-page-order-items-addresses-bill-to-email">
875 <?php echo esc_html($order->customer->email); ?>
876 </div>
877 <?php endif; ?>
878 <?php
879 $phoneNumber = Arr::get($order->billing_address->meta ?? [], 'other_data.phone', '');
880 if ($phoneNumber !== ''):
881 ?>
882 <div class="fct-thank-you-page-order-items-addresses-bill-to-phone">
883 <?php echo esc_html($phoneNumber); ?>
884 </div>
885 <?php endif; ?>
886 <?php
887 $companyName = $order->billing_address
888 ? Arr::get($order->billing_address->meta ?? [], 'other_data.company_name', '')
889 : '';
890 if ($companyName === '') {
891 $companyName = $order->getCustomerTaxName();
892 }
893 if ($companyName !== ''):
894 ?>
895 <div class="fct-thank-you-page-order-items-addresses-bill-to-company-name">
896 <?php echo esc_html($companyName); ?>
897 </div>
898 <?php endif; ?>
899 <?php
900 $legalRegId = $order->billing_address
901 ? Arr::get($order->billing_address->meta ?? [], 'other_data.legal_registration_id', '')
902 : '';
903 if ($legalRegId === '') {
904 $legalRegId = Arr::get($order->getBusinessInfo(), 'legal_registration_id', '');
905 }
906 if ($legalRegId !== ''):
907 ?>
908 <div class="fct-thank-you-page-order-items-addresses-bill-to-legal-reg">
909 <?php echo esc_html__('Reg. ID', 'fluent-cart') . ': ' . esc_html($legalRegId); ?>
910 </div>
911 <?php endif; ?>
912 <div class="fct-thank-you-page-order-items-addresses-bill-to-vat-number">
913 <?php
914 $vatNumber = $order->getCustomerTaxNumber();
915 if ($vatNumber !== '') {
916 $vatLabel = __('VAT/Tax ID', 'fluent-cart');
917 echo esc_html($vatLabel) . ': ' . esc_html($vatNumber);
918 }
919 ?>
920 </div>
921 <?php
922 $reverseChargeDeclaration = Arr::get($order->getBusinessInfo(), 'reverse_charge_declaration', '');
923 if ($reverseChargeDeclaration !== ''):
924 ?>
925 <div class="fct-thank-you-page-order-items-addresses-bill-to-reverse-charge">
926 <strong><?php echo esc_html__('Reverse Charge Declaration', 'fluent-cart'); ?>:</strong>
927 <?php echo esc_html($reverseChargeDeclaration); ?>
928 </div>
929 <?php endif; ?>
930 </div>
931 <?php
932 }
933
934 public function renderShipToAddress()
935 {
936 $order = Arr::get($this->config, 'order', null);
937 ?>
938 <div class="fct-thank-you-page-order-items-addresses-ship-to">
939 <h5 class="fct-thank-you-page-order-items-addresses-ship-to-title">
940 <?php echo esc_html__('Ship To', 'fluent-cart'); ?>
941 </h5>
942 <?php if (!empty($order->shipping_address)) : ?>
943 <div class="fct-thank-you-page-order-items-addresses-ship-to-address">
944 <?php echo esc_html($order->shipping_address->getAddressAsText()); ?>
945 </div>
946 <!-- show phone number -->
947 <?php
948 $phone = Arr::get($order->shipping_address->meta ?? [], 'other_data.phone', '');
949 if ($phone !== ''):?>
950 <div class="fct-thank-you-page-order-items-addresses-ship-to-phone">
951 <?php echo esc_html($phone); ?>
952 </div>
953 <?php endif; ?>
954 <?php else: ?>
955 <div class="fct-thank-you-page-order-items-addresses-ship-to-name">
956 <?php echo esc_html($order->customer->full_name); ?>
957 </div>
958 <div class="fct-thank-you-page-order-items-addresses-ship-to-email">
959 <?php echo esc_html($order->customer->email); ?>
960 </div>
961 <?php endif; ?>
962 </div>
963 <?php
964 }
965
966 public function renderFooter()
967 {
968 ?>
969 <div class="fct-thank-you-page-footer">
970 <?php do_action('fluent_cart/receipt/thank_you/before_footer_buttons', $this->config); ?>
971 <?php $this->renderViewOrderButton(); ?>
972 <?php $this->renderDownloadReceiptButton(); ?>
973 <?php do_action('fluent_cart/receipt/thank_you/after_footer_buttons', $this->config); ?>
974 </div>
975 <?php
976 }
977
978 public function renderViewOrderButton()
979 {
980 $order = Arr::get($this->config, 'order', null);
981 $profilePage = $this->settings->getCustomerProfilePage();
982
983 ?>
984 <a
985 class="fct-thank-you-page-view-order-button"
986 href="<?php echo esc_url($profilePage . 'order/' . $order->uuid); ?>">
987 <?php echo esc_html__('View Order', 'fluent-cart'); ?>
988 </a>
989 <?php
990 }
991
992 public function renderDownloadReceiptButton()
993 {
994 $order = Arr::get($this->config, 'order', null);
995 ?>
996 <a
997 class="fct-thank-you-page-download-receipt-button"
998 href="<?php echo esc_url(\FluentCart\App\Services\URL::appendQueryParams(
999 home_url(),
1000 [
1001 'fluent-cart' => 'receipt',
1002 'order_hash' => $order->uuid,
1003 'download' => 1
1004 ]
1005 )) ?>">
1006 <?php echo esc_html__('Download Receipt', 'fluent-cart'); ?>
1007 </a>
1008 <?php
1009 }
1010
1011 /**
1012 * Build a parent → bundle items relationship from flat order items
1013 *
1014 * Converts a flat order items list into:
1015 * - Parent items
1016 * - Each parent contains a ` bundle_items ` array
1017 *
1018 * @param array $orderItems
1019 * @return array
1020 */
1021 protected function buildBundleItemsTree($orderItems)
1022 {
1023 if (!$orderItems) {
1024 return [];
1025 }
1026
1027 $parents = [];
1028 $childrenByParent = [];
1029
1030 // Separate parents and children
1031 foreach ($orderItems as $item) {
1032 $parentId = Arr::get($item, 'line_meta.bundle_parent_item_id', null);
1033
1034 // If bundle child → group by parent ID
1035 if ($parentId) {
1036 $childrenByParent[$parentId][] = $item;
1037
1038 // Otherwise it's a parent item
1039 } else {
1040 $item['bundle_items'] = [];
1041 $parents[$item['id']] = $item;
1042 }
1043 }
1044
1045 // Attach children to their parent
1046 foreach ($childrenByParent as $parentId => $children) {
1047 if (isset($parents[$parentId])) {
1048 $parents[$parentId]['bundle_items'] = $children;
1049 }
1050 }
1051
1052 // Re-index a final array
1053 return array_values($parents);
1054 }
1055
1056 public function renderBundleProducts($item)
1057 {
1058 //dd($item);
1059 if (!$item['bundle_items']) {
1060 return;
1061 }
1062
1063 $total = count($item['bundle_items']);
1064 ?>
1065 <div class="fct-bundle-products" data-fluent-cart-collapsibles>
1066 <h4 class="fct-bundle-products-title">
1067 <?php echo esc_html__('Bundle of', 'fluent-cart') . ':'; ?>
1068 </h4>
1069
1070 <div class="fct-bundle-products-list">
1071 <?php foreach (array_slice($item['bundle_items'], 0, 2) as $bundleItem): ?>
1072 <p>
1073 <?php echo esc_html(Arr::get($bundleItem, 'title', '')); ?>
1074 </p>
1075 <?php endforeach; ?>
1076
1077 <?php if ($total > 2): ?>
1078 <div class="fct-bundle-products-more">
1079 <div class="fct-bundle-products-more-list">
1080 <?php foreach (array_slice($item['bundle_items'], 2) as $bundleItem): ?>
1081 <p>
1082 <?php echo esc_html(Arr::get($bundleItem, 'title', '')); ?>
1083 </p>
1084 <?php endforeach; ?>
1085 </div>
1086 </div>
1087 <?php endif; ?>
1088 </div>
1089
1090 <?php if ($total > 2) : ?>
1091 <a href="#" class="fct-see-more-btn" data-fluent-cart-collapsible-toggle>
1092 <span class="see-more-text">
1093 <?php echo esc_html__('See More', 'fluent-cart'); ?>
1094 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="7" viewBox="0 0 12 7" fill="none">
1095 <path d="M0.75 0.75L5.04289 5.04289C5.37623 5.37623 5.54289 5.54289 5.75 5.54289C5.95711 5.54289 6.12377 5.37623 6.45711 5.04289L10.75 0.75" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
1096 </svg>
1097 </span>
1098
1099 <span class="see-less-text">
1100 <?php echo esc_html__('See Less', 'fluent-cart'); ?>
1101 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="7" viewBox="0 0 14 8" fill="none">
1102 <path d="M0.75 6.54297L6.04289 1.25008C6.37623 0.916742 6.54289 0.750076 6.75 0.750076C6.95711 0.750076 7.12377 0.916742 7.45711 1.25008L12.75 6.54297" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
1103 </svg>
1104 </span>
1105 </a>
1106 <?php endif; ?>
1107 </div>
1108 <?php
1109 }
1110
1111 public function renderTaxSummaryBox()
1112 {
1113 $order = Arr::get($this->config, 'order', null);
1114 $summary = TaxSummaryHelper::computeTaxSummary($order);
1115 if (!$summary['shouldRender']) {
1116 return;
1117 }
1118 ?>
1119 <div class="fct-thank-you-tax-summary">
1120 <div class="fct-thank-you-tax-summary-header">
1121 <span class="fct-thank-you-tax-summary-title">
1122 <?php echo esc_html__('TAX SUMMARY', 'fluent-cart'); ?>
1123 </span>
1124 <span class="fct-item-tax-hint" tabindex="0"
1125 aria-label="<?php echo esc_attr__('Tax breakdown explanation', 'fluent-cart'); ?>">
1126 <span class="fct-item-tax-hint-icon">i</span>
1127 <span class="fct-item-tax-hint-tooltip">
1128 <?php echo esc_html__('Inclusive tax is embedded in item prices. Exclusive tax is added on top.', 'fluent-cart'); ?>
1129 </span>
1130 </span>
1131 </div>
1132
1133 <?php if ($summary['isReverseCharge']): ?>
1134 <?php
1135 $rcReversedTotal = (int) Arr::get($summary, 'reversedTaxTotal', 0);
1136 $rcReversedShipping = (int) Arr::get($summary, 'reversedShippingTax', 0);
1137 $rcReversedValue = $rcReversedTotal > 0
1138 ? Helper::toDecimal($rcReversedTotal)
1139 : __('Charge reversed', 'fluent-cart');
1140 ?>
1141 <?php if ($summary['showRcShippingRow'] && $rcReversedShipping > 0): ?>
1142 <div class="fct-thank-you-tax-summary-row fct-thank-you-tax-summary-row--muted">
1143 <span><?php echo esc_html__('Added on shipping', 'fluent-cart'); ?></span>
1144 <span style="text-decoration:line-through;opacity:0.6;"><?php echo esc_html(Helper::toDecimal($rcReversedShipping)); ?></span>
1145 </div>
1146 <?php endif; ?>
1147 <div class="fct-thank-you-tax-summary-row fct-thank-you-tax-summary-row--total">
1148 <span><?php echo esc_html__('Tax reversed', 'fluent-cart'); ?></span>
1149 <span><?php echo esc_html($rcReversedValue); ?></span>
1150 </div>
1151 <?php else: ?>
1152 <?php
1153 $tyFeeRows = Arr::get($summary, 'feeTaxLineRows', []);
1154 $rowCount = (int) ($summary['inclusiveTax'] > 0) + (int) ($summary['exclusiveTax'] > 0) + count($tyFeeRows) + (int) ($summary['shippingTax'] > 0);
1155 $shouldShowBreakdown = $rowCount >= 2 || ($rowCount === 1 && !($summary['payableTax'] > 0 || $summary['inclusiveTax'] > 0 || (int) Arr::get($summary, 'inclusiveFeeTax', 0) > 0));
1156 ?>
1157 <?php if ($summary['inclusiveTax'] > 0 && $shouldShowBreakdown): ?>
1158 <div class="fct-thank-you-tax-summary-row fct-thank-you-tax-summary-row--muted">
1159 <span><?php echo esc_html__('Included in item prices', 'fluent-cart'); ?></span>
1160 <span><?php echo esc_html(Helper::toDecimal($summary['inclusiveTax'])); ?></span>
1161 </div>
1162 <?php endif; ?>
1163 <?php if ($summary['exclusiveTax'] > 0 && $shouldShowBreakdown): ?>
1164 <div class="fct-thank-you-tax-summary-row">
1165 <span><?php echo esc_html__('Added on products', 'fluent-cart'); ?></span>
1166 <span><?php echo esc_html(Helper::toDecimal($summary['exclusiveTax'])); ?></span>
1167 </div>
1168 <?php endif; ?>
1169 <?php if ($shouldShowBreakdown) : ?>
1170 <?php foreach ($tyFeeRows as $feeRow) : ?>
1171 <div class="fct-thank-you-tax-summary-row<?php echo $feeRow['inclusive'] ? ' fct-thank-you-tax-summary-row--muted' : ''; ?>">
1172 <span><?php echo esc_html($feeRow['display_label']); ?></span>
1173 <span><?php echo esc_html(Helper::toDecimal($feeRow['tax_amount'])); ?></span>
1174 </div>
1175 <?php endforeach; ?>
1176 <?php endif; ?>
1177 <?php if ($summary['shippingTax'] > 0 && $shouldShowBreakdown):
1178 $isShippingInclusive = (bool) Arr::get($summary, 'isShippingInclusive', false);
1179 $shippingTaxLines = Arr::get($summary, 'shippingTaxLines', []);
1180 $shippingRowClass = 'fct-thank-you-tax-summary-row' . ($isShippingInclusive ? ' fct-thank-you-tax-summary-row--muted' : '');
1181 if (!empty($shippingTaxLines)):
1182 foreach ($shippingTaxLines as $shLine): ?>
1183 <div class="<?php echo esc_attr($shippingRowClass); ?>">
1184 <span><?php echo esc_html($shLine['label']); ?></span>
1185 <span><?php echo esc_html(Helper::toDecimal($shLine['shipping_tax'])); ?></span>
1186 </div>
1187 <?php endforeach;
1188 else: ?>
1189 <div class="<?php echo esc_attr($shippingRowClass); ?>">
1190 <span>
1191 <?php if ($isShippingInclusive): ?>
1192 <?php echo esc_html__('Included in shipping prices', 'fluent-cart'); ?>
1193 <?php else: ?>
1194 <?php echo esc_html__('Added on shipping', 'fluent-cart'); ?>
1195 <?php endif; ?>
1196 </span>
1197 <span><?php echo esc_html(Helper::toDecimal($summary['shippingTax'])); ?></span>
1198 </div>
1199 <?php endif; ?>
1200 <?php endif; ?>
1201 <?php if ($summary['payableTax'] > 0): ?>
1202 <div class="fct-thank-you-tax-summary-row fct-thank-you-tax-summary-row--total">
1203 <span><?php echo esc_html__('Total payable tax', 'fluent-cart'); ?></span>
1204 <span><?php echo esc_html(Helper::toDecimal($summary['payableTax'])); ?></span>
1205 </div>
1206 <?php endif; ?>
1207 <?php if ($summary['inclusiveTax'] > 0 || $summary['inclusiveFeeTax'] > 0): ?>
1208 <div class="fct-thank-you-tax-summary-row fct-thank-you-tax-summary-row--muted">
1209 <span><?php echo esc_html__('Total tax in this order', 'fluent-cart'); ?></span>
1210 <span><?php echo esc_html(Helper::toDecimal($summary['totalOrderTax'])); ?></span>
1211 </div>
1212 <?php endif; ?>
1213 <?php endif; ?>
1214 </div>
1215 <?php
1216 }
1217
1218 public function renderItemTaxPill($item, $order)
1219 {
1220 $rates = TaxSummaryHelper::getItemTaxRates($item);
1221 $isReversed = $order->isReverseChargeTaxOrder();
1222 $rcMode = $order->getOrderRcMode();
1223
1224 if (!empty($rates)) {
1225 $this->renderTaxRatePills($rates, $isReversed, $rcMode);
1226 return;
1227 }
1228
1229 // Fallback: existing aggregate pill for old orders without tax_config
1230 $taxAmount = (int) ($item['tax_amount'] ?? 0);
1231 if ($taxAmount <= 0) {
1232 return;
1233 }
1234 $isInclusive = TaxSummaryHelper::isPrimaryTaxInclusive($order);
1235 $pillClass = $isInclusive ? 'fct-tax-pill--inclusive' : 'fct-tax-pill--exclusive';
1236 $reversedClass = ($isReversed && (!$isInclusive || $rcMode === 'dynamic')) ? ' is-reversed' : '';
1237 ?>
1238 <div class="fct-item-tax-pills">
1239 <div class="fct-item-tax-pill-row">
1240 <span class="fct-tax-pill <?php echo esc_attr($pillClass); ?>">
1241 <?php echo $isInclusive ? esc_html__('Incl.', 'fluent-cart') : esc_html__('Add.', 'fluent-cart'); ?>
1242 </span>
1243 <span class="fct-item-tax-pill-amount <?php echo esc_attr(($isInclusive ? 'is-inclusive' : 'is-exclusive') . $reversedClass); ?>">
1244 <?php if ($isInclusive): ?>
1245 <?php echo esc_html__('incl.', 'fluent-cart'); ?> <?php echo esc_html(Helper::toDecimal($taxAmount)); ?>
1246 <?php else: ?>
1247 + <?php echo esc_html(Helper::toDecimal($taxAmount)); ?>
1248 <?php endif; ?>
1249 </span>
1250 </div>
1251 </div>
1252 <?php
1253 }
1254
1255 public function renderItemSetupFeeTaxPills($item, $order)
1256 {
1257 $isSubscription = $item['payment_type'] === 'subscription'
1258 || !empty(Arr::get($item, 'other_info.signup_fee'));
1259
1260 if (!$isSubscription) {
1261 return;
1262 }
1263
1264 $isReversed = $order->isReverseChargeTaxOrder();
1265 $rcMode = $order->getOrderRcMode();
1266 $signupFeeItem = null;
1267 if ($order->order_items) {
1268 $signupFeeItem = $order->order_items
1269 ->where('payment_type', 'signup_fee')
1270 ->where('object_id', $item['object_id'])
1271 ->first();
1272 }
1273
1274 if ($signupFeeItem) {
1275 $rates = TaxSummaryHelper::getItemTaxRates($signupFeeItem->toArray());
1276 if (!empty($rates)) {
1277 $this->renderTaxRatePills($rates, $isReversed, $rcMode);
1278 return;
1279 }
1280 }
1281
1282 $signupFeeTax = (int) Arr::get($item, 'other_info.signup_fee_tax', 0);
1283 if ($signupFeeTax <= 0) {
1284 return;
1285 }
1286 $sfIsInclusive = TaxSummaryHelper::isPrimaryTaxInclusive($order);
1287 $reversedClass = ($isReversed && (!$sfIsInclusive || $rcMode === 'dynamic')) ? ' is-reversed' : '';
1288 ?>
1289 <div class="fct-item-tax-pills">
1290 <div class="fct-item-tax-pill-row">
1291 <span class="fct-item-tax-pill-amount<?php echo esc_attr($reversedClass); ?>"><?php
1292 /* translators: %1$s: formatted setup fee tax amount */
1293 echo sprintf(esc_html__('Setup fee tax: %1$s', 'fluent-cart'), esc_html(Helper::toDecimal($signupFeeTax)));
1294 ?></span>
1295 </div>
1296 </div>
1297 <?php
1298 }
1299
1300 private function renderTaxRatePills(array $rates, bool $isReversed = false, string $rcMode = 'fixed')
1301 {
1302 ?>
1303 <div class="fct-item-tax-pills">
1304 <?php foreach ($rates as $rate) : ?>
1305 <?php
1306 $pillClass = $rate['inclusive'] ? 'fct-tax-pill--inclusive' : 'fct-tax-pill--exclusive';
1307 $percent = rtrim(rtrim(number_format($rate['rate_percent'], 3, '.', ''), '0'), '.');
1308 $rateIsInclusive = !empty($rate['inclusive']);
1309 $rateReversedClass = ($isReversed && (!$rateIsInclusive || $rcMode === 'dynamic')) ? ' is-reversed' : '';
1310 ?>
1311 <div class="fct-item-tax-pill-row">
1312 <span class="fct-tax-pill <?php echo esc_attr($pillClass); ?>">
1313 <?php echo esc_html($rate['label']) . ' (' . esc_html($percent) . '%)'; ?>
1314 </span>
1315 <span class="fct-item-tax-pill-amount <?php echo esc_attr(($rate['inclusive'] ? 'is-inclusive' : 'is-exclusive') . $rateReversedClass); ?>">
1316 <?php if ($rate['inclusive']): ?>
1317 <?php echo esc_html__('incl.', 'fluent-cart'); ?> <?php echo esc_html(Helper::toDecimal($rate['tax_amount'])); ?>
1318 <?php else: ?>
1319 + <?php echo esc_html(Helper::toDecimal($rate['tax_amount'])); ?>
1320 <?php endif; ?>
1321 </span>
1322 </div>
1323 <?php endforeach; ?>
1324 </div>
1325 <?php
1326 }
1327
1328 }
1329