<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: hyunjun12312</title>
    <description>The latest articles on DEV Community by hyunjun12312 (@hyunjun12312).</description>
    <link>https://dev.to/hyunjun12312</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4060900%2F83d2f087-e3dd-48e7-a005-3e5ef75f6ac8.png</url>
      <title>DEV Community: hyunjun12312</title>
      <link>https://dev.to/hyunjun12312</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hyunjun12312"/>
    <language>en</language>
    <item>
      <title>Why Steam Market fee calculators should use integer minor units</title>
      <dc:creator>hyunjun12312</dc:creator>
      <pubDate>Mon, 03 Aug 2026 15:04:58 +0000</pubDate>
      <link>https://dev.to/hyunjun12312/why-steam-market-fee-calculators-should-use-integer-minor-units-1be5</link>
      <guid>https://dev.to/hyunjun12312/why-steam-market-fee-calculators-should-use-integer-minor-units-1be5</guid>
      <description>&lt;p&gt;A fee calculator looks simple until the displayed total differs from the marketplace by one cent. The usual cause is not the percentage itself. It is the order of operations, minimum component fees, and rounding.&lt;/p&gt;

&lt;p&gt;I built a small, dependency-free calculator to make those decisions visible and testable. The implementation works in integer minor units instead of floating-point currency values.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with floating-point money
&lt;/h2&gt;

&lt;p&gt;Code such as this is tempting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sellerAmount&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But binary floating-point values do not represent every decimal amount exactly. Formatting the final number can hide that problem without fixing the intermediate calculations.&lt;/p&gt;

&lt;p&gt;The safer approach is to convert a displayed value into the currency's smallest configured unit and keep all fee calculations as integers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sellerReceives&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// cents&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;steamRate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;publisherRate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each fee component is calculated separately because each component can have its own minimum and rounding rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  Forward and reverse calculations are different
&lt;/h2&gt;

&lt;p&gt;There are two useful questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If the seller should receive a specific amount, what should the buyer pay?&lt;/li&gt;
&lt;li&gt;If the buyer pays a fixed displayed price, what can the seller receive?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first direction can add calculated fee components to the seller amount. The reverse direction is less convenient because rounding makes a closed-form percentage division unreliable near boundaries.&lt;/p&gt;

&lt;p&gt;The calculator solves the reverse direction with an integer binary search. It finds the greatest seller amount whose computed buyer price does not exceed the requested buyer price. This keeps the result deterministic and avoids loops over every possible cent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make assumptions configurable
&lt;/h2&gt;

&lt;p&gt;The open-source implementation includes configurable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;marketplace fee rate;&lt;/li&gt;
&lt;li&gt;publisher fee rate;&lt;/li&gt;
&lt;li&gt;minimum fee for each component;&lt;/li&gt;
&lt;li&gt;integer rounding behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Its defaults model the common 5% marketplace fee plus 10% publisher fee example in USD cents. Those are defaults, not a promise that every game, currency, region, tax situation, or future Steam rule behaves identically.&lt;/p&gt;

&lt;p&gt;You can inspect the code and tests in the &lt;a href="https://github.com/hyunjun12312/steam-market-fee-calculator" rel="noopener noreferrer"&gt;Steam Market fee calculator repository&lt;/a&gt;. A browser version is also available as a &lt;a href="https://steamvaults.org/tools/steam-market-fee-calculator" rel="noopener noreferrer"&gt;localized Steam Market fee calculator&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests matter at the boundaries
&lt;/h2&gt;

&lt;p&gt;Percentage examples in the middle of a price range rarely reveal mistakes. Better tests include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the smallest permitted seller amount;&lt;/li&gt;
&lt;li&gt;a price where a component minimum starts or stops applying;&lt;/li&gt;
&lt;li&gt;a value immediately before and after a rounding boundary;&lt;/li&gt;
&lt;li&gt;a game configured with no publisher fee;&lt;/li&gt;
&lt;li&gt;invalid and negative input;&lt;/li&gt;
&lt;li&gt;forward and reverse results for the same displayed total.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project currently includes automated tests for the common fee example, reverse calculation, minimum component fees, invalid input, and a zero-publisher-fee configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical limitation
&lt;/h2&gt;

&lt;p&gt;This remains an estimate. Steam can change fee rules, publisher fees, minimums, currency increments, regional handling, and taxes. The amount shown by Steam immediately before a listing is submitted should remain the final source of truth.&lt;/p&gt;

&lt;p&gt;The project is independent and is not affiliated with Valve or Steam. Its main purpose is to make the calculation logic auditable instead of hiding it behind a single percentage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related live service
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://steamvaults.org/" rel="noopener noreferrer"&gt;SteamVaults&lt;/a&gt; is an independent third-party service currently focused only on buying and selling Mann Co. Supply Crate Keys with USDT. The live transaction service and this general-purpose fee calculator are separate.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>javascript</category>
      <category>gamedev</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
