Ping
A request we send you when a shop's sequence has grown, so that you call seq. It says which shop, and where the sequence ends now, and nothing else.
When we ping
You give an API key a ping URL in the dashboard, and we ping it about every shop that the key can act on: one shop for a shop's key, and every shop that the user or partner has for theirs. We ping:
- As soon as a shop's sequence grows: a payment, an act, or a change to
a subscriber, whoever made it. Changes that come together give one
ping, with the latest
"seq". - Every 5 minutes after the last ping, whether anything changed or
not, with the
"seq"as it is then.
A ping that fails is not sent again: the next change, or the next 5
minutes, brings another. Pings can arrive out of order, and more than
once with the same "seq".
Request
POST {your ping URL}
We connect to your URL's host, on its port, or 443 for https and 80
for http. With https, your certificate must be valid for the host,
as a browser would require: we don't ping a host whose certificate
fails. We don't follow redirects.
Headers
| HTTP header | Description |
|---|---|
Content-Type |
application/json; charset=UTF-8 |
Content-Length |
The length of the body. |
X-Signature |
The body's signature, as base64: see Signature. |
Connection |
close. Each ping has a connection of its own. |
Body
| Field | Type | Description |
|---|---|---|
shopid |
integer | The shop whose sequence has grown. |
seq |
integer | Where the shop's sequence ends now: the "seq" that seq returns when you have read all of it. |
{"shopid":1234,"seq":164}
Signature
X-Signature is the base64, with padding, of the HMAC-SHA256 of the
body as sent, with the API key as the HMAC's key: the whole key, as
you give it to Basic authentication before base64, such as
s1234#1:FhnIJVS2ZgRi2B35.... Check it before you trust the ping:
want := Base64(HMAC-SHA256(key: apikey, message: rawbody))
if not ConstantTimeEqual(want, headers["X-Signature"]) then
return 403
end if
ping := JSONDecode(rawbody)
if ping.seq > LoadSeq() then
WakeSynchronizer(ping.seq)
end if
return "ok"
Sign the bytes as received, before any parsing, and compare in constant time. Receiving pings has the mistakes to avoid.
A ping carries no data but the shop's ID and a number, so a forged one can do no worse than make you call seq. The signature lets you skip even that.
Response
Answer with 200 OK and the body ok, at once. We give a ping 7
seconds from connecting until the first byte of your answer, and then
hang up, so synchronize after answering, or in another process: see
Synchronizing with seq.
We don't act on your answer: a ping that you answer with an error, or not at all, is not sent again, as the next one comes anyway.