How many programmers does it take to sell perfume on the Internet?
The correct answer, well, it depends on a number of factors. It ranges from how to whom, and why to sell. Hi, my name is Andrey Rebrov, I am the CTO and co-founder of the company Scentbird, a perfume subscription service. Currently, 37 people work with me in the development team. Frontend, backend, and mobile developers, as well as testers, a SRE, and a data scientist. One of the most frequent questions I am asked is why we have so many developers in the company. On the one hand, I will try to answer this question, on the other, I will tell you how a modern e-commerce/subscription business works in conditions when the company's business model has some peculiarities.
Some information about our business
It all started in 2013, when we just started working on our startup and a question quickly arose - do we want to use a ready-made solution, for example do we use Warby Parker (which inspired our first business model), which uses Magento, or do we write everything from scratch? Due to my own recklessness and experience in development (and knowledge of only Java) my head was drunk on ideas. I actively insisted on the second option, saying that this is the only way we could make the online service that we wanted. The irony is that we have changed the business model several times since then. In the summer of 2014, communicating with the guys from Warby Parker and asking them for advice, the very first thing they said was not to use Magento.
I will pause for a moment here and tell you how the service works. From the point of view of the buyer, everything is simple. You go to the site, register, enter your card details and address and in a few days your first package arrives. Then every month money is withdrawn from your account and you receive a new parcel. It all seems super easy (c) But we still need to talk about the business model, so let's talk about everything in order.
So, the first part of the original business model was the “try before you buy” approach. It works like this:
· The client chooses up to three bottles of perfume
· They place an order
· They try it for a week, choose what to keep and what to return
· As soon as we receive the parcel back, we charge the customer for the amount that the fragrances cost
Let's leave aside issues of fraud and deception on the part of customers (if you only knew how many people in Russia would call this model "idiotic" and "this cannot work". Meanwhile, Warby Parker's revenue is $250 million. There are a lot of solutions on the market to protect against this, although if you go deeper, you need a custom solution). So, the “try before you buy” approach itself does not lend itself to standard e-commerce solutions (although if you know of any it will be interesting to hear about them). What are the nuances here:
· Variations in how much money to take immediately and how much at the end, depending on the order placed
· How long can a transaction be kept open
· The relationship between the status of the package and the status of the transaction - as soon as the package is returned, you need to perform the transaction, and so on
The second part of the first business model was recommendations. I immediately foresee tons of comments that there are many such services, such as Retail Rocket. Yes, there are. But there are a few "buts":
· Third party solutions cost money, but a startup doesn't have money to burn
· External solutions usually work with big data, but at the beginning we had few users and not many products
· I wanted to make a decision that was deeply tied to the properties of perfumes, and not just the similarity of products to each other
Then several months passed while we attempted to promote sales, but it became clear that something had to change. After trying out a few more ideas, we finally arrived at what we have today, a monthly subscription. Let's see what it consists of:
· A mechanism that debits money from the client on the desired month and day (billing day)
· A mechanism for the automatic recovery of clients in cases where a payment has failed, including communicating with the client (recycling & dunning)
· Functionality for customizing orders, since we allow the client to choose the exact products they will receive the following month
· Integration with the Order Management System (OMS) to place orders, receive the tracking number of the package, and the status of the package itself
Let's stop and go over each item separately, since there are many interesting things to consider
About payments
These days there are many systems that allow you to manage subscriptions. These are called subscription management systems. The most famous of them are: Stripe, Recurly, Zuora, Braintree. These platforms usually have the following capabilities:
· Define a subscription plan - how often and how much should it cost
· Create a customer profile with an address book (billing & shipping address. In the USA the tax amount depends on this), payment method, and their subscriptions and payments
· Create various discounts and promotions (e.g. second month free)
· Various analytics - the number of active subscriptions, MRR — monthly recurring revenue (one of the main metrics of the subscription business describes how much per month you earn from active subscriptions, including discounts and other things), churn rate - the rate of customer loss, and so on
· Integrate with external tools to automate tax reporting, fraud prevention, and more
· Automatic renewal of customer subscriptions in cases where the payment has failed
Now we come to one of the cornerstones of subscription services - how well you do with payments. Let's consider what are the difficulties associated with the functions of the payment services that are described above.
Historically, most of them work with purely digital services, such as listening to music. We are a service that sends physical goods and the difference is that we generate value just once during the billing cycle. That is when we send out a package, while digital services generate value every day. What's the problem with this? In cases where you have several subscription plans and you need to calculate the charges for the plan, then in the case of digital (specifically, this is hardwired into the system by default), a prorate system works, the calculation depends on the number of days that have passed since the last payment. In our case, it is tied to the event of sending a parcel. So, we need to calculate and support this by ourselves.
Now, let’s move on to the customer profile. As a rule, there are no problems here, but there are a lot of nuances with various payment systems (Apple Pay, PayPal, Google Wallet) and how well the payment service is supported, which version, and in what volume. So, sometimes you have to use a supporting solution here and there.
Discounts and promotional offers. This is one of my favorites because we have such opportunities on our site now:
· X% discount for the first month
· $Y Discount for the first month
· Second month for free
· Pay for two months at once and get a third for free
· Get a 3/4/5 month discount for Z%
· Groupon promotions with variations (fixed length of subscription without auto-renewal, fixed length of subscription with auto-renewal, collecting card data or not collecting, whether to make an initial payment or not)
· Trial period
· Referral program
· …
God save the marketers! If you think that this is all available out of the box, then I will have to upset you - no it isn’t. You have to understand that some of these actions are mutually exclusive, some can be used only once and many other factors need to be considered. So, you have to put in effort and support all this yourself.
Let's look at the next factor, analytics. One can talk about this for a long time and in-depth, because this topic is complex. First, we conditionally divide analytics into several levels:
· Products - funnels, experiments. Mixpanel copes very well here, but it can become very expensive, so now we are looking at self-hosted solutions
· Marketing - the cost of customer acquisition, conversions, average bill. Google Analytics does a good job for the time being, but good luck setting it up without the help of an expert
· The financial side is generally a separate consideration
Again, I repeat that this division is arbitrary, because all these data are closely related to each other and it makes no sense to consider them separately from each other. And here's the situation, the payment services themselves provide only basic features, but they provide the ability to export, so then you can work with the raw data. There are many interesting external systems (e.g. Revealytics), but they also have hardcoded rules for calculating certain metrics, so you need to start maintaining certain calculations on your side. At the same time, the most stupid situation happens when you have a dozen systems and the numbers do not agree with each other. As the saying goes "happy debugging you bastards" (c)
In the end, 2 years ago, we came to the conclusion that we should enter all the data in AWS Redshift. Looker works on top of it and that allows you to visualize the data. You can hear how we came to this solution in this story by the leader of our analytics team, Vanya Zerina.
Now let's talk about the most critical functionality of payment services, the recovery of customers whose payment did not go through on the day of billing. There can be many reasons why a payment has not gone through:
· No money in the account (most popular reason)
· Card canceled
· Card expired
· The card was stolen and blocked
· The bank thought there was a fraudulent transaction
· There was actually fraud
· The bank had maintenance
· And many many others
The main reasons for losing customers
As I wrote above, most of the services do not process payments themselves, but support one or more payment processors. Each of these processors has (if it has) its own individual code for each error, and then the payment service either sends them as is, or they provide their own message. For this reason we stopped using Stripe as in 90% of cases they gave a generic payment declined message and it was not clear what to do next. Why is it important to receive these codes? Because, depending on the error, the solution can be different.
First, we can divide the errors into hard failures (for example, the card is blocked/stolen) and soft failures (no money). This is so that don’t try to perform unnecessary transactions for a hard failure, so that we do not lose money on this and so we do not have problems with Visa/MC. But here there is also a nuance regarding exactly how the payment service classifies the error in one category or another. For example, PayPal has error number 10417. Transaction cannot complete — "Instruct the customer to retry the transaction using an alternative payment method from the customer's PayPal wallet" or "The transaction did not complete with the customer's selected payment method". As we found out, it can mean either the payment method is unavailable or there are not enough funds in the account. Our previous default gateway defined this error as a hard failure. But after we reconfigured it, we began to recover many more people.
The second point is why you need to know the error code. Communication with the client depends on this. The more accurate the instructions on what a person needs to do, the higher the percentage of recovered payments will be. In our case, we were able to raise this number by about 18% after we started writing different text, and even for cases of first-time payments. Unfortunately, out of the box payment services do not do this, and so we built all the communication ourselves.
Well, now onto the last factor, which is recovery. It is very important to try to conduct a transaction several times after the initial attempt, as there is a very, very high chance that it will pass. We recover from about 85% of all failed payments using this mechanic. There are also several nuances:
· The United States have different approaches to paying wages. On the 1st day of the month, twice a month on Fridays, every week on Friday, and so on. We try to process payments in such a way as to fall on days close to those described, which increases the likelihood of a successful transaction
· Many banks do maintenance at night, so transactions are best done during the day
· Also, banks can think a transaction is fraud if it is carried out at a time when the client usually does not spend money
· There is a force deposit mechanism that allows you to withdraw money and take the account balance into a minus, but here you have to be careful, as it can only come from Visa/MC
As a rule, very few payment services have recovery mechanisms that take into account all this, so you either have to look for such a service, or do it yourself, or combine both, as we ended up doing.
Finally, let's talk about payment processors. Having several makes sense if you:
· You have a large volume of traffic and want to optimize the transaction fees (how much money do you pay Visa/MC/... for a transaction; different processors have different contracts for different types of cards)
· It is important for you to have a backup processor if one does not work for some reason
· You work in several countries. In this case, different processors work differently with local banks and national methods of payment (for example, Vantiv works very well in the States, and Adyen works very well in Europe)
Often, only large subscription services integrate directly with processors, bypassing the gateway, and here's why they do it:
· As a rule, each gateway has its own abstraction layer regarding working with subscriptions, discounts, customers, and others. If the service has complex logic, then at some point it already seriously limits the development of new functionality
· At some point, paying for gateway services becomes more expensive than developing and maintaining your own solution
· Direct integration provides great opportunities to use the functionality of the processors themselves, since the gateway can only do many things superficially
We have not yet reached the stage when we need our own solution, but in the future, in 2-3 years, we will need it. Again, we must understand that in this case we will be responsible for security, since we will have to undergo PCI certification and perform many other additional tasks, but it will be worth it.
About parcels and delivery
Okay, we've talked about payments, now let’s talk about parcels. As I wrote before, we give our customers a choice of what they want to receive. This distinguishes us from most subscription services, where there is no customization at all, or it is very simple (2-3 options, such as Dollar Shave Club). Many services now offer more choices, so they start to face the same challenges as us.
First, it is the selection of choices for clients. In this regard we created an analog of the Netflix queue, while they were still messing around with discs. Everything is very simple, there is a visual element that contains N cells for each future month. The client adds a product to the queue and after that they don’t even need to return to the site. As long as there is money on their card they will receive a parcel every month.
Basically, everything is quite simple, but let's walk through it as we did above. First, the client's choice must be fixed (we call it “freeze the queue”) a day before the payment is made, so that later on the person does not say that we sent them the wrong thing. That element must be removed as soon as the parcel is delivered to the addressee. But what if the person entered the wrong address and the package is returned? Or if the payment hasn't gone through by the end of the month? What if the warehouse ran out of the perfume and new stock will not arrive soon? For these possibilities you need to think about your solutions.
Secondly, we don’t have just one subscription plan, but 46. Of course, a person does not see all these plans in the form of a list on the site, THAT would be madness. Some of these plans are upgrade options:
· Immediate payment for several months in advance
· A plan with 2-3 products
· A combination of the first two options
Then there are gift subscriptions and the ability to change the frequency of receiving a parcel to every two or three months, and a few more technical plans. Additionally, sometimes customers can have free months (for example, through a referral program) that people want to see. And now we can sit down and think about how to get this out of the box using Shopify. It isn’t possible.
Thirdly, not all perfumes are the same for all clients. There are limited edition perfumes (this means we cannot sell more than there are in stock), there are perfumes from a more expensive category (+$5/$10 for each such perfume selected for the current month). If your head is already spinning, don't worry, ours are too. Thank God, there are integration and functional tests that allow you not to break such a complex system with one simple commit.
Let's say everything is fine, the client has chosen a perfume, the payment was successful, and now the simplest thing is left, to send the parcel. Yes, but no. Everything is simple until there are parcels with several products.
Now, let's take a step aside and talk a little about logistics in the USA. As a rule, most companies use the services of a logistics and warehouse partner, the so-called 3PL companies (3rd party logistic). They take on the responsibilities of receiving and storing goods at the warehouse, sending parcels, dealing with returns, and contracts with transport operators (carriers). Carriers are usually large companies (USPS, UPS, DHL, FedEx) and many other services in the category “last mile delivery”. Last mile delivery is the delivery of goods to the client from the last warehouse. As a rule, these are either small regional companies or USPS, which delivers everywhere in the United States. And there is also a special mail service that delivers parcels to military bases, embassies and so on. (We had several clients whose address pointed to service on an aircraft carrier. The sea also wants to smell good.)
So, 3PL companies use so-called WMS (warehouse management systems) in their work. These systems are designed to account for goods in the warehouse, receive and send goods, and all activities around them. Very often a WMS is part of a larger ERP system. An example of an ERP is the well-known SAP system. There are quite a lot of WMS systems on the market at the moment, most of them are well integrated with services such as Shopify or Magento. If you use them, then everything is great. But everything will fall apart once we start talking about subscriptions again, because there is the same factor related to billing day, when after all payments have gone through, a large number of orders must be transferred. This is where the problem comes in, as most of these systems are simply not designed for that kind of load.
The first few years we were able to work with external vendors, but as soon as we passed the mark of 200 thousand subscribers, everything collapsed with one of our regular partners and we had to urgently sort it out ourselves. All in all, it's easy to ship packages. We take the goods, card, pack in a bubble mailer (plastic packaging with bubble wrap inside), paste the shipping label on it (a sticker indicating where to deliver, with what rate, tracking number, and so on), and then carry it to the post office. Profit! But everything is a little more complicated when dealing with 200 thousand parcels and even printing labels becomes an interesting task. Let's analyze it.
Let's start with what to print on. For this purpose, an industrial printer is used, in our case a Zebra ZT-510, capable of producing 2 labels per second, in theory. In practice, this is somewhere around 1.6. Simple math says that in about 35 hours we can handle it if we print on 1 printer without stopping. But as always, there are nuances:
· It is necessary to change the paper because there are usually 2000 sheets on a roll
· You must be able to separate orders by similarity, this is called batching
· Sometimes the printer chews on a sheet and printing needs to restarted
· Duplication cannot be allowed due to the operation above
· There is a need to clean the platen roller from time to time
· For speed, you need to use several printers, so you need to be able to manage printing in parallel
Moving on, where can you get the actual labels? That's right, use a service that generates them. Here, of course, you can do direct integration, but we still do not like problems so much that we enjoy digging into SOAP, so we use the Shippo service and everything is more or less great.
This and much more gave the guys a pretty solid headache, but in a couple of days they were able to make a console solution and the printing started. It went something like this.
Now, two years later, we have both an application on Electron for managing printing, and our own WMS for managing the work in the warehouse, an algorithm for smart splitting into batches, and much more.
Afterword
As you can imagine, this is only a part of all the work that our team does, in addition to this there are:
· Mobile applications where our audience is most active
· Advanced analytics, including financial
· CRM (client relationship management) for our technical support, which was also written from scratch to support all our capabilities
· Personalization and recommendations
· Dozens of integrations with external services
· Integration with Oracle NetSuite, that was epic all by itself
· And many many others
Was it possible to do this with ready-made services using only the capabilities out of the box? Definitely not, we would still be waiting for improvements and customization. Would we be in a better or worse state in terms of subscriptions? I don't know, but we would definitely be a different company.
So, answering the question in the title, as many as it will allow you to build a cool, tech business.