Info This feature is not available by default and is enabled only for some clients

Reservation code allows to accept transaction using API, similarly to user's PIN code. Each reservation code is unique and is valid for only one transaction.

To generate reservation codes, data is needed for seeding the generator. Generating reservation codes follows this flow:

  • Client requests for reservation code seed data;
  • SMS or email is sent to the user with random code;
  • User provides this code to the client;
  • Client sends the code to the API, getting seed data as a response;
  • Client generates first reservation code from seed data, all other codes from the previous generated code;
  • Reservation codes are used by the client to accept transactions or to be provided as QR code or barcode for other clients.

Sending user request for reservation code seed data

This method initiates SMS or email for the user with confirmation code to initialize generator. This request must be made using OAuth access token, by which user is determined.

Request

POST https://wallet.paysera.com/rest/v1/generator/code

Request body structure

Request body is optional in this request.

Parameter
Type
Remarks
Description
link
string
optional
Link to include in SMS or email for quick confirmation. Must include {code}, which will be replaced with code, needed for initial generator data.
scopes
array of string
optional
Additional permissions to relate with sent code. Currently supported scopes: convert_currency - lets the same code to be used with token refresh to extend current access token scope with convert_currency

Response data structure

Parameter
Type
Remarks
Description
valid_until
integer
always
Date in UNIX timestamp until when this code is valid.

Errors

rate_limit_exceeded

Example request

POST /rest/v1/generator/code HTTP/1.1
Host: wallet.paysera.com
Content-Type: application/json;charset=utf-8
User-Agent: Paysera WalletApi PHP library
Authorization: MAC id="wkVd93h2uS", ts="1343811600", nonce="nQnNaSNyubfPErjRO55yaaEYo9YZfKHN", mac="Xtfj2zavWXLcUKWcm0G5j/+X+Ng+fV4dmplXOpvAoFQ=", ext="body_hash=XqUMu%2B1I2uXJtMXZhK%2Fc4nr0DXZ88ca63KYuehJmkqU%3D"
{
    "link": "my_app://generator/{code}"
}

Example response

HTTP/1.1 200 OK
Content-type: application/json;charset=utf-8
{
    "valid_until": 1355314332
}

Requesting initial generator data

This method exchanges code, received from the user, to initial data, needed for generating reservation codes.

Request

POST https://wallet.paysera.com/rest/v1/generator

Request body structure

Parameter
Type
Remarks
Description
code
string
required
Code received from the user

Response data structure

Parameter
Type
Remarks
Description
id
integer
always
ID of this generator, used when generating the reservation codes
status
string
always
One of the following: valid, invalid. Latter means that reservation codes, related to this generator, will not be valid for reserving transactions. Generator must be re-initialised for further reservation code generation.
expires_in
integer
always
Time in seconds until generator expires. Expiration time is extended by this size every time reservation code is used for accepting the transaction (even if it's used by some other client)
identifiers
array of objects
always
Reservation code identifiers for each wallet of current user. See bellow for more information.
seed
string
Only in response for code exchange request
Initial data for generating first reservation code. Must be kept secret. Given in base64-encoded format, should be decoded before using in generator
type
string
Only in response for code exchange request
Type of algorithm used when generating reservation codes. Currently only pbkdf2-sha256 is available
params
object
Only in response for code exchange request
Parameters for generation algorithm. Structure depends on type parameter. See bellow for more information.

Identifier data structure

Parameter
Type
Remarks
Description
identifier
integer
always
Identifier to use if generating code for this wallet
wallet_id
integer
always
ID of the wallet, related to this identifier

Parameters data structure for pbkdf2-sha256 algorithm

Parameter
Type
Remarks
Description
secret_iterations
integer
always
Iterations used while generating next secret key
secret_length
integer
always
Length of the secret key in bytes
sign_iterations
integer
always
Iterations used while generating signature
sign_length
integer
always
Length of the signature in bytes

Errors

rate_limit_exceeded, invalid_code

Example request

POST /rest/v1/generator HTTP/1.1
Host: wallet.paysera.com
Content-Type: application/json;charset=utf-8
User-Agent: Paysera WalletApi PHP library
Authorization: MAC id="wkVd93h2uS", ts="1343811600", nonce="nQnNaSNyubfPErjRO55yaaEYo9YZfKHN", mac="4QMxznZfLYKNtBlcmEuda1VUUeUxtyfhiEOl1LNFvxE=", ext="body_hash=gKf8N9VnifXglboUYFyvOdYX6siZ5yYhfRuGctAoVSY%3D"
{
    "code": "758604"
}

Example response

HTTP/1.1 200 OK
Content-type: application/json;charset=utf-8
{
    "id": 8754,
    "status": "valid",
    "expires_in": 3600,
    "identifiers": [
        {
            "identifier": 2147483782,
            "wallet_id": 6
        },
        {
            "identifier": 2147483784,
            "wallet_id": 94
        }
    ],
    "seed": "m1ZSFUArP1iN/xc1/iGCCci7B8QQ1SEu9JCnBz22Dss=",
    "type": "pbkdf2-sha256",
    "params": {
        "secret_iterations": 1024,
        "secret_length": 32,
        "sign_iterations": 1024,
        "sign_length": 4
    }
}

Getting generator data by ID

This method gets generator data by it's ID. It can be used for checking expires_in field or status of the generator

Request

GET https://wallet.paysera.com/rest/v1/generator/:generatorId

Parameters

generatorId - ID of the generator

Response data structure

Response is the same as when getting initial generator data, except missing fields, related to the generation algorithm: seed, type and params.

Reservation code generation algorithm

When generating reservation code, process consists of three steps:

  • Getting current secret key, used for signing;
  • Encoding information, identifying this reservation code;
  • Generating signature for this information, using the generated secret key.

Process can be provided as a set of functions:

salt(index) = index == 1 ? base64_decode(response.seed) : secret(index - 1)
secret(index) = generateSecret(accessTokenSecretKey, salt(index), response.parameters)
info(index) = encodeInfo(identifier, lifetime, constraints)
signature(index) = generateSignature(secret(index), info(index), response.parameters)
reservationCode(index) = info(index) || signature(index)

index - Index starts with 1 and increases by 1 with each generated reservation code

response - Response data for generator request

accessTokenSecretKey - mac_key related to the access token, used in generator request. If access token changes (after refresh), this parameter does not. Thus it should be saved together with other generator data and kept secret even after disposing related access token.

identifier - Identifier from generator initial data, depending on the wallet. Reservation code will be related to this generator data and specific wallet by this identifier

lifetime - Seconds passed after issuing the generator data

constraints - Constraints, related to the reservation code. For example, maximum sum for transaction, reserved by this code

generateSecret and generateSignature functions depend on type parameter, for which only pbkdf2-sha256 is supported at the time.

In the description of the algorithm function PBKDF2(P, S, c, dkLen) is used, which is described in RFC2898, where pseudorandom function PRF is SHA-256.

Function generateSecret(secret, seed, parameters) is defined in the following way:

PBKDF2(secret, seed, parameters.secret_iterations, parameters.secret_length)

Function generateSignature(secret, info, parameters) is defined in the following way:

PBKDF2(secret, info, parameters.sign_iterations, parameters.sign_length)

Function encodeInfo(identifier, lifetime, constraints) is defined in the following way:

be4(identifier) || be3(lifetime) || extensions

Here be4 and be3 are functions, encoding integer number in big-endian format with 4 bytes and 3 bytes result accordingly. extensions are optional and described bellow. In another words, be4 is four-octet encoding of an integer, most significant octet first.

Information extensions

Extensions are optional and can be appended to the information data in any order. Each extension is identified by an integer ID and can contain additional information.

Setting maximum sum for reservation code

There are 2 extensions for each of supported currencies. Each extension consists of 2 bytes - extension identifier and maximum sum identifier. Each byte is encoded in big-endian format. Value of second byte is multiplied by specified multiplier to get the actual sum in cents.

Extension ID, currency and multipliers are provided in the table bellow.

Currency
Extension ID
Multiplier
Example
AUD
64
100
x40x1F means maximum of 31.00 AUD
BYR
65
1000000
x41x1F means maximum of 310,000.00 BYR
CAD
66
100
x42x1F means maximum of 31.00 CAD
CHF
67
100
x43x1F means maximum of 31.00 CHF
CZK
68
1000
x44x1F means maximum of 310.00 CZK
DKK
69
100
x45x1F means maximum of 31.00 DKK
EUR
70
100
x46x1F means maximum of 31.00 EUR
GBP
71
100
x47x1F means maximum of 31.00 GBP
HUF
72
10000
x48x1F means maximum of 3,100.00 HUF
JPY
73
10000
x49x1F means maximum of 3,100.00 JPY
NOK
76
1000
x4Cx1F means maximum of 310.00 NOK
PLN
77
100
x4Dx1F means maximum of 31.00 PLN
RUB
78
1000
x4Ex1F means maximum of 310.00 RUB
SEK
79
1000
x4Fx1F means maximum of 310.00 SEK
USD
80
100
x50x1F means maximum of 31.00 USD
AUD
96
1000
x60x1F means maximum of 310.00 AUD
BYR
97
10000000
x61x1F means maximum of 3,100,000.00 BYR
CAD
98
1000
x62x1F means maximum of 310.00 CAD
CHF
99
1000
x63x1F means maximum of 310.00 CHF
CZK
100
10000
x64x1F means maximum of 3,100.00 CZK
DKK
101
1000
x65x1F means maximum of 310.00 DKK
EUR
102
1000
x66x1F means maximum of 310.00 EUR
GBP
103
1000
x67x1F means maximum of 310.00 GBP
HUF
104
100000
x68x1F means maximum of 31,000.00 HUF
JPY
105
100000
x69x1F means maximum of 31,000.00 JPY
NOK
108
10000
x6Cx1F means maximum of 3,100.00 NOK
PLN
109
1000
x6Dx1F means maximum of 310.00 PLN
RUB
110
10000
x6Ex1F means maximum of 3,100.00 RUB
SEK
111
10000
x6Fx1F means maximum of 3,100.00 SEK
USD
112
1000
x70x1F means maximum of 310.00 USD

Allowing reservation code to be used with allowances

By default, transactions with allowances cannot be accepted using reservation codes. For reservation code to be valid on transactions, including allowances, this extension must be included.

This extension is defined as one byte, indicating extension ID: %01 in URL-encoded format, AQ== in base64-encoded format.

Encoding reservation code

Before sending reservation code to API or encoding into QR code or barcode, it must be encoded into format, easily used in any of these use-cases. Reservation code is string in ASCII symbols of decimal representation of binary reservation code result. Big-endian encoding is used for converting binary data to decimal representation.

Encoding example

Bellow there are examples of random binary data encoded in base64 format and in format, used for reservation code.

First example in base64 - PcJKPsUUN4kUytE=

First example in decimal representation - 74661983676274174854482641

Second example in base64 - Pw2q40XZFOKbat0rqyXoRUsEmw==

Second example in decimal representation - 1406137557324345164655494461243726425100059803

Encoding reservation code as a QR code

Reservation code can be encoded as a QR code. It's encoded as an ASCII string, adding prefix PAYSERA$.

Encoding reservation code as a barcode

Reservation code can be encoded as a barcode of type Code128. It's encoded as an ASCII string, adding prefix 9999. As only ASCII encoded digits are used in the barcode, only C code table should be used. Also for smallest barcode possible, 0 should be added in front of reservation code before adding prefix, if reservation code length is odd.

Reservation code in base64
Contents
Example QR code
Example barcode
rp7X/eHUSn/w
QR: PAYSERA$3221179364949818507248
Bar: 99993221179364949818507248
+9HTizWCgbFNnA==
QR: PAYSERA$1189184600047884648402332
Bar: 999901189184600047884648402332
hD4APgOzxeNEwOg=
QR: PAYSERA$159870999379681886848991464
Bar: 99990159870999379681886848991464

Reservation code generation example

Example response

HTTP/1.1 200 OK
Content-type: application/json;charset=utf-8
{
    "id": 8754,
    "status": "valid",
    "expires_in": 3600,
    "identifiers": [
        {
            "identifier": 2147483782,
            "wallet_id": 6
        },
        {
            "identifier": 2147483784,
            "wallet_id": 94
        }
    ],
    "seed": "m1ZSFUArP1iN/xc1/iGCCci7B8QQ1SEu9JCnBz22Dss=",
    "type": "pbkdf2-sha256",
    "params": {
        "secret_iterations": 512,
        "secret_length": 32,
        "sign_iterations": 1024,
        "sign_length": 4
    }
}

In example, it is assumed, that mac_key for current access token is NlNypbXcTGxK10fy8BsYAFtD9mP39uzL, time passed after generator response is 2113 seconds (35 minutes and 13 seconds) and one more minute before generating second code, selected wallet ID is 94 for first code, 6 for the second one.

secret(1) - Generation algorithm: PBKDF2('NlNypbXcTGxK10fy8BsYAFtD9mP39uzL', base64_decode('m1ZSFUArP1iN/xc1/iGCCci7B8QQ1SEu9JCnBz22Dss='), 512, 32). Result when base64 encoded: MhhNKPdt3gGuNb3iRCfiWuN3eXred/uVnOKfw3iMfog=

info(1) - Generation parameters: 2147483784, 2113. Result when base64 encoded: gAAAiAAIQQ==

signature(1) - Result when base64 encoded: hxVs/Q==

reservationCode(1) - Result: 0154742514710514401052814589

secret(2) - Generation algorithm: PBKDF2('NlNypbXcTGxK10fy8BsYAFtD9mP39uzL', base64_decode('MhhNKPdt3gGuNb3iRCfiWuN3eXred/uVnOKfw3iMfog='), 512, 32). Result when base64 encoded: BULycPtSHbzpXnucmEpZszA9Rom3NEBVJEblsOurrJA=

info(2) - Generation parameters: 2147483782, 2173. Also extensions are used: maximum sum is restricted to 12.00 USD and allowance is allowed. Result when base64 encoded: gAAAhgAIfVAMAQ==

signature(2) - Result when base64 encoded: zNbTHw==

reservationCode(2) - Result when base64 encoded: 2596148591263630246308602000626463

Generating long-term transaction authorisation code

This method allows client to create authorisation code attached to specific amount and wallet. It can be used to authorise specific transaction

Create AuthorisationCode

POST /authorisation-code/rest/v1/authorisation-codes HTTP/1.1
Host: wallet.paysera.com
User-Agent: Paysera WalletApi PHP library
Authorization: MAC id="wkVd93h2uS", ts="1343811600", nonce="nQnNaSNyubfPErjRO55yaaEYo9YZfKHN", mac="PJ9DW82J3Pk5j3GGQ8r3aRwkRmOik5CX3sU3+UFiZ3s="

Request body structure

Parameter
Type
Remarks
Description
description
string
optional
Some description for this authorisation code
valid_until
integer
required
Timestamp until this authorisation code is valid
authorised_amount
Money object
required
Object, containing authorised "amount" (float) and "currency" (string) keys

Example request

POST /authorisation-code/rest/v1/authorisation-codes HTTP/1.1
Host: wallet.paysera.com
Content-Type: application/json;charset=utf-8
User-Agent: Paysera WalletApi PHP library
Authorization: MAC id="wkVd93h2uS", ts="1343811600", nonce="nQnNaSNyubfPErjRO55yaaEYo9YZfKHN", mac="KgVIpVqlRBbwziBwTryv58rX/yRE6+ABr8Gue9Nnw0I=", ext="body_hash=Zm3nvOGqbglham9zf83gr4y%2FNtwXQvx51tnCokuSG6k%3D"
{
    "description": "some description",
    "valid_until": 1234567890,
    "authorised_amount": {
        "amount": 100,
        "currency": "EUR"
    }
}

Response body structure

Parameter
Type
Remarks
Description
id
integer
always
Identifier of this authorisation code
description
string
only if provided
Some description for this authorisation code
valid_until
integer
always
Timestamp until this authorisation code is valid
authorised_amount
Money object
always
Object, containing authorised "amount" (float) and "currency" (string) keys
status
string
always
Status of this authorisation code, possible values: new, used, expired
code
string
always
The authorisation code itself

Example response

HTTP/1.1 200 OK
Content-type: application/json;charset=utf-8
{
    "id": 8754,
    "description": "some description",
    "valid_until": 1234567890,
    "authorised_amount": {
        "amount": 100,
        "currency": "EUR",
        "amount_decimal": "1.00"
    },
    "status": "new",
    "code": "AC_KDFDFDFSD6PTSN"
}

Get created AuthorisationCode

GET https://wallet.paysera.com//authorisation-code/rest/v1/authorisation-codes/:id

Response body structure

Response body structure is same as in Create Authorisation Code

Delete created AuthorisationCode

DELETE https://wallet.paysera.com//authorisation-code/rest/v1/authorisation-codes/:id

Response structure

HTTP/1.1 204 Accepted
No content will be returned on success.