FAQ | This is a LIVE service | Changelog

Create payment vouchers authored by Dr Abraham Martin's avatar Dr Abraham Martin
# Payment vouchers
This document specifies how payment vouchers are handled by the Self-Service
Storage Gateway (SSGW).
A payment voucher is a small section of text which represents a payment of a
specified value. A voucher has the following properties:
* A unique id preventing "double-spending" of a voucher.
* A "value" giving the payment amount the voucher represents.
* An "issuer" known to the SSGW. (See below.)
* Optionally, a fixed user who can "spend" the voucher.
* Optionally, an expiry and start-of-validity date.
The SSGW supports multiple issuers. An issuer is responsible for choosing the
unique token id, the value to the token, the validity period (if any) and the
spending user (if any).
Administrators of the SSGW may add a trusted voucher issuer in the admin
interface. A voucher issuer consists of:
* A short slug identifying the issuer which matches the "iss" claim in the
voucher. Generally this is randomly generated using a tool such as
``pwgen``. It is not a secret so do not be tempted to use any existing
credential.
* An ECDSA public key for the issuer used to verify vouchers.
* Optionally, a human-readable description of the issuer.
For the moment all issuers are treated equally; any trusted issuer may issue a
token for any storage which supports voucher payments. This may change in
future.
## Issuing vouchers
This section describes how an issuer may create a voucher.
Firstly, you will need to create an ECDSA public/private key pair. You can do
this using the ``openssl`` command on Linux or OS X machines:
```
$ openssl ecparam -genkey -name prime256v1 -noout -out private.pem
$ openssl ec -in private.pem -pubout -out public.pem
```
Send the public key to the SSGW admins who will respond with your issuer id.
This should be used for the "iss" claim described below.
A "voucher" is actually a [JSON Web Token](https://jwt.io/) (JWT). A JWT allows
a JSON document (the "claims") to be encoded in a manner which is verifiable.
JWT supports multiple verification algorithms but the SSGW only supports the
"ES256" algorithm. All vouchers should be signed with the private key
corresponding to the public key sent to the SSGW admins.
JWT is [a standard](https://tools.ietf.org/html/rfc7519) and has an
[implementation](https://pyjwt.readthedocs.io/) available for Python.
### Voucher payload
The payload of the token has the following form. Some of the claims use
[registered claim names](https://tools.ietf.org/html/rfc7519#section-4.1) so
refer to the JWT standard for more information
```js
{
// REQUIRED. Unique id of JWT. Must be globally unique. The Base64
// representation of a v4 UUID is a good choice.
// The SSGW DOES NOT attempt to parse this value beyond using it to
// prevent double-spending.
"jti": string, // example: "njnsEdjkquFWiqfFEWjq8"
// REQUIRED. "Issuer" of token. Used to identify the private key which
// issued the token. Matched to a database of public keys in the SSGW. This
// should be your issuer id as given to you by the SSGW admins.
"iss": string, // example: "ifs-freemium"
// REQUIRED. Value of the voucher in Pounds Sterling. Must be a textual
// representation since JSON uses double precision floating point for
// numerical values which cannot represent certain common decimal values.
// (See the output of "python -c 'print(repr(0.1+0.2))'" for example.)
"val": string, // example "75.60"
// REQUIRED. Audience of the token. Vouchers for the SSGW should have
// this set to "ssgw".
"aud": "ssgw",
// OPTIONAL. Authorised user of token. If specified the crsid of the user
// making the purchase must match this field.
"crsid": string, // example: "spqr1"
// OPTIONAL. Number of seconds from 1970-01-01T00:00:00Z UTC at which
// the voucher expires. The voucher cannot be spent after this time.
"exp": number, // example: 12345
// OPTIONAL. Number of seconds from 1970-01-01T00:00:00Z UTC at which
// the voucher becomes valid. The voucher cannot be spent before this time.
"nbf": number, // example: 12345
// OPTIONAL. Number of seconds from 1970-01-01T00:00:00Z UTC at which
// this voucher was issued.
"iat": number, // example: 12345
}
```
### Header
The JWT standard allows [some
claims](https://tools.ietf.org/html/rfc7519#section-10.4.1) to be repeated in
the header. The "iss" and "aud" claims MUST be present in the header and MUST be
identical to the corresponding claims in the payload.