This document describes the protocol of Mono Corp API Proxy (MCAP). This protocol is created for Mono PWA project.
- Root: describes the publicly available URL path, which contains methods as subfolders;
- Method: Named public command, the way to interact with MCAP for different actions. A simulated subfolder of Root;
- Response: JSON marshaled output of Method with
application/json
Content-Type and200 OK
response code; - Error: A Response with an
error
key instead of the expected output. The key contains error description ->{"error": "description"}
; - Long-Polling: Keeping an HTTP request alive without outputting the response body until a trigger;
- %METHOD% /%resource% Monobank Request: An HTTP %METHOD% (GET|POST|...) request to https://api.monobank.ua/%resource% ->
POST /personal/auth/request Monobank Request
. See Sending requests to Monobank; - Roll-In Token: A random string, which is paired with a Monobank Token Request ID;
- Request Token: A random string, which is paired with a Monobank token and a roll-in token;
- Private Key: An OpenSSL generated key, which was passed to Monobank team while Corporative API set up;
- Public Key: A public key, which was extracted from the Private key;
- Key-ID: Marshaled Public key representation, hashed with sha1 (in hex). Received from Monobank team.
The methods are placed in the auth lifecycle order:
Method | Server action |
---|---|
check-proto | Describes itself by telling name, author, protocol version, homepage and optionally setting a UI message |
roll-in | Creates a roll-in token |
exchange-token | Checks if there are available Monobank user tokens for current roll-in token, and if so, creates a pair request token and gives it |
request | Sends requests to Monobank |
Every method should always return Access-Control-Allow-Origin: *
header
Monobank API is sensible to HTTP method
The Root for Monobank API is https://api.monobank.ua
Header | Content | Description |
---|---|---|
X-Time | Unix timestamp | php time() |
X-Sign | Sign | See Signing the request |
X-Key-Id | Key-ID | See Entities |
X-Token | Monobank token | If present |
Not to be confused with encryption
The signed string contains 3 ingredients:
- Timestamp from X-Time
- Monobank token
- Requested Monobank /%resource%
If it's an auth request to /personal/auth/request
, token permissions from X-Permissions
are being used instead of 2nd ingredient
The string contains all the ingredients concatenated together ($ing1.$ing2.$ing3
for PHP, ${ing1}${ing2}${ing3}
or ing1+ing2+ing3
for JavaScript)
- Make a sign of the string, that corresponds to the OpenSSL signing
Property | Value |
---|---|
Algorithm | SHA256 |
Key | Private Key |
- Encode the sign to Base64
$key = openssl_get_privatekey("file://private.key", "");
$str = $time.$t.$url;
openssl_sign($str, $sig, $key, OPENSSL_ALGO_SHA256);
openssl_free_key($key);
return base64_encode($sig);
import base64
import ecdsa
...
data = (timestamp + permissions + url).encode('utf-8')
sign = PrivateSigningKey.sign(data, hashfunc=hashlib.sha256)
signB64 = base64.b64encode(sign)
See https://github.com/shal/mono
Describes itself by telling name, author, protocol version, homepage and optionally setting a UI message
All fields are required unless otherwise specified
{
// Describes used MCAP protocol
"proto": {
"version": 1,
"patch": 0
},
// Describes the implementation of protocol
"implementation": {
"name": "PHP Mono Corp API Proxy",
"author": "Sominemo",
"homepage": "https://github.com/Sominemo/Mono-Corp-API-Proxy-PHP"
},
// Describes the state of the running instance of this implementation
"server": {
// Tells the client to display a message to the user, optional
"message": {
// The text to display
"text": "content",
// Adds clickable URL at the end of text, optional
"link": "https://example.com"
}
}
}
Creates an auth request in Monobank, generates a paired roll-in token and returns both
User interacts with Monobank interface and confirms the auth request, then Monobank sends a request to a Webhook. More details in Getting the Monobank token.
- POST /personal/auth/request Monobank request Headers(X-Callback: %webhook%; X-Permissions: %permissions%)
- %webhook% is a public http resource to receive the resulting request from Monobank
- %permissions%:
List of rights that the service wants to receive from the client (1 letter per 1 permission). List of possible rights:s - statement (includes balance and statement itself)
p - Personal information (name and surname)
- Get Monobank Token Request ID %requestId% from the response
{"tokenRequestId": "***"}
and Auth URL %url%{"acceptUrl": "***"}
- Error, if the request went wrong
- Generate Roll-In token %token% and a random %proof% string for it, pair the token with Monobank Token Request ID
- Generate QR code from Auth URL (250px, e.g. using Google Charts API)
- Encode the QR to Base64 %qr%
{
"token": %token%,
"requestId": %requestId%,
"url": %url%,
"qr": %qr%
}
- Set up an endpoint, that will receive a %proof% and %token% as GET parameters or in-uri (e.g.
/webhook/%token%/%proof%
or/webhook?token=%token%&proof=%proof%
) - Receive the Monobank User Token in
X-Request-Id
(can be alsox-request-id
) incoming header - Check if %proof% and %token% from GET correspond each other, else Error
- Generate a Request Token, pair Roll-In and the Monobank User tokens with it
- Response
200 OK
Long-polling until received roll-in token won't get a corresponding request token or the request will timeout. Checks if there are available Monobank user tokens for current roll-in token, and if so, creates a pair request token and gives it
- Receive an existing roll-in token from user
- Error, if the token does not exist
- Check if Request Token that corresponds to the Roll-In Token already exists
- If so, skip to authed
- Start Long-Polling until token receive. On trigger skip to authed
- If current Long-Polling session is out of time, %return_token% = false & Response (In this case client will send a request to this method again)
- Error, if current Roll-In Token is out of time
- authed
- Discontinue & Unlink Roll-In token
- %return_token% = Request Token & Response
{
"token": %return_token%
}
This method is a synthetic path, which signs and redirects requests to Monobank.
e.g. : POST /request/personal/auth/request
turns to a Monobank request POST /personal/auth/request
- Get Monobank token paired with Request token from
X-Token
incoming header, else Error - Clone incoming headers %headers%
- Clone the raw HTTP request body (e.g.
php://input
) - Remove
Host
header from the request (there also can be more inappropriate headers added by your HTTP server, such asSSL
orGeoIp-Country-Code
). Replace the originalX-Token
with paired Monobank token - Send the request to Monobank with the same HTTM method as incoming request, get the answer
- Clone response headers and answer to output