diff --git a/app/controllers/api/v1/invoices_controller.rb b/app/controllers/api/v1/invoices_controller.rb
index 2381f0fdd97..23e4976b65f 100644
--- a/app/controllers/api/v1/invoices_controller.rb
+++ b/app/controllers/api/v1/invoices_controller.rb
@@ -202,6 +202,31 @@ def sync_salesforce_id
         end
       end
 
+      def preview
+        result = Invoices::PreviewContextService.call(
+          organization: current_organization,
+          params: preview_params.to_h.deep_symbolize_keys
+        )
+        return render_error_response(result) unless result.success?
+
+        result = Invoices::PreviewService.call(
+          customer: result.customer,
+          subscription: result.subscription,
+          applied_coupons: result.applied_coupons
+        )
+        if result.success?
+          render(
+            json: ::V1::InvoiceSerializer.new(
+              result.invoice,
+              root_name: 'invoice',
+              includes: %i[customer integration_customers credits applied_taxes preview_subscriptions preview_fees]
+            )
+          )
+        else
+          render_error_response(result)
+        end
+      end
+
       private
 
       def create_params
@@ -234,6 +259,44 @@ def update_params
         )
       end
 
+      def preview_params
+        params.permit(
+          :plan_code,
+          :billing_time,
+          :subscription_at,
+          coupons: [
+            :code,
+            :name,
+            :coupon_type,
+            :amount_cents,
+            :amount_currency,
+            :percentage_rate,
+            :frequency,
+            :frequency_duration,
+            :frequency_duration_remaining
+          ],
+          customer: [
+            :external_id,
+            :name,
+            :tax_identification_number,
+            :currency,
+            :timezone,
+            shipping_address: [
+              :address_line1,
+              :address_line2,
+              :city,
+              :zipcode,
+              :state,
+              :country
+            ],
+            integration_customers: [
+              :integration_type,
+              :integration_code
+            ]
+          ]
+        )
+      end
+
       def sync_salesforce_id_params
         params.permit(
           :external_id,
diff --git a/app/serializers/v1/invoice_serializer.rb b/app/serializers/v1/invoice_serializer.rb
index f2f26044180..0481196cde6 100644
--- a/app/serializers/v1/invoice_serializer.rb
+++ b/app/serializers/v1/invoice_serializer.rb
@@ -42,6 +42,8 @@ def serialize
       payload.merge!(error_details) if include?(:error_details)
       payload.merge!(applied_usage_thresholds) if model.progressive_billing?
       payload.merge!(applied_invoice_custom_sections) if include?(:applied_invoice_custom_sections)
+      payload.merge!(preview_subscriptions) if include?(:preview_subscriptions)
+      payload.merge!(preview_fees) if include?(:preview_fees)
 
       payload
     end
@@ -63,6 +65,12 @@ def subscriptions
       ).serialize
     end
 
+    def preview_subscriptions
+      ::CollectionSerializer.new(
+        model.subscriptions, ::V1::SubscriptionSerializer, collection_name: 'subscriptions'
+      ).serialize
+    end
+
     def fees
       ::CollectionSerializer.new(
         model.fees.includes(
@@ -80,6 +88,12 @@ def fees
       ).serialize
     end
 
+    def preview_fees
+      ::CollectionSerializer.new(
+        model.fees, ::V1::FeeSerializer, collection_name: 'fees'
+      ).serialize
+    end
+
     def credits
       ::CollectionSerializer.new(model.credits, ::V1::CreditSerializer, collection_name: 'credits').serialize
     end
diff --git a/app/serializers/v1/invoices/applied_tax_serializer.rb b/app/serializers/v1/invoices/applied_tax_serializer.rb
index dced172d0ea..234c4d51d23 100644
--- a/app/serializers/v1/invoices/applied_tax_serializer.rb
+++ b/app/serializers/v1/invoices/applied_tax_serializer.rb
@@ -15,7 +15,7 @@ def serialize
           amount_cents: model.amount_cents,
           amount_currency: model.amount_currency,
           fees_amount_cents: model.fees_amount_cents,
-          created_at: model.created_at.iso8601
+          created_at: model&.created_at&.iso8601
         }
       end
     end
diff --git a/app/services/coupons/preview_service.rb b/app/services/coupons/preview_service.rb
index 251ed673a9b..1a385787dce 100644
--- a/app/services/coupons/preview_service.rb
+++ b/app/services/coupons/preview_service.rb
@@ -17,7 +17,7 @@ def call
 
       applied_coupons.each do |applied_coupon|
         break unless invoice.sub_total_excluding_taxes_amount_cents&.positive?
-        next unless invoice.currency == applied_coupon.amount_currency
+        next if applied_coupon.coupon.fixed_amount? && invoice.currency != applied_coupon.amount_currency
 
         fees = fees(applied_coupon)
 
diff --git a/app/services/invoices/preview_context_service.rb b/app/services/invoices/preview_context_service.rb
index 8612d8b4aba..e1141b25451 100644
--- a/app/services/invoices/preview_context_service.rb
+++ b/app/services/invoices/preview_context_service.rb
@@ -34,6 +34,7 @@ def find_or_build_customer
           organization: organization,
           tax_identification_number: customer_params[:tax_identification_number],
           currency: customer_params[:currency],
+          timezone: customer_params[:timezone],
           shipping_address_line1: customer_params.dig(:shipping_address, :address_line1),
           shipping_address_line2: customer_params.dig(:shipping_address, :address_line2),
           shipping_city: customer_params.dig(:shipping_address, :city),
@@ -73,7 +74,7 @@ def build_subscription
         subscription_at: params[:subscription_at].presence || Time.current,
         started_at: params[:subscription_at].presence || Time.current,
         billing_time:,
-        created_at: Time.current,
+        created_at: params[:subscription_at].presence || Time.current,
         updated_at: Time.current
       )
     end
@@ -94,6 +95,7 @@ def find_or_build_applied_coupons
         coupon || Coupon.new(coupon_attr)
       end.map do |coupon|
         AppliedCoupon.new(
+          id: SecureRandom.uuid,
           coupon:,
           customer: result.customer,
           amount_cents: coupon.amount_cents,
diff --git a/app/services/invoices/preview_service.rb b/app/services/invoices/preview_service.rb
index e569bba352a..cbfd19db496 100644
--- a/app/services/invoices/preview_service.rb
+++ b/app/services/invoices/preview_service.rb
@@ -33,6 +33,7 @@ def call
       compute_tax_and_totals
 
       result.invoice = invoice
+      result.subscription = subscription
       result
     end
 
@@ -56,8 +57,9 @@ def date_service
 
     def billing_time
       return @billing_time if defined? @billing_time
+      return subscription.subscription_at if subscription.plan.pay_in_advance?
 
-      ds = Subscriptions::DatesService.new_instance(subscription, Time.current, current_usage: true)
+      ds = Subscriptions::DatesService.new_instance(subscription, subscription.subscription_at, current_usage: true)
 
       @billing_time = ds.end_of_period + 1.day
     end
diff --git a/config/routes.rb b/config/routes.rb
index 10be88c1c3a..31452f1c346 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -61,6 +61,7 @@
         post :retry, on: :member
         post :retry_payment, on: :member
         post :payment_url, on: :member
+        post :preview, on: :collection
         put :refresh, on: :member
         put :finalize, on: :member
         put :sync_salesforce_id, on: :member
diff --git a/spec/requests/api/v1/invoices_controller_spec.rb b/spec/requests/api/v1/invoices_controller_spec.rb
index b73d8400bdf..0545713af05 100644
--- a/spec/requests/api/v1/invoices_controller_spec.rb
+++ b/spec/requests/api/v1/invoices_controller_spec.rb
@@ -1008,4 +1008,50 @@
       end
     end
   end
+
+  describe 'POST /api/v1/invoices/preview' do
+    subject { post_with_token(organization, '/api/v1/invoices/preview', preview_params) }
+
+    let(:plan) { create(:plan, organization:) }
+    let(:preview_params) do
+      {
+        customer: {
+          name: 'test 1',
+          currency: 'EUR',
+          tax_identification_number: '123456789'
+        },
+        plan_code: plan.code,
+        billing_time: 'anniversary'
+      }
+    end
+
+    it 'creates a preview invoice' do
+      subject
+
+      expect(response).to have_http_status(:success)
+      expect(json[:invoice]).to include(
+        invoice_type: 'subscription',
+        fees_amount_cents: 100,
+        taxes_amount_cents: 20,
+        total_amount_cents: 120,
+        currency: 'EUR'
+      )
+    end
+
+    context 'when customer does not exist' do
+      let(:preview_params) do
+        {
+          customer: {
+            external_id: 'unknown'
+          },
+          plan_code: plan.code
+        }
+      end
+
+      it 'returns a not found error' do
+        subject
+        expect(response).to have_http_status(:not_found)
+      end
+    end
+  end
 end
diff --git a/spec/services/invoices/preview_service_spec.rb b/spec/services/invoices/preview_service_spec.rb
index 153396471ac..5fa383b9250 100644
--- a/spec/services/invoices/preview_service_spec.rb
+++ b/spec/services/invoices/preview_service_spec.rb
@@ -64,6 +64,38 @@
         end
       end
 
+      context 'with in advance billing in the future' do
+        let(:plan) { create(:plan, organization:, interval: 'monthly', pay_in_advance: true) }
+        let(:subscription) do
+          build(
+            :subscription,
+            customer:,
+            plan:,
+            billing_time:,
+            subscription_at: timestamp + 1.day,
+            started_at: timestamp + 1.day,
+            created_at: timestamp + 1.day
+          )
+        end
+
+        it 'creates preview invoice for 1 day' do
+          travel_to(timestamp) do
+            result = preview_service.call
+
+            expect(result).to be_success
+            expect(result.invoice.subscriptions.first).to eq(subscription)
+            expect(result.invoice.fees.length).to eq(1)
+            expect(result.invoice.invoice_type).to eq('subscription')
+            expect(result.invoice.issuing_date.to_s).to eq('2024-03-31')
+            expect(result.invoice.fees_amount_cents).to eq(3)
+            expect(result.invoice.sub_total_excluding_taxes_amount_cents).to eq(3)
+            expect(result.invoice.taxes_amount_cents).to eq(2)
+            expect(result.invoice.sub_total_including_taxes_amount_cents).to eq(5)
+            expect(result.invoice.total_amount_cents).to eq(5)
+          end
+        end
+      end
+
       context 'with applied coupons' do
         let(:applied_coupon) do
           build(