{"info":{"_postman_id":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","name":"NeoPay API","description":"<html><head></head><body><h2 id=\"neopay-api-postman-collection\">NeoPay API Postman Collection</h2>\n<p>This Postman collection provides comprehensive coverage of the NeoPay API, specifically designed for creating and monitoring SEPA instant account-to-account transactions.</p>\n<h3 id=\"prerequisites\">Prerequisites</h3>\n<p><a href=\"https://www.postman.com/downloads/\">Postman</a></p>\n<p>NeoTransfer Account and Certificate - Obtainable from Neosoft +30 2108991010 or <a href=\"https://mailto:support@neosoft.gr\">support@neosoft.gr</a></p>\n<h3 id=\"getting-started\">Getting Started</h3>\n<p>Install NeoTransfer certificate in Postman [<a href=\"https://learning.postman.com/docs/sending-requests/authorization/certificates/\">https://learning.postman.com/docs/sending-requests/authorization/certificates/</a>]</p>\n</body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[],"owner":"42430888","collectionId":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","publishedId":"2sAYdZsYQG","public":true,"customColor":{"top-bar":"f8fafc","right-sidebar":"303030","highlight":"013CFE"},"publishDate":"2025-02-18T15:12:13.000Z"},"item":[{"name":"Authentication","item":[{"name":"Login","event":[{"listen":"test","script":{"id":"d2d5025e-50c0-47c0-a311-315aede79c14","exec":["if (pm.response.code == 200){","    console.log(\"PreRequest -> Saving auth token\")","    const authHeader = pm.response.headers.find(h => h.key.toLowerCase() === \"authentication\")","    pm.environment.set(\"jwt_token\", authHeader.value.split(\" \")[1])","}"],"type":"text/javascript","packages":{},"requests":{}}}],"id":"5d394603-bd8f-49f7-908f-132a66194f60","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"username\": \"{{username}}\",\n    \"password\": \"{{password}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://a2a.neopayments.gr/api/login","description":"<h3 id=\"post-apilogin\"><strong>POST</strong> <code>/api/login</code></h3>\n<h4 id=\"request\">Request</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>username</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>The user’s username.</td>\n</tr>\n<tr>\n<td><code>password</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>The user’s password.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h4 id=\"responses\">Responses</h4>\n<p><strong>200 OK</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{\n  \"token\": \"string\",\n  \"token_expires_at\": 0,\n  \"uiflags\": \"string or null\",\n  \"max\": 0\n}\n\n</code></pre><div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>token</code></td>\n<td>string</td>\n<td>Authentication token.</td>\n</tr>\n<tr>\n<td><code>token_expires_at</code></td>\n<td>integer</td>\n<td>Unix timestamp of token expiration.</td>\n</tr>\n<tr>\n<td><code>uiflags</code></td>\n<td>string (nullable)</td>\n<td>Optional UI configuration flags.</td>\n</tr>\n<tr>\n<td><code>max</code></td>\n<td>integer</td>\n<td>Maximum allowed amount for the user in cents.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<p><strong>401 Unauthorized</strong></p>\n<p>Returned when credentials are invalid. No response body.</p>\n","urlObject":{"path":["api","login"],"host":["https://a2a.neopayments.gr"],"query":[],"variable":[]}},"response":[],"_postman_id":"5d394603-bd8f-49f7-908f-132a66194f60"},{"name":"Renew","id":"0a749d0a-1444-459d-ab9b-29ad42513233","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"https://a2a.neopayments.gr/api/renew","description":"<h3 id=\"get-apirenew\"><strong>GET</strong> <code>/api/renew</code></h3>\n<h4 id=\"request\">Request</h4>\n<p><strong>Headers</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Authorization</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Bearer token in the format <code>Bearer</code> .</td>\n</tr>\n</tbody>\n</table>\n</div><p>No body is required.</p>\n<hr />\n<h4 id=\"responses\">Responses</h4>\n<p><strong>200 OK</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{\n  \"token\": \"string\",\n  \"expires_at\": 0\n}\n\n</code></pre><div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>token</code></td>\n<td>string</td>\n<td>Newly generated JWT.</td>\n</tr>\n<tr>\n<td><code>expires_at</code></td>\n<td>integer</td>\n<td>Unix timestamp of token expiration.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<p><strong>401 Unauthorized</strong>  </p>\n<p>Returned when the provided bearer token is missing, invalid, or expired. No response body.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt_token}}"}]},"isInherited":true,"source":{"_postman_id":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","id":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","name":"NeoPay API","type":"collection"}},"urlObject":{"path":["api","renew"],"host":["https://a2a.neopayments.gr"],"query":[],"variable":[]}},"response":[],"_postman_id":"0a749d0a-1444-459d-ab9b-29ad42513233"}],"id":"143a18e5-d8d0-4389-a685-55651279431a","description":"<p>The <strong>Authentication</strong> folder contains documentation for endpoints related to user authentication and session management. These endpoints ensure secure login and token renewal for accessing protected resources. The folder includes:</p>\n<ol>\n<li><p><strong><code>/login</code></strong> <strong>Endpoint</strong>:</p>\n<ul>\n<li><p>A <code>POST</code> endpoint that allows users to authenticate using their username and password.</p>\n</li>\n<li><p>Returns user details and an access token upon successful login.</p>\n</li>\n</ul>\n</li>\n<li><p><strong><code>/renew</code></strong> <strong>Endpoint</strong>:</p>\n<ul>\n<li><p>A <code>GET</code> endpoint that refreshes the user's JWT using a valid bearer token.</p>\n</li>\n<li><p>Extends the session without requiring reauthentication.</p>\n</li>\n</ul>\n</li>\n</ol>\n<p>These endpoints are foundational for managing user sessions and ensuring secure access to the API.</p>\n","_postman_id":"143a18e5-d8d0-4389-a685-55651279431a","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt_token}}"}]},"isInherited":true,"source":{"_postman_id":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","id":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","name":"NeoPay API","type":"collection"}}},{"name":"Transaction","item":[{"name":"Initialize","event":[{"listen":"test","script":{"id":"a9f53223-ebc2-4fe3-9bb0-c415aea5fe1f","exec":["pm.test(\"Status code is 200\", function () {","    pm.response.to.have.status(200);","});"],"type":"text/javascript","packages":{},"requests":{}}}],"id":"39ea8f0f-c722-4612-b851-bb08d58285b8","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"description\": \"Payment for order 123\",\n  \"amount\": 100,\n  \"expires_at\": \"2025-05-16T12:00:00Z\",\n  \"documents\": [\n    {\n      \"id\": \"INV2025001\",\n      \"title\": \"Invoice 2025-001\",\n      \"invoice\": true,\n      \"tags\": \"sales,product\",\n      \"amount\": 100,\n      \"net_amount\": 80,\n      \"vat_amount\": 20,\n      \"published\": \"2025-05-13T09:00:00Z\",\n      \"due\": \"2025-05-27T17:00:00Z\"\n    }\n  ],\n  \"payer_tin\": \"171717333\"\n}","options":{"raw":{"language":"json"}}},"url":"https://a2a.neopayments.gr/api/initialize","description":"<h3 id=\"post-apiinitialize\">POST <code>/api/initialize</code></h3>\n<h4 id=\"request\">Request</h4>\n<p><strong>Headers</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Authorization</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Bearer token in the format <code>Bearer</code> .</td>\n</tr>\n<tr>\n<td><code>Content-Type</code></td>\n<td>string</td>\n<td>Yes</td>\n<td><code>application/json</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Body (JSON)</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{\n  \"description\": \"string\",\n  \"amount\": 0,\n  \"expires_at\": \"ISO8601 string (optional)\",\n  \"payer_tin\": \"string (optional)\",\n  \"documents\": [\n    {\n      \"id\": \"string\",\n      \"title\": \"string\",\n      \"invoice\": true,\n      \"tags\": \"string (comma-separated, optional)\",\n      \"amount\": 0,\n      \"net_amount\": 0,\n      \"vat_amount\": 0,\n      \"published\": \"ISO8601 string (optional)\",\n      \"due\": \"ISO8601 string (optional)\"\n    }\n  ]\n}\n\n</code></pre><div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Transaction description. Regex: <code>^[A-Za-z0-9 ]+$</code>.</td>\n</tr>\n<tr>\n<td><code>amount</code></td>\n<td>integer</td>\n<td>Yes</td>\n<td>Total amount in the smallest currency unit (e.g., cents).</td>\n</tr>\n<tr>\n<td><code>expires_at</code></td>\n<td>string</td>\n<td>No</td>\n<td>Expiration timestamp (ISO 8601).</td>\n</tr>\n<tr>\n<td><code>payer_tin</code></td>\n<td>string</td>\n<td>When document is invoice</td>\n<td>Payer’s Tax Identification Number.</td>\n</tr>\n<tr>\n<td><code>documents</code></td>\n<td>array</td>\n<td>No</td>\n<td>List of related document objects.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Document object</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Document identifier (e.g., invoice ID).</td>\n</tr>\n<tr>\n<td><code>title</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Document title.</td>\n</tr>\n<tr>\n<td><code>invoice</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether this document is an invoice.</td>\n</tr>\n<tr>\n<td><code>tags</code></td>\n<td>string</td>\n<td>No</td>\n<td>Comma-separated tags.</td>\n</tr>\n<tr>\n<td><code>amount</code></td>\n<td>integer</td>\n<td>Yes</td>\n<td>Document amount in the smallest currency unit.</td>\n</tr>\n<tr>\n<td><code>net_amount</code></td>\n<td>integer</td>\n<td>No</td>\n<td>Net amount before VAT (smallest unit).</td>\n</tr>\n<tr>\n<td><code>vat_amount</code></td>\n<td>integer</td>\n<td>No</td>\n<td>VAT amount (smallest unit).</td>\n</tr>\n<tr>\n<td><code>published</code></td>\n<td>string</td>\n<td>No</td>\n<td>Publication date (ISO 8601).</td>\n</tr>\n<tr>\n<td><code>due</code></td>\n<td>string</td>\n<td>No</td>\n<td>Due date (ISO 8601).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h4 id=\"responses\">Responses</h4>\n<p><strong>200 OK</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{\n  \"id\": \"string\",\n  \"payload\": \"string\"\n}\n\n</code></pre><div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td>string</td>\n<td>Unique transaction identifier.</td>\n</tr>\n<tr>\n<td><code>url</code></td>\n<td>string</td>\n<td>URL for further interaction with the transaction.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>401 Unauthorized</strong>  </p>\n<p>Invalid or missing bearer token. No response body.</p>\n<p><strong>400 Bad Request</strong>  </p>\n<p>Invalid request body. No response body.</p>\n<hr />\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt_token}}"}]},"isInherited":true,"source":{"_postman_id":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","id":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","name":"NeoPay API","type":"collection"}},"urlObject":{"path":["api","initialize"],"host":["https://a2a.neopayments.gr"],"query":[],"variable":[]}},"response":[],"_postman_id":"39ea8f0f-c722-4612-b851-bb08d58285b8"},{"name":"Initialize With Credentials","event":[{"listen":"test","script":{"id":"a9f53223-ebc2-4fe3-9bb0-c415aea5fe1f","exec":["pm.test(\"Status code is 200\", function () {","    pm.response.to.have.status(200);","});"],"type":"text/javascript","packages":{},"requests":{}}}],"id":"7f00a953-fff1-4774-9efb-2266214ee4d8","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"username\": \"{{username}}\",\n    \"password\": \"{{password}}\",\n    \"description\": \"Payment for order 123\",\n    \"amount\": 100,\n    \"expires_at\": \"2025-05-16T12:00:00Z\",\n    \"documents\": [\n        {\n            \"id\": \"INV2025001\",\n            \"title\": \"Invoice 2025-001\",\n            \"invoice\": true,\n            \"tags\": \"sales,product\",\n            \"amount\": 100,\n            \"net_amount\": 80,\n            \"vat_amount\": 20,\n            \"published\": \"2025-05-13T09:00:00Z\",\n            \"due\": \"2025-05-27T17:00:00Z\"\n        }\n    ],\n    \"payer_tin\": \"171717333\",\n    \"qrsize\": 256\n}","options":{"raw":{"language":"json"}}},"url":"https://a2a.neopayments.gr/api/wcrd/initialize","description":"<h3 id=\"post-apiwcrdinitialize\">POST <code>/api/wcrd/initialize</code></h3>\n<h4 id=\"request\">Request</h4>\n<p><strong>Headers</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Authorization</code></td>\n<td>string</td>\n<td>No</td>\n<td>Bearer token in the format <code>Bearer</code> . Optional if <code>username</code> and <code>password</code> are provided in the request body.</td>\n</tr>\n<tr>\n<td><code>Content-Type</code></td>\n<td>string</td>\n<td>Yes</td>\n<td><code>application/json</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Body (JSON)</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"username\": \"string (optional)\",\n  \"password\": \"string (optional)\",\n  \"description\": \"string\",\n  \"amount\": 0,\n  \"expires_at\": \"ISO8601 string (optional)\",\n  \"payer_tin\": \"string (optional)\",\n  \"documents\": [\n    {\n      \"id\": \"string\",\n      \"title\": \"string\",\n      \"invoice\": true,\n      \"tags\": \"string (comma-separated, optional)\",\n      \"amount\": 0,\n      \"net_amount\": 0,\n      \"vat_amount\": 0,\n      \"published\": \"ISO8601 string (optional)\",\n      \"due\": \"ISO8601 string (optional)\"\n    }\n  ]\n}\n\n</code></pre>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>username</code></td>\n<td>string</td>\n<td>Conditional</td>\n<td>Required if no bearer token is provided.</td>\n</tr>\n<tr>\n<td><code>password</code></td>\n<td>string</td>\n<td>Conditional</td>\n<td>Required if no bearer token is provided.</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Transaction description. Regex: <code>^[A-Za-z0-9 ]+$</code>.</td>\n</tr>\n<tr>\n<td><code>amount</code></td>\n<td>integer</td>\n<td>Yes</td>\n<td>Total amount in the smallest currency unit (e.g., cents).</td>\n</tr>\n<tr>\n<td><code>expires_at</code></td>\n<td>string</td>\n<td>No</td>\n<td>Expiration timestamp (ISO 8601).</td>\n</tr>\n<tr>\n<td><code>payer_tin</code></td>\n<td>string</td>\n<td>No</td>\n<td>Payer’s Tax Identification Number.</td>\n</tr>\n<tr>\n<td><code>qrsize</code></td>\n<td>integer</td>\n<td>No</td>\n<td>Number of pixels of each side of the QR code image</td>\n</tr>\n<tr>\n<td><code>documents</code></td>\n<td>array</td>\n<td>No</td>\n<td>List of related document objects.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Document object</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Document identifier (e.g., invoice ID).</td>\n</tr>\n<tr>\n<td><code>title</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Document title.</td>\n</tr>\n<tr>\n<td><code>invoice</code></td>\n<td>boolean</td>\n<td>No</td>\n<td>Whether this document is an invoice.</td>\n</tr>\n<tr>\n<td><code>tags</code></td>\n<td>string</td>\n<td>No</td>\n<td>Comma-separated tags.</td>\n</tr>\n<tr>\n<td><code>amount</code></td>\n<td>integer</td>\n<td>Yes</td>\n<td>Document amount in the smallest currency unit.</td>\n</tr>\n<tr>\n<td><code>net_amount</code></td>\n<td>integer</td>\n<td>No</td>\n<td>Net amount before VAT (smallest unit).</td>\n</tr>\n<tr>\n<td><code>vat_amount</code></td>\n<td>integer</td>\n<td>No</td>\n<td>VAT amount (smallest unit).</td>\n</tr>\n<tr>\n<td><code>published</code></td>\n<td>string</td>\n<td>No</td>\n<td>Publication date (ISO 8601).</td>\n</tr>\n<tr>\n<td><code>due</code></td>\n<td>string</td>\n<td>No</td>\n<td>Due date (ISO 8601).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h4 id=\"responses\">Responses</h4>\n<p><strong>200 OK</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"token\": \"string\",\n  \"token_expires_at\": 0,\n  \"id\": \"string\",\n  \"qr\": \"base64 string\"\n}\n\n</code></pre>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>token</code></td>\n<td>string</td>\n<td>Newly issued JWT (if authentication occurred via username/password).</td>\n</tr>\n<tr>\n<td><code>token_expires_at</code></td>\n<td>integer</td>\n<td>Unix timestamp of token expiration.</td>\n</tr>\n<tr>\n<td><code>id</code></td>\n<td>string</td>\n<td>Unique transaction identifier.</td>\n</tr>\n<tr>\n<td><code>qr</code></td>\n<td>string</td>\n<td>Base64-encoded Bitmap QR code for the transaction.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>401 Unauthorized</strong></p>\n<p>Returned when authentication fails (invalid bearer token or incorrect username/password). No response body.</p>\n<h4 id=\"400-bad-request\"><strong>400 Bad Request</strong></h4>\n<p>Returned when the request body is invalid. No response body.</p>\n<hr />\n","urlObject":{"path":["api","wcrd","initialize"],"host":["https://a2a.neopayments.gr"],"query":[],"variable":[]}},"response":[],"_postman_id":"7f00a953-fff1-4774-9efb-2266214ee4d8"},{"name":"Status","event":[{"listen":"test","script":{"id":"6f5e1e9c-16d7-42d9-aed4-08b3f8d44fc1","exec":["pm.test(\"Status code is 200\", function () {","    pm.response.to.have.status(200);","});"],"type":"text/javascript","packages":{}}}],"id":"b84195a9-04a4-470a-ba29-b6819f7aa6b1","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"ids\":[\"ac3fdf3b-11d0-4b02-9d80-aa939a6d24ca\"]\n}","options":{"raw":{"language":"json"}}},"url":"https://a2a.neopayments.gr/api/status","description":"<h3 id=\"post-apistatus\">POST <code>/api/status</code></h3>\n<h4 id=\"request\">Request</h4>\n<p><strong>Headers</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Authorization</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Bearer token in the format <code>Bearer</code> .</td>\n</tr>\n<tr>\n<td><code>Content-Type</code></td>\n<td>string</td>\n<td>Yes</td>\n<td><code>application/json</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Body (JSON)</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"ids\": [\"string\"]\n}\n\n</code></pre>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>ids</code></td>\n<td>array</td>\n<td>Yes</td>\n<td>Array of transaction IDs to query.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h4 id=\"responses\">Responses</h4>\n<p><strong>200 OK</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">[\n  {\n    \"status\": \"I\",\n    \"id\": \"string\"\n  }\n]\n\n</code></pre>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>status</code></td>\n<td>string</td>\n<td>Transaction status: <code>I</code> or <code>P</code> = in progress, <code>S</code> = successful, <code>F</code> = failed.</td>\n</tr>\n<tr>\n<td><code>id</code></td>\n<td>string</td>\n<td>Transaction ID.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>401 Unauthorized</strong>  </p>\n<p>Invalid or missing bearer token. No response body.</p>\n<p><strong>400 Bad Request</strong>  </p>\n<p>Invalid request body. No response body.</p>\n<p><strong>404 Not Found</strong>  </p>\n<p>Transaction not found. No response body.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt_token}}"}]},"isInherited":true,"source":{"_postman_id":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","id":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","name":"NeoPay API","type":"collection"}},"urlObject":{"path":["api","status"],"host":["https://a2a.neopayments.gr"],"query":[],"variable":[]}},"response":[],"_postman_id":"b84195a9-04a4-470a-ba29-b6819f7aa6b1"},{"name":"Status With Credentials","event":[{"listen":"test","script":{"id":"6f5e1e9c-16d7-42d9-aed4-08b3f8d44fc1","exec":["pm.test(\"Status code is 200\", function () {","    pm.response.to.have.status(200);","});"],"type":"text/javascript","packages":{},"requests":{}}}],"id":"16f630cc-1e29-4db3-b2ad-42888e3ee101","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"username\" : \"{{username}}\",\n    \"password\" : \"{{password}}\",\n    \"ids\":[\"ac3fdf3b-11d0-4b02-9d80-aa939a6d24ca\"]\n}","options":{"raw":{"language":"json"}}},"url":"https://a2a.neopayments.gr/api/wcrd/status","description":"<h3 id=\"post-apiwcrdstatus\">POST <code>/api/wcrd/status</code></h3>\n<h4 id=\"request\">Request</h4>\n<p><strong>Headers</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Authorization</code></td>\n<td>string</td>\n<td>No</td>\n<td>Bearer token in the format <code>Bearer</code> . Optional if <code>username</code> and <code>password</code> are provided in the body.</td>\n</tr>\n<tr>\n<td><code>Content-Type</code></td>\n<td>string</td>\n<td>Yes</td>\n<td><code>application/json</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Body (JSON)</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"ids\": [\"string\"],\n  \"username\": \"string (optional)\",\n  \"password\": \"string (optional)\"\n}\n\n</code></pre>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>ids</code></td>\n<td>array</td>\n<td>Yes</td>\n<td>Array of transaction IDs to query.</td>\n</tr>\n<tr>\n<td><code>username</code></td>\n<td>string</td>\n<td>Conditional</td>\n<td>Required if no bearer token is provided.</td>\n</tr>\n<tr>\n<td><code>password</code></td>\n<td>string</td>\n<td>Conditional</td>\n<td>Required if no bearer token is provided.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h4 id=\"responses\">Responses</h4>\n<p><strong>200 OK</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">[\n  {\n    \"status\": \"I\",\n    \"id\": \"string\"\n  }\n]\n\n</code></pre>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>status</code></td>\n<td>string</td>\n<td>Transaction status: <code>I</code> or <code>P</code> = in progress, <code>S</code> = successful, <code>F</code> = failed.</td>\n</tr>\n<tr>\n<td><code>id</code></td>\n<td>string</td>\n<td>Transaction ID.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>401 Unauthorized</strong>  </p>\n<p>Invalid or missing authentication credentials. No response body.</p>\n<p><strong>400 Bad Request</strong>  </p>\n<p>Invalid request body. No response body.</p>\n<p><strong>404 Not Found</strong>  </p>\n<p>Transaction not found. No response body.</p>\n","urlObject":{"path":["api","wcrd","status"],"host":["https://a2a.neopayments.gr"],"query":[],"variable":[]}},"response":[],"_postman_id":"16f630cc-1e29-4db3-b2ad-42888e3ee101"}],"id":"914105f1-c308-486c-9fe8-91551660962d","description":"<p>The <strong>Transactions</strong> folder contains endpoints for managing and monitoring financial transactions. This includes initiating new transactions and checking the status of previously initiated ones. These endpoints ensure secure and efficient transaction processing, requiring authentication via a valid bearer token.</p>\n","_postman_id":"914105f1-c308-486c-9fe8-91551660962d","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt_token}}"}]},"isInherited":true,"source":{"_postman_id":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","id":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","name":"NeoPay API","type":"collection"}}},{"name":"Reports","item":[{"name":"Transactions","event":[{"listen":"test","script":{"id":"e647f9ad-6206-4645-bbfb-34ca8d780b7a","exec":["pm.test(\"Status code is 200\", function () {","    pm.response.to.have.status(200);","});"],"type":"text/javascript","packages":{},"requests":{}}}],"id":"9d6f78b0-1b0e-4009-abce-61cd54446a5f","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"to\": \"2025-01-18T23:00:00.000Z\",\n    \"from\": \"2025-01-01T23:59:59.999Z\"\n}","options":{"raw":{"language":"json"}}},"url":"https://a2a.neopayments.gr/api/transactions","description":"<h3 id=\"post-apitransactions\">POST <code>/api/transactions</code></h3>\n<h4 id=\"request\">Request</h4>\n<p><strong>Headers</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Authorization</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Bearer token in the format <code>Bearer</code> .</td>\n</tr>\n<tr>\n<td><code>Content-Type</code></td>\n<td>string</td>\n<td>Yes</td>\n<td><code>application/json</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Body (JSON)</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"from\": \"ISO8601 string\",\n  \"to\": \"ISO8601 string\"\n}\n\n</code></pre>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>from</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>Start of date range (ISO 8601).</td>\n</tr>\n<tr>\n<td><code>to</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>End of date range (ISO 8601).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h4 id=\"responses\">Responses</h4>\n<p><strong>200 OK</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">[\n  {\n    \"id\": \"string\",\n    \"name\": \"string or null\",\n    \"description\": \"string or null\",\n    \"amount\": 0,\n    \"status\": \"I\",\n    \"url\": \"string\",\n    \"invoices\": [\"string\"],\n    \"final_status_date\": \"ISO8601 string\",\n    \"created\": \"ISO8601 string\"\n  }\n]\n\n</code></pre>\n<p>Each item has the schema:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td>string</td>\n<td>Unique transaction identifier.</td>\n</tr>\n<tr>\n<td><code>name</code></td>\n<td>string (nullable)</td>\n<td>Short name/identifier for the merchant or store.</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string (nullable)</td>\n<td>Transaction description.</td>\n</tr>\n<tr>\n<td><code>amount</code></td>\n<td>integer</td>\n<td>Amount in the smallest currency unit.</td>\n</tr>\n<tr>\n<td><code>status</code></td>\n<td>string</td>\n<td><code>I</code>/<code>P</code> = in progress, <code>S</code> = successful, <code>F</code> = failed.</td>\n</tr>\n<tr>\n<td><code>url</code></td>\n<td>string</td>\n<td>URL related to the transaction.</td>\n</tr>\n<tr>\n<td><code>invoices</code></td>\n<td>array</td>\n<td>Related invoice identifiers.</td>\n</tr>\n<tr>\n<td><code>final_status_date</code></td>\n<td>string</td>\n<td>When the transaction reached final status (ISO 8601).</td>\n</tr>\n<tr>\n<td><code>created</code></td>\n<td>string</td>\n<td>Creation timestamp (ISO 8601).</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>401 Unauthorized</strong>  </p>\n<p>Invalid or missing bearer token. No response body.</p>\n<p><strong>400 Bad Request</strong>  </p>\n<p>Invalid request body. No response body.</p>\n<p><strong>404 Not Found</strong>  </p>\n<p>No transactions found in the given date range. No response body.</p>\n","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt_token}}"}]},"isInherited":true,"source":{"_postman_id":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","id":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","name":"NeoPay API","type":"collection"}},"urlObject":{"path":["api","transactions"],"host":["https://a2a.neopayments.gr"],"query":[],"variable":[]}},"response":[],"_postman_id":"9d6f78b0-1b0e-4009-abce-61cd54446a5f"}],"id":"0d2c8dd5-6f68-4475-8ab9-5770c39b8a9d","description":"<p>The <strong>Reports</strong> folder contains endpoints designed to generate and retrieve detailed data summaries and analytics. These endpoints enable users to query transaction records, statuses, and other relevant metrics, often filtered by specific parameters such as date ranges. The folder is intended to support monitoring, auditing, and reporting needs with secure access via bearer tokens.</p>\n","_postman_id":"0d2c8dd5-6f68-4475-8ab9-5770c39b8a9d","auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt_token}}"}]},"isInherited":true,"source":{"_postman_id":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","id":"cc49d762-1b7d-44c5-b02b-64bd73c57a4c","name":"NeoPay API","type":"collection"}}}],"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt_token}}"}]}},"event":[{"listen":"prerequest","script":{"id":"770ca3dd-f2b0-4bd8-8d4b-9b15360e6fa5","type":"text/javascript","requests":{},"exec":["// Pre-request auth helper (works with /api/login JSON OR header token)","","// ===== Config (optional) =====","// Set to \"true\" in environment to always re-login before protected calls.","const FORCE_LOGIN = (pm.environment.get(\"force_login\") || \"false\").toLowerCase() === \"true\";","","// ===== Utils =====","function nowSec() { return Math.floor(Date.now() / 1000); }","function pathParts() {","  // pm.request.url.path can be string or array depending on how the request is built","  const raw = pm.request.url.path;","  if (Array.isArray(raw)) return raw.filter(Boolean);","  const s = String(raw || \"\");","  return s.replace(/^\\/+/, \"\").split(\"/\").filter(Boolean);","}","function isLoginPath(p) { return p.length >= 2 && p[0] === \"api\" && p[1] === \"login\"; }","function isWcrdPath(p) { return p.length >= 2 && p[0] === \"api\" && p[1] === \"wcrd\"; }","","function upsertAuthHeader(token) {","  pm.request.headers.upsert({ key: \"Authorization\", value: `Bearer ${token}` });","}","","function parseJwtExp(token) {","  try {","    const payloadB64 = token.split(\".\")[1];","    const json = JSON.parse(atob(payloadB64.replace(/-/g, \"+\").replace(/_/g, \"/\")));","    return typeof json.exp === \"number\" ? json.exp : null;","  } catch (_) { return null; }","}","","function getStoredToken() { return pm.environment.get(\"jwt_token\") || \"\"; }","function getStoredExpiry() {","  const v = pm.environment.get(\"jwt_expires_at\");","  return (v !== undefined && v !== null && v !== \"\") ? Number(v) : null;","}","function saveToken(token, expTs) {","  pm.environment.set(\"jwt_token\", token || \"\");","  if (typeof expTs === \"number\" && !Number.isNaN(expTs)) {","    pm.environment.set(\"jwt_expires_at\", String(expTs));","  } else {","    pm.environment.unset(\"jwt_expires_at\");","  }","}","","function isExpired(expTs) { return expTs !== null && expTs <= nowSec(); }","function isExpiringSoon(expTs, skew = 60) { return expTs !== null && expTs <= (nowSec() + skew); }","","// Extract token from response: prefer JSON body {token, token_expires_at/expires_at}; fallback to headers","function extractTokenFromResponse(res) {","  let token = null, exp = null;","","  // Try JSON body first (if any)","  try {","    const txt = res.text();","    if (txt && txt.trim().length > 0) {","      const data = res.json();","      if (data && typeof data === \"object\") {","        if (typeof data.token === \"string\" && data.token.length > 0) token = data.token;","        // supports both login and renew field names","        if (typeof data.token_expires_at === \"number\") exp = data.token_expires_at;","        else if (typeof data.expires_at === \"number\") exp = data.expires_at;","      }","    }","  } catch (e) {","    // Body either empty or not JSON — ignore; we'll try headers next.","  }","","  // Fallback to token in headers if body absent/empty","  if (!token) {","    const authH = res.headers.find(h => (h.key || \"\").toLowerCase() === \"authentication\")","              || res.headers.find(h => (h.key || \"\").toLowerCase() === \"authorization\");","    if (authH && typeof authH.value === \"string\") {","      const parts = authH.value.split(/\\s+/);","      if (parts.length === 2 && /^Bearer$/i.test(parts[0])) token = parts[1];","    }","  }","","  // If we still don't have explicit exp, derive from JWT (if valid format)","  if (!exp && token && token.includes(\".\")) {","    exp = parseJwtExp(token);","  }","","  return { token, exp };","}","","// ===== Network calls =====","function login(cb) {","  const req = {","    url: `${pm.variables.get(\"api_host\")}/api/login`,","    method: \"POST\",","    header: { \"Content-Type\": \"application/json\" },","    body: {","      mode: \"raw\",","      raw: JSON.stringify({","        username: pm.variables.get(\"username\"),","        password: pm.variables.get(\"password\"),","      })","    }","  };","  console.log(\"PreRequest -> Logging in to acquire token\");","  pm.sendRequest(req, (err, res) => {","    if (err) { console.error(\"PreRequest -> Login error:\", err); return cb && cb(err); }","    if (res.code !== 200) {","      console.error(`PreRequest -> Login failed: HTTP ${res.code}`);","      return cb && cb(new Error(`login http ${res.code}`));","    }","    const { token, exp } = extractTokenFromResponse(res);","    if (!token) {","      console.error(\"PreRequest -> Login parse error: token not found in body or headers\");","      return cb && cb(new Error(\"no-token\"));","    }","    saveToken(token, exp || null);","    upsertAuthHeader(token);","    console.log(\"PreRequest -> Token saved from login\");","    return cb && cb(null);","  });","}","","function renew(existingToken, cb) {","  const req = {","    url: `${pm.variables.get(\"api_host\")}/api/renew`,","    method: \"GET\",","    header: { Authorization: `Bearer ${existingToken}` }","  };","  console.log(\"PreRequest -> Renewing token\");","  pm.sendRequest(req, (err, res) => {","    if (err) { console.error(\"PreRequest -> Renew error:\", err); return cb && cb(err); }","    if (res.code !== 200) {","      console.warn(`PreRequest -> Renew failed: HTTP ${res.code}`);","      return cb && cb(new Error(`renew http ${res.code}`));","    }","    const { token, exp } = extractTokenFromResponse(res);","    if (!token) {","      console.error(\"PreRequest -> Renew parse error: token not found\");","      return cb && cb(new Error(\"no-token\"));","    }","    saveToken(token, exp || null);","    upsertAuthHeader(token);","    console.log(\"PreRequest -> Token renewed\");","    return cb && cb(null);","  });","}","","// ===== Main flow =====","const parts = pathParts();","if (!isLoginPath(parts)) {","  const isWcrd = isWcrdPath(parts);","  let token = getStoredToken();","  let expTs = getStoredExpiry();","","  // Derive exp from JWT if not explicitly stored","  if (!expTs && token && token.includes(\".\")) {","    expTs = parseJwtExp(token);","  }","","  // For WCRD: attach bearer if valid, but do not force login","  if (isWcrd) {","    if (token && (!expTs || !isExpired(expTs))) {","      upsertAuthHeader(token);","      if (expTs && isExpiringSoon(expTs)) {","        renew(token, function () { /* optional refresh; header already set */ });","      }","    }","    // else: rely on body username/password or the request's own auth","  } else {","    // Protected endpoints (non-WCRD)","    const needFreshLogin = FORCE_LOGIN || !token || (expTs && isExpired(expTs));","    if (needFreshLogin) {","      console.log(\"PreRequest -> No token / expired / force_login: performing login\");","      login(function () { /* header set in login */ });","    } else if (expTs && isExpiringSoon(expTs)) {","      renew(token, function (e) {","        if (e) { // fallback to login if renew failed","          console.warn(\"PreRequest -> Renew failed, falling back to login\");","          login(function () { /* header set in login */ });","        }","      });","    } else {","      upsertAuthHeader(token);","    }","  }","}",""]}},{"listen":"test","script":{"id":"1b336e6a-7e4e-459c-94c1-e33c817a620f","type":"text/javascript","requests":{},"exec":[""]}}],"variable":[{"key":"api_host","value":"https://a2a.neopayments.gr"},{"key":"versionUserAgent","value":"NeoTransfer Postman Collection 01 Feb 2025"}]}