I am working on a service that lets event organizers sell tickets to their events online (a lot like Eventbrite to be honest).
The customers then print the tickets themselves (each ticket has a barcode) and present them at the event, where they are scanned using a mobile app. The mobile app communicates with the server and checks in the ticket code, and the person is allowed entry to the event.
Now, we have just started developing the mobile app, and already we are at an impasse. Normally, to mitigate the effects of potential server downtime, and also to avoid making a ton of requests when a lot of people attend an event, especially when those requests might be sent over a flaky 3G connection, I would go with this approach:
- Mobile app periodically polls the server and pulls the ticket codes that have been generated since the last request
- The app checks its local database of ticket codes when a customer presents a ticket. If the ticket isn’t found, initiate a data pull.
- It also periodically sends “checked in” ticket codes, so they can also be updated on the server.
This approach would probably work just fine, if not for the possibility that an event might have multiple entry points, thus making this solution vulnerable to cheating by someone printing two copies of the same ticket and using them for two separate people at different entries. We would only discover this when both instances of the mobile app push data to the server.
One workaround would be to have the applications also communicate with each other, but this raises other problems:
- Bluetooth is not feasible, because of the limited range.
- 3G can be flaky, just as above.
- Wifi availability cannot be guaranteed at all events.
I would really like to find a solution to this that doesn’t involve having to send one request for each ticket code, because I can see them now, hundreds of people lined up, the line going nowhere because the server is down, or the internet connection is down, and I can hear my phone ringing on a Saturday night, and I really, really, really don’t want that.
Sorry for the long story. Any thoughts?
4
The ideal situation is to have a reliable connection to a single server so you can verify in real time that the presented ticket has not already been admitted to the event.
As you pointed out, this is not always possible.
A couple of nontechnical workarounds:
- Use assigned seating. Holders of duplicate tickets would have to sit on each other’s laps. This is probably not an option for you.
- Since tickets are unique, it should be possible after the event to identify which tickets were used multiple times. Have the business bill the ticket purchaser for the additional admission fees, plus a nuisance fee.
- Assume most people are honest and don’t worry about it – you’ll spend more time & money preventing the problem than you’ll lose by ignoring it. (This is only sometimes true – it depends on the event and the audience)
Back to technology:
-
Obviously, a single device can check/prevent multiple entries since it knows which ticket holders have been admitted through that gate. That would limit your loss to (worst case) the number of gates you have.
-
Code for a 3G/4G/Wifi/Internet solution, but gracefully fall back to “local enforcement only” and/or “update (both server and device – 2 way sync) when able”
Since you can’t get “perfect”, go for “good enough”.
As GlenH7 has already stated, given the constraints you have listed in the question your problem is effectively unsolvable. Assuming “it can’t be done” is not an acceptable answer we’re left with having to change the constraints.
One option you mentioned involved getting the mobile devices to preload the entire set of tickets. Your concern was that fraud would not be detected in realtime.
How about relaxing this constraint of “realtime fraud detection?”
To me that seems like a decent enough compromise. Especially considering that periodic synchronizing of the system state (when possible) would help prevent most ticket fraud.
Also, the vast majority of your users 1) won’t know about this vulnerability, and 2) probably wouldn’t care enough to exploit it.
And finally, since there doesn’t seem to be a technical solution to your problem, you could consider social or legal options. For example, you could further mitigate the kind of abuse mentioned above by adding something to your Terms and Agreements (disclaimer: I am not a lawyer). I doubt it would actually be enforceable, but you could add a financial penalty to anybody trying to cheat the system.
What about an adhoc wifi network among the mobile devices essentially if a device scans something it broadcasts it to the other scanners so they know not to accept it again. You could lose data between the devices but assuming you have some level of connectivity working then you get enough data through to make attempting to exploit the system not worth it.
This solution obviously doesn’t scale well, and could be difficult to physically setup.
After the event you can dump all of the records back to the server on real wifi or whatever other communication method you want.