Synchronization
Unlike absolutely everyone else's, and for a whole host of very good reasons, our synchronization mechanism is completely decoupled from the creation and modification of transactions, subscribers, etc. There is no webhook for pushing updated data (changes) to you. You pull changes from us:
We call this synchronization mechanism seq because it fetches a sequence of events. Fundamentally, what you're trying to do is to call seq in an infinte loop, where every call to seq uses the "seq" value returned from the previous call, like so:
localSeq := 0
loop
data := JSONDecode(GET "https://api.scanpay.dk/v2/{shopid}:seq:" ‖ localSeq)
for each change in data.changes do
Update(change)
end for
localSeq := data.seq
end loop
However since seq does not block until a new change comes in, this would result in pegging the CPU at 100%. To address that, we have a service called ping. Whenever a change happens in our database, we will send a ping request to a URL of your choosing. This is your prompt to call seq:
localSeq := LoadLocalSeq()
while localSeq < ping.seq do
data := JSONDecode(GET "https://api.scanpay.dk/v2/{shopid}:seq:" ‖ localSeq)
for each change in data.changes do
Update(change)
end for
StoreLocalSeq(data.seq)
localSeq := data.seq
end while
And with that, you've implemented what was shown in the drawing. Now you're done... or are you?
There are two hard problems in computer science: cache invalidation and naming things, and unfortunately we're not talking about naming things. The requests are simple but synchronization at scale is extremely difficult and full of pitfalls. For a deep dive into the intricacies, see the implementation notes. It's long and boring and extremely recommended reading.