<?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>Forem: Hong Phat Ly</title>
    <description>The latest articles on Forem by Hong Phat Ly (@hongphatly).</description>
    <link>https://forem.com/hongphatly</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3683004%2F283b66cb-9a6b-46cb-9541-48bec6296bed.jpg</url>
      <title>Forem: Hong Phat Ly</title>
      <link>https://forem.com/hongphatly</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hongphatly"/>
    <language>en</language>
    <item>
      <title>How I Built a Self-Hosted PayPal &amp; Stripe Checkout (and Why I Avoided Middlemen)</title>
      <dc:creator>Hong Phat Ly</dc:creator>
      <pubDate>Sun, 28 Dec 2025 17:43:15 +0000</pubDate>
      <link>https://forem.com/hongphatly/how-i-built-a-self-hosted-paypal-stripe-checkout-and-why-i-avoided-middlemen-3b79</link>
      <guid>https://forem.com/hongphatly/how-i-built-a-self-hosted-paypal-stripe-checkout-and-why-i-avoided-middlemen-3b79</guid>
      <description>&lt;p&gt;Accepting payments should be easy.&lt;/p&gt;

&lt;p&gt;Yet every time I started a new side project or SaaS, I found myself stuck choosing between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy-pasting PayPal buttons from outdated docs&lt;/li&gt;
&lt;li&gt;Wrestling with Stripe Checkout flows I didn’t fully control&lt;/li&gt;
&lt;li&gt;Or using hosted tools that added fees, lock-in, or abstraction I didn’t need&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted something simpler:&lt;br&gt;
👉 a small, self-hosted layer that turns a snippet into a real PayPal or Stripe payment button&lt;br&gt;
No middleman. No platform lock-in. My keys, my server, my funds.&lt;br&gt;
So I built one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with “just use Stripe / PayPal”
&lt;/h2&gt;

&lt;p&gt;Don’t get me wrong — Stripe and PayPal are great payment processors.&lt;br&gt;
The problem isn’t them.&lt;br&gt;
It’s everything around them.&lt;br&gt;
Common issues I kept hitting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Too much boilerplate for simple payments&lt;/li&gt;
&lt;li&gt;Different flows for PayPal vs Stripe&lt;/li&gt;
&lt;li&gt;Hosted tools that:

&lt;ul&gt;
&lt;li&gt;take a cut&lt;/li&gt;
&lt;li&gt;store transaction data&lt;/li&gt;
&lt;li&gt;break when pricing changes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Little control over UI and behavior
For many projects, I just wanted:&lt;/li&gt;

&lt;li&gt;A button&lt;/li&gt;

&lt;li&gt;A price&lt;/li&gt;

&lt;li&gt;A callback&lt;/li&gt;

&lt;li&gt;Done&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I wanted instead
&lt;/h2&gt;

&lt;p&gt;My requirements were simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Self-hosted&lt;/li&gt;
&lt;li&gt;✅ Works with my own PayPal &amp;amp; Stripe API keys&lt;/li&gt;
&lt;li&gt;✅ No transaction fees&lt;/li&gt;
&lt;li&gt;✅ Simple embed snippet&lt;/li&gt;
&lt;li&gt;✅ Optional cloud version for people who don’t want to host
That was the idea behind what eventually became FreshLimePay.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How it works (high level)
&lt;/h2&gt;

&lt;p&gt;The core idea is intentionally boring (on purpose):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You connect your PayPal or Stripe keys&lt;/li&gt;
&lt;li&gt;You define a product or amount&lt;/li&gt;
&lt;li&gt;The system generates a small snippet&lt;/li&gt;
&lt;li&gt;That snippet renders a real checkout button&lt;/li&gt;
&lt;li&gt;Payment goes directly to your account
No proxying money.
No holding funds.
No “platform wallet”.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Example: from snippet to button
&lt;/h2&gt;

&lt;p&gt;The goal was something like this:&lt;/p&gt;

&lt;p&gt;PayPal:&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2Fzdd4bursusmyrxoebqmh.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.amazonaws.com%2Fuploads%2Farticles%2Fzdd4bursusmyrxoebqmh.png" alt="Integrate PayPal" width="800" height="159"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stripe:&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2Fonm8ia5crx3bejmldd1r.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.amazonaws.com%2Fuploads%2Farticles%2Fonm8ia5crx3bejmldd1r.png" alt="Integrate Stripe" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And you instantly get a working payment button.&lt;br&gt;
That’s it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Self-Hosted vs Cloud (why I support both)
&lt;/h2&gt;

&lt;p&gt;While building this, I realized something important:&lt;br&gt;
Not everyone wants to self-host.&lt;/p&gt;

&lt;p&gt;So FreshLimePay ended up with &lt;strong&gt;two modes&lt;/strong&gt;:&lt;br&gt;
🔒 Self-Hosted&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install on your own server&lt;/li&gt;
&lt;li&gt;Full control&lt;/li&gt;
&lt;li&gt;One-time or yearly license&lt;/li&gt;
&lt;li&gt;Best for developers, agencies, SaaS founders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;☁️ Cloud&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No installation&lt;/li&gt;
&lt;li&gt;Instant setup&lt;/li&gt;
&lt;li&gt;Subscription&lt;/li&gt;
&lt;li&gt;Best for non-technical users or quick launches&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same idea. Same philosophy.&lt;br&gt;
Different levels of control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why self-hosting still matters (for some of us)
&lt;/h2&gt;

&lt;p&gt;Self-hosting isn’t about nostalgia.&lt;br&gt;
It’s about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ownership&lt;/li&gt;
&lt;li&gt;Predictable costs&lt;/li&gt;
&lt;li&gt;Fewer dependencies&lt;/li&gt;
&lt;li&gt;Sleeping better when pricing pages change elsewhere 😅&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re a developer, you probably know the feeling.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you don’t want to build this yourself
&lt;/h2&gt;

&lt;p&gt;I ended up packaging this into FreshLimePay so others wouldn’t have to rebuild the same thing again and again.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://freshlimepay.com" rel="noopener noreferrer"&gt;https://freshlimepay.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Cloud app: &lt;a href="https://cloud.freshlimepay.com" rel="noopener noreferrer"&gt;https://cloud.freshlimepay.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you do want to build your own — great.&lt;br&gt;
If you don’t, this might save you some time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;This isn’t meant to replace Stripe or PayPal.&lt;/p&gt;

&lt;p&gt;It’s meant to make them simpler to use, especially for small products, MVPs, and indie projects.&lt;/p&gt;

&lt;p&gt;If you’re interested, I’m happy to answer questions or share more implementation details in the comments.&lt;/p&gt;

&lt;p&gt;Thanks for reading 👋&lt;/p&gt;

</description>
      <category>stripe</category>
      <category>saas</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
