config = $config; $this->is_first_time = Arr::get($this->config, 'is_first_time', false); $this->order_operation = Arr::get($this->config, 'order_operation', false); $this->settings = new StoreSettings(); AssetLoader::enqueueThankYouPageAssets(); } private function getMemoizedTaxSummary($order) { if (!$order) { return TaxSummaryHelper::computeTaxSummary($order); } $id = (int) $order->id; if (!isset($this->fctTaxSummaryCache[$id])) { $this->fctTaxSummaryCache[$id] = TaxSummaryHelper::computeTaxSummary($order); } return $this->fctTaxSummaryCache[$id]; } public function renderWrapperStart() { ?>
config, 'order', null); if (!$order) { return; } ?> renderWrapperStart(); } ?> config); ?> renderHeader(); ?> config); ?> config); ?> renderBody(); ?> config); ?> renderWrapperEnd(); } ?> renderFooter(); do_action('fluent_cart/after_receipt', [ 'order' => $order, 'is_first_time' => $this->is_first_time ?? false, 'order_operation' => $this->order_operation ?? null ]); if (!empty($this->is_first_time)) { do_action('fluent_cart/after_receipt_first_time', [ 'order' => $order, 'order_operation' => $this->order_operation ?? null ]); } } protected function getHeaderState() { $order = Arr::get($this->config, 'order', null); $status = $order ? $order->payment_status : ''; if ($status === Status::PAYMENT_REFUNDED) { return 'refunded'; } if ($status === Status::PAYMENT_FAILED) { return 'failed'; } if (in_array($status, [Status::PAYMENT_PAID, Status::PAYMENT_PARTIALLY_REFUNDED], true)) { return 'success'; } return 'pending'; } public function renderHeader() { $state = $this->getHeaderState(); $styles = [ 'success' => ['bg' => '#d4edda', 'title' => '#155724', 'iconBg' => '#155724bd'], 'pending' => ['bg' => '#fff3cd', 'title' => '#856404', 'iconBg' => '#856404bd'], 'failed' => ['bg' => '#f8d7da', 'title' => '#721c24', 'iconBg' => '#721c24bd'], 'refunded' => ['bg' => '#e2e3e5', 'title' => '#383d41', 'iconBg' => '#383d41bd'], ]; $titles = [ 'success' => __('Purchase Successful!', 'fluent-cart'), 'pending' => __('Payment Pending!', 'fluent-cart'), 'failed' => __('Payment Failed', 'fluent-cart'), 'refunded' => __('Order Refunded', 'fluent-cart'), ]; $bgColor = $styles[$state]['bg']; $titleColor = $styles[$state]['title']; $iconBg = $styles[$state]['iconBg']; ?>

config); ?>
config, 'order', null); if (!$order) { return; } ?>
config); ?> renderOrderHeader(); ?> config); ?> renderStoreTaxInformation(); ?> config); ?> renderOrderItems(); ?> config); ?> renderSubscriptionItems(); ?> renderDownloads(); ?> renderLicenses(); ?> renderAddress(); ?> renderThankYouPageInstructions(); ?>
config, 'order', null); $profilePage = $this->settings->getCustomerProfilePage(); ?>
customer->full_name) ); ?>
getHeaderState(); ?>

#%s%s', esc_html__('Your order ', 'fluent-cart'), esc_url($profilePage . 'order/' . $order->uuid), esc_html($order->invoice_no), esc_html__(' has been placed successfully.', 'fluent-cart') ); ?>

#%s%s', esc_html__('Your order ', 'fluent-cart'), esc_url($profilePage . 'order/' . $order->uuid), esc_html($order->invoice_no), esc_html__(' has been refunded.', 'fluent-cart') ); ?>

#%s%s %s.', esc_html__('The payment for your order ', 'fluent-cart'), esc_url($profilePage . 'order/' . $order->uuid), esc_html($order->invoice_no), esc_html__(' could not be completed. You can try again from', 'fluent-cart'), esc_url(\FluentCart\App\Services\Payments\PaymentHelper::getCustomPaymentLink($order->uuid)), esc_html__('here', 'fluent-cart') ); ?>

%s %s %s.', esc_url($profilePage . 'order/' . $order->uuid), esc_html__('Your order', 'fluent-cart'), esc_html__('has payment due. You can pay from', 'fluent-cart'), esc_url(\FluentCart\App\Services\Payments\PaymentHelper::getCustomPaymentLink($order->uuid)), esc_html__('here', 'fluent-cart') ); ?>

config, 'order', null); $orderTaxRates = $order->getPrimaryOrderTaxRate(); if ($order->tax_total > 0 || $orderTaxRates): ?>
meta, 'store_vat_number', ''); $taxcountry = Arr::get($orderTaxRates->meta ?? [], 'tax_country', ''); if ($storeVatNumber !== '') { echo '

' . esc_html(TaxModule::getCountryTaxTitle($taxcountry)) . ': ' . esc_html($storeVatNumber) . '

'; } } ?>
config, 'order', null); if ($order->order_items) : ?>
renderOrderItemsHeader(); ?> renderOrderItemsBody(); ?>
config, 'order', null); $fctTaxDisplayMode = TaxSummaryHelper::getTaxDisplayMode(); ?>
loadMissing(['order_items']); $orderItems = $order->getProductItems()->toArray(); $orderItems = $this->buildBundleItemsTree($orderItems); foreach ($orderItems as $item) : ?>

1): ?> x

-

renderBundleProducts($item); ?>
renderItemTaxPill($item, $order); ?>
renderItemSetupFeeTaxPills($item, $order); ?>
renderOrderTotal(); ?> renderTaxNote(); ?>
config, 'order', null); if (!$order) { return; } $transaction = $order->getLatestTransaction(); $methodSlug = ''; $thankYouPageInstructions = ''; if ($transaction && !empty($transaction->payment_method)) { $methodSlug = $transaction->payment_method; } if (GatewayManager::has($methodSlug)) { $gatewayInstance = GatewayManager::getInstance($methodSlug); if ($gatewayInstance && isset($gatewayInstance->settings)) { $gatewaySettings = (array) $gatewayInstance->settings->get(); $thankYouPageInstructions = Arr::get($gatewaySettings, 'thank_you_page_instructions', ''); } } if (!empty($thankYouPageInstructions)) : ?>
renderSubtotal(); ?> renderDiscount(); ?> renderShipping(); ?> renderFees(); ?> renderTaxSummaryBox(); ?> renderProrateCredit(); ?> renderRefund(); ?> renderTotal(); ?> renderPaymentMethod(); ?>
config, 'order', null); if ($order->isReverseChargeTaxOrder()): ?>
config, 'order', null); if ($order->subtotal != $order->total_amount || $order->tax_total > 0): ?>
subtotal)); ?>
config, 'order', null); $prorateCredit = (int) Arr::get($order->config, 'prorate_credit', 0); $upgradeDiscount = $order->manual_discount_total - $prorateCredit; // When the prorate credit IS the whole discount, label the row directly // instead of showing "Discount" with a single redundant breakdown row. $onlyProrateCredit = $prorateCredit > 0 && $upgradeDiscount <= 0 && $order->coupon_discount_total <= 0; if ($order->manual_discount_total + $order->coupon_discount_total > 0): ?>
- manual_discount_total + $order->coupon_discount_total)); ?>
0 && $upgradeDiscount > 0): ?>
0 && !$onlyProrateCredit): ?>
config, 'order', null); if ($order->shipping_total <= 0) { return; } $displayShipping = (int) $order->shipping_total; if ($order->isReverseChargeTaxOrder()) { $rcAdj = (int) Arr::get($this->getMemoizedTaxSummary($order), 'rcShippingAdjustment', 0); if ($rcAdj > 0) { $displayShipping = max(0, $displayShipping - $rcAdj); } } $shippingMethodTitle = (string) Arr::get($order->config, 'shipping_method_title', ''); ?>
config, 'order', null); if (!$order || $order->fee_total <= 0) { return; } $feeItems = $order->feeItems()->get(); foreach ($feeItems as $feeItem): ?>
title); ?>
subtotal)); ?>
config, 'order', null); if ($order->total_refund > 0): ?>
- total_refund)); ?>
config, 'order', null); $displayTotal = (int) $order->total_amount - (int) $order->total_refund; if ($order->isReverseChargeTaxOrder()) { $rcAdj = (int) Arr::get($this->getMemoizedTaxSummary($order), 'rcTotalAdjustment', 0); if ($rcAdj > 0) { $displayTotal = max(0, $displayTotal - $rcAdj); } } ?>
config, 'order', null); $transaction = $order->getLatestTransaction(); ?>
card_last_4) : echo esc_html($transaction->card_brand) . ' ' . esc_html($transaction->card_last_4); else: $title = $transaction->payment_method; $gateway = GatewayManager::getInstance($transaction->payment_method); $title = $gateway ? $gateway->getMeta('title') : $title; echo esc_html($title); endif; ?>
config, 'order', null); $subscriptions = $order->subscriptions; if ($subscriptions->count() == 0) { return; } ?>

render('invoice.parts.subscription_items', [ // 'subscriptions' => $order->subscriptions, // 'order' => $order // ]); } public function renderDownloads() { $order = Arr::get($this->config, 'order', null); $downloads = $order->getDownloads(); if (!$downloads) { return; } ?>

renderDownloadsNotice(); ?> config, 'order', null); $licenses = $order->getLicenses(); if (!$licenses || $licenses->count() == 0) { return; } ?>

renderLicenseNotice(); ?> config, 'order', null); ?>
renderBillToAddress(); ?> fulfillment_type === 'physical') : ?> renderShipToAddress(); ?>
config, 'order', null); ?>
billing_address)) : ?>
billing_address->getAddressAsText()); ?>
customer->email); ?>
customer->full_name); ?>
customer->email); ?>
billing_address->meta ?? [], 'other_data.phone', ''); if ($phoneNumber !== ''): ?>
billing_address ? Arr::get($order->billing_address->meta ?? [], 'other_data.company_name', '') : ''; if ($companyName === '') { $companyName = $order->getCustomerTaxName(); } if ($companyName !== ''): ?>
billing_address ? Arr::get($order->billing_address->meta ?? [], 'other_data.legal_registration_id', '') : ''; if ($legalRegId === '') { $legalRegId = Arr::get($order->getBusinessInfo(), 'legal_registration_id', ''); } if ($legalRegId !== ''): ?>
getCustomerTaxNumber(); if ($vatNumber !== '') { $vatLabel = __('VAT/Tax ID', 'fluent-cart'); echo esc_html($vatLabel) . ': ' . esc_html($vatNumber); } ?>
getBusinessInfo(), 'reverse_charge_declaration', ''); if ($reverseChargeDeclaration !== ''): ?>
:
config, 'order', null); ?>
shipping_address)) : ?>
shipping_address->getAddressAsText()); ?>
shipping_address->meta ?? [], 'other_data.phone', ''); if ($phone !== ''):?>
customer->full_name); ?>
customer->email); ?>
config, 'order', null); $profilePage = $this->settings->getCustomerProfilePage(); ?> config, 'order', null); ?> $children) { if (isset($parents[$parentId])) { $parents[$parentId]['bundle_items'] = $children; } } // Re-index a final array return array_values($parents); } public function renderBundleProducts($item) { //dd($item); if (!$item['bundle_items']) { return; } $total = count($item['bundle_items']); ?>

2): ?>

2) : ?>
config, 'order', null); $summary = $this->getMemoizedTaxSummary($order); if (!$summary['shouldRender']) { return; } $tyIsSimplified = (($summary['displayMode'] ?? '') === 'simplified') && !empty($summary['simpleLine']); if ($tyIsSimplified) : ?>
▾
renderTaxBreakdownCardInner($summary); ?>
renderTaxBreakdownCardInner($summary); ?>
i
0 ? Helper::toDecimal($rcReversedTotal) : __('Charge reversed', 'fluent-cart'); ?>
0): ?>
0 && $tyIncludedInPrices > 0): ?>
0): ?>
0) + (int) ($summary['exclusiveTax'] > 0); $rowCount = $productTaxRowCount + count($tyFeeRows) + (int) ($summary['shippingTax'] > 0); $shouldShowBreakdown = !empty($taxRateLines) || !empty($shippingTaxLines) || $rowCount >= 2 || ($rowCount === 1 && !($summary['payableTax'] > 0 || $summary['inclusiveTax'] > 0 || (int) Arr::get($summary, 'inclusiveFeeTax', 0) > 0)); ?>
0 && $shouldShowBreakdown): ?>
0 && $shouldShowBreakdown): ?>
0 && $shouldShowBreakdown): $isShippingInclusive = (bool) Arr::get($summary, 'isShippingInclusive', false); $shippingRowClass = 'fct-thank-you-tax-summary-row' . ($isShippingInclusive ? ' fct-thank-you-tax-summary-row--muted' : ''); if (!empty($shippingTaxLines)): foreach ($shippingTaxLines as $shLine): ?>
0): ?>
0 || $summary['inclusiveFeeTax'] > 0): ?>
isReverseChargeTaxOrder(); $rcMode = $order->getOrderRcMode(); if (!empty($rates)) { $this->renderTaxRatePills($rates, $isReversed, $rcMode); return; } // Fallback: existing aggregate pill for old orders without tax_config $taxAmount = (int) ($item['tax_amount'] ?? 0); if ($taxAmount <= 0) { return; } $isInclusive = TaxSummaryHelper::isPrimaryTaxInclusive($order); $pillClass = $isInclusive ? 'fct-tax-pill--inclusive' : 'fct-tax-pill--exclusive'; $reversedClass = ($isReversed && (!$isInclusive || $rcMode === 'dynamic')) ? ' is-reversed' : ''; ?>
+
isReverseChargeTaxOrder(); $rcMode = $order->getOrderRcMode(); $signupFeeItem = null; if ($order->order_items) { $signupFeeItem = $order->order_items ->where('payment_type', 'signup_fee') ->where('object_id', $item['object_id']) ->first(); } if ($signupFeeItem) { $rates = TaxSummaryHelper::getItemTaxRates($signupFeeItem->toArray()); if (!empty($rates)) { $this->renderTaxRatePills($rates, $isReversed, $rcMode); return; } } $signupFeeTax = (int) Arr::get($item, 'other_info.signup_fee_tax', 0); if ($signupFeeTax <= 0) { return; } $sfIsInclusive = TaxSummaryHelper::isPrimaryTaxInclusive($order); $reversedClass = ($isReversed && (!$sfIsInclusive || $rcMode === 'dynamic')) ? ' is-reversed' : ''; ?>
+