Hacker News new | past | comments | ask | show | jobs | submit login
Payment systems while working at a pizza place (nickjanetakis.com)
260 points by nickjj on July 18, 2023 | hide | past | favorite | 149 comments



I'll chime in with a lesson learned from my own experience in niche POS systems: it can be amazingly valuable (in certain contexts) to let clerks pause sales and put them off to one side (think "git stash", but for sales). Customers wander in and out, run back for one more thing, or put things on hold while they go out to get cash out of an ATM. Letting a clerk wrap up a whole sale with context (some items rung up, payments created but not processed, etc.) and put it on a shelf to restore later is a superpower for POS systems.

And that's not even _starting_ on the nonsense and bizarre home-rolled systems that small businesses concoct around layaways.


I used to work in a supermarket without this feature and when a customer would run away mid-order, my options were either stand there awkwardly while another potentially irate customer stares at me or call over a manager to get the override key to let me cancel the order (any voids/cancels over a certain dollar amount required a manager override key). Neither option was good. Both wasted time and created a bad experience for the customers. I occasionally see cashiers these days doing these `git stash` maneuvers and honestly I get jealous every time.


The store I managed had a suspend/recall. Cart full of groceries only to realize you left your wallet (at home, in the car, whatever) suspend the transaction and print a slip with a barcode on it. Move the cart out of the way and take the next customer. The customer comes back and scans the slip at any register to recall the transaction, pay and collect their cart and leave without having to hold up lines/etc... Was a nice convenience many appreciated.


When I was studying (late 00s) I worked at a large supermarket chain in the UK that had this. The system was surprisingly well designed.

It was based on Windows NT (somehow hardened, as I never saw a checkout show a BSOD or fail to boot) and was designed before a time when you had a continuous internet connection. There was a mini-server in the back office, and every night it would sync with HQ.

This meant all functionality, including taking credit card payments and loyalty, could be done offline. One time we had a electrical systems failure in the store, and everything - including chillers - went down. However each checkout had its own UPS and continued to operate without issue.


If, let's just say, every little (feature of the checkout software) helps — if you follow my drift — the architect of that system is a mate of mine. I've never worked with him (I know him through music stuff, not tech stuff), but he's a deeply thoughtful guy.


I worked at a store that had this feature except if you reloaded the transaction on a different register it still got attributed to the originating register and caused a headache at closing :(


Manual probably dictated that a policy of receipt transfer and (irrationally) presumed synchronous cash out times.

Management just didn't RTFM/FTFM.


This very thing happened to me, and I was very pleasantly surprised with how this worked. It definitely took some of the embarrassment away from being a dolt


It was an option in the register when I was a cashier during the crash of '08 and I couldn't find a gig elsewhere.

But it was against policy to use the feature, since previous cashiers had worked out a way to scam the system somehow and pocket some of the cash being exchanged. I'm cloudy on the exact details after so long, but it was very, very annoying to have such a useful feature sitting there mocking me and a write up if I dared hit the button.


Instead of dealing with the offenders... punish everyone - workers and customers (with delayed/crappy checkout experiences). That's great management, sure. Situations like these - which I noticed as a kid - contributed to my early-onset cynicism.


If it's too hard to detect, management doesn't have much choice.

It would be smarter for that feature to require a manager's key, and then the manager could actively monitor the situation. But since the manager can't implement that feature, they have to work with what they have.


It read like they DID know how to spot it, and the reaction was... "never again for anyone under any circumstances".

Blanket bans like the one described are always wrong. ;)

If there's a problem, monitor it after every shift, or every day, or weekly. You know who worked what registers; monitor/scan/review, then take action against the offenders.

I worked food service with POS; we had to review things every drawer change, and discrepancies were noted. Repeated discrepancies (either money or between food usage and money) would be tied to someone (or multiple people) and action was taken. It's not always that hard, just a bit time consuming, but... it's part of the job (or was for me).


Solving personnel problems with policy is unfortunately common at companies in the small-medium space. Very small companies tend to be more person oriented, and very large companies tend to have outgrown it (though they may still do it at the department level).

It is also one of the most annoying mistakes I see frequently repeated at startups and young businesses.


Solving problems with policy is common in all companies. It’s programming at the organisation level. Every policy is either a good candidate for automation or an indication of automation limitations.


It's incredibly easy to detect.


Presumably suspend your partner in crimes transaction receipt is printed walk away. Partner slips you some money later.

Solution: don't hire scummy people, pay enough that you can afford decent folks, watch for a friend that always comes to a certain cashier especially while alone, watch for cashier being nervous when observed, watch for partner to break off transaction if observed, "forget card", or return goods shortly.

It's also obviously trivial to catch with the receipt but they will probably refuse to show it. A transaction log will also trivially show it if matched with register and time.

Anyone could potentially get away with this once but any dishonest person is going to want to do this repeatedly.

There is basically no excuse for not catching this as a manager and I see no reason to deny associates this useful feature.


The cashiers would 'fake' the completion and instead just suspend the transaction.

Management didn't bother checking for unusual rates of suspended transactions nor 'check off' on abandoned transactions.

It's almost always a management failure, as it's most likely they just didn't want to do the work instead of wasting time hitting on the inappropriately young employees...


Shouln't that be easy to spot if the items are never returned and inventory doesn't match up? You'd think any abandoned transactions would require signoff by someone else that the items were actually returned (or trashed if perished).


As I said, management is lazy and would rather engage in inappropriate conduct than try to actually do a good job.


In the store I worked in, which was a notable spot for people attempting credit card/gift card fraud and/or theft, the manager literally just gave me the override code because it happened so often I'd have him coming over like every 15 minutes to cancel something. We were also a super busy store at the same time as this so it would just leave a bunch of hyper-angry customers in line.


Do you know how the gift cards integrate with your POS system ? Do each provider have an API that was called to activate a card or was there something more centralized?


Open loop cards just hit the usual network rails.

Closed loop cards are integrated between the POS backend and the program manager. Some large merchants manage their own card programs.


Not sure, this was like 10 years ago at this point and I didn't really pay attention to these details at that time.


The psychology of this is funny. The right thing with such a POS is to have customer pay for everything so far, move their cart to the side, let them run and get their item, and then let them be front of line at that point to finish their full set of purchases.


99% of the stores I've ever seen don't have checkout aisles wide enough to allow this.


No, I meant, purchase, move cart beyond checkout area in front of cashier.

I guess there is fear their purchased goods might be stolen.


Honestly, to add on to what you said, it's amazing about the lack of domain knowledge that developers and product owners have in making systems for people.

For the clerks and workers using the POS, it's often more of a hinderence than it is a help. When you look at less technically reliant societies (i.e. market places in Asia) you'll see this more often. Prices are negotiated, they can be their own warehouse, smaller companies work together (your package getting from maker, middleman, aliexpress to your door is incredibly complex but they can make it happen within 2-3 weeks).


To be fair, though, the "customers" aren't the customers. In modern software companies, you don't sell products to be profitable, you sell them to be plausible. As a software company, your value to a venture investor is much greater than it could possibly be to a potential customer. The objective of the startup is to look plausible until the current round of investors sells their stake to the next round of investors. Part of they way those investors value the company is whether or not they think they can sell the company to a greater set of fools.

In the modern software company there is only one customer, the next early stage investor. I can assure you, your execs know how to pitch to them, otherwise they wouldn't have received their A round.


It's always much faster to check out with a couple of things in a New York bodega/deli, even while making small talk with the clerk, than to check out with the same items at the chain drugstore down the street.


I maintained a POS for a large retail chain - and the variety of transactions that it could handle was far narrower and less subtle than the type of trades that I witnessed working at a weekend open air market.

At the market there was all sorts of bartering and swapping and deal making - my “business analyst” brain recognised that to model all the “transactions” occurring at a typical market would be super complex.

However… the large retail chain should not support subtle/overlapping transactions of that sort- not because it’s too complex to model, even if it was free to model it, make the software track it — the reason the retail chain would avoid it is: profit margin.

You do profitable things, you do them a lot, and you don’t pay the opportunity cost of doing less profitable things. That’s the open secret of successful retail. And small businesses everywhere do not internalise this.


Isn’t the reason rather that management will say: Is this absolutely necessary and will it increase sales?

And often the answer is no unless you can demonstrate the time gain and emotion of your customer. When the margins are super thight anything that won’t help margings is left away and home delivery /online shopping will be prioritised for the tech team/budget.


Of course they'll say no. It presents a version of the technology that is not commonly done. Justification for their stubborn resistance to support the customer and the users is not relivant here.

We're still stuck filling out forms and passing validation to complete transactions.

My complaint here is that arrogance that POs and devs have in how humans operate with the software is way off. What happens if you want to buy out Aldi's entire stock of brie? Is it reasonable that you should be paying stockprice*quantity? (The answer outside of technology enforced rules is no.. Additionally to aldi corp, theres no reason not to offer a discount here) [Also, in practice they try to hack their way arround it by overriding the price]


The thing a smart manager will ask is "does this open up new avenues for theft/scams". I suspect that it does, unless there is a shit ton of auditing in place.


At scale yes. In realistic common edge case scenarios that don't involve demotivated and exploitive businesses, no.


I always like to say something meaningful before plugging my project, but that's exactly why I started working on https://notionsmith.ai

Overall I'm really excited about LLMs being integrated deeper into product development, there are a lot of insights already captured in their output that people building products could use


This is awesome have you posted it to HN yet?


I see that you have a month ago. Anyways I think it’s great, wondering what it costs you to run it for free


Glad someone liked it! :)

It's currently ~$100 a month, I'm working on a paid version but a lot of my users ended up being people BRIC countries so I don't mind footing the bill if they find it useful


I was really impressed when the cashier at my neighborhood supermarket recently transferred my order in progress over to an empty lane so that I could deal with a credit card issue without delaying the people behind me. Seems like an obvious function but it had never even occurred to me!


I maintained a POS for a retail chain for a few years.

Our suspend/resume sale feature assumed that a suspended sale could only be resumed on the machine that suspended it. Then we had to change it to be resumable on any machine in the store. But only show a flashing notification that there’s a suspended sale, on the original machine.

(Thanks for storing that knowledge for me for the last decade, neurons. I doubt you’ll be asked to recall it again.)


Why only the light on the original machine? Why bother showing the light at all?


Real answer: that’s what the client wanted.

> why bother showing the light at all?

Probably so that the operator can more easily find the suspended sale in order to resume it. Suspend / resume happens rarely enough that operators aren’t fluent with that feature.

> why only the light on the original machine?

Because it’s far more likely that the original machine is the one on which it will be resumed, say 500 times more likely. So that’s 99.8 of the time you’re not alerting a second machine unnecessarily - and if there’s three or four machines it goes into more nines of false alerts being avoided.

But the sufficient answer is - the customer wanted that.

Everyone in the retail chain had experience as an operator (self included) so the user experience decisions were generally well grounded.


> ...let clerks pause sales and put them off to one side...

I dreamed about just such a feature when I worked at a convenience store back in high school. That was 30 years ago. Such progress... >sigh<


>And that's not even _starting_ on the nonsense and bizarre home-rolled systems that small businesses concoct around layaways.

There are a number of things that even many just modestly-paid developers don't grok because they obviously make no sense.

Many years ago I remember asking a then-gf why such and such a store customer service accepted utility payments. And she was "Umm. Some people don't have checking accounts." Layaways are different but in the same general category.


That's a bit like opening a tab in a bar, isn't it?

I think it depends a lot in the country or the business, in some places is so easy, but in others is so difficult.

I remember at least 20 years ago, in the grocery store with the most basic digital scales, every clerk would have their "tab", shared between all the scales. So each one could use the scale nearest to the fruit they were weighing in that moment, then switch to a different one... And finally print the whole ticket without interfering with the other clerks.

Something like this... https://cdn.wallapop.com/images/10420/5j/p7/__/c10420p335420...


We called that feature "parking" the invoice. It's pretty standard on every good POS system.

It can also become a challenge if you have a lot of those and want to find the right one. We had some users that prepared a lot of orders in advance into bags, so they can hand them to the customers right away when they come. Best solution was to print a delivery note for every order, attach them to the bag and then scan a barcode on the bag when the customer comes for pick up/payment. And you also need to be able to add or remove items before the customer pays, people often change their mind.


I developed POS software, and it is an extremely challenging job. The workflow described in this article is still rather simple, there are so many more possibilities (some apply more to shops than restaurants).

One hypothetical example: a tiramisu with coffee has a special price, but you still need to put them separately on the invoice, either because you track if the tiramisus are out of stock and want to stop people ordering more. Or coffee and tiramisu may have different sales taxes (very common in Europe to have a lower tax for food).

Different prices for take away and eating in the restaurant, happy hours. Payment in different currencies, some articles may have fixed prices in a foreign currency, others need conversion with the current exchange rate.

The possibility to split or join invoices.

Usability and speed is crucial at the POS, the users go crazy if they are busy and their software is too slow or has too many submenus. It has to be easy to learn too, often they hire people that fill in for a few days, and they need to be able to use it. A lot of people using it are also not very skilled with computers, or have no interest in learning how to use the software.

The owner may restrict some features to some users, so they can't cheat the system (taking cash payments, cancelling the invoice and keeping the money). There may be some tax fraud prevention laws to be implemented, vastly varying on the region, like digitally signed invoices or the need to report every issued invoice to the authorities in real time.


Those kind of tax and price variations are quite common in the U.S. too.

Some examples: Bread from bakery plus lunchmeat from deli = taxed at grocery rate, but a shrinkwrapped sandwich using the same bread and lunchmeat = taxed at the higher 'prepared meal' rate (because that's a luxury).

One candy bar is taxed at the grocery rate, because it includes wheat in the ingredients, while another is taxed at the junk food rate because it doesn't. They're both mostly chocolate and nougat, but one has some wheat, so it's legally considered a cereal.

And of course all of that varies from town to town and state to state, and sometimes even in different neighborhoods within the same town. And of course, some towns cross those political boundaries. I used to live just down the street from a shopping center where the tax rates were different depending on which store you were in (east side of the mall vs west side of the mall).

That's all before you get to sales and specials and membership discounts and such. Oh, and tax-exempt shoppers (because they work for a charity or something).

People always make fun of the U.S. for not just putting the total final price (tax included) on the shelf but the reality is, we can't because quite often we just can't know what it will be until you checkout.

For something that seems so simple and everyday, it really is bafflingly complex.


What an interesting and timely article.

My extended family recently opened a pizza place which just happened to be at the same time as me wanting to take a break from startup grind. I worked at a pizza place in high school, and have continued to make pizza at home, and loved the idea of being able to combine that knowledge with the experience of building software startups, so I have been heavily involved in the last 6 weeks on everything from ordering, to kitchen layout, to POS and other IT systems, to marketing.

In short, the experience has been super interesting, not only in terms getting to learn tons of new things and get familiar with how the tech side is done (spoiler alert, not that well) but also just generally how much of an opportunity there is to take the sort of thinking and skills required to build tech products and to apply them to a quick-serve restaurant (and I would guess lots of other small business).

I have been planning on writing something up, but this article is giving me good motivation to actually do it :)


I wouldn't be surprised if the author visited your newly opened place and was inspired to write the article based off their experiences! It's a small world, after all.


You should talk to some of your local newspapers/culture magazines about your experience as well, they love these types of stories and you can get free exposure for it.


> That means you shouldn’t have something like a reference to a product’s foreign key to dynamically grab the price when you render the receipt.

This is vastly underrated principle that is rarely understood and should be much broadly applicable. My data is separate from other people's data. In Carta, I have had my startup investments leave the system (die, acquired, etc) and I am left taking screenshots of everything because my records are just foreign keys into some other data store. If they had mailed me PDFs even paper or something, I would be fine.


I feel like this is one of those cases where people take a mantra too seriously.

Storing values that could otherwise be derived results in complexity and discrepancy.

This may lead people to the conclusion that all values which can be derived should be derived, but in the case of a receipt/invoice, this is not the right call. Discretion must be applied.


I think the biggest deciding factor in this particular situation is what the article says in the sub heading. 'A “Receipt” is immutable'. You don't care about the consistency guarantees of normalization. You don't care about being able to re-derive it with new logic or additional features. And in all likelihood the storage savings from not storing the final generated output is going to be miniscule.

If some data is meant to be truly immutable, and storing it separately won't impact your storage costs, store it separately. Because otherwise that immutability needs to be somewhere else in the system.

If you normalize your data and dynamically derive receipts, your logic needs to include all receipt logic you have ever used, cordoned by timerange. Was the price of a large Pizza changed in 2018? Your receipt logic and data has to reflect that forever. Did you allow stacking coupons but in March 2017 you started limiting it to 1 coupon per customer? Your receipt logic and data has to reflect that forever. Did you have a week where prices were rounding in the wrong direction when a certain coupon code was used? That has to be in your receipt handling forever.

There's just so much additional effort, so much potential to go wrong, and so little to gain.


your comment doesn't provide when to decide one way or the other, which makes it more warning and less useful.

when the data is stuff that could be paperwork - you get a copy, i get a copy - it should not be the case that one side gets to unilaterally decide if the data is deleted or modified.


I think it is not difficult to decide: sometimes you want to reference an entity with its current state, some other times you mean with the properties that it has at a specific point in time.

For example if I don't pay yearly tax on my car I will receive a fine. The fine may arrive one or two year later, but it should be sent to me even if I sold the car meanwhile, because what matters is that I was the owner at the time. On the other side, the fine should be sent to my current address, not the one I had when I forgot to pay.

There a number of ways to handle this. The simplest is to make a copy of the data, but you can also decide to keep all the historical data and reference the state during a certain time interval. Both can be valid choices, depending on the context, frequency of change, number of references....


I am in agreement with you.

I’m just saying that developers need to apply discretion rather than following arbitrary “rules” or “patterns”. When to store or derive depends on the use case, of which are infinite.


The general way I'd do this is to have the foreign key, but not to a "current prices" table, rather to an "all prices" table containing present and past prices. Which goes back to immutability. Maybe over-engineered for a small pizza shop that could get by fine with $ values copy-pasted everywhere, but we're talking about general principles.

It's not like the customers' data is meant to be separate, like they're all paying the same price that we decided for the day, other than promotions which would be a separate table or misc adjustments that would just be a col directly on the sales table.


There are a lot of things that can change, not only the price. The name of the product can change. What was "Medium crispy crusted pepperoni pizza" yesterday, may be called "Extra large pepperoni pizza" today. If you re-print the invoice, it should look the same as on the first print. Otherwise you may get some issues with the authorities (manipulating your copy of the invoices).

There may also be a lot of related tables for finding the price (in the system I worked it was about 10 joins to get from the article to the price). It can be done in an immutable way, but it is possible that the way of calculating prices may change after an update. There may even have been a bug in the first place (like incorrect rounding, issuing rebates that shouldn't have been issued, incomplete sync of the prices table from the main server to the cash register, ...). Once you fix it all the previously issued invoices would show a different price. Which means you "lost" your copy of the invoice. Authorities don't like that. Credit card companies don't like it, if the customer disputes the charge and you show them an invoice with a different amount. Your bookkeeper doesn't like it, if a lot of payments don't match the invoices exactly, ...

Edit: Example for rounding: Two people split a pizza for 19,99$. Version 1.0 creates two invoices with 10,00$ each. Version 2.0 creates one invoice with 9,99$ and a second one with 10,00$. Then the authorities pass a law that rounding prices must always floor them. So Version 3.0 creates two invoices for 9,99$.


Right, other things can change, and you record those changes as immutable rows in a table too. You don't forget that the "super pizza" used to be called "uber pizza," so you can print the same exact receipt again, but you know they're the same product.


Sure, you can do that. But if you do some changes in your data model or logic you need to be extremely careful that all existing invoices still show exactly the same data. You probably need to use immutable price calculation logic for that too. Keep the old logic after an update and only use the new logic for new invoices. Because over the years there will be braking changes in your price calculation logic.

A lot of effort for not so much added value. The systems I worked on put the calculated price of every item on every invoice into the database. So it can’t “drift“ over time. Off course they still keep the reference to the article too.

It’s also much easier/faster to calculate sums and statistics one one table column instead of doing many joins every time you need the price.


Maybe I'm not thinking of a complicated enough case, but I don't see why there'd be so many breaking changes. Say you add a new table for some special kind of promo, that doesn't affect the old receipts. At least this wasn't an issue in the last few e-commerce sites I dealt with. In any case, I would stay far away from having to preserve multiple versions of logic.

It's also fine to denormalize a bit by copying the final price somewhere for performance, convenience, or sanity checking, but that's the kind of thing you bolt on after. If you're managing account balances, you actually need this for concurrency control alone.


I think you can't compare e-commerce to POS.

Another example: A customer can stay a few hours inside a restaurant. Their tab stays open during that time, items are added at different times, and in the end the tab is closed and the invoice created.

Prices of the items could change during that time (somebody noticed a wrong price during the shift and fixed it). There could be a happy hour with lower prices.

Let's say Version 1.0 uses the prices that were valid when the invoice was finalized. Version 2.0 implements a happy hour feature, and now prices need to be calculated based on the time the item was added to the invoice. Without the right backwards compatible logic that may change the previous invoices.

Or let's say you have two branches with one POS system. It's a small business, so they don't have a redundant internet connection, and a system that can work offline. One branch goes offline for a day, they receive the price updates a day late. They may know about that, but off course they don't close for the day, they just keep operating with the old prices. Their system will sync back the created invoices once connectivity is established again. The manager notices it and calls the branch to update the price for the caviar, because it recently tripled and that's a really important change. So they change the price of that item now in the disconnected database, at a different time than in the main database. On the next day the branch reconnects again and you need to sync that. Sounds like fun, doesn't it? :D

It's much easier to just copy the new invoices to the main database as they are and replace the price list with the version from the main database.

Let's imagine an airline, with a lot of cash registers on the plane for food and drinks. Some of them don't connect for maybe a week on a regular basis.

There are perfectly immutable solutions for all those cases for sure. But they may become really complex really quick.


If you mean just recording the product without the actual price used, that loses information and isn't what I'd do. I would write the price IDs that were used and input different prices during happy hour. Same complexity as writing the $ amounts except I'm writing fkeys instead so I track which pricing structure was used.

If the customer uses a coupon, I relate to it. If I have a distributed system with often-disconnected followers, I sync in new prices and coupons without affecting the old ones. If local managers are allowed to temporarily change prices, I preserve the local price when syncing in the headquarters' price (in fact the local one would probably be in a separate "price overrides" table).


Isn't it the easiest to copy them in with the price that was charged?

I don't imagine it's fun to find out that the price charged did not match the price list, after you've already forgotten how much you charged


The systems I contributed to did exactly that. They stored the resolved price and other metadata to the invoice tables. To store the exact prices, article names and so on that the cashier saw on his screen and the customer on the printed invoice. Even if the price calculation was wrong in the first place, that is the data that was available at the moment of the sale and that is what the customers paid. Correcting the invoice is a manual step anyway, the customer needs to come back, dispute the invoice and ask for a refund. If the customer was charged less that's usually just bad luck for the business. "Fixing" the bug in the database/software doesn't get them the missing money.

Another thing are prices from external systems. For example if a hotel puts parking charges on the invoice. They may park the cars in a garage of another company and on check out they validate the ticket with the system of the external company and just put the calculated price on the invoice. "Parking - 43.21$". There may be no price calculation for parking in the hotels POS system at all, so no relation to a price table can be referenced.


> A lot of effort for not so much added value.

It's not a lot of effort; in fact I'd argue it's free, or even negative cost. If you're in the habit of following that paradigm then it's no harder than the mutate-everything-in-place paradigm.

> It’s also much easier/faster to calculate sums and statistics one one table column instead of doing many joins every time you need the price.

WTF? Did 1970 call and ask for their hardware back?


I've seen POS databases with millions of invoice positions. There is a substantial delay if you do 10 joins on a few million records. Calculating a sum over one column of millions of rows is substantially faster. It could be 2 seconds vs 200 seconds.


> WTF? Did 1970 call and ask for their hardware back?

The joins can actually get slow enough to matter for a UI. Depending on your use case, denormalized $ values can make total sense, but that should be separate from your properly normalized tables.


I made an online store where I just stored the price in the order itself, as an immutable snapshot of the price at the time of purchase. I also included the product title and SKU, just in case someone decided to reuse an old product instead of creating a new one (it happened several times)

Alternatively you could go "all in" and create some form of versioning system, where you store the version number of the product


What happened when the tax _rule_ changes?

Do you keep the code for every historical tax law in your country?


No, I'd store the sales tax structures (%, city, etc) in the DB so we're not forgetting where the final price adjustments came from.


The receipt sounds like a place for an event driven approach, IMHO. It’s more like a journal entry in an accounting ledger.


> You would still want that free pie to be put through the workflow and tracked. The only difference is you wouldn’t collect a payment.

In some jurisdictions you don't just want to put the pie through the POS system, you have to for both tax reasons and to make sure your employees don't ring up their friends on "faked" coupons.

The rest of the article is really nice as well and reflects with my personal experiences in bartending... indeed having experience in hospitality jobs is a major plus for anyone working in IT or design, simply because you learn to value first hand how important performance and good UX is at some of the highest-stress jobs there are.


Lots of retail businesses have a sign that reads "If you don't receive a receipt, your purchase is free!" It enlists the customer as an auditor to make sure the employee uses the POS system, rather than pocketing the customer's payment. If the cash in the till doesn't match receipts at the end of the day, the proprietor knows something's wrong.

(Just in case you're one of today's lucky 10,000.)


As a teenager I worked at a popular coffee chain. Once I started working the cash register autonomously I got very lightly reprimanded by co-workers for charging a customer (I forgot his name, this was a long time ago). They were like “oh you charged Tim? We don’t charge Tim!”. There were a couple regulars who we didn’t charge. I’m not sure if they were people on hard times or friends with the franchise owner.

It’s something I wouldn’t have expected to happen regularly before I worked there and I surmise it happens everywhere.


Wouldn't it just be easier to stop accepting cash? Dominos is card/internet only.


Some people (a vanishingly small minority, admittedly) will only use cash. But some more realistic reasons for accepting cash:

- 3% credit card fees aren't nothing when your entire business operates on 4-5% margins

- It's much harder to launder money if you're 100% cashless - if you have even a small proportion of legitimate cash buyers you can now funnel more illicit money through that


FWIW handling cash isn't free either. It can be 2-3% as well (depending on a lot of things like volume, change requirements and typical patterns, insurance can be less if you have no cash on premises, ...)

In many cases the cost of credit cards and cash are surprisingly similar. Especially in Europe with capped fees.


Not that vanishingly small once you start working with the poor. A lot of those folks don't even have checking accounts, never mind a credit (not debit) card.

This has been a real issue in a few places that have now banned cashless, because it puts a heavy burden on the un/under banked.


Some people (a vanishingly small minority, admittedly) will only use cash.

130 million Americans don't have a credit card: https://www.fool.com/credit-cards/2020/11/19/nearly-30-of-am...

Six percent of American households don't have a bank account: https://www.fdic.gov/analysis/household-survey/index.html

Outside the tech bubble, it's not "vanishingly" small at all.


Dominos is card/internet only

Where you are. You are not everywhere.

The Dominos down the street from me takes cash.

In a growing number of cities, it's illegal for a retail business to not take cash.


If the merchant had another means to accept payment, sure. The sign has been around since the invention of the cash register, possibly even earlier.


But you don't receive a receipt until after you pay, so you'd already given them the money before you realize if you're getting a receipt or not. That means you have to then escalate the issue, cause a scene, take up your time, deal with the whole your word vs theirs, etc.


I'm probably missing your point. The cops don't show up to every crime scene, but the chance they will is enough to deter crime.


Unless you know the owner is a Mensch, don’t be a narc. Let the underpaid overworked employee pocket whatever. Whole Foods doesn’t fucking care.

Temporarily embarrassed millionaires eat my ass.


Until you have a problem, and don't have a receipt, and now you're out your money with a defective product and nothing to do except - buy a new one, I guess?

And I'm not sure what makes you think the person buying the thing is doing any better financially than the person ringing them up. Working class people shop too. You're letting your Poli Sci 101 take on class and economics cloud the fact that it's most likely another working class person getting taken advantage of.


The relevant parties aren't the cashier and the buyer. They're the cashier and the business owner. The whole scheme is meant as a deterrent, not as a remedy. If the buyer observes that the cashier isn't ringing up the sale, and the buyer challenges the cashier, the cashier will say "oops!" and proceed to ring it up correctly. That's because the cashier has nothing to gain by continuing the deceit at that point; either he's just letting people walk out without paying (thus risking being fired for no gain), or he's back to doing his job of collecting revenue in exchange for his wage. In any rational play of this game, the buyer ends up the same -- paying what he owed for the sale.

This assumes, of course, that everyone is behaving rationally. If you believe grocery stores are evil, as the parent comment suggests, I suppose you also believe you have license to make up your own rules.


A memetic formula for societal decay has never been expressed so succinctly.

It's "Fuck you, got mine" all the way down.


Solidarity between workers. No tears for Bezos losing the price of a broccoli.


If you see someone stealing food, no you didn't.


Or really in any job in general where you actually use the tool for longer periods of time.

So that "eh, it's not that slow" and "It's only extra click" will bother you to no end when you have to constantly waste time on it.


The value of domain expertise in combination with technical expertise cannot be overstated.


When they first started calling these systems "POS", I thought that it was an unfortunate coincidence that they used the common acronym for "piece of shit". But later, I began to wonder if it wasn't intentional, a kind of inside joke.


Regan faced the engineers and fought to keep the annoyance from reaching his face. "What did you call it?"

"POS." Brenda's bubbly demeanor was reflected in a little dance that she did while saying each letter in an almost singsong pattern.

"You ..." Regan stops fighting his instincts, takes off his glasses, bows his head, and pinches his nose. "All of you understand that we can't call it that."

The rest of the engineers stood silently and without movement. They have to have planned it this way. He should have known something was up from the moment he walked in here.

"Why's that?" Brenda tilts her head to the side.

"Because it stands for piece of ..."

"Point of sale." Brenda blurts out before Regan can finish.

Regan slowly puts his glasses back on. "Is the POS going to be completed by the deadline?" He forces the words out through a clenched jaw.

Brenda remains still with wide eyes and a frozen smile on her face. The rest of the room nods that the deadline will be met.

"Then fine." Regan leaves; they can make the deadline then they can have their stupid little name.


Some people on the IT side where I work who deal with these things on a daily basis do that. Even I sometimes see POS as "piece of shit" now, even though whatever documentation I'm reading is obviously referring to 'Point of Sale'


Began my coding career because of the family hotel business. Started coding websites, progressed onto building status boards (vertically mounted tvs) for the today’s Programm, dabbled in document management (instapdf.com), employee management (baseping.com) and worked my way up to actually implementing 3 different versions of iOS apps interfacing with different POS systems (ordervisto.com). Getting live feedback from these systems was invaluable and really helped with finding out what works and what doesn’t instantly.

The hotel is sold now and I’m wondering if I’ll ever work in such a challenging and multifaceted environment again.


Has Undercover Boss taught nothing. Things are never how you think they’ll be with boots on the grounds. DoorDash was so right making devs do like an hour of actual gigging. Yeah, shit is really pretty and seamless from your Herman Miller chair and Uplift desk…


Yeah builders should understand the domain they're building for as well as humanly possible. On the topic of chairs, imagine the difference between a chair built by someone who has never sat in one, and someone who is absolutely passionate about sitting in chairs and is looking to build the perfect most comfortable one. It's actually deranged that such a large portion of the software industry has built up an insane game of telephone between the builders and the users and convinced people that it's an essential practice for success.


This is also true for regulatory regimes. I've been shocked at how cavalierly some regulators will treat decisions that have career altering consequences for those being regulated.

It doesn't just affect the regulations, it also means their entire mental model of how the regulated will behave can be wrong.


This is what happens when you view your job as "make regulations" (or even worse, enforce the ideological will of $PERSON on $INDUSTRY) instead of "make $INDUSTRY safer and better for consumers and the public."


I knew an early dev at DoorDash, and he hated that policy.

That said, I personally agree with that approach. It's the practical vs academic argument: the ideal is both. Anecdotally, the most productive dev on my team was hired from a customer of ours where he personally used and integrated with our software.


My son worked at Chipotle. The biggest problem with their system was inability to set a time-to-ready for online orders. Delivery time was set fixed to say half an hour, no feedback from the location. So in rush times there were a lot of unhappy customers, venting their unhappiness on personnel and - forget tips (during rush hour!).

If developers had experience at retail locations… strike that - if persons responsible for software purchases had experience at locations, this probably would have been avoided.

The article also does not mention communicating time-to-ready back as an issue. Or may be I’ve missed it - too many details already…


I worked at Domino's from about 2011-2013. Their digital system was really impressive to me. The POS was pretty good for fast-food. But what really impressed me was the station management system, aka the pizza tracker.

An order had to be keyed in/out of each station to the next by employee pin. Each station had a screen displaying the pending and in-progress orders. It was connected to the "pizza tracker", so when it said "John is adding your toppings" it really meant someone else had keyed it out of the sauce/cheese station and "John" had keyed it into the toppings station. Orders came in from the cashier or online, then went to dough/sauce/cheese, toppings, oven, prep (cutting and garlic crust sauce, dipping addons), then delivery.

Of course on things like superbowl Sunday "John" was just the manager keying in every station and deligating orders manually, because that was still slightly faster.

But what really impressed me, after a few other years of various fast food jobs, was that it was not tied to any financial incentives. Managers couldn't view the historical data in any way. There were no bonuses or rewards based on it. So there was no reason to lie and send it to a new station screen early.

I had worked at Burger King and Taco Bell prior. At both of those locations there was a similar, but simplified system. You keyed in an order as taken. Then as done. Then as served. From what I could tell, management bonuses were based on certain metrics on these times. The burger king actually had a single 8 segment display hanging in the kitchen showing us our current letter grade (A-F) for performance in the past hour. We were told to just key in any order that would take longer than normal as instantly done.

Domino's must have had some great data to optimize their kitchens on. While BK and Taco Bell have their kitchens telling them everything is fine, because they will be punished if they say some new specialty sandwich takes too long to prepare.


I worked on/around Pulse (the POS system), Pizza tracker (GPS), Order screen, and other backend systems in the largest Non-US market for a few years. Other than Pulse, most of the instore software appears to have been market specific. The managers didn't have person specific data, but the Franchisee and Headoffice does -at least in my market. Also Tracker data was used for awards at the end of the year at Rally by the head office (best avg delivery time, most deliveries, highest reviews, etc - again this was out of the GPS system). The in store tracking data was never clean enough to profile employees in our market as the instore people were trained to move and cover others during a crunch. (to the extent that in our market we didnt' track instore stations that often)

In my time at a national Dominos HQ (several years), we were told Pulse was being re-written but it never arrived. It was managed by the US HQ, and all the international franchises (Each country is a franchise, that then subfranchises) were required to license it -we assumed it was calling sales #'s home to validate franchisee payments. The POS system has to handle an enormous db of combos/deals/sizes and then filter by available ingredients, national sales, buy one get one, franchisee overrides, which was then patched to have overrides that match the online ordering every hour. (eg. national large peperoni sale, limited by franchisee to just buy two get one deal, only off peak, on tuesdays, when sales are slow). Oh and it has to run on comodity hardware that the franchisee paid for 5 years ago and is too cheap to replace.

The fun logic was in profiling stores and making predictions about ingredients requirements.


That's really cool. I gotta say as an employee, the system was pretty awesome. My store also had computers for the POS which were orders of magnitudes better than any restaurant I had worked, which probably helped as well.

I worked a corporate store, which might be a difference. But I remember our awards being only based on orders delivered, time until ready for delivery, and customer reviews. I was told actual delivery time wasn't up for awards because they didn't want to encourage reckless driving. There also wasn't any sort of GPS system for drivers, so tracking that would have been unreliable anyways. I was one of the only guys with a Garmin and the old-timers made fun of me for using it.

I'm surprised there wasn't more profiling the data for bottlenecks on the menu. I remember several improvements while I was there. The bottle for the garlic crust sauce was changed which made it way less messy to use. And the pan pizza underwent like 5 revisions. I think my store was one of the first to trial it because at first it underwent changes every other week. The first version took at least 3x as long as a regular "hand tossed" pizza to go from ordered to oven. It was such a pain. They eventually made it as fast to make as a regular pizza. I always assumed they were using the tracker system to help notice this.

> The fun logic was in profiling stores and making predictions about ingredients requirements.

So here's a funny story. Every weekend my store would run out of feta. The nearest neighboring store would also run out of pepperoni. Neither store's management reported it or anything, instead our stores would do a trade of feta for pepperoni every Friday.


> Managers couldn't view the historical data in any way. There were no bonuses or rewards based on it. So there was no reason to lie and send it to a new station screen early.

It seems like the system described would be resilient to that? If there were incentives, tracking, and punishment, the process still involves the earlier-stage employee keying the pizza out and then the later-stage employee keying it in. If the earlier-stage guy benefits from lying about how quickly he finishes his stage of the pizza, how does he persuade the later-stage guy to take the fall of incredible slowness by keying the pizza in to his stage early?


At the other places I worked, the main persuasion was the manager being less of a hard-ass. With delivery it's a bit harder, customers will probably complain if the online tracker says it was delivered and it actually is still in the oven.

I still think not tying metrics into goals made a big difference. The manager goals were things like store profit and customer satisfaction surveys.


I work for a POS company and yeah, it's crazy how much more complex something like this is than you think at first.

Another wrinkle that wasn't covered in this post: variable pricing.

What I mean by that can best be explained with this example: You have a S/M/L pizza but the additional toppings are priced differently for the S vs M vs L ($0.50, $1, $2). But you probably want a "Toppings" option set with choices like "Sausage, Tomatoes, etc" that's reusable across all your pizzas (for stock/reporting purposes). Also you want to be able to mark a topping as out of stock and have it apply to all your pizzas. So how do you handle the price differences? Remember this 1 option (Size) modifying the pricing for a totally different option (Toppings). Also you might want to set this on a per-pizza basis, since you also need to modify the "Toppings" option to include "Beef, Sausage, and Pepperoni" for free on the "Meat Lovers" and you also need to have some kind of handling for "2-Topping pizza" where you get 2 toppings for free then have to pay for any extras.

Another fun concepts is bundles. Maybe you want to offer a pizza+2-Liter or 2 2-Toppings pizza deal. All of it gets extremely complicated very quickly. Even more fun is finding a way to translate your internal menu structure into something DoorDash/etc can understand and let me tell you, it will /not/ be a 1-to-1 mapping.

Sure, for something like variable pricing you could just say "screw it" and make all additional toppings $2/each (let's pretend that's what they cost on the Large) that way you are always doing as good or better than your normal POS or you could "flatten" all your menu items so you end up shipping "Small Pizza", "Medium Pizza", etc over to DoorDash (Don't forget, you have to do that for every pizza then unflatten it on the way back into your system). Don't get me started on how DoorDash does testing, they literally use their live site for testing. There is a town in Alaska where they add your demo location to and they give you a login with a card on file that they just refund at the end of the day or something like that. It's super janky.


That's a good point about the toppings being different, especially on different types of pies or slices. For example on their personal pizza, there isn't an option for half toppings, it's full or nothing.

We do have bundles, such as multiple lunch or dinner combos. They are a distinct menu item in the POS system as "Dinner combo 1" with a description of what's included.

What was really fun was helping design a printed menu where we wanted to display 25 different pies in S / M / L variants as well as having gluten free options for most of them. We opted for a 3 column price layout for the 3 sizes and put gluten free in its own little section with a different way to associate the prices to at least 20 different pies since the size and price was the same for all gluten free options.

It was a good lesson in dealing with "actual constraints". Especially when the font size couldn't be reduced and we couldn't use more than 1.2 pages for listing all of the pies.


Back in college we ordered pizza and when the driver arrived there was some confusion finding money for a tip and after he was gone we realised that three of us had given him cash. After that every time we ordered it seemed like the pizza arrived in minutes. We assumed that someone had put a note in their system next to our phone number like "amazing tippers".


There are a few nice restaurants where I've given a normal tip but in cash, which isn't common there, and it seems like waiters remember me (in a good way) just because of that.


Early in my career, I learned that it's possible to accidentally credit thousands of dollars to people's credit cards instead of charging them.

On the bright side, I learned a valuable lesson and did not get fired.


As someone who has built the tech behind an online ordering platform just for pizzerias (Slice), this is all exactly on point.


Hah, it's a small world. That's the system we're using. I wonder if you could tell based on the terms I used in the post.


That’s awesome! I can’t claim to have quite connected the dots, but it caught my eye right away and completely vibed. Great work breaking it down and writing it up so nicely!


If anybody here is suddenly considering a startup in the PoS industry, please just turn around and run as fast as you can in the other direction. It's an endless pit of hell.


> For example, if a pie costs $16.95 right now and you have 1,000 orders that happened in the past at that price and then bump your pie to $17.95 you can’t go back and adjust all of those previous orders to have $17.95.

> Just about everything about that receipt should be denormalized, AKA. the details about the receipt are all self contained in that 1 row.

The way I'd probably model this would be to mark the $16.95 pie as deleted/deprecated/no longer for sale and create a duplicate entry with the price changed to $17.95, rather than creating copies of all of the product details each time I record a sale.


> The way I'd probably model this would be to mark the $16.95 pie as deleted/deprecated/no longer for sale...

That technically works, but it plays hell with reporting and stockkeeping. The latter of which isn't a problem for pizza, of course, but can be significant in other sectors. (Nobody wants to have to keep track of a stock of "$16.95 widgets" separate from a stock of identical "$17.95 widgets".)

But there's enough other data in a receipt/invoice which needs to not change after the invoice is created, like tax rates, that it really is best to make the whole thing self-contained and immutable. Being able to confidently make statements like "yes, this is exactly the same invoice that we presented to the customer 3 years ago, and nothing about it has changed" can be incredibly important as well.


How its handled in the system I work in is that a copy the product data is made to a new object. That new object gets converted to a final invoice eventually.

A product is copied to a quote (or cart) item. A cart item is copied to an order item. A receipt or invoice is generated from an order and its items. The price of products and all their attributes can be changed without the SKU or identifier changing, but the quote, order, and invoice item is an immutable artifact.

The key problem with this system is order modifications. In order to modify an order you cancel and recreate the order from scratch. We get around this usually by piping the orders to a dedicated order management system and when orders are finalized/auth'd captured/shipped there is one final order modification that comes back to the system to capture the final state and we don't update orders continuously. This way customers see their final order state, but we don't have to cancel/recreate every change to the order along the way.


Just as the receipts are immutable, you should preferably have your products be immutable too. From the user's point of view, the foreign keys are a part of a separate layer: They will only see the products by a shortcode/name. In turn, having a modification on a product (or any other object) 'archiving' the existing version and creating a new copy can be made seamless while avoiding normalisation.

Is it a better way to do it than an audit log for changes? Maybe!


That works great until you want to see how many pizzas you sold of each size last year then you realize that you presented wrong data to the CEO because small pizzas changed price in January and large pizzas changed price in July. Your reporting only included the "current" products so the counts were all off.

The ideal schema would probably have some sort of "product" and "product revision". Orders would reference a particular revision and menu/reporting would use the product (joining in the revision).

But in this case since there are likely legal requirements to have exact copies of receipts it may also be smart to just archive a "fully rendered" copy as well to ensure that a code cleanup doesn't change rounding and accidentally modify the data on old orders.


I get your point but I am not quite sure about that example. If you have the receipts linked to a certain version of a product (via an unique ID) in a give receipt, then you can easily derive these figures via a separate item code. A large pizza could be PIZZA_L and have revision IDs 1, 2, 3... I assume that's what you mean by product/product revision, you don't need a separate table for it per se (as any number of fields for a given model may need to be changed, which makes the classification of what field belongs where much harder than having one model and a shared identifier).

You can always prepare a bad report, I don't think that this schema or that schema will solve all problems, but having a schema which keeps a complete history of changes to its data should be better than one that just lets you run an UPDATE query to actually mess the price history up.


Traditional point of sale systems generally have the notion of a “transaction log” or “tlog” which is a sequence of events within the transaction including items sold and their price at the time.


You could also use a temporal table.


This is a great article. IMO engineers and product managers building e-commerce and related systems should at the very least spend a few days at a physical store to observe and document how they work. A great number of engineers are asked to build software in domains for which they have very little idea.

For example, Uber engineers would learn a great deal by spending a few days with a driver. They can then place their own system components in context and make sense of it all.

Failing to learn domain knowledge has resulted in so many half ass wheels being reinvented.


20 years as an eCommerce developer/architect.

This is really good for a first take. It covers quite a lot of what we document in most of our initial pre-project planning sessions. A couple considerations not covered here that we would dig into are:

.05) Integrations! A Point of Sale and a Website an Enterprise Record System, a Product Information Management tool, A content management and authoring tool, A digital image and media management tool, Warehouse management and Order management software, and Business Intelligence Data Lake, Customer Data Platform, Email Marketing Platform, Ratings and Reviews Service, Search, and a rainbow of minor 3rd party web based services don't really help much unless they all talk to each other. Nowadays, you also need a way to mix the data from all these services together to provide unified data management and a unified user experience. To achieve this we usually build a dedicated orchestration layer to handle the services that merge data from all these sources.

1) Products. Bundles, Groups, Configurables, Packs that can or cannot be split, special pricing (distinct from discounts), add-ons, virtual products, inventory, stocking from warehouse, resale through market places or other omnichannel availability, attributes that affect pricing or shipping or purchase availability, etc.

2) Order Management. Order modification and workflows for different types of returns and exchanges. How long/can orders be modified between placement and delivery. How are chargebacks and price differences handled? What's the workflow? How is manufacturing/warehouse/shipping notified?

3) Sales channels. Specifically BOPIS (Buy Online, Pickup In Store) inter-store transfers for sales, or inventory stocking), delivery types (freight, refrigerated, courier, plus the usual UPS/USPS/FedEx options). Return and delivery tracking services and customer assistance programs.

4) Reporting. Financial, marketing, service and technical performance, Data Warehousing and Cross functional Business Intelligence, taxes, refunds, breakage, etc.

5) Customer service integrations, customer management, customer support, ticketing and tracking through customer data platforms like Salesforce.

6) Loyalty and reward programs including virtual and physical ledgers of points and campaigns to earn points. Loyalty as payment type. Ratings and reviews. Social media engagement. Gift cards.

7) Transactional communications systems such as email, text, and social media integrations, mailing lists, newsletters, and push notifications.

8) Multi-language and international sales considerations. There is a LOT to consider here. From tax to payment types, to product availability and shipping.

9) There is a mention of payment types, but payments get so much more complex than what is covered here. Who is your merchant bank? What payment gateway to use? International payments get even more complex. When to auth and capture. Services to tokenize and preserve payment info for future purchases or changing order amounts.

10) Fraud detection for payments. Mitigating carding attacks and other fraud attempts through monitoring and 3rd party integration.

11) Recurring payments/subscriptions.


For the love of god don't forget taxes.. fucking taxes.

Federal, state, local, type, etc.


I hope your taxes system has a concept of only applying to certain item groups and/or certain specific items. Some places have food taxed, others do not, water isn't taxed, alcohol is taxed differently, food with enough sugar is taxed differently than just "food", and the list goes on.

Also your clients might want to be able to add their own "taxes" (aka service charges) for certain days/weeks of the year or by the channel that the order was placed.

POS system are incredibly complicated and even more-so if they span multiple restaurant industries or types. Think table service vs drive thru vs carryout vs curbside and things like pizza vs coffee. A lot of what you build will not transfer over. Your logic to handle half and half pizza probably isn't going to be reusable in other industries.

I will say one thing, it's never dull.


Your coffee in a café in Germany is taxed differently based on the amount and type of milk in your coffee. Oh and of course the tax rate is different depending on whether you consume it in the café or take it to go.


I seriously thought you had to be joking. But no! Ok I figure, the carbon footprint of milk is massive[0], it must be taxed at a higher rate?

> In some European countries, plant-based milk is subjected to a significantly higher VAT than cow’s milk.

Still haven't understood this one yet though. Some kind of protectionist tax rate for the farmers?

[0](https://www.co2everything.com/co2e-of/milk)


This is 100% normal and happens in America. It's a huge reason why hard seltzers took off. (They're brewed instead of distilled)

On top of this, you can have local based taxes or tax breaks. (I.e. Chicago has a bag tax, leave the city.. no bag tax)

https://www.efile.com/unusual-strange-funny-taxes-throughout...


On the other hand, here in the US, I can walk into one location of a store, and tax is X. I walk 3 blocks to another location, and tax is Y.

That's because one is juuuuuust (like 100ft) outside the city limit and county vs city tax is different.


Delivery is taxed if the food is taxed...in most jurisdictions. You could easily have any variation apply in edge cases. Your software has to do it all.


I'm building an online ordering system right now. Just for pizzerias. Generalized systems suck hard.


Service charge isn't a tax. It's the POS's flexbility with autograting.

It maybe considered to be taxable.


I include that mostly under integrations. These days most companies are smart enough to use a centralized service instead of rate tables. The services are pretty good and provide pre-built integrations for most common frameworks. A security audit, install, and QA and you're 90% done.


My first job was supporting and developing order related systems for retail and wholesale (separate systems, but we operated both the wholesale and retail operations).

Wait until you start having to deal with Forward Orders, Back Orders, Special Orders, Cancelled Orders, and Refunds. Not to mention the General Ledger postings you have to make for each transaction too.

An "order" sounds super simple, but there are so many variations and corner cases.


I tried to order a pizza at a big pizza chain near me, but their website wouldn't take my address!

It was one of these autocomplete drop-down but it won't let you enter anything not in the options.

I tried calling them but the guy on the phone was also telling me the system wouldn't accept my address!

In the end he did the delivery himself since there were not a lot of customers that day and knew the correct address.


So if I'm familiar with databases in general and slightly familiar with financial transactions, what's the most surprising thing about the pizza payment systems in particular?


There are no big surprises. There are hundreds of tiny ones. You need to identify them, keep track of them and don't miss any.


Every few quarters a post like this shows up on HN from an engineer who has ventured into sales reporting. Always a good reminder on why project scoping is so important!


What are the best POS systems out there?


Any that are text/TUI/"green-screen"-based are often lauded for speed once you are familiar with them, so there is that kind of best. And if they are still in use even today, then that survival is a strong point in favor of them being "the best".

As far as specific products, NCR Counterpoint is one that stands out amongst those I have used. Fast and flexible, kind of easy to figure out most things on your own.

The Costco cafeteria self-service kiosk seems to be an amazing POS (customer perspective). Incredibly optimized in every regard. The receipt seems to print out before you have even finished removing your card from the chip reader.


You stick it in? Sometimes it feels faster than tapping!


Anecdotally (in Australia), as a customer I found the square readers [1] linked to ipads were the smoothest and quickest. And I use a mix of cards - credit, prepaid gift cards, debit.

[1] Probably this thing: https://squareup.com/shop/hardware/au/en/products/chip-credi...


Klarna has none of those issues. disclaimer: used to consult for a bit at Klarna. But payment sure is a solved problem.


I recently tried to use Klarna, and I can only say that of course payment is a solved problem when you just lie to customers until it's too late in the checkout process to cancel it. Never again.


In my day we didn't have a fancy computer to calculate change. We had to count up change, just like my grandpappy did in nineteen-aught-three. And change! MEH! All we had were sheets of zinc and steel and copper foil. We had to manually pound out pennies in the back of the shop in a mold stolen from the mint in DC. And even if we did get a computing device, all we had were zeros. We had to pound half of 'em into ones manually. AND WE LIKED IT THAT WAY!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: