mirror of
https://gitplac.si/aljaxus/upn-qr.git
synced 2025-12-17 04:00:59 +00:00
Merge branch 'topic/payment-deadline' into 'master'
added payment deadline field See merge request aljaxus/upn-qr!5
This commit is contained in:
20
README.md
20
README.md
@@ -1,9 +1,19 @@
|
|||||||
<div align="center">
|
|
||||||
|
|
||||||
# upn-qr
|
# upn-qr
|
||||||
|
|
||||||
A public API for generating UPN-QR codes on the fly
|
|
||||||
|
|
||||||
https://upn-qr.gitapp.si
|
https://upn-qr.gitapp.si
|
||||||
|
|
||||||
</div>
|
## Local development
|
||||||
|
|
||||||
|
**requirements:**
|
||||||
|
|
||||||
|
* Docker
|
||||||
|
* Docker-compose
|
||||||
|
|
||||||
|
|
||||||
|
The local devserver is accessible via http://localhost:8080
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose up
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
22
docker-compose.yaml
Normal file
22
docker-compose.yaml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
version: 3.8
|
||||||
|
|
||||||
|
services:
|
||||||
|
image: node:14
|
||||||
|
build:
|
||||||
|
context: ./
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
command: ["yarn", "run", "dev"]
|
||||||
|
environment:
|
||||||
|
ENV: development
|
||||||
|
NODE_ENV: development
|
||||||
|
volumes:
|
||||||
|
- ./src:/var/src
|
||||||
|
- /var/src/node_modules
|
||||||
|
ports:
|
||||||
|
- 8080:80
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-sSG", "http://localhost/healthcheck"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 15s
|
||||||
12
src/index.js
12
src/index.js
@@ -45,12 +45,20 @@ app.get('/api/qrcode', async (req, res) => {
|
|||||||
// SET DEFAULT PURPOSE_CODE
|
// SET DEFAULT PURPOSE_CODE
|
||||||
if (!req.query.purpose_code) req.query.purpose_code = "OTHR"
|
if (!req.query.purpose_code) req.query.purpose_code = "OTHR"
|
||||||
else {
|
else {
|
||||||
req.query.amount = String(req.query.amount).trim()
|
|
||||||
if (!String(req.query.purpose_code).match(/^[A-Z]{4}$/)) {
|
if (!String(req.query.purpose_code).match(/^[A-Z]{4}$/)) {
|
||||||
errors.push("purpose_code does not match the required format")
|
errors.push("purpose_code does not match the required format")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DEADLINE is optional
|
||||||
|
if (req.query.deadline ) {
|
||||||
|
if(!String(req.query.deadline).match(/^[0-9]{2}\.[0-9]{2}\.[0-9]{4}$/)) {
|
||||||
|
errors.push("deadline does not match the required format")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
req.query.deadline = ""
|
||||||
|
}
|
||||||
|
|
||||||
if (errors.length > 0) return res.status(400).send({
|
if (errors.length > 0) return res.status(400).send({
|
||||||
ok: false,
|
ok: false,
|
||||||
errors
|
errors
|
||||||
@@ -69,7 +77,7 @@ ${req.query.amount}
|
|||||||
|
|
||||||
${String(req.query.purpose_code).toUpperCase()}
|
${String(req.query.purpose_code).toUpperCase()}
|
||||||
${String(req.query.payment_purpose).toUpperCase()}
|
${String(req.query.payment_purpose).toUpperCase()}
|
||||||
|
${req.query.deadline}
|
||||||
${req.query.iban}
|
${req.query.iban}
|
||||||
${req.query.reference}
|
${req.query.reference}
|
||||||
${String(req.query.issuer_name).toUpperCase()}
|
${String(req.query.issuer_name).toUpperCase()}
|
||||||
|
|||||||
@@ -72,10 +72,11 @@ div {
|
|||||||
{ n: "issuer-address", d: "Issuer address", p: "Za deveto smreko 15 k", t: "text" },
|
{ n: "issuer-address", d: "Issuer address", p: "Za deveto smreko 15 k", t: "text" },
|
||||||
{ n: "issuer-city", d: "Issuer city", p: "1000 Ljubljana", t: "text" },
|
{ n: "issuer-city", d: "Issuer city", p: "1000 Ljubljana", t: "text" },
|
||||||
{ n: "iban", d: "IBAN", p: "SI56047500000280672", t: "text" },
|
{ n: "iban", d: "IBAN", p: "SI56047500000280672", t: "text" },
|
||||||
{ n: "amount", d: "Amount", p: "35090 (350.90€)", t: "number" },
|
{ n: "amount", d: "Amount", p: "35090 (350.90€)", t: "number" },
|
||||||
{ n: "code", d: "Code", p: "OTHR", t: "text" },
|
{ n: "code", d: "Code", p: "OTHR", t: "text" },
|
||||||
{ n: "purpose", d: "Purpose", p: "moutain bike first half", t: "text" },
|
{ n: "purpose", d: "Purpose", p: "moutain bike first half", t: "text" },
|
||||||
{ n: "reference", d: "Reference", p: "SI121234567890120", t: "text" }
|
{ n: "reference", d: "Reference", p: "SI121234567890120", t: "text" },
|
||||||
|
{ n: "deadline", d: "Deadline", p: "01.02.2034", t: "text" }
|
||||||
]
|
]
|
||||||
%>
|
%>
|
||||||
<% for (const i of items) { %>
|
<% for (const i of items) { %>
|
||||||
@@ -119,6 +120,7 @@ function getNewUrl () {
|
|||||||
["issuer_name", val("issuer-name")],
|
["issuer_name", val("issuer-name")],
|
||||||
["issuer_address", val("issuer-address")],
|
["issuer_address", val("issuer-address")],
|
||||||
["issuer_city", val("issuer-city")],
|
["issuer_city", val("issuer-city")],
|
||||||
|
["deadline", val("deadline")]
|
||||||
].map(v => `${v[0]}=${v[1]}`).join("&")
|
].map(v => `${v[0]}=${v[1]}`).join("&")
|
||||||
return `${window.location.origin}/api/qrcode?${qstring}`
|
return `${window.location.origin}/api/qrcode?${qstring}`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,10 @@ section div {
|
|||||||
<label for="amount">Amount</label>
|
<label for="amount">Amount</label>
|
||||||
<input type="number" placeholder="00000001132" min="0" max="99999999999" name="amount">
|
<input type="number" placeholder="00000001132" min="0" max="99999999999" name="amount">
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="deadline">Deadline</label>
|
||||||
|
<input type="text" placeholder="01.02.2034" min=0 max=10 name="deadline">
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="code">Purpose code</label>
|
<label for="code">Purpose code</label>
|
||||||
<input type="text" placeholder="OTHR" name="code">
|
<input type="text" placeholder="OTHR" name="code">
|
||||||
@@ -132,6 +136,7 @@ function getNewUrl () {
|
|||||||
["issuer_name", val("issuer-name")],
|
["issuer_name", val("issuer-name")],
|
||||||
["issuer_address", val("issuer-address")],
|
["issuer_address", val("issuer-address")],
|
||||||
["issuer_city", val("issuer-city")],
|
["issuer_city", val("issuer-city")],
|
||||||
|
["deadline", val("deadline")],
|
||||||
].map(v => `${v[0]}=${v[1]}`).join("&")
|
].map(v => `${v[0]}=${v[1]}`).join("&")
|
||||||
return encodeURI(`${window.location.origin}/api/qrcode?${qstring}`)
|
return encodeURI(`${window.location.origin}/api/qrcode?${qstring}`)
|
||||||
}
|
}
|
||||||
@@ -201,9 +206,9 @@ updateQR()
|
|||||||
<br>
|
<br>
|
||||||
<pre>
|
<pre>
|
||||||
<!-- Meant to be used as direct image source, for example -->
|
<!-- Meant to be used as direct image source, for example -->
|
||||||
<img src="https://upn-qr.gitapp.si/api/qrcode?client_name=Dobri človek&client_address=Kristanova ulica 1&client_city=1000 Ljubljana&amount=00000001000&payment_purpose=Donacija&iban=SI56021400015556761&reference=SI99&issuer_name=Slovenska Karitas&issuer_address=Kristanova ulica 1&issuer_city=1000 Ljubljana">
|
<img src="https://upn-qr.gitapp.si/api/qrcode?client_name=Dobri človek&client_address=Kristanova ulica 1&client_city=1000 Ljubljana&amount=00000001000&deadline=01.02.2034&payment_purpose=Donacija&iban=SI56021400015556761&reference=SI99&issuer_name=Slovenska Karitas&issuer_address=Kristanova ulica 1&issuer_city=1000 Ljubljana">
|
||||||
</pre>
|
</pre>
|
||||||
<img src="/api/qrcode?client_name=Dobri človek&client_address=Kristanova ulica 1&client_city=1000 Ljubljana&amount=00000001000&payment_purpose=Donacija&iban=SI56021400015556761&reference=SI99&issuer_name=Slovenska Karitas&issuer_address=Kristanova ulica 1&issuer_city=1000 Ljubljana">
|
<img src="/api/qrcode?client_name=Dobri človek&client_address=Kristanova ulica 1&client_city=1000 Ljubljana&amount=00000001000&deadline=01.02.2034&payment_purpose=Donacija&iban=SI56021400015556761&reference=SI99&issuer_name=Slovenska Karitas&issuer_address=Kristanova ulica 1&issuer_city=1000 Ljubljana">
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@@ -254,6 +259,17 @@ updateQR()
|
|||||||
<span>Example (11,32€): 00000001132</span>
|
<span>Example (11,32€): 00000001132</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h5 id="api-qrcode-deadline"><a href="#api-qrcode-deadline">🔗</a> <code>deadline</code></h5>
|
||||||
|
<div>
|
||||||
|
<span>Regex: <code>^[0-9]{2}\.[0-9]{2}\.[0-9]{4}$</code></span>
|
||||||
|
<br>
|
||||||
|
<span>Demo: <a href="https://regex101.com/r/JDZT9P/1">regex101.com/r/JDZT9P/1</a></span>
|
||||||
|
<br>
|
||||||
|
<span>Description: Payment deadline. Field is optional. Format DD.MM.YYYY</span>
|
||||||
|
<br>
|
||||||
|
<span>Example: 01.02.2034</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h5 id="api-qrcode-purpose_code"><a href="#api-qrcode-purpose_code">🔗</a> <code>purpose_code</code></h5>
|
<h5 id="api-qrcode-purpose_code"><a href="#api-qrcode-purpose_code">🔗</a> <code>purpose_code</code></h5>
|
||||||
<div>
|
<div>
|
||||||
<span>Regex: <code>^[A-Z]{4}$</code></span>
|
<span>Regex: <code>^[A-Z]{4}$</code></span>
|
||||||
|
|||||||
Reference in New Issue
Block a user