[УКР](https://hackmd.io/g3cItPVFStez0ql3Xj-2TA) | ENG # General API Integration Information :::info [TOC] ::: ## Security Measures Description :::warning :bulb: Follow next security rules to interact with the XPAY system: - network connection performes within the pool of allowed Partner IP addresses. - data exchange performes within a connection protected by the [SSL protocol](https://en.wikipedia.org/wiki/Transport_Layer_Security#SSL_1.0,_2.0,_and_3.0). - data packet must be encrypted using a personal public key (read keys description below). - Partner sends requests as a JSON structure (in UTF-8 encoding). ::: ## API Access Parameters ### URI Operator enables the Partner to operate in two environments: **test** (for testing and API requests) and **product** (for direct operation with clients). URIs for API requests depending on environment: **Test Environment** ``` https://stage-papi.xpay.com.ua:488/xpay ``` **Product Environment** ``` https://papi.xpaydirect.com/xpay ``` ### Partner Token **"Partner token"** is a unique Partner identifier (token) generated by the Operator and used for each request **to identify the Partner** in the system. Token is a string, formed from a set of numbers and Latin letters separated by the symbol "-". :::info All methods are available for **test token**: ~~~ 72a8ddb8-9145-4a41-af1a-8c48ecaa4be1 ~~~ ::: ### RSA Keys The Partner's interaction with the XPAY system is performed using [RSA encryption algorithms](https://en.wikipedia.org/wiki/RSA_(cryptosystem)), that require the exchange of Operator and Partner personal keys. To implement the algorithm, use the private part of the Partner's key **"private key"** and the public part of the Operator's key **"public key XPAY"**. :::info **Partner private key** is a secret cryptographic code created using encryption algorithms, that is generated in a pair with the public key on the Partner's side and is used **to sign the data packet**. **Partner public key** is an open cryptographic code created using encryption algorithms, that is generated in a pair with the private key on the Partner's side and is given to the Operator **to verify the Partner's signature** in the system. Example of commands for generating a pair of keys and forming the **public part**: ~~~ openssl genrsa -out keypair.pem 2048 ~~~ ~~~ openssl rsa -in keypair.pem -pubout -out publickey.crt ~~~ **Operator's public key XPAY** is an open cryptographic code generated by the Operator and used for crypto-transformation (encryption) of the data packet: <details> <summary>for test environment</summary> <br> ~~~ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0IH2V0Ot1ej4FdOihujG ON37sqql62vFFR/4IK+w4xqHRvD+SEwwkLL9EO72e42bV9VaKOqKbX81A+0hbBXi W7axjHU2Sc97EXTHjpwX++HduUXbXhRteyzcHDLZCGKT8WzoNgQeXcieLUYUp2bb gjElGecKprcprkMeHmffmelwlzcv61auGU0o10CTyyCqhOKofdqJq6A2KOBCLL49 5z1700oCRo9qL4loe95r4wGh6AmHZNvAnAwLgzwzyLvWCz479CVIWEaMY/+uczfL 0yRjN+8uqNK3A09wOD+wO1I+YfU9YXcQ75L8ibxzWcNgMHrhJQ9ZtnoVltiTWEEB 9QIDAQAB -----END PUBLIC KEY----- ~~~ </details> <details> <summary>for product environment</summary> <br> ~~~ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9+1AEFfD9MoO0IWeMk3f aFoYBBekFgHmUGM48AVh6BW/s5r16mtUfMfRfezVgqluwV/liEd6hArmmEZIKwYE mJoAYuY/ny9QJpc8zY+toR5IJEtYxfStHmVwKSuvHL3KY/U/Ok5UUT2u075JPZb+ FtDZwW9KXkwmT53HQ6iS0XFyy621vGrs6XcdGwO6eZPptkvc8SYKDwClgLjI69Iz b6K/dfdQUioMPvZOXpdzrEQXjnipmsYh1VxOufqsX1SDzqR67Zs114OnHWAZhTXE ksUjKavJkCc07T+nu1O/r99rsrRCaQODVq8SMAoK1vxJLf29WFv4ydp4vIk+n98/ DQIDAQAB -----END PUBLIC KEY----- ~~~ </details> ::: ### Partner Identification and Verification Procedure - Operator generates and gives the Partner a unique **partner token** and **public key XPAY** for the interaction with Operator's system. - Partner generates a pair of personal keys: **"private key"** (to generate the signature) and **"public key"** (is given to Operator to verify the signature). - Partner sends request as a **data packet** signed with private key and passes the signature verification on the Operator's side using the Partner public key. ### Test Partner Settings ![](https://i.imgur.com/gtxKB22.png) :::warning **Test Partner** with all necessary permissions is created for testing any operations and getting acquainted with XPAY services. See details in the section: ["Test Partner Settings"](https://hackmd.io/1Ftkd9PVSvGBc9JV8f9b9A). ::: ## Rules of Request/Response Sending *See the response codes and signs of fatality in the table ["Response Code"](https://hackmd.io/16yLv895Qo-FWTvrWWQwbg#Response-Code).* Getting an HTTP code with **"no"** fatality, it is necessary to continue the operation in the Operator/Partner system. To request the current operation status, repeat the request [[20003](https://hackmd.io/_eAjmoG-QPWoWWmsLOGf1g)] with previously sent parameters until getting the HTTP code with **"yes"** fatality. The operation status will be changed in the response. :::warning A repeat request can be sent to the Operator: **no more than once every 60 seconds**. ::: The time for sending a **response** is limited to **55 seconds**. If the operation is not completed, the XPAY system generates a response with the code `102`. :::warning Getting a `timeout` for any API request, including a status request - must be treated as a response with code `102` and continue to request status until a fatal code is received. ::: ## Request Structure **Partner Request** is a data packet in the form of [JSON structure](https://en.wikipedia.org/wiki/JSON), sent to the Operator to perform the transaction. Request consists of 4 attributes: "Partner", "Data", "KeyAES" and "Sign" (see below the description of attributes). Choose one of two algorithms for the request crypto-transformation and key signature generation: * [PKCS](https://en.wikipedia.org/wiki/PKCS) * [OAEP](https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding) :::success <details> <summary>Example of Partner request with encrypted data, key and signature</summary> <br> ~~~md { "Partner": { "PartnerToken": "72a8ddb8-9145-4a41-af1a-8c48ecaa4be1", "OperationType": 10005 }, "Data": "AAAAAAAAAAAAAAAAAAAAAC+kIDAcwzpMy55qVKGeMLuOWh0INgMBfRkYyIUHpw89vsN0HwRLc8B3bPVtwONPEnm4AMAyltWL+OFNCZJL5ODc/4x6/vT8pmsOhoQcmSS1gtr3FcvbyHOIYwLDC+mQxMWyEvfN0bmsR9pAqkQh67/JzFyuS8KZ2gtT4IAcnq2vYyn4WsY6JBuJVpHEvipHB6orQAcEHZ9UjS4JGh5OV/JG7OMFSunoblniE1/YO4sT", "KeyAES": "et/DigMfEL16uH+8Trvp86/jd7N6CUsK8C8jvcQMJSKnDfkirkRS760uKmtDnVapGIJhAK5CmN+/tsqMxSH+czDYSGotHmW3BacocccgrrHbfdtKPuKbLCAGmDo0SlISj2URix4kJTGZztqy8pWTkVde0RAr7SOWwUHBlSIRklDLwEvGb45kmnqeV2AjCA/EiTMMez/rRt3T5Bc674Cc9G/6usu8yRj9Hw2q4ZLmcGRSLxae196vt9aZBmeOvy71gjUaedfxEud0ldLPvE0FyxE5nmlz59GPURvD9UT0fbFH3zdEghJ5hm+oTaDuvJFobCrjAiXpQGpryywHLFwuOw==", "Sign": "Ehn3kb3Cqk+B8wqJJEwl5Kwj68ldaq0pfReEUfpGrC68pZQEPl/K8VYuUBhfhDkklVOsOsxqTCAW0izitUyfqd67Afdg6dRxO5leUuKfS9llhrJwYLbcWVf36Rh+Xva95p22GBlbmS2/DD3f0b1zFZoNv9AZe62EMe37d11S6G42RJfSM9z2HQCOcs50XEID8Z56wI3ezHoeOk8uvKcMaZo+exWVr0pqg/LoN0yM53vQn/2t7uwIkt8y/lTPTo6jW2EXtA/lp5SiBZx0Jnh9QPg2I/h7WEa1oYysNcizHeXIr6j6+U7cquQp8XmJh1pJodAhMiG2jMRgLgPlWq0PKg==" } ~~~ </details> ::: ### 1. Partner **Partner** is JSON structure of request, that transmits data to identify the Partner in the system and determine the operation. This attribute is formed from the following parameters: `PartnerToken`, `OperationType` та `Locale`. |Parameter|Required|Type|Description|Example| |:----:|:----:|:----:|----|:----:| | `PartnerToken`|Yes|String|Unique Partner identifier in the Operator system, used in each request to identify the Partner.| For the **Test Environment**, use: </br> `72a8ddb8-9145-4a41-af1a-8c48ecaa4be1`| | `OperationType`|Yes|String | Digital code (both financial and informational) assigned by Operator to determine the Partner operation type. Code can be viewed in the name of each request as: **[code] "request name"**. |`10005`,`10102`,`20003`, etc. (according to the table "[Operation Types](https://hackmd.io/16yLv895Qo-FWTvrWWQwbg?both#Operation-Types)”). | | `Locale` | No |String | Locale (language) of displaying interface elements, support files and documentation. | `uk`-Ukrainian (default), </br>`en`-English, </br>`ru`-Russian. :::success <details> <summary>Example of "Partner" JSON structure</summary> <br> ~~~md { "PartnerToken":"72a8ddb8-9145-4a41-af1a-8c48ecaa4be1", "OperationType":10005, "Locale":"uk" } ~~~ </details> ::: ### 2. Data **Data** is an encrypted using the AES algorithm operation data in a string format. In the Data structure parameters and data structures differ depending on the operation type. Basic one is `Transaction`. #### Transaction Structure :::danger **Transaction** structure is transmitted each time with a unique value of `TransactionID` parameter (read description below). If a final response was received to the previous request, for example, "operation failed" - in this case a re-request must be sent with a new unique TransactionID value. ::: |Parameter|Required|Type|Description|Example| |:----:|:----:|:----:|----|:----:| |`Transaction`^1^|Yes/No|Structure|Data structure that contains transaction information.|See example below.| :::warning ^1^ **Transaction** structure is not required only for information requests (such as [20001], [20002], [20003], etc.), but it's required for all financial transactions. ::: **Transaction** structure parameters: |Parameter|Required|Type|Description|Example| |:----:|:----:|:----:|----|:----:| |`TransactionID`|Yes|String|Unique transaction identifier in the Partner system.| `45913135c6e2be0cbf58`| |`TerminalID`|Yes|String|Unique terminal identifier in the Partner system. Pass `1` іn case of empty value.|`1`| |`DateTime`|No|String|Transaction date and time in format: YYYYMMDD HH24:MM:SS.|`20220521 06:41:04`| :::success <details> <summary>Example of "Transaction" JSON structure</summary> <br> ~~~md { "Transaction": { "TransactionID": "8fd04e6ec7c1", "TerminalID": "802", "DateTime": "20220504 08:14:07" } } ~~~ </details> ::: #### Data Crypto Transformation Consider the crypto transformation process as an example: :::success <details> <summary>Example of "Data" JSON structure to be encrypted</summary> <br> ~~~md { "ClientIP": "133.36.78.88", "PaymentSum": 1000, "PayType": "0", "Phone": "380633214565", "Transaction": { "TerminalID": "1", "DateTime": "20210303_132011", "TransactionID": "123" } } ~~~ </details> ::: #### 2.1. AES Key Generation Generate a 16-byte AES key, which encrypts transaction data using the AES-128 algorithm in [CBC mode](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation) (see the scheme below, pointer 2.1). :::success <details> <summary>Generated AES key for data encryption ([]byte)</summary> <br> ~~~md [49 50 51 52 53 54 55 56 57 48 97 98 99 100 101 102] ~~~ </details> ::: :::success <details> <summary>Generated AES key for data encryption in a string format</summary> <br> ~~~md 1234567890abcdef ~~~ </details> ::: #### 2.2. Alignment of Data Operation Transform the operation data from the JSON structure to []byte format and align it to x16 bytes ending with a symbol equal to the number of added symbols (see the scheme below, pointer 2.2). For example, to add 5 bytes, you need to add the symbol “5” 5 times. :::success <details> <summary>Data array to be encrypted ([]byte)</summary> <br> [123 34 67 108 105 101 110 116 73 80 34 58 34 49 51 51 46 51 54 46 55 56 46 56 56 34 44 34 80 97 121 109 101 110 116 83 117 109 34 58 49 48 48 48 44 34 80 97 121 84 121 112 101 34 58 34 48 34 44 34 80 104 111 110 101 34 58 34 51 56 48 54 51 51 50 49 52 53 54 53 34 44 34 84 114 97 110 115 97 99 116 105 111 110 34 58 32 123 34 84 101 114 109 105 110 97 108 73 68 34 58 32 34 49 34 44 32 34 68 97 116 101 84 105 109 101 34 58 32 34 50 48 50 49 48 51 48 51 95 49 51 50 48 49 49 34 44 34 84 114 97 110 115 97 99 116 105 111 110 73 68 34 58 32 34 49 50 51 34 125 125] </details> ::: :::success <details> <summary>ALIGNED data array to be encrypted ([]byte)</summary> <br> [123 34 67 108 105 101 110 116 73 80 34 58 34 49 51 51 46 51 54 46 55 56 46 56 56 34 44 34 80 97 121 109 101 110 116 83 117 109 34 58 49 48 48 48 44 34 80 97 121 84 121 112 101 34 58 34 48 34 44 34 80 104 111 110 101 34 58 34 51 56 48 54 51 51 50 49 52 53 54 53 34 44 34 84 114 97 110 115 97 99 116 105 111 110 34 58 32 123 34 84 101 114 109 105 110 97 108 73 68 34 58 32 34 49 34 44 32 34 68 97 116 101 84 105 109 101 34 58 32 34 50 48 50 49 48 51 48 51 95 49 51 50 48 49 49 34 44 34 84 114 97 110 115 97 99 116 105 111 110 73 68 34 58 32 34 49 50 51 34 125 125 5 5 5 5 5] </details> ::: #### 2.3. Generation of Initialization Vector Generate the [initialization vector](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation) (see the scheme below, pointer 2.3). :::success <details> <summary>Initialization vector ([]byte)</summary> <br> ~~~md IV = [49 50 51 52 53 54 55 56 57 48 97 98 99 100 101 102] ~~~ </details> ::: #### 2.4. Addition of Initialization Vector Add a randomly generated initialization vector to the first 16 bytes of the unencrypted aligned data (see the scheme below, pointer 2.4). #### 2.5. Transformation of Operation Data in Base64 Standardly transform the binary array as a result of encryption with AES key to a [base64](https://en.wikipedia.org/wiki/Base64) encoded string (see the scheme below, pointer 2.5). :::success <details> <summary>Encrypted operation data in a string format (base64)</summary> <br> MTIzNDU2Nzg5MGFiY2RlZi+kIDAcwzpMy55qVKGeMLuOWh0INgMBfRkYyIUHpw89vsN0HwRLc8B3bPVtwONPEnm4AMAyltWL+OFNCZJL5ODc/4x6/vT8pmsOhoQcmSS1gtr3FcvbyHOIYwLDC+mQxMWyEvfN0bmsR9pAqkQh67/JzFyuS8KZ2gtT4IAcnq2vYyn4WsY6JBuJVpHEvipHB6orQAcEHZ9UjS4JGh5OV/JG7OMFSunoblniE1/YO4sT </details> ::: ### 3. KeyAES **KeyAES** is an RSA encrypted AES key in a string format. #### 3.1. AES Key Encryption Encrypt the AES key (generated above and with which the operation data is encrypted) with **XPAY public key** using [PKCS1 v1.5](https://en.wikipedia.org/wiki/PKCS_1) / [OAEP](https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding) algorithm (see the scheme below, pointer 3.1). #### 3.2. Transformation of AES Key in Base64 Standardly transform the binary array as a result of encryption to a base64 encoded string (see the scheme below, pointer 3.2). :::success <details> <summary>Encrypted AES key (base64)</summary> <br> SG/brF1UrUem/2BakqbYnLu6CD6JYqRbB2SdN+xNE89smpnFtsjXfZljtEpbNA3JjJNuPLPU6dxlki1sSvGe1PofVt1HFGKPxqVyMNyhZ4FYqM79A53Iw5ODJJ53UM94kdb2YHT0drRYGNOHeFbIeVluuVMyPhGoVsGkbwONUQ9BE78JKQArHvRoKYJhKzYQ5undnv/oiOCXTfW+5Mt5+qdm7ZmQ80D6NmZJI+IgOFEkaQ9nFdPBuYpOhoFEZiRbxRLNYUNLCVifCaJXoi7GILSHVfXDwx+3kWQX8o91pxEmwmZU/yE/KPtXqINgXVgMoWu7CCMgU576fZyLHy+X7A== </details> ::: ### 4. Sign **Sign** is a signature generated by the RSA algorithm in a string format. #### 4.1. Generation of Sign Before transformation in base64, sign the encrypted above AES key with the **Partner private key**: [SHA256](https://en.wikipedia.org/wiki/SHA-2) hash, using PKCS1 v1.5 / OAEP algorithm (see the scheme below, pointer 4.1). #### 4.2. Transformation of Signature in Base64 Standardly transform the binary array as a result of signing to a base64 encoded string (see the scheme below, pointer 4.2). :::success <details> <summary>Generated signature (base64)</summary> <br> L+H2PL0lOpGZno4cvWG+BsoiGCbJbkHVgZOC2RmVHNM+Y9GHzqAJrzncgfo/ltqZUM6F0/kjaFE5J/MaqLsysSwMd04YRqkc+RNGqBVMj3oPpejOhdYyMQWiuW5x4rOXoI/nYx8IZCtIzloqqwudZApcYEtrajnACqCZKKZmcyXZcB9HUbUi+WULfo6xTtcSx3W5Lwq8p0WQo8l48AzbtOIIMpLULhFu0a6o21Mz28p0qmIybvKtLdlQT8Nj5+j86wsKjdaCzI9rILzI3s+vyVibZIflptwRnhef83NtDSmorAyUIXoIl+cYSdYgxiQTsYnodtt+zr42rKEFjW1Dlw== </details> ::: #### 4.3. Signature Verification on the Operator Side The signature is verified using the **Partner public key**, during which the signature is decoded from base64 format, and the received data is verified with the signed data: SHA256 hash, using PKCS1 v1.5 / OAEP algorithm. The result of the request is the **XPAY response**, described below in the section "Response structure". ### Scheme of Crypto Transformation ![](https://i.imgur.com/1DTn1PI.png) ## Response Structure The Operator service responds to the operation request by JSON structure, formed from the following parameters: `Code`, `Message`, `Data`, `KeyAES`, `Sign`. |Parameter|Required|Type|Description|Example| |:----:|:----:|:----:|----|:----:| | `Code` | Yes| Integer | Request response code, or so-called [HTTP Status Code](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes). Available codes are listed in the table "[Response Codes](https://hackmd.io/16yLv895Qo-FWTvrWWQwbg?view#Response-Codes)". | `401` | | `Message` | Yes| String | Text message describing the request status. | `Operation not permitted` | | `Data`^2^ | Yes |Structure | Additional operation data (operation ID, URL - operation confirmation, balance statement, operations status, etc.)| `"OperationID":11`, </br> `"OperationStatus":10`| | `KeyAES` | Yes | String | AES key encrypted using the RSA algorithm, which encrypts the operation data (base64). For responses with unencrypted data leave the value empty. |See example below.| | `Sign` | Yes| String | Signature generated by the RSA algorithm (base64). For responses with unencrypted data leave the value empty. |See example below.| :::warning ^2^ **Data** parameter in the response structure contains two required fields (other fields are formed depending on operation type and its status): 1. `OperationID:` - unique operation identifier in the Operator system. 2. `OperationStatus:` - the operation status code, listed in the table "[Operation Status](https://hackmd.io/16yLv895Qo-FWTvrWWQwbg?view#Operation-Status)". If there is a `Reason` parameter in the response, see the **reason code** in the table ["Reasons of Operation Rejection"](https://hackmd.io/16yLv895Qo-FWTvrWWQwbg?both#Reason-of-Operation-Rejection). Analyzing the **operation status** priority is given to the `OperationStatus` value. The `Code` parameter has a more informative function and shows whether the processing was successful according to the protocol, or there were no internal errors and all services were available. ::: ### Response Examples :::success <details> <summary>Operation Successfully Completed ("OperationStatus": 10)</summary> <br> ~~~md { "Code": 200, "Message": "done", "Data": { "OperationID": 11, "OperationStatus": 10, "URI": "https://stage-mapi.xpay.com.ua/ru/frame/widget/f3cd72b6-e1ea-406f-9b44-a9b93b401b7f", "uuid": "f3cd72b6-e1ea-406f-9b44-a9b93b401b7f" }, "KeyAES": "", "Sign": "" } ~~~ </details> ::: :::success <details> <summary>Invalid Token</summary> <br> ~~~md { "Code": 401, "Message": "wrong token", "Data": null, "KeyAES": "", "Sign": "" } ~~~ </details> ::: :::success <details> <summary>Operation Not Permitted</summary> <br> ~~~md { "Code": 403, "Message": "Operation not permitted", "Data": null, "KeyAES": "", "Sign": "" } ~~~ </details> ::: :::success <details> <summary>Operation Failed ("OperationStatus": 21)</summary> <br> ~~~md { "Code": 200, "Message": "done", "Data": { "OperationID": 111, "OperationStatus": 21, "Reason": 3 }, "KeyAES": "", "Sign": "" } ~~~ </details> ::: ## Cipher Service :::danger If it is not possible to implement cryptographic data transformation - please contact the Operator to integrate using the XPAY encryption service [**Cipher**](https://hackmd.io/mW_dr90eRriYJ6OpXj7ASA). ::: ## Reference Materials General parameters of the XPAY system are given in the section ["Reference Materials"](https://hackmd.io/16yLv895Qo-FWTvrWWQwbg):  operation types, payment types, response codes, operation status, reasons of operation rejection, etc. ## XPAY Support <details> <summary>Contacts</summary> </br> Phone: +38 (096) 099 20 59 Email: info@xpay.com.ua Telegram: @xpaysupportbot </details> </br> :::info **API navigation:** :bookmark_tabs: [XPAY API Guide](https://hackmd.io/QA2NYRliRLGviJl5P4-ZCw) :arrow_left: [Registration](https://hackmd.io/wsBxZ4WwQDm10OuxDgjo3g) :::