<?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: Stanislav</title>
    <description>The latest articles on DEV Community by Stanislav (@smilesk).</description>
    <link>https://dev.to/smilesk</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%2F4089712%2Fda664508-b26c-49e2-8015-7cd45e28a690.jpg</url>
      <title>DEV Community: Stanislav</title>
      <link>https://dev.to/smilesk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/smilesk"/>
    <language>en</language>
    <item>
      <title>From Screwdrivers to Python: How a Storage Array Made Me a Developer</title>
      <dc:creator>Stanislav</dc:creator>
      <pubDate>Mon, 24 Aug 2026 21:47:40 +0000</pubDate>
      <link>https://dev.to/smilesk/from-screwdrivers-to-python-how-a-storage-array-made-me-a-developer-3192</link>
      <guid>https://dev.to/smilesk/from-screwdrivers-to-python-how-a-storage-array-made-me-a-developer-3192</guid>
      <description>&lt;p&gt;I'm the person you call when a server is physically broken. My toolbox has a screwdriver, spare RAM, a bootable USB with memtest, and zero textbooks on algorithms. I never planned to become a developer. For a long time, I wasn't one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5xmpc9rb1j8l0eiidz9v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5xmpc9rb1j8l0eiidz9v.jpg" alt="System administrator writing code on a laptop in a server room, racks of servers with blinking LEDs behind him — a sysadmin who became a developer through automation" width="800" height="447"&gt;&lt;/a&gt;&lt;br&gt;
Then two storage arrays changed my career without asking for permission.&lt;/p&gt;
&lt;h2&gt;
  
  
  Level 1: tech support and the psexec years
&lt;/h2&gt;

&lt;p&gt;I started in the IT department of one of the largest retail companies in Ukraine. Thousands of employees, hundreds of stores, and a constant stream of tickets like "install Chrome on 40 PCs by Friday".&lt;/p&gt;

&lt;p&gt;When you do the same thing 40 times, you learn the first rule of IT: &lt;strong&gt;the machine will not judge your laziness.&lt;/strong&gt; So I wrote my first script — a &lt;code&gt;foreach&lt;/code&gt; loop over &lt;code&gt;psexec&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$computers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Get-Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;\pcs.txt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kr"&gt;foreach&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$pc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$computers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;psexec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;\\&lt;/span&gt;&lt;span class="nv"&gt;$pc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;msiexec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"\\fileserver\apps\chrome.msi"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/quiet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/norestart&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;-s&lt;/code&gt; runs as SYSTEM. &lt;code&gt;-d&lt;/code&gt; doesn't wait. It was ugly, it was glorious, and it turned a three-hour Friday into a ten-minute coffee break. I was hooked.&lt;/p&gt;

&lt;p&gt;Then came Active Directory utilities: creating users in bulk, group membership, password resets, reports. PowerShell got an &lt;code&gt;ActiveDirectory&lt;/code&gt; module. Python started showing up too — for parsing CSV exports, generating logins, renaming files. Nothing academic. Every script was born from "I refuse to click this 200 times."&lt;/p&gt;

&lt;p&gt;I didn't learn programming. I learned it by accident, one ugly script at a time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 2: hardware, SAN, and the wall of text
&lt;/h2&gt;

&lt;p&gt;Eventually I moved from tech support to hardware and infrastructure: racks, fiber optics, servers, storage. That's where the fun ended.&lt;/p&gt;

&lt;p&gt;The company had two NetApp clusters — C400 and C800. And the vendor's answer to everything was: "Use the CLI."&lt;/p&gt;

&lt;p&gt;The CLI is fine. The problem is the &lt;em&gt;commands&lt;/em&gt;. Creating one volume looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;volume create -vserver svm0 -volume ORACLE_DATA_01 -aggregate C400_02_01_SSD_CAP_1
  -size 500GB -security-style ntfs -autosize-mode off -snapshot-policy none
  -percent-snapshot-space 0 -qos-policy-group qos-gold-svm0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's one line. For one volume. Now do it 30 times, and each time pray you didn't typo the aggregate name — because a volume on the wrong aggregate is a ticket, a rollback, and a very long evening.&lt;/p&gt;

&lt;p&gt;QoS policies were fun too: bronze, silver, gold, platinum, vip — each with its own IOPS limit you had to remember. Gold is 10k IOPs, platinum is 20k, and "vip" is unlimited, obviously.&lt;/p&gt;

&lt;p&gt;I typed these commands often enough to hate them. And one day I caught myself thinking: &lt;em&gt;the web UI is painful, the CLI is dangerous, and I'm the only one who can read this wall of text. What if I build a form?&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 3: the NetApp utility — PowerShell edition
&lt;/h2&gt;

&lt;p&gt;So I built a Windows tool: a form with tabs — "Create Volume", "Create LUN", "Map LUN", "Show LUN". Radio buttons for aggregates and QoS policies, so nobody has to remember that platinum is 937.5 Mb/s. It connected to the cluster over SSH and sent the commands.&lt;/p&gt;

&lt;p&gt;The first version was PowerShell with WinForms. If you've ever built a GUI in PowerShell, you know the pain: &lt;code&gt;New-Object System.Windows.Forms.Label&lt;/code&gt;, coordinates by hand, and a base64-encoded logo bigger than your script.&lt;/p&gt;

&lt;p&gt;The interesting part was the SSH interaction. NetApp doesn't have a friendly API in this scenario — you open a shell and &lt;em&gt;read the output&lt;/em&gt;. The trick: wait for a success marker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;send-commands&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="kr"&gt;param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$Command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$Stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$Prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;$Timeout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$Command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$found&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$Prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;New-TimeSpan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Seconds&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$Timeout&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="c"&gt;# $Prompt = 'Successful'            for volume create&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="c"&gt;# $Prompt = 'Created a LUN of size' for lun create&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;volume create&lt;/code&gt; answers with &lt;code&gt;Successful&lt;/code&gt;. &lt;code&gt;lun create&lt;/code&gt; answers with &lt;code&gt;Created a LUN of size&lt;/code&gt;. You wait for the marker, you read the output, you move on. It's &lt;code&gt;expect&lt;/code&gt; from 1991, but it works — and it's still how I do it today.&lt;/p&gt;

&lt;p&gt;The tool worked. Colleagues started using it. The wall of text became a form, and the form became a habit.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bugs that taught me more than any course
&lt;/h2&gt;

&lt;p&gt;This is where I realized I was actually &lt;em&gt;programming&lt;/em&gt; now — because real programs have real bugs, and real bugs teach you things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bug 1: the +3% quirk.&lt;/strong&gt; Our process required volumes to be created with a 3% size buffer. &lt;code&gt;100GB&lt;/code&gt; → &lt;code&gt;103GB&lt;/code&gt;. The original script did &lt;code&gt;100 + 100 * 0.03 = 103.0&lt;/code&gt; — but ONTAP's &lt;code&gt;-size&lt;/code&gt; only accepts integers. &lt;code&gt;33GB&lt;/code&gt; became &lt;code&gt;33.99GB&lt;/code&gt;, and the array politely refused. The fix: &lt;code&gt;math.ceil(33 * 1.03) = 34&lt;/code&gt;. I learned about integer math not from a textbook — from a storage array that doesn't do fractions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bug 2: names.&lt;/strong&gt; What makes a valid volume name? I read the NetApp KB instead of guessing: starts with a Latin letter, then letters/digits/underscores, no hyphens, no spaces, max 203 characters. That became a regex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;_NAME_RE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^[A-Za-z][A-Za-z0-9_]{2,202}$&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Bug 3: the false failure.&lt;/strong&gt; The first backend gave up after one second of silence from the array. On slow storage the command was still running — but the tool already reported failure. Users don't trust a tool that lies. The fix: wait for the marker until the 30-second deadline, and only use the "silence" heuristic for commands where output &lt;em&gt;is&lt;/em&gt; the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;deadline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;
&lt;span class="nb"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
&lt;span class="n"&gt;matched&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;deadline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv_ready&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="nb"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;65535&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;replace&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;expect&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;expect&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;matched&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;expect&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&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="n"&gt;success&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matched&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;expect&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Bug 4: my own reference code was wrong.&lt;/strong&gt; The original scripts had the LUN mapping fields swapped: the volume name went into &lt;code&gt;-lun&lt;/code&gt; and the LUN name into &lt;code&gt;-volume&lt;/code&gt;. It "worked" for years only because both names were usually identical. When I rewrote the tool, I fixed it — and documented why it was a deliberate divergence from the reference.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rewrite: PowerShell → Python
&lt;/h2&gt;

&lt;p&gt;The PowerShell version did its job. But I wanted a real app: dark theme, three languages (UA/RU/EN), validation before the command ever touches the array, credentials that live only in memory.&lt;/p&gt;

&lt;p&gt;So I rewrote it in Python with PySide6 and paramiko. One SSH session for the whole app instead of a new one per click. A fake backend so you can test the UI without a real cluster. An exe that runs on any Windows machine without Python installed.&lt;/p&gt;

&lt;p&gt;The funniest part: a QA audit of the first version found one critical bug — the false failure I described above — plus a pile of notes. I was no longer a sysadmin with a script. I had a codebase, a changelog, and tests. Somewhere along the way, without a single CS course, I had become a developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell my old self
&lt;/h2&gt;

&lt;p&gt;Sysadmins make great developers — probably better than most bootcamp grads, and I say that as someone who has been both:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;You already know the problem domain.&lt;/strong&gt; Nobody needs to explain to you what a LUN is, why storage matters, or why your users are angry. Half of software engineering is understanding the problem; you've been living inside it for years.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real pain beats tutorials.&lt;/strong&gt; Every script I wrote was a tool I actually needed. Motivation on demand — you can't buy that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The machine will not judge your laziness.&lt;/strong&gt; Automate the boring stuff. That itch you feel when you type the same command for the 40th time? That's your brain telling you to write code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You don't need permission.&lt;/strong&gt; Nobody asked me to build the NetApp utility. I built it because I was annoyed. That's a legitimate engineering process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Today the little utility is still used in production. It has a changelog with bug numbers, a test suite, and a QA report. And I'm writing this article — not because I'm a developer now, but because I finally admitted it.&lt;/p&gt;

&lt;p&gt;If you're a sysadmin reading this: that long command you keep pasting? Build a form around it. It'll take you a weekend, it'll save you a year, and it might just change your career.&lt;/p&gt;

</description>
      <category>sysadmin</category>
      <category>python</category>
      <category>career</category>
      <category>automation</category>
    </item>
    <item>
      <title>Accept USDT in Telegram bots with 0% fees, no KYC — in 10 minutes</title>
      <dc:creator>Stanislav</dc:creator>
      <pubDate>Sat, 22 Aug 2026 14:07:04 +0000</pubDate>
      <link>https://dev.to/smilesk/accept-usdt-in-telegram-bots-with-0-fees-no-kyc-in-10-minutes-5gcb</link>
      <guid>https://dev.to/smilesk/accept-usdt-in-telegram-bots-with-0-fees-no-kyc-in-10-minutes-5gcb</guid>
      <description>&lt;h1&gt;
  
  
  Accept USDT in Telegram bots with 0% fees, no KYC — in 10 minutes
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv4gprqyxzkq28zddc1h4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv4gprqyxzkq28zddc1h4.png" alt="CleanTrade — non-custodial USDT TRC20 payment gateway, 0% fees, no KYC" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you run a Telegram bot that sells anything — subscriptions, digital goods, services — you've hit the same wall: Stripe and PayPal ban crypto and bot-related businesses, classic crypto gateways take a percentage of every payment and hold your funds until payout, and KYC verification takes days.&lt;/p&gt;

&lt;p&gt;There is a simpler way: &lt;strong&gt;a non-custodial USDT (TRC20) payment gateway with a flat subscription fee and 0% per-transaction fees.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this tutorial you'll build a Telegram bot that accepts USDT payments end-to-end in about 10 minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  The idea: non-custodial means money goes straight to you
&lt;/h2&gt;

&lt;p&gt;CleanTrade is a payment gateway that works without a middleman holding your funds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The customer pays &lt;strong&gt;directly to your TRC20 wallet&lt;/strong&gt; — you never share custody of your money&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No KYC&lt;/strong&gt;, no registration documents, no approval queue — API key in 1 minute&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0% commission&lt;/strong&gt; — a flat subscription instead of a percentage cut&lt;/li&gt;
&lt;li&gt;Payment detection in &lt;strong&gt;~30 seconds&lt;/strong&gt; via unique-amount matching&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How does detection work without smart contracts? Each order gets a &lt;strong&gt;unique amount&lt;/strong&gt; (e.g. &lt;code&gt;9.84&lt;/code&gt; USDT instead of &lt;code&gt;10.00&lt;/code&gt;). When that exact amount lands on your wallet, the poller matches it to the order and fires a &lt;strong&gt;webhook&lt;/strong&gt; with the full payload. Elegant, cheap, and no gas fees on top.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Get an API key
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://pay.cleantrade.info/subscribe.html" rel="noopener noreferrer"&gt;pay.cleantrade.info/subscribe.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Pick a plan (there's a free tier — enough to test)&lt;/li&gt;
&lt;li&gt;Copy your API key&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. No documents, no waiting.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Create an order
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://pay.cleantrade.info/v1/orders &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-Key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"product_id": "premium_access", "webhook_url": "https://my.site/hook"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"order_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ord_8f3a..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;9.84&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"wallet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TXYZ..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pending"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-08-22T12:00:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You show the customer the &lt;code&gt;wallet&lt;/code&gt; address and the exact &lt;code&gt;amount&lt;/code&gt;. When they send it, the poller detects the transaction and your webhook fires.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. The complete Telegram bot (Python + aiogram)
&lt;/h2&gt;

&lt;p&gt;Here's a minimal bot that sells digital goods. When a user taps &lt;strong&gt;Buy&lt;/strong&gt;, the bot creates an order, shows the wallet and amount, and waits for the webhook to deliver the product.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;aiogram&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Bot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Dispatcher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;types&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;aiogram.filters&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Command&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cleantrade&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;

&lt;span class="n"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_api_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;BOT_TOKEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_bot_token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;ct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Bot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BOT_TOKEN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;dp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Dispatcher&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@dp.message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;start&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;kb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;InlineKeyboardMarkup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inline_keyboard&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;
        &lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;InlineKeyboardButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Buy Premium — 9.84 USDT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;callback_data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;buy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;]])&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Premium access: 9.84 USDT (TRC20). No KYC, direct to wallet.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reply_markup&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;kb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@dp.callback_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;buy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;buy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CallbackQuery&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;premium_access&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;webhook_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://my.site/hook&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Send exactly **&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; USDT** (TRC20) to:&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;`&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;`&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Order: `&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;`&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;I&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ll deliver the product automatically once the payment lands (~30 sec).&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start_polling&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;aiogram
pip &lt;span class="nb"&gt;install &lt;/span&gt;git+https://github.com/smile-sk/cleantrade-python.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Webhook server: deliver the product automatically
&lt;/h2&gt;

&lt;p&gt;Create a small FastAPI app that receives payment notifications and releases the goods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cleantrade&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;parse_webhook&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;make_fastapi_handler&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;deliver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_paid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# deliver your product here
&lt;/span&gt;        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Order &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; paid: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; USDT, tx &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tx_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/webhook&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;webhook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;make_fastapi_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deliver&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pass your &lt;code&gt;webhook_url&lt;/code&gt; when creating the order, and payments become fully automatic: customer pays → webhook fires → product delivered. No polling code on your side needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. What it costs
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Monthly&lt;/th&gt;
&lt;th&gt;Yearly&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Starter&lt;/td&gt;
&lt;td&gt;$9.99&lt;/td&gt;
&lt;td&gt;$99.90 (12 months for the price of 10)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;$29.99&lt;/td&gt;
&lt;td&gt;$299.90&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Business&lt;/td&gt;
&lt;td&gt;$79.99&lt;/td&gt;
&lt;td&gt;$799.90&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Compare with classic gateways: at 0.5% (NOWPayments, Plisio), $10,000/month of volume costs ~$50 in fees — close to CleanTrade's flat $29.99 Pro. The real reason to switch is custody and DX: money lands on your wallet instantly, no gateway balance, no KYC queue.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No bans&lt;/strong&gt;: USDT on your own wallet can't be frozen by a payment processor&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No KYC wall&lt;/strong&gt;: your customers stay private, you stay private&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0% fees&lt;/strong&gt;: flat subscription, the math is predictable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;~30 sec detection&lt;/strong&gt;: webhooks with up to 5 retries, full &lt;code&gt;tx_id&lt;/code&gt; payload&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The SDK is open source: &lt;a href="https://github.com/smile-sk/cleantrade-python" rel="noopener noreferrer"&gt;github.com/smile-sk/cleantrade-python&lt;/a&gt; — includes the client, webhook server example, and this Telegram bot.&lt;/p&gt;

&lt;p&gt;Full docs: &lt;a href="https://pay.cleantrade.info/" rel="noopener noreferrer"&gt;pay.cleantrade.info&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy building! 🚀&lt;/p&gt;

</description>
      <category>telegram</category>
      <category>python</category>
      <category>cryptocurrency</category>
      <category>bots</category>
    </item>
  </channel>
</rss>
