Alex

computer science engineer

Last edited: Nov 11, 2024

blog projects github

Oct, 2024

🥳 el-cumple.de

build fast & iterate.


Building a complete product is hard. You fear your UI may not be good enough, you never want to let your users down and you can always add new features to improve things.

How can we build something then?
The trusty old waterfall model has turned out to be too rigid compared to other more agile methods. The MVP (Minimum Viable Product) approach seems to be the go to in the startup world, as Michael Seibel said in How to plan an MVP - "If you can walk away with one thing from this presentation, it's launch something bad quickly." and I took that personally.

So our journey begins, we want to build something that the user wants, and most important we want to build it fast.
I also made having online payments a requirement. To test how hard was to setup stripe and because the possibility of earning money brought excitement to the mix.

mark I iron man suit

The age-old question. What to build?


The goal wasn't to have a great idea, let's get that out of the way. I just wanted something very simple that felt somewhat complete and that I could build in about a week.
So... birthdays!🥳 Everyone likes birthdays right? Families are reunited, there's cake for everyone, you get those fancy socks from your granny, a peak experience.
And how can we make that better? Birthday cards, but not the lame old analog expecience, we're talking blockchain wishes, the revolutionizing new way of expressing ❤️.
Okay, that was some jargon to see if any angel investor took the bait, we're just going to create some basic birthday cards webpage, nothing too special. Build fast, remember?
We'll use the domain el-cumple.de to target a spanish audience, I picked this name becuase it's a good domain hack that could be translated as the-birthday.of .

Time to get our hands dirty. We need to create a path with very little resistance for the user to buy something from us, in this case a webpage. After some thought I decided on taking some basic user input in two initial steps. Then we can let the user try some templates with their info to see how their page would look like.

At first I wanted to include images as an input field, it could be nice to have that personal touch integrated with some other details to wish a happy birthday. But ensuring that the images didn't have sensitive or ilegal content, and handling the different possible aspect ratios would take some time, we can't afford that.

What then should we take as input? I settled on the basic stuff:

  • Name of the birthday person
  • Birthday date
  • Name of the person sending the happy birthday
  • Age of the birthday person (optional)
  • Small happy birthday text where you can write up to 190 characters
First design of the home page

Oh and if you're wondering about that incredible marketing image, which transmits the pricing information so effectively and in such an efficient way. I did that myself, yes...

The template temple


Anyway, we need some templates right? Let's start by designing the first one, we can give it a party look with some disco lights. We're also going to add some confetti effect to complete the look, which should give us a decent start.

And as you may have noticed I added a little pulse animation to highlight the main message, not too bad.
We still have a lot of free space that I'm not sure what to do with. I'm also not really convinced by the background color at the top. So as I do every time I have blank space on a webpage, I headed to pexels to grab some cool images that could improve the aesthetic of the page.

And just like that our first two templates were created (we ended up only having three).

preview of the first template with the addition of pexel images preview of the second template refactor of the first template

As you could see in the third picture, I refactored the first template to only use one image. The first result was just too ugly 😅, fixing it didn't take much time.
The second template is just a simple static design in which I also included the confetti throw when the page is loaded, this was very easy to do and I thought it looked pretty clean.

For our final template I wanted to do something dynamic. Something that could catch your attention with multiple moving pieces. After a little while I came up with the following idea, flying emojis. Yup, that sounds great 😎.

If you want, you can now go to el-cumple.de to try all the templates for yourself. Althought the confetti effect will only be shown when the page is actually bought and set with its own link.

Get it up and running


Okay, we can now take of the designing hat and start focusing on how we can actually receive payments from clients. Handling it ourselves would be nice, but there's a bunch of responsibility and possible issues involved, that's why I choose stripe, a pretty standard solution.
We just need to create an account, create the product and the pricing, add the keys to our code and link to the payment page with the keys info, pretty simple. Oh, and also add some callback urls for when the payment is successful or canceled.
Sounds good right? Well, there's a little issue, how can we retrieve the user input info on the success callback? From what I read, there's no such thing as sending the info to stripe so when the payment is completed it can send that info back.

Yes, I know what you're thinking query parameters, you're right. But as I didn't want to possibly have 300 characters of query params I took the backend local session route.
When the user clicks on the payment button, we create a backend entry into a map stored in memory, with all the info we have collected and a new generated id. When we redirect the user to the stripe payment we define the success and failure url callbacks with the addition of said id as a query parameter. Then, when we receive the confirmation or cancelation from stripe, we can either create the page or clean the information from the memory map using that id.

Very simple right? Another cool thing about stripe is the test mode, which as the name implies lets you test the payment system as if it was really running, but without making any charges. You can even use a test card number like 4242 4242 4242 4242 alongside other fake data to test the system.
Once everything works nicely, you just have to switch the links to the live version and you're set.

What's not so cool about stripe for this project is the fixed fees per transaction, with the loss of 0.25€ per each sale we are left only with 3/4 of profit from our price (before taxes, and without counting stripe 1.5% cut). Don't get me wrong, I think stripe has an amazing service going on, but how could we improve our margin?

Inflation baby😎

We outdid ourselves with this second marketing masterpiece, which raises the price just a little bit to get more margin over the fixed costs of transactions. Okay it doubles the price.

My assumption was that the limiting factor for the average purchase is the user not wanting to introduce his card on my page, not really the difference between 1€ or 2€.

As long as we keep it on the coin range I think we are good.

final landing page with price increase

Now let's talk about deployement. In the past, for most of my webpage projects I opted for using a VPS (Virtual Private Server), in particular I went with Linode using the cheapest plan available. But as time went on I grew a little bit tired of having to pay those 5€ monthly, and because I have an old PC laying around I decided it would be better to self-host, spending about 10€ in electricity bills monthly 🙄.

The setup turned out to be decently simple, but we had some silly issues that resulted in the process taking a bit longer.

First we needed to setup the DDNS (Dynamic Domain Name System), since at home I don't have a static IP address. I headed to no-ip to configure my account and then link my home network address. After completing all that correctly I quickly set up a simple ssh server and to my surprise I could not reach it from outside my network.
Wow, the DDNS must have something wrong right? Well, after checking and checking the configuration for some hours I found nothing, everything seemed to be well configured and working, but it was not. So I kept digging until I found out that my provider used CG-NAT which means that I don't even have a public IP so I cannot reach my home network.
A quick call to my internet provider fixed the issue, and after that we now have our reachable ssh server, from anywhere in the world, nice.

Next I installed nginx, got the ssl certificates with certbot, and started receiving http & https petitions on my home server. At this point I thought about setting the el-cumple.de DNS records pointing to my home IP, that way we could actually use the server for the webpage with the domain name.

But it didn't feel good. I don't really want to expose my home server IP that easily right? So with the amazing free plan that cloudflare offers, I couldn't resist to set a proxy with them. With this we don't expose our IP, we get free statistics with their online dashboard and even some DDoS mitigation, seems like a great deal to me.

The only problem was that when I was setting everything up, I already had configured nginx to reroute the http traffic to https, and by default cloudflare connects to http on the origin server (their Flexible mode). So long story short I was getting a bunch of redirects in the client that lead to browser errors, and me not being able to load the page. The fix was easy, we just needed to set the connection to the origin server with https (the Strict mode) and everything worked fine, but it did take me a while to figure out what the problem was.

So anyway, after all that we now have a complete web page running in our domain el-cumple.de .
What should we do now?

Spread the word


Most people when they publish their first project think that traffic is going to come flying towards them for some magical reason, making them instantly the new hottest thing around. Well, since this isn't my first rodeo, I know that the most traffic you're going to get if you do nothing is some crawl bots and maybe family and friends.

But first let me make a disclaimer, when I got the idea of making this simple page to create birthday cards, I knew that the most likely result was that no one would want to pay for it. I wasn't even convinced that if I made it free it would actually get much traction.
My main goal with this was to publish something where the possibility of getting payed existed, and to actually get feedback from possible users to transform it into something useful.

So I went out there and spread the word on Reddit, and to my surprise I got more engagement than expected. With about 15.000 views on the first day from a single post and 57 comments. How did that translate to actual page visits to our site? Well, not splendidly, looking at the cloudflare analytics we saw an increase of about 230 new unique visitors to our page, which is decent but only represents a 1.5% conversion rate from reddit view to page visit.

What I really loved was the commenting interactions. I'm really thankful for all the feedback which has given me new perspectives that I may have not considered on my own. I also believe that I've gotten a much more insightful view on the market response to such a type of product. This made me discover some adaptions that could make the service actually useful for some type of users.

But the real question that you may all be asking.

Did you sell anything? The answer to that one is yes, but sadly I was the only client and only because I wanted to make sure that the payment was really working 😂🥲. The real answer: nope. So if you have 2€ laying around, and you want to make a young man very happy ❤️, you can go to el-cumple.de and purchase yourself an incredible birthday page to gift to anyone you know.

What's up next?


As I said earlier, getting all the feedback gave me some ideas on what should be the actual service that this page offers. But when am I going to take on that refactor? I'm not really sure, for now I want to go back to working on my main thing. I may do it on the side if I feel like it, but I'm not really in a rush to get it done.
All in all, I feel like I learned a bunch with this project and I'm really happy about how it turned out. I have strengthened my belief for the importance of shipping fast, and more so when you don't have reasons to believe that your product has good market fit.

As always I hope you enjoyed this story.

- Alex