Kupon Plus

For retail partners

Your till. One call.

What your team needs from the dataset owner, and the one rule to get right.

Your first call needs no token.

Connecting your systems to voucher distribution

If an issuer has approached you about distributing its vouchers, we work with your technical team or till supplier on the connection to our service, from set-up to go-live. Before anything is signed, the technical talks and sandbox access are free of charge.

What you get from the dataset owner

  • the dataset name, the first part of every address;
  • X-API-TOKEN, which identifies your merchant account and goes with every call;
  • X-DATA-TOKEN, the key that decrypts vouchers; it goes with the call that issues one;
  • which IP addresses they have allowed for you, and whether the daily report is enabled for your account;
  • which voucher values the dataset holds, a number such as 5 or 0.5, and in which currency;
  • for the Advanced and Asymmetric models, the decryption specification.

Keep both tokens in your server configuration. They never belong in a web page or a mobile app, except the API reference on this site, for sandbox tests.

Call ping first

ping/200 needs no token and returns data.myIP, the address the owner must allow. ping/400, ping/401 and ping/500 return that status, so you can test your error handling before you have a token.

curl -sS https://kupon.plus/api/sandbox/ping/200

Then the first real call. Export both tokens in your shell first; the line runs as pasted and your values never appear in it.

curl -sS https://kupon.plus/api/sandbox/getVoucherByValue/10 \
  -H "X-API-TOKEN: $X_API_TOKEN" \
  -H "X-DATA-TOKEN: $X_DATA_TOKEN"

What the API does

  • issues one voucher of a value: GET getVoucherByValue/{value}, or POST with your own JSON, for example {"TxID": "tx-0001"}, stored with the voucher;
  • cancels a voucher when the sale is reversed: PUT cancelVoucher/{vid};
  • returns your daily report of issued and cancelled vouchers, generated every night between 02:00 and 03:00 UTC;
  • answers ping.

Every call answers in the same envelope {"error": {"code", "text"}, "data": {}}. The daily report alone answers as a plain JSON array on success and in the envelope on error.

Decide by error.code

HTTP 200 is not a voucher. A voucher was issued only when data.voucher is present and not empty. An empty result happens when there is no voucher of that value and also when X-DATA-TOKEN is missing or wrong, so an empty result alone does not prove the stock is empty: your cashier message must not say "out of stock".

Some refusals keep HTTP 200 and carry the result in error.code: a call from an IP address that is not allowed answers Unauthorized access (0000). The number in brackets identifies the place of the refusal; quote it to support.

There is no idempotency key. Send POST with your own transaction ID; the next day's report carries it, so an orphaned issue is found by metadata.TxID and cancelled with cancelVoucher/{vid}.

Which security model

You and the dataset owner agree how much security you want and how much implementation complexity you accept for it. The value of the codes you exchange decides, and you judge that value yourselves. The chosen model then applies to the whole dataset. What each one asks of you:

Basic symmetric

security implementation complexity

You send X-DATA-TOKEN with each issue call and receive a readable code. Nothing to decrypt.

Advanced symmetric

security implementation complexity

You decrypt on your side with a key shared with the dataset owner.

Asymmetric

security implementation complexity

You give the owner your public key and decrypt with your private key. Kupon Plus holds the code only as ciphertext, never a key.

What you are not responsible for

  • no stock of codes on your side;
  • no key custody in the Basic model;
  • no access to the issuer's network, and none for them to yours.

What does not change for you

  • Each issuer gives you its own dataset name and tokens; the integration stays the same.

Test in the sandbox

sandbox is the shared dataset for testing; vouchers issued there are test vouchers. Which values it holds depends on what was uploaded, so ask the owner if a call returns nothing. In your own dataset every call is real.

Already asked to connect? Your dataset owner issues your tokens and sandbox access; go to them first.