7 dk

Çoklu-döviz abonelik faturaları: uyumlu yuvarlama kuralları

Çoklu-döviz abonelik faturaları: web, mobil ve muhasebe dışa aktarımlarında toplamların tutarlı kalması için pratik yuvarlama ve minimal tablo yaklaşımları.

Çoklu-döviz abonelik faturaları: uyumlu yuvarlama kuralları

Abonelik faturalarının sistemler arasında neden kaydığı

Yaygın bir baş ağrısı: web ödeme sayfası bir toplam gösterir, mobil uygulama hafifçe farklı bir toplam gösterir ve muhasebe dışa aktarımı üçüncü bir sayıya düşer. Her sistem "mantıklı" bir matematik yapıyor ama aynı matematiği uygulamıyor.

Abonelikler bu durumu daha da kötüleştirir çünkü hesaplamayı tekrar tekrar yaparsınız. Küçük farklar yenilemelerde, birisi dönemde yükseltme yaptığında proration, kredi ve iadeler, başarısız ödemeler sonrası yeniden denemeler ve planın başındaki veya sonundaki kısmi dönemlerde bile üst üste birikir.

Sürüklenme genellikle küçük tercihlerin görünmez kaldığı bir noktadan başlar: ne zaman yuvarlanacak (satır başı mı yoksa sonunda mı), hangi vergi tabanı kullanılacak (net mi yoksa brüt mü), 0 veya 3 ondalıklı küçük birimlere sahip para birimleri nasıl ele alınacak ve hangi FX oranı uygulanacak (hangi zaman damgası, hangi sağlayıcı, hangi hassasiyet). Eğer web satır başına 2 ondalık yuvarluyor ve mobil sadece son toplamı yuvarlıyorsa, aynı girdilerle bile 0.01 fark alabilirsiniz.

Hedef sıkıcı ama önemli: aynı fatura ID ve versiyonu için her yerde aynı toplamların üretilmesi. Bu müşterileri sakin tutar, destek taleplerini azaltır ve denetimlerde işe yarar.

"Tutarlı" demek, belirli bir fatura ID ve versiyon için:

  • Para birimi ve küçük birim kuralları web, mobil ve dışa aktarımlarda aynı.
  • Vergi yöntemi eşleşiyor (verginin satır başına mı yoksa fatura düzeyinde mi yuvarlandığı dahil).
  • Yuvarlama ve kalan birimlerin ele alınması sabit ve tekrarlanabilir.
  • Kullanılan herhangi bir FX oranı faturaya sabitlenmiş (oran, hassasiyet ve geçerli zaman).

Örnek: bir müşteri EUR 19.99'dan EUR 29.99'a ay ortasında yükseltiyor, prorata bir ücret oluşuyor, sonra kesinti için küçük bir kredi. Bir sistem her prorata satırını yuvarluyor, başka bir sistem sadece nihai toplamı yuvarluyorsa, dışa aktarılan fatura müşterinin gördüğüyle uyuşmaz; her sayı "yeterince yakın" görünse bile.

Temeller: para birimi, küçük birimler, net-vergi-brüt

FX oranları veya vergi yuvarlama kuralları hakkında tartışmaya girmeden önce temelleri kilitleyin. Bunlar belirsizse faturalar web uygulamanız, mobil uygulamanız ve muhasebe dışa aktarımlarınız arasında kayar.

Her fatura satırı ve fatura toplamı açıkça üç tutar taşımalı: net (vergi öncesi), vergi ve brüt (net + vergi). Depolama ve hesaplama için birini kaynak olarak seçin, sonra diğerlerini her yerde aynı şekilde türetin. Birçok ekip net ve vergiyi saklar, sonra brütü net + vergi olarak hesaplar çünkü bu denetimler ve iadeler için daha uygundur.

Hangi para biriminde olduğunuzu açıkça belirtin. Ekipler genellikle üç farklı fikri karıştırır:

  • Fatura para birimi: faturada basılı yasal para birimi ve toplamlar için kullanılan para birimi.
  • Müşteri görüntüleme para birimi: birisi planlara bakarken UI'de gösterdiğiniz para birimi.
  • Tahsilat/settlement para birimi: ödeme işlemcisinin banka hesabınıza yatırdığı para birimi.

Bunlar aynı olabilir ama olmak zorunda değildir. Faturanız EUR ise ama kart USD olarak tahsil ediyorsa, fatura yine EUR'de tutarlı olmalı, banka yatırımı farklı olsa bile.

Son olarak, parayı küçük birimlerde tam sayı olarak ele alın (örneğin kuruş). 9.99'u kayan nokta olarak saklamak, özellikle vergi, indirim, prorata veya birden fazla öğe eklediğinizde 9.989999 tarzı sorunlar yaratmanın yaygın yoludur. 9.99'u 999 (kuruş) olarak para birimi koduyla saklayın ve yalnızca görüntüleme için formatlayın.

Fiyat vergilendirme modunuzu da belirleyin:

  • Vergi hariç: fiyat nettir, vergi üzerine eklenir.
  • Vergi dahili: fiyat zaten vergiyi içerir, dolayısıyla net vergi çıkarılarak elde edilir.

Somut bir kontrol: 10.00 (vergi dahil, %20 KDV) olarak gösterilen bir plan, web ve mobilde aynı saklanan brütü (minör birimlerde) üretmeli ve net ile vergiyi ortak bir kuralla türetmelidir.

FX oranları: farkların genelde başladığı yer

FX farkları genellikle vergi ve yuvarlama kurallarından önce başlar. İki sistem de "doğru" olabilir ama farklı kaynaklar, farklı zaman damgaları veya farklı hassasiyetler kullandıkları için uyuşmazlık çıkar.

Oran sağlayıcıları nadiren birebir eşleşir. Bazıları mid-market oranı verir, bazıları spread içerir. Bazıları dakikada günceller, bazıları saatlik veya günlük. Aynı sağlayıcı kullanılsa bile bir sistem oranı 4 ondalığa yuvarlarken diğer 8+ ondalık tutabilir; bu, abonelik tutarları ve vergilerle çarpınca toplamları değiştirir.

En önemli karar oran zaman damgasının ne anlama geldiğidir. Eğer ücret EUR cinsinden kesiliyorsa ama müşteri USD ile ödeme yapıyorsa, FX oranını faturanın düzenlendiği anda mı yoksa ödemenin alındığı anda mı kilitleyeceksiniz? Her iki yaklaşım da yaygındır, ama web, mobil ve muhasebe dışa aktarımlarında karıştırmak uyuşmazlık garantiler.

Bir kural seçtikten sonra kullandığınız kesin oranı faturaya kaydedin. Daha sonra "güncel" oranlardan yeniden hesaplama yapmayın, hatta tarihsel oranlara bakabiliyor olsanız bile. Sağlayıcı düzeltmeleri, saat dilimi farklılıkları ve küçük hassasiyet değişiklikleri eski faturaların dışa aktarılmasında sapmaya yol açar.

Basit bir örnek: faturayı 23:59'da düzenlediniz, ama ödeme 00:02'de başarılı oldu. Bu zaman damgaları genelde sağlayıcı için farklı günlere düşer, bu yüzden günlük oran tablosu farklı sayılar üretebilir.

Belirleyip belgeleyin:

  • Sağlayıcı ve teklif türü (mid-market vs ücretleri içeriyor)
  • Zaman damgası kuralı (düzenleme zamanı vs yakalama zamanı) ve saat dilimi
  • Oran için saklanan hassasiyet (örneğin 8 ondalık)
  • Yuvarlama noktası (dönüştürülmüş satır tutarlarını mı yuvarlarsınız yoksa sadece nihai toplamı mı)

Önceden ele alınması gereken özel durumlar: sıfır-ondalık para birimleri (ör. JPY), çok yüksek hassasiyetli oranlar ve iadeler. İadeler genelde orijinal faturanın saklanan FX oranını yeniden kullanmalıdır. Aksi takdirde iade tutarı müşterinin beklediğinden ve muhasebe dışa aktarımınızın gösterdiğinden farklı olabilir.

Hala işe yarayan minimal bir fatura veri modeli

Faturaların web, mobil ve muhasebe dışa aktarımlarında eşleşmesini istiyorsanız, veri modeliniz yalnızca girdileri değil sonuçları saklamalı. Amaç basit: aynı fatura her yerde aynı minör birimleri render etsin, aylar sonra bile.

Küçük bir varlık seti genellikle yeterlidir:

  • Subscription: customer_id, plan_id, billing_currency, billing_interval, next_renewal_at, status
  • Invoice: invoice_id, customer_id, subscription_id, issued_at, period_start, period_end, status (draft/final), currency, fx_rate_id (or provider), fx_rate_value, rounding_mode, totals (net_minor, tax_minor, gross_minor)
  • Invoice_line: invoice_id, description, quantity, unit_price_minor, line_net_minor, line_tax_minor, line_gross_minor, tax_rate_id (or tax_code)
  • Payment: invoice_id, paid_at, amount_minor, currency, provider, provider_payment_id, status

Ana kural: para alanları minör birimlerde tamsayı olmalı. Hem birim fiyatı hem de hesaplanmış satır toplamlarını saklayın. Bu, daha sonra farklı bir yuvarlama kuralıyla veya farklı bir FX kaynağıyla yeniden hesaplama yapılmasını engeller.

FX, faturada yakalanmalıdır, çıkarılmamalıdır. Ortak bir FX tablosu saklasanız bile fatura, finalize edildiği anda kullanılan kesin fx_rate_value'yi (ve nereden geldiğini) tutmalıdır ki dışa aktarımlar aynı sayıları yeniden üretebilsin.

Tek bir faturada birden fazla vergi oranı veya yargı varsa (örneğin karışık ürünler, AB KDV + yerel vergi veya adres tabanlı vergi değişiklikleri) ayrı bir vergi dökümü tablosuna ihtiyacınız olabilir. Bu durumda vergiye tabi taban ve vergi tutarı için her vergi oranı başına bir satır saklayın.

Son olarak, finalize edilmiş bir faturayı değişmez (immutable) olarak ele alın. Fatura finalize edildiği anda hesaplanan değerlerin bir anlık görüntüsünü kaydedin ve daha sonra toplamları tekrar hesaplamayın. Bu tek seçim, çoğu "kuruş neden değişti?" hatasını ortadan kaldırır.

Bir yuvarlama stratejisi seçin ve ona bağlı kalın

Export and customize your billing code
Own the full source so you can extend invoice logic and keep it consistent.

Yuvarlama bir matematik detayı değildir. Ürün kuralıdır. Web uygulamanız bir şekilde yuvarlıyorsa, mobil başka bir şekilde ve muhasebe dışa aktarımı üçüncü bir şekilde yuvarlıyorsa, girdiler aynı görünse bile farklı toplamlar alırsınız.

Üç yaygın strateji vardır ve bunlar minör birimleri "kilitlediğiniz" adımda farklılık gösterir:

  • Birim başına yuvarlama: her birim fiyatını yuvarlayın (indirimler, FX, vergi mantığından sonra) sonra miktarla çarpın.
  • Satır başına yuvarlama: tam satır tutarını hesaplayın, sonra satır başına bir kez yuvarlayın.
  • Fatura toplamında yuvarlama: tüm satırlar için tam hassasiyeti tutun, sonra yalnızca nihai fatura toplamlarını yuvarlayın.

Abonelikler için iyi bir varsayılan satır başına yuvarlamadır. Müşteriler için öngörülebilirdir (her satır doğru görünür), denetimi kolaydır (her satır toplamını açıklayabilirsiniz) ve yenilemelerde kararlıdır. Birim başına yuvarlama miktar değiştiğinde veya UI'de birim fiyatlarını gösterdiğinizde sapma yaratabilir. Sadece fatura toplamında yuvarlama genellikle "bu satır toplamları neden tutmuyor?" destek biletleri yaratır çünkü görünen satır toplamları gösterilen toplamla uyuşmayabilir.

Klasik kuruş problemi, çok küçük öğeler veya kesirli vergiler olduğunda ortaya çıkar. Örnek: 20 satır her biri 0.004 yuvarlama kalıntısı üretiyorsa, satır başına yuvarlama ile sadece toplamda 0.08 fark oluşabilir. FX dönüşümlerinde bu küçük kalıntılar daha sık ortaya çıkar ve dışa aktarımlarda ile gelir raporlarında zamanla birikebilir.

Ne seçerseniz seçin, deterministik olsun. Aynı girdiler her zaman aynı çıktıları üretmeli:

  • Aynı hassasiyet kurallarını kullanın (para birimi minör birimleri, vergi ondalık yerleri, FX hassasiyeti).
  • Yuvarlamayı aynı adımda ve aynı sırayla uygulayın (birim, satır veya toplam).
  • Aynı bağ-kesme (tie-break) kuralını kullanın (örneğin half-up vs half-even) her yerde.

Hem web hem de mobil faturalama akışları inşa ediyorsanız, yuvarlama kuralını UI davranışı olarak değil test edilebilir bir spes olarak yazın.

Adım adım: toplamları tekrarlanabilir şekilde hesaplama

Web, mobil ve muhasebe dışa aktarımlarında aynı sayıları tutmak için hesaplamayı bir tarif gibi ele alın. Ana fikir: yüksek hassasiyetle hesaplayın, ama faturada yalnızca o para biriminin minör birimlerindeki tam sayıları saklayın.

Tekrarlanabilir bir tarif

  1. Her satır öğe net tutarıyla başlayın, yüksek hassasiyette tutun. Miktarla çarparken, indirim uygularken ve (gerekirse) para birimini dönüştürürken ekstra ondalıkları koruyun. Sonra seçtiğiniz kurala göre faturanın para biriminin minör birimlerine bir kez yuvarlayın. Bu tamsayıyı satır neti olarak saklayın.

  2. Vergiyi saklanan satır netten hesaplayın (veya kurallarınız izin veriyorsa bir vergi grup ara toplamından). Aynı yuvarlama kuralını uygulayın ve vergiyi minör birimlerde tamsayı olarak saklayın. İşte sistemlerin genelde kaydığı yer: bir taraf vergiyi önce yuvarlarken, diğer taraf sonra yuvarlar.

  3. Her satır brütünü (saklanan net + saklanan vergi) olarak hesaplayın. Fatura toplamları saklanan minörlerin toplamıdır. Görüntüleme için toplamları kayan noktayla yeniden hesaplamayın. Görünümler ve dışa aktarımlar saklanan tamsayıları okumalı ve formatlamalıdır.

  4. Yerel kurallar fatura düzeyinde vergi toplamları gerektiriyorsa, bir kalan dağıtmanız gerekebilir. Örnek: üç satır her biri 0.01 vergi üretiyorsa toplam 0.03 eder, ama fatura düzeyinde yuvarlama 0.02 diyorsa deterministik bir tie-break belirleyin (örneğin en büyük vergiye sahip satırdan başlayarak 1 minör birim ekle veya çıkar, sonra satır id ile stabil sırala). Bu düzeltmeyi etkilenmiş satırlarda küçük bir vergi düzeltmesi olarak saklayın ki her sistem bunu yeniden üretebilsin.

  5. Faturayı kilitleyin. Nihai yuvarlama ve kalan dağıtımından sonra faturayı değişmez kabul edin. Abonelik fiyatı sonra değişirse yeni bir fatura veya kredi notu oluşturun, eski sayıları asla yeniden yazmayın.

Somut bir kontrol: eğer EUR 9.99 plan %19 KDV içeriyorsa, saklanan netiniz 999 kuruş, vergi 190 kuruş, brüt 1189 kuruş olabilir. Her istemci bu saklanan tamsayılardan 11.89 EUR render etmelidir, KDV'yi yeniden hesaplayarak değil.

Vergi yuvarlama: satır başı vs fatura düzeyi ve kalan dağıtımı

Vergi yuvarlama, doğru matematiğin fatura uyuşmazlıklarına dönüştüğü yerdir. Sorunun özü basit: daha erken yuvarlama final toplamı değiştirir.

Eğer vergi satır başı (veya miktar başı) yuvarlanır, sonra toplanırsa, yuvarlanmamış verginin fatura düzeyinde toplanıp bir kez yuvarlanmasıyla farklı bir toplam elde edebilirsiniz. Çok sayıda satırda farklar birikir, özellikle minör birimler ve FX dönüşümleri zaten küçük kesirler üretiyorsa.

Somut örnek (2 ondalık): iki satırın her biri vergilendirilebilir 0.05 ve vergi %10. Satır başı için yuvarlanmamış vergi 0.005. Eğer satır başı yuvarlarsanız her biri 0.01 olur ve toplam vergi 0.02'dir. Eğer fatura seviyesinde yuvarlarsanız, toplam vergi mat. 0.01 olur. Her ikisi de savunulabilir ama uyuşmazlar.

Satır başı vergiyi göstermeniz ama aynı zamanda fatura toplamının tam eşleşmesini sağlamanız gerekirse, kalan yuvarlamayı deterministik olarak tahsis edin:

  • Satır başına yuvarlanmamış vergiyi hesaplayın, sonra her satırı aşağı yuvarlayın.
  • Bu yuvarlanmış-aşağı vergileri toplayın ve hedef vergi (fatura seviyesinde yuvarlanmış toplam) ile karşılaştırın.
  • Kalan minör birimleri en büyük kesirsel parça olan satırlara öncelik vererek dağıtın.
  • Bağlarda tutarlı şekilde kırılım yapın (örneğin: satır pozisyonu, sonra stabil satır id).
  • Dağıtımı UI sıralamasına göre değiştirmeyin.

Muhasebe satırları gruplarken (ürün, vergi oranı veya yargı bazında) dışa aktarımlar yine de kayabilir. Eşleşmeleri korumak için gereken grup içinde kalanları önce dağıtın, sonra grup toplamlarının fatura vergi ve brütüne yuvarladığını doğrulayın.

Muhasebe bir vergi split'i (oran veya yargı bazında) istiyorsa ama UI tek bir vergi sayısı gösteriyorsa, yine de dökümü saklayın (oran veya yargı başına ara toplamlar ve denetime uygun bir tahsis kuralı). UI tek bir toplam gösterebilir, dışa aktarımlar detaylı kovalar taşıyabilir ama fatura grand total değişmemelidir.

Karar vermeniz gereken köşe durumları

Offset costs with earned credits
Get credits by sharing what you built or inviting teammates to try Koder.ai.

Çoğu fatura uyuşmazlığı köşe durumlarda olur. Kuralları erken karar verin, sürpriz kalmaz.

Sıfır-ondalık para birimleri özel dikkat ister. JPY ve KRW'nin minör birimi yoktur, bu yüzden "kuruş" varsayan herhangi bir adım sessizce farklar yaratır. Her istemcinin aynı para birimi ayarlarını kullandığından emin olun: satır başı mı, vergi düzeyinde mi yoksa sadece nihai toplamda mı yuvarlama yapılacağı gibi.

Sınır ötesi KDV veya GST, vergi oranını müşteri konumuna ve kabul ettiğiniz kanıtlara (fatura adresi, IP, vergi kimliği) göre değiştirebilir. Zor kısım oran değil, onu ne zaman kilitlediğinizdir. Zaman noktasını seçin (checkout, fatura düzenleme tarihi veya hizmet dönemi başlangıcı) ve ona sadık kalın.

Prorasyon, kesirlerin çoğaldığı yerdir. Ay ortasında yükseltme, günde 9.3333... gibi tutarlar yaratabilir. Önce net mi prorate edeceğinize, brüt mü yoksa hizmet periyodu mu önce hesaplanacağına karar verin; işlemlerin sırasını değiştirmek son minör birimi değiştirir.

Bu kuralları yazılı hale getirin:

  • Sıfır-ondalık para birimi işlemi: yuvarlama yöntemi ve hangi adımda uygulandığı.
  • Konuma bağlı vergi: oranı hangi alanların ve hangi zamanın belirlediği ve ne zaman dondurulduğu.
  • Prorasyon matematiği: esas (gün, saniye, sabit 30 günlük ay) ve yuvarlama noktaları.
  • İndirimler ve krediler: vergiye tabi tabanı azaltıp azaltmadığı ve satır başına mı yoksa fatura düzeyinde mi uygulandığı.
  • İade simetrisi: iadeler orijinal satır tutarlarını ve vergiyi yeniden oluşturmalı, bugünkü oranlarla yeniden hesaplama yapmamalıdır.

İadeler son tuzaktır. Orijinal faturada 0.01 kalan birim bir satıra atanmışsa, iade bu aynı tahsisi tersine çevirmelidir. Aksi halde müşteri bir toplam görür, muhasebe defteriniz başka bir toplam; uyumsuzluk ortaya çıkar.

Pratik bir uygulama olarak her faturayla birlikte açık bir hesaplama anlık görüntüsü saklayın: para birimi, minör birim hassasiyeti, yuvarlama modu, FX oranı ve zaman damgası, ve finalize edilmiş satır minörleri.

Uyuşmaz faturalara yol açan yaygın hatalar

Çoğu fatura uyuşmazlığı "zor matematik"ten kaynaklanmaz. Farklı yığın parçalarında yapılan küçük, tutarsız seçimlerden gelir.

Büyük hatalardan biri parayı kayan noktayla saklamaktır. 19.99 gibi bir değer birçok sistemde tam temsil edilemez, bu yüzden satırları toplarken, indirim uygularken veya vergi hesaplanırken küçük hatalar birikir. Tutarları minör birimlerde tam sayı olarak saklayın, para birimi kodu ve minör birim ölçeğiyle birlikte.

Bir diğer yaygın sorun dışa aktarım sırasında FX'i yeniden hesaplamaktır. Müşteri belirli bir orana göre ödeme yaptı. Muhasebe dışa aktarımı "bugünün" oranını alırsa, her adım doğru olsa bile farklı bir toplam çıkabilir. Faturayı bir anlık görüntü olarak görün: kullanılan FX oranını, dönüştürülmüş tutarları ve yuvarlama sonuçlarını saklayın.

Yuvarlama farkları ayrıca UI ve backend'in farklı aşamalarda yuvarlamasından ortaya çıkar. Örneğin backend vergiyi satır başı yuvarlarken, web UI yalnızca fatura toplamında yuvarlayabilir. İkisi de makul görünebilir ama uyuşmazlık olur.

Beş tekrar eden suçlu çoğu boşluğu açıklar:

  • Fiyatları, vergileri, indirimleri veya FX dönüşümlerini float ile saklamak
  • Dışa aktarım sırasında FX'i yeniden hesaplamak yerine saklanan fatura değerlerini kullanmamak
  • UI'da ve backend'de vergiyi farklı şekillerde yuvarlamak
  • Aynı faturada vergi-dahil ve vergi-haric mantığını karıştırmak
  • Mobilin kendi matematiğini uygulamasına izin verip backend toplamlarını render ettirmemek

Hızlı bir gerçek kontrol: mobil uygulama EUR 9.99 olan üç öğeyi %20 vergiyle gösteriyorsa ve uygulama vergiyi sonda yuvarluyorsa ama backend satır başına yuvarlıyorsa, EUR 0.01 fark çıkabilir. O tek kuruş uzlaştırmayı bozmak ve destek taleplerini tetiklemek için yeterlidir.

En basit çözüm sıkıcı ama etkili: hesaplamayı backend'de bir kez yapın, tam fatura anlık görüntüsünü saklayın ve web ile mobil bu saklanan sayıları tam olarak render etsin.

Tutarlı faturalar için hızlı kontrol listesi

Handle proration without penny drift
Add proration, credits, and refunds that mirror the original line amounts exactly.

Web uygulamanız, mobil uygulamanız ve muhasebe dışa aktarımınız arasında sayılar farklıysa, genellikle sorun matematik değil saklama ve yuvarlama pratiğidir.

Temel ilke: istemciler faturanın sakladığını göstermeli, yeniden hesaplama yapmamalıdır. Backend tek kaynak olmalı ve her kanal aynı saklanan değerleri okumalıdır.

Çoğu uyuşmazlığı önleyen beş kontrol

  • Her satır tutarını minör birimlerde saklayın ve fatura toplamlarının saklanan satır minörlerinin toplamına eşit olduğundan emin olun. Web veya mobilin birim fiyatlardan toplamları yeniden hesaplamasına izin vermeyin.
  • Kullandığınız kesin FX oranını (ve ne zaman kullanıldığını) kaydedin. Faturayı yeniden oluşturduğunuzda saklanan oranı yeniden kullanın, yeni bir oran değil.
  • Bir yuvarlama kuralı yazın (nerede yuvarlanacağı ve nasıl) ve bunu her yerde uygulayın: backend hesaplamaları, mobil render, PDF üretimi ve muhasebe dışa aktarımları.
  • Vergi uzlaştırmasını kanıtlanabilir yapın: saklanan vergi tutarlarının toplamı (satır bazlı veya fatura bazlı hangi yöntemi seçtiyseniz) her zaman fatura vergi toplamına eşit olmalı.
  • Bir round-trip testi çalıştırın: fatura verilerini dışa aktarın, sonra geri içe aktarın ve toplamların ile vergilerin minör birimler dahil tam olarak eşleştiğini doğrulayın.

İadeleri ve kredileri unutmayın

İadeler ve kredi notları orijinal faturanın yuvarlama çıktısını yansıtmalıdır. Orijinal fatura satır başı vergi yuvarlama yaptıysa, iade de aynı şekilde yapmalı, aynı para birimi hassasiyeti ve saklanan FX oranını kullanmalıdır. Aksi halde küçük kalanlar zamanla toplanır.

Bunu zorunlu kılmanın pratik yolu: her faturayla birlikte açık bir hesaplama anlık görüntüsü saklayın: para birimi, minör birim hassasiyeti, yuvarlama modu, FX oranı ve zaman damgası, ve finalize edilmiş satır minörleri.

Örnek: web, mobil ve dışa aktarımlarda eşleşen bir fatura

İşte her yerde tutarlı kalan bir fatura örneği.

Faturanın EUR (2 ondalık) cinsinden düzenlendiğini, KDV'nin %20 olduğunu ve müşterinin USD ile tahsil edildiğini varsayalım. Backend bir FX anlık görüntüsü saklar: 1 EUR = 1.0857 USD.

ItemNet (EUR)
Pro plan (monthly)19.99
Extra seats10.00
Discount (10% of 29.99, rounded)-3.00

Net total (EUR) = 26.99

VAT 20% (EUR) = 5.40 (çünkü 26.99 x 0.20 = 5.398, 5.40 olarak yuvarlandı)

Gross total (EUR) = 32.39

Şimdi backend saklanan EUR toplamlarından charge para birimi tutarlarını saklanan FX anlık görüntüsünden türetir:

  • Gross (USD) = 32.39 x 1.0857 = 35.17
  • Net (USD) = 26.99 x 1.0857 = 29.30
  • VAT (USD) = 5.40 x 1.0857 = 5.86

Eğer ayrıca satır başına USD değerlerini de saklıyorsanız, her dönüştürülmüş satırı yuvarlayıp topladığınızda genelde 0.01 fark oluşur. Faturaların genelde kaydığı yer burasıdır.

Bunu deterministik yapın: her satırı dönüştürüp yuvarlayın, sonra per-line toplamların zaten sabitlenmiş gross USD toplamına eşit olması için kalan kuruşları (pozitif veya negatif) sabit bir sırayla (örneğin line_id artan) dağıtın.

Web ve mobil backend'de saklanan satır toplamlarını, vergi toplamlarını, FX oranını ve brütü yeniden hesaplamamalı; bunları direkt göstermeğe karşılık render etmelidir. Muhasebe dışa aktarımı aynı saklanan sayıları ve FX anlık görüntüsünü (oran, zaman damgası veya kaynak) çıkarmalı ki defterler müşterinin gördüğüyle eşleşsin.

Pratik bir sonraki adım, hesaplamayı tek bir paylaşılan servis olarak uygulayıp tek bir fatura anlık görüntüsü (satırlar, vergiler, toplamlar, FX, yuvarlama düzeltmeleri) üreten bir yapı kurmaktır ve her kanal bunun üzerinden render yapsın. Eğer bu akışları Koder.ai (koder.ai) üzerinde inşa ediyorsanız, bu anlık görüntü modelini merkezde tutmak web, mobil ve dışa aktarımların aynı saklanan değerlere ulaşmasını sağlayarak hizalamayı kolaylaştırır.

SSS

Why does the same subscription show different totals on web, mobile, and accounting exports?

Çünkü her sistem genellikle ne zaman yuvarlama yapacağı, neyi yuvarlayacağı (net vs. brüt) ve vergi ile döviz (FX) için hangi hassasiyeti tutacağı konusunda biraz farklı seçimler yapar. Bu küçük farklar, özellikle proration, kredi ve yeniden denemeler tekrarlandıkça 0.01–0.02 gibi farklara yol açar.

Should I store money as floats or integers?

Tutarları kesirli birimlerde (örneğin kuruş) yani tam sayılar olarak saklayın ve yalnızca görüntüleme için formatlayın. Ondalık kayan nokta (float) değerler birçok ondalığı tam olarak temsil edemez; bu da satır toplamları, indirimler veya vergi hesaplandığında küçük hatalar biriktirir.

Which amounts should an invoice store: net, tax, or gross?

Birini kaynak olarak saklayın ve diğerlerini her yerde aynı şekilde türetin. Yaygın bir varsayılan, geri ödemeleri ve denetimleri kolaylaştırdığı için net ve tax (vergi) değerlerini kuruş gibi minör birimlerde saklamak ve gross = net + tax şeklinde brütü hesaplamaktır.

What’s the difference between invoice currency, display currency, and settlement currency?

Fatura para birimi, fatura toplamlarının yasal olarak ifade edildiği para birimidir ve uzlaştırma için ona bakmalısınız. Görüntüleme para birimi, fiyatlara göz atarken gösterdiğiniz şeydir. Settlement (tahsilat) para birimi ise ödeme sağlayıcısının banka hesabınıza yatırdığı para birimidir; bunlar farklı olabilir, ama fatura para birimi tutarlı olmalıdır.

How do I prevent FX rates from changing old invoices?

Dışa aktarım veya PDF yeniden oluşturma sırasında oranları yeniden almayın. Faturada kullanılan kesin FX oranını (değer, hassasiyet, sağlayıcı ve etkili zaman) saklayın ve her zaman onu kullanın ki eski faturalar aylar sonra aynı sayıları üretsin.

Should FX be locked at invoice issue time or payment capture time?

Bir kural belirleyin ve ona sadık kalın: ya “fatura düzenlendiği andaki oran” ya da “ödeme yakalandığı andaki oran”. Sistemlerde farklı zaman damgalarını karıştırmak, özellikle gece yarısı veya saat dilimi sınırlarında, uyuşmazlıklara yol açar.

What rounding strategy is safest for subscriptions?

Abonelik faturaları için güvenli bir varsayılan, satır başına yuvarlamadır (round per line). Satır başına yuvarlama genellikle müşteriler için tahmin edilebilirdir, açıklaması kolaydır ve her kanal aynı kuralı kullanırsa yenilemelerde istikrarlı kalır.

How do I handle tax rounding without getting mismatched totals?

Vergi yuvarlamasında satır başı ile fatura düzeyinde yuvarlama arasında seçim yapın ve bunu deterministik hale getirin. Fatura düzeyine uyum sağlamak gerekiyorsa, kalan kuruşları sabit bir yöntemle dağıtın ve sonuçta oluşan satır başı vergi tutarlarını saklayın ki her sistem aynı sonucu gösterebilsin.

Why does proration cause so many “penny” differences, and how do I stop them?

Prorasyon, günlük veya periyodik oranlardan tekrarlayan ondalıklar üretir; bu yüzden işlem sırası önemlidir. Bir yöntemi seçin (örneğin önce net’i prorate etmek, sonra vergiyi net’ten hesaplamak), hangi adımda yuvarlama yapılacağını belirleyin ve son satır minör birimlerini finalize edip saklayın ki yükseltme/düşürme ve iade işlemleri orijinal matematiği yansıtsın.

What’s the simplest architecture to keep invoices consistent across all clients?

Backend'in tek bir finalize edilmiş fatura anlık görüntüsü üretmesi (satırlar, vergiler, toplamlar, para birimi minör birim kuralları, FX anlık görüntüsü, yuvarlama modu) ve bunun finalize edildikten sonra değişmez (immutable) kabul edilmesi en basit ve güvenilir yaklaşımdır. Web, mobil, PDF ve dışa aktarımlar bu saklı tam sayıları okumalı, yeniden hesaplama yapmamalıdır; bu yöntem Koder.ai ile faturalama akışları oluştururken de işe yarar.

Related posts