From f5e0a0899ab7b1bf1ba0eae3c7766cdce5ebd5a0 Mon Sep 17 00:00:00 2001 From: Christian Wick Date: Thu, 18 Feb 2021 12:57:34 +0100 Subject: [PATCH 1/5] Added support for X-Auka-Integrator --- index.html | 33 ++++++++-- index.js | 184 ++++++++++++++++++++++++++++++++++------------------- 2 files changed, 147 insertions(+), 70 deletions(-) diff --git a/index.html b/index.html index ab5b042..df3d076 100644 --- a/index.html +++ b/index.html @@ -23,6 +23,10 @@ animation: pulse 0.5s 1; } + .pure-form-aligned .pure-control-group label { + width: 11em; + } + @keyframes pulse { 0% { background-color: rgb(230, 255, 230); @@ -40,17 +44,38 @@

Settle API PKCS#1 1.5 signature generator

- +
-
- +

Is an Integrator acting as a proxy on behalf of a Merchant client?

+
+
+ + +
+
+ + +
+
+ +
+
+
+ + +
+
- +
diff --git a/index.js b/index.js index 6773fd0..fd48722 100644 --- a/index.js +++ b/index.js @@ -1,46 +1,46 @@ // dec2hex :: Integer -> String // i.e. 0-255 -> '00'-'ff' function dec2hex(dec) { - return ('0' + dec.toString(16)).substr(-2) + return ("0" + dec.toString(16)).substr(-2); } // generateId :: Integer -> String function generateId(len) { - var arr = new Uint8Array((len || 10) / 2) - window.crypto.getRandomValues(arr) - return `"${Array.from(arr, dec2hex).join('')}"` + var arr = new Uint8Array((len || 10) / 2); + window.crypto.getRandomValues(arr); + return `"${Array.from(arr, dec2hex).join("")}"`; } // getAukaTimestamp :: Void -> String function getAukaTimestamp() { const d = new Date(); - const fYear = d.getUTCFullYear().toString() - const month = (d.getUTCMonth()+1).toString() - const day = d.getUTCDate().toString() - const hours = d.getUTCHours().toString() - const minutes = (parseInt(d.getUTCMinutes())).toString() - const seconds = (parseInt(d.getUTCSeconds())).toString() - - const fMonth = month.length == 2 ? month : `0${month}` - const fDay = day.length == 2 ? day : `0${day}` - const fHours = hours.length == 2 ? hours: `0${hours}` - const fMinutes = minutes.length == 2 ? minutes: `0${minutes}` - const fSeconds = seconds.length == 2 ? seconds: `0${seconds}` + const fYear = d.getUTCFullYear().toString(); + const month = (d.getUTCMonth() + 1).toString(); + const day = d.getUTCDate().toString(); + const hours = d.getUTCHours().toString(); + const minutes = parseInt(d.getUTCMinutes()).toString(); + const seconds = parseInt(d.getUTCSeconds()).toString(); + + const fMonth = month.length == 2 ? month : `0${month}`; + const fDay = day.length == 2 ? day : `0${day}`; + const fHours = hours.length == 2 ? hours : `0${hours}`; + const fMinutes = minutes.length == 2 ? minutes : `0${minutes}`; + const fSeconds = seconds.length == 2 ? seconds : `0${seconds}`; return `${fYear}-${fMonth}-${fDay} ${fHours}:${fMinutes}:${fSeconds}`; } // generatePubKey :: String -> Void function generatePubKey(privateKey) { - console.log('Generating new public key from private key') + console.log("Generating new public key from private key"); const crypt = new JSEncrypt(); crypt.setKey(privateKey); - document.getElementById('public_key').value = crypt.getPublicKey() + document.getElementById("public_key").value = crypt.getPublicKey(); } // getHash :: String -> String function getHash(body) { - return CryptoJS.SHA256(body).toString(CryptoJS.enc.Base64) + return CryptoJS.SHA256(body).toString(CryptoJS.enc.Base64); } // getSignedMessage :: String -> String @@ -59,69 +59,121 @@ function triggerAnimation(element) { // copyToClipboard :: Object -> Void function copyToClipboard(event) { - const element = event.target - void triggerAnimation(element) - console.log(`Copying contents of ${element.name} to clipboard`) - element.select() - document.execCommand('copy') - window.getSelection().removeAllRanges() + const element = event.target; + void triggerAnimation(element); + console.log(`Copying contents of ${element.name} to clipboard`); + element.select(); + document.execCommand("copy"); + window.getSelection().removeAllRanges(); } +let isIntegrator = false; + // setDefaultValues :: Void function setDefaultValues() { - const method = '' - const url = '' - const merchantID = '' - const apiUser = '' - const privateKey = '' - const body = '' - - document.getElementById('private_key').value = privateKey - document.getElementById('method').value = method - document.getElementById('url').value = url - document.getElementById('body').value = body - document.getElementById('merchant_id').value = merchantID - document.getElementById('api_user').value = apiUser + const method = ""; + const url = ""; + const merchantID = ""; + const apiUser = ""; + const integratorID = ""; + const privateKey = ""; + const body = ""; + + document.getElementById("private_key").value = privateKey; + document.getElementById("method").value = method; + document.getElementById("url").value = url; + document.getElementById("body").value = body; + document.getElementById("merchant_id").value = merchantID; + document.getElementById("api_user").value = apiUser; + document.getElementById("X_Auka_Integrator").value = integratorID; +} + +document.getElementById("controllGroupIntegrator").style.display = "none"; + +function integratorFalse() { + document.getElementById("controllGroupApiUser").style.display = "block"; + document.getElementById("controllGroupIntegrator").style.display = "none"; + isIntegrator = false; + // console.log(isIntegrator); +} + +function integratorTrue() { + document.getElementById("controllGroupApiUser").style.display = "none"; + document.getElementById("controllGroupIntegrator").style.display = "block"; + isIntegrator = true; + // console.log(isIntegrator); } // generateHeaders :: Void function generateHeaders() { - console.log('Generating hedears') - const element = document.getElementById('bulk_headers'); - void triggerAnimation(element) - - const privateKey = document.getElementById('private_key').value - const method = document.getElementById('method').value - const url = document.getElementById('url').value - const merchantID = document.getElementById('merchant_id').value - const timestamp = getAukaTimestamp() - const apiUser = document.getElementById('api_user').value - const body = document.getElementById('body').value - const bodyHash = getHash(body) - const contentDigest = `SHA256=${bodyHash}` - const headers = `X-AUKA-CONTENT-DIGEST=${contentDigest}&X-AUKA-MERCHANT=${merchantID}&X-AUKA-TIMESTAMP=${timestamp}&X-AUKA-USER=${apiUser}` - const message = `${method}|${url}|${headers}` - const signature = getSignedMessage(privateKey, message) - const authorization = 'RSA-SHA256 ' + signature - const bulkHeaders = -`Accept:application/vnd.mcash.api.merchant.v1+json + // console.log("Generating hedears"); + const element = document.getElementById("bulk_headers"); + void triggerAnimation(element); + + if (isIntegrator == false) { + console.log("Generating hedears with X-Auka-User"); + + const privateKey = document.getElementById("private_key").value; + const method = document.getElementById("method").value; + const url = document.getElementById("url").value; + const merchantID = document.getElementById("merchant_id").value; + const timestamp = getAukaTimestamp(); + const apiUser = document.getElementById("api_user").value; + const body = document.getElementById("body").value; + const bodyHash = getHash(body); + const contentDigest = `SHA256=${bodyHash}`; + const headers = `X-AUKA-CONTENT-DIGEST=${contentDigest}&X-AUKA-MERCHANT=${merchantID}&X-AUKA-TIMESTAMP=${timestamp}&X-AUKA-USER=${apiUser}`; + const message = `${method}|${url}|${headers}`; + const signature = getSignedMessage(privateKey, message); + const authorization = "RSA-SHA256 " + signature; + const bulkHeaders = `Accept:application/vnd.mcash.api.merchant.v1+json Content-Type:application/json X-Auka-Merchant:${merchantID} X-Auka-User:${apiUser} X-Auka-Timestamp:${timestamp} X-Auka-Content-Digest:${contentDigest} -Authorization:${authorization}` +Authorization:${authorization}`; + + element.value = bulkHeaders; + + } else { + console.log("Generating hedears with X-Auka-Integrator"); + + const privateKey = document.getElementById("private_key").value; + const method = document.getElementById("method").value; + const url = document.getElementById("url").value; + const merchantID = document.getElementById("merchant_id").value; + const timestamp = getAukaTimestamp(); + const integratorID = document.getElementById("X_Auka_Integrator").value; + const body = document.getElementById("body").value; + const bodyHash = getHash(body); + const contentDigest = `SHA256=${bodyHash}`; + const headers = `X-AUKA-CONTENT-DIGEST=${contentDigest}&X-AUKA-MERCHANT=${merchantID}&X-AUKA-TIMESTAMP=${timestamp}&X-Auka-Integrator=${integratorID}`; + const message = `${method}|${url}|${headers}`; + const signature = getSignedMessage(privateKey, message); + const authorization = "RSA-SHA256 " + signature; + const bulkHeaders = `Accept:application/vnd.mcash.api.merchant.v1+json +Content-Type:application/json +X-Auka-Merchant:${merchantID} +X-Auka-Integrator:${integratorID} +X-Auka-Timestamp:${timestamp} +X-Auka-Content-Digest:${contentDigest} +Authorization:${authorization}`; + + element.value = bulkHeaders; - element.value = bulkHeaders; + } } // Main script -document.getElementById('generate').onclick = () => generateHeaders() -document.getElementById('method').onchange = () => generateHeaders() -document.getElementById('url').onchange = () => generateHeaders() -document.getElementById('body').onchange = () => generateHeaders() -document.getElementById('bulk_headers').onclick = event => copyToClipboard(event) +document.getElementById("generate").onclick = () => generateHeaders(); +document.getElementById("method").onchange = () => generateHeaders(); +document.getElementById("url").onchange = () => generateHeaders(); +document.getElementById("body").onchange = () => generateHeaders(); +document.getElementById("bulk_headers").onclick = (event) => + copyToClipboard(event); +setDefaultValues(); +generateHeaders(); -setDefaultValues() -generateHeaders() +// console.log(isIntegrator); From 9e6ba2d7c3a4c13e289574bd6e9fca047f5246d9 Mon Sep 17 00:00:00 2001 From: Christian Wick Date: Thu, 18 Feb 2021 13:28:35 +0100 Subject: [PATCH 2/5] Added Netlify Status to README --- README.md | 1 + index.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/README.md b/README.md index 3ca209c..3d5b169 100644 --- a/README.md +++ b/README.md @@ -70,3 +70,4 @@ jFUCQQCEKcuxG/huGU5PuNRKA5TfpOE9l0cquiI9613YdbbUszc19PWXFywu5ttHzp29y3jE ``` +[![Netlify Status](https://api.netlify.com/api/v1/badges/a7197edc-db66-4a23-b006-657a5868fdbf/deploy-status)](https://app.netlify.com/sites/settle-request-generator/deploys) diff --git a/index.js b/index.js index fd48722..6868a1a 100644 --- a/index.js +++ b/index.js @@ -95,6 +95,7 @@ function integratorFalse() { document.getElementById("controllGroupIntegrator").style.display = "none"; isIntegrator = false; // console.log(isIntegrator); + generateHeaders(); } function integratorTrue() { @@ -102,6 +103,7 @@ function integratorTrue() { document.getElementById("controllGroupIntegrator").style.display = "block"; isIntegrator = true; // console.log(isIntegrator); + generateHeaders(); } // generateHeaders :: Void From 64036c4223d2e3f0cd5ffd52538b371595d52250 Mon Sep 17 00:00:00 2001 From: Christian Wick Date: Thu, 18 Feb 2021 13:38:25 +0100 Subject: [PATCH 3/5] Code formating --- index.js | 220 +++++++++++++++++++++++++++---------------------------- 1 file changed, 109 insertions(+), 111 deletions(-) diff --git a/index.js b/index.js index 6868a1a..9863660 100644 --- a/index.js +++ b/index.js @@ -1,134 +1,134 @@ // dec2hex :: Integer -> String // i.e. 0-255 -> '00'-'ff' function dec2hex(dec) { - return ("0" + dec.toString(16)).substr(-2); + return ('0' + dec.toString(16)).substr(-2); } // generateId :: Integer -> String function generateId(len) { - var arr = new Uint8Array((len || 10) / 2); - window.crypto.getRandomValues(arr); - return `"${Array.from(arr, dec2hex).join("")}"`; + var arr = new Uint8Array((len || 10) / 2); + window.crypto.getRandomValues(arr); + return `"${Array.from(arr, dec2hex).join('')}"`; } // getAukaTimestamp :: Void -> String function getAukaTimestamp() { - const d = new Date(); - const fYear = d.getUTCFullYear().toString(); - const month = (d.getUTCMonth() + 1).toString(); - const day = d.getUTCDate().toString(); - const hours = d.getUTCHours().toString(); - const minutes = parseInt(d.getUTCMinutes()).toString(); - const seconds = parseInt(d.getUTCSeconds()).toString(); - - const fMonth = month.length == 2 ? month : `0${month}`; - const fDay = day.length == 2 ? day : `0${day}`; - const fHours = hours.length == 2 ? hours : `0${hours}`; - const fMinutes = minutes.length == 2 ? minutes : `0${minutes}`; - const fSeconds = seconds.length == 2 ? seconds : `0${seconds}`; - - return `${fYear}-${fMonth}-${fDay} ${fHours}:${fMinutes}:${fSeconds}`; + const d = new Date(); + const fYear = d.getUTCFullYear().toString(); + const month = (d.getUTCMonth() + 1).toString(); + const day = d.getUTCDate().toString(); + const hours = d.getUTCHours().toString(); + const minutes = parseInt(d.getUTCMinutes()).toString(); + const seconds = parseInt(d.getUTCSeconds()).toString(); + + const fMonth = month.length == 2 ? month : `0${month}`; + const fDay = day.length == 2 ? day : `0${day}`; + const fHours = hours.length == 2 ? hours : `0${hours}`; + const fMinutes = minutes.length == 2 ? minutes : `0${minutes}`; + const fSeconds = seconds.length == 2 ? seconds : `0${seconds}`; + + return `${fYear}-${fMonth}-${fDay} ${fHours}:${fMinutes}:${fSeconds}`; } // generatePubKey :: String -> Void function generatePubKey(privateKey) { - console.log("Generating new public key from private key"); - const crypt = new JSEncrypt(); - crypt.setKey(privateKey); - document.getElementById("public_key").value = crypt.getPublicKey(); + console.log('Generating new public key from private key'); + const crypt = new JSEncrypt(); + crypt.setKey(privateKey); + document.getElementById('public_key').value = crypt.getPublicKey(); } // getHash :: String -> String function getHash(body) { - return CryptoJS.SHA256(body).toString(CryptoJS.enc.Base64); + return CryptoJS.SHA256(body).toString(CryptoJS.enc.Base64); } // getSignedMessage :: String -> String function getSignedMessage(privateKey, message) { - const crypt = new JSEncrypt(); - crypt.setKey(privateKey); - return crypt.sign(message, CryptoJS.SHA256, "sha256"); + const crypt = new JSEncrypt(); + crypt.setKey(privateKey); + return crypt.sign(message, CryptoJS.SHA256, 'sha256'); } // triggerAnimation :: Object -> Void function triggerAnimation(element) { - element.classList.remove("change-animation"); - void element.offsetWidth; - element.classList.add("change-animation"); + element.classList.remove('change-animation'); + void element.offsetWidth; + element.classList.add('change-animation'); } // copyToClipboard :: Object -> Void function copyToClipboard(event) { - const element = event.target; - void triggerAnimation(element); - console.log(`Copying contents of ${element.name} to clipboard`); - element.select(); - document.execCommand("copy"); - window.getSelection().removeAllRanges(); + const element = event.target; + void triggerAnimation(element); + console.log(`Copying contents of ${element.name} to clipboard`); + element.select(); + document.execCommand('copy'); + window.getSelection().removeAllRanges(); } let isIntegrator = false; // setDefaultValues :: Void function setDefaultValues() { - const method = ""; - const url = ""; - const merchantID = ""; - const apiUser = ""; - const integratorID = ""; - const privateKey = ""; - const body = ""; - - document.getElementById("private_key").value = privateKey; - document.getElementById("method").value = method; - document.getElementById("url").value = url; - document.getElementById("body").value = body; - document.getElementById("merchant_id").value = merchantID; - document.getElementById("api_user").value = apiUser; - document.getElementById("X_Auka_Integrator").value = integratorID; + const method = ''; + const url = ''; + const merchantID = ''; + const apiUser = ''; + const integratorID = ''; + const privateKey = ''; + const body = ''; + + document.getElementById('private_key').value = privateKey; + document.getElementById('method').value = method; + document.getElementById('url').value = url; + document.getElementById('body').value = body; + document.getElementById('merchant_id').value = merchantID; + document.getElementById('api_user').value = apiUser; + document.getElementById('X_Auka_Integrator').value = integratorID; } -document.getElementById("controllGroupIntegrator").style.display = "none"; +document.getElementById('controllGroupIntegrator').style.display = 'none'; function integratorFalse() { - document.getElementById("controllGroupApiUser").style.display = "block"; - document.getElementById("controllGroupIntegrator").style.display = "none"; - isIntegrator = false; - // console.log(isIntegrator); - generateHeaders(); + document.getElementById('controllGroupApiUser').style.display = 'block'; + document.getElementById('controllGroupIntegrator').style.display = 'none'; + isIntegrator = false; + // console.log(isIntegrator); + generateHeaders(); } function integratorTrue() { - document.getElementById("controllGroupApiUser").style.display = "none"; - document.getElementById("controllGroupIntegrator").style.display = "block"; - isIntegrator = true; - // console.log(isIntegrator); - generateHeaders(); + document.getElementById('controllGroupApiUser').style.display = 'none'; + document.getElementById('controllGroupIntegrator').style.display = 'block'; + isIntegrator = true; + // console.log(isIntegrator); + generateHeaders(); } // generateHeaders :: Void function generateHeaders() { - // console.log("Generating hedears"); - const element = document.getElementById("bulk_headers"); - void triggerAnimation(element); - - if (isIntegrator == false) { - console.log("Generating hedears with X-Auka-User"); - - const privateKey = document.getElementById("private_key").value; - const method = document.getElementById("method").value; - const url = document.getElementById("url").value; - const merchantID = document.getElementById("merchant_id").value; - const timestamp = getAukaTimestamp(); - const apiUser = document.getElementById("api_user").value; - const body = document.getElementById("body").value; - const bodyHash = getHash(body); - const contentDigest = `SHA256=${bodyHash}`; - const headers = `X-AUKA-CONTENT-DIGEST=${contentDigest}&X-AUKA-MERCHANT=${merchantID}&X-AUKA-TIMESTAMP=${timestamp}&X-AUKA-USER=${apiUser}`; - const message = `${method}|${url}|${headers}`; - const signature = getSignedMessage(privateKey, message); - const authorization = "RSA-SHA256 " + signature; - const bulkHeaders = `Accept:application/vnd.mcash.api.merchant.v1+json + // console.log("Generating hedears"); + const element = document.getElementById('bulk_headers'); + void triggerAnimation(element); + + if (isIntegrator == false) { + console.log('Generating hedears with X-Auka-User'); + + const privateKey = document.getElementById('private_key').value; + const method = document.getElementById('method').value; + const url = document.getElementById('url').value; + const merchantID = document.getElementById('merchant_id').value; + const timestamp = getAukaTimestamp(); + const apiUser = document.getElementById('api_user').value; + const body = document.getElementById('body').value; + const bodyHash = getHash(body); + const contentDigest = `SHA256=${bodyHash}`; + const headers = `X-AUKA-CONTENT-DIGEST=${contentDigest}&X-AUKA-MERCHANT=${merchantID}&X-AUKA-TIMESTAMP=${timestamp}&X-AUKA-USER=${apiUser}`; + const message = `${method}|${url}|${headers}`; + const signature = getSignedMessage(privateKey, message); + const authorization = 'RSA-SHA256 ' + signature; + const bulkHeaders = `Accept:application/vnd.mcash.api.merchant.v1+json Content-Type:application/json X-Auka-Merchant:${merchantID} X-Auka-User:${apiUser} @@ -136,25 +136,24 @@ X-Auka-Timestamp:${timestamp} X-Auka-Content-Digest:${contentDigest} Authorization:${authorization}`; - element.value = bulkHeaders; - - } else { - console.log("Generating hedears with X-Auka-Integrator"); - - const privateKey = document.getElementById("private_key").value; - const method = document.getElementById("method").value; - const url = document.getElementById("url").value; - const merchantID = document.getElementById("merchant_id").value; - const timestamp = getAukaTimestamp(); - const integratorID = document.getElementById("X_Auka_Integrator").value; - const body = document.getElementById("body").value; - const bodyHash = getHash(body); - const contentDigest = `SHA256=${bodyHash}`; - const headers = `X-AUKA-CONTENT-DIGEST=${contentDigest}&X-AUKA-MERCHANT=${merchantID}&X-AUKA-TIMESTAMP=${timestamp}&X-Auka-Integrator=${integratorID}`; - const message = `${method}|${url}|${headers}`; - const signature = getSignedMessage(privateKey, message); - const authorization = "RSA-SHA256 " + signature; - const bulkHeaders = `Accept:application/vnd.mcash.api.merchant.v1+json + element.value = bulkHeaders; + } else { + console.log('Generating hedears with X-Auka-Integrator'); + + const privateKey = document.getElementById('private_key').value; + const method = document.getElementById('method').value; + const url = document.getElementById('url').value; + const merchantID = document.getElementById('merchant_id').value; + const timestamp = getAukaTimestamp(); + const integratorID = document.getElementById('X_Auka_Integrator').value; + const body = document.getElementById('body').value; + const bodyHash = getHash(body); + const contentDigest = `SHA256=${bodyHash}`; + const headers = `X-AUKA-CONTENT-DIGEST=${contentDigest}&X-AUKA-MERCHANT=${merchantID}&X-AUKA-TIMESTAMP=${timestamp}&X-Auka-Integrator=${integratorID}`; + const message = `${method}|${url}|${headers}`; + const signature = getSignedMessage(privateKey, message); + const authorization = 'RSA-SHA256 ' + signature; + const bulkHeaders = `Accept:application/vnd.mcash.api.merchant.v1+json Content-Type:application/json X-Auka-Merchant:${merchantID} X-Auka-Integrator:${integratorID} @@ -162,18 +161,17 @@ X-Auka-Timestamp:${timestamp} X-Auka-Content-Digest:${contentDigest} Authorization:${authorization}`; - element.value = bulkHeaders; - - } + element.value = bulkHeaders; + } } // Main script -document.getElementById("generate").onclick = () => generateHeaders(); -document.getElementById("method").onchange = () => generateHeaders(); -document.getElementById("url").onchange = () => generateHeaders(); -document.getElementById("body").onchange = () => generateHeaders(); -document.getElementById("bulk_headers").onclick = (event) => - copyToClipboard(event); +document.getElementById('generate').onclick = () => generateHeaders(); +document.getElementById('method').onchange = () => generateHeaders(); +document.getElementById('url').onchange = () => generateHeaders(); +document.getElementById('body').onchange = () => generateHeaders(); +document.getElementById('bulk_headers').onclick = (event) => + copyToClipboard(event); setDefaultValues(); generateHeaders(); From 3de7e1f456addd5e3a3457fb9ef8f6b3db904365 Mon Sep 17 00:00:00 2001 From: Christian Wick Date: Thu, 18 Feb 2021 13:49:00 +0100 Subject: [PATCH 4/5] Form layout improvements --- index.html | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/index.html b/index.html index df3d076..b99eee7 100644 --- a/index.html +++ b/index.html @@ -24,7 +24,7 @@ } .pure-form-aligned .pure-control-group label { - width: 11em; + width: 13em; } @keyframes pulse { @@ -42,27 +42,24 @@

Settle API PKCS#1 1.5 signature generator

- -
- - -
-

Is an Integrator acting as a proxy on behalf of a Merchant client?

-
-
+

+
+ + +
@@ -80,12 +77,12 @@

Settle API PKCS#1 1.5 signature generator

- +
- +
From f3ae812d7ea0f2f2115cee4df31e389f75528325 Mon Sep 17 00:00:00 2001 From: Christian Wick Date: Thu, 18 Feb 2021 14:56:56 +0100 Subject: [PATCH 5/5] Updated README with new examples --- README.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 3d5b169..b22a7fd 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,14 @@ # Settle Request Generator -This small utility can be used to help with testing the `KEY` authentication method for integration with the Settle API. It generates the correct headers for a signed request using the request parameters and a private key. + +This small utility can be used to help with testing the `KEY` authentication method for integration with the Settle API. It generates the correct headers for a signed request using the request parameters and a private key. ## Try it here -https://settleapi.github.io/settle-request-generator + ## Authentication with the Settle API -Please visit the [Settle API documentation](https://developer.settle.eu/authentication.html) for more information on the two types of authentication, `SECRET` and `KEY`. + +Please visit the [Settle API documentation](https://developer.settle.eu/authentication.html) for more information on the two types of authentication, `SECRET` and `KEY`. The api credentials are managed in the [Settle Business portal](https://business.settle.eu/) (a [sandbox version](https://business.sandbox.settle.eu/) is also available) under the *Integration* tab. @@ -15,6 +17,7 @@ To get started you can just let Settle generate the key-pair for you, but please You can also generate your own key and just upload the public part to Settle. ### Generate RSA private key + ```bash openssl genrsa -des -out private.pem 2048 ``` @@ -25,22 +28,24 @@ You'll have to to enter a passphrase. Under appropriate conditions (noninteracti openssl rsa -in private.pem -out private.pem ``` - ### Generate RSA public key ```bash openssl rsa -in private.pem -outform PEM -pubout -out public.pem ``` - ## Field data examples -* **Merchant ID**: `abc123` -* **API key ID**: `xyz789` -* **Method**: `POST` -* **URL**: `https://api.sandbox.settle.eu/merchant/v1/payment_request/` +### For default use with `X-Auka-User` + +* **X-Auka-Merchant**: `abc123` +* **X-Auka-User**: `xyz789` +* **REST API Method**: `POST` +* **REST API Endpoint URL**: `https://api.sandbox.settle.eu/merchant/v1/payment_request/` * **Request body**: -```{ + +``` +{ "payer": "abc123", "payee": "msisdn:47123456789", "idempotency_id": "04449a4866", @@ -51,7 +56,9 @@ openssl rsa -in private.pem -outform PEM -pubout -out public.pem "expires_in": 120 } ``` -* **Private keyfor** `xyz789`: + +* Private RSA key for **X-Auka-User** `xyz789`: + ``` -----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQCotJXYCo9VPuS1qjBRPAP5jAN9Wj8qmYnKMy31w81jiL3QegVQ/w6pCoy3 @@ -69,5 +76,47 @@ jFUCQQCEKcuxG/huGU5PuNRKA5TfpOE9l0cquiI9613YdbbUszc19PWXFywu5ttHzp29y3jE -----END RSA PRIVATE KEY----- ``` +### For integrator use with `X-Auka-Integrator` + +* **X-Auka-Merchant**: `fzkmhy0q` +* **X-Auka-Integrator**: `7e3cbb17` +* **REST API Method**: `POST` +* **REST API Endpoint URL**: `https://api.sandbox.settle.eu/merchant/v1/payment_request/` +* **Request body**: + +``` +{ + "payer": "fzkmhy0q", + "payee": "msisdn:47123456789", + "idempotency_id": "04449a4866", + "currency": "NOK", + "amount": 1000, + "require_identified": "True", + "chat_text": "Some text", + "expires_in": 120 +} +``` + +### Private RSA key + +For **X-Auka-Integrator** `7e3cbb17`: + +``` +-----BEGIN RSA PRIVATE KEY----- +MIICWgIBAAKBgGeEsepm1Dm0LMW9H4cgO8+RpyiQh6JcWKlKfGZahTo3iXq55wGh +DLOHVP1i5ULPuz8IA3HG1W481AlBeIvT/fmlKy/zjNUebAClvujpKjMRkn2p0Npg +kyC4b17ZtoEkmixM2SrVhxBpy1PJoLFNKILqOGF+nFJ3Du/AEDOTNMrzAgMBAAEC +gYAJYriW3hfj23grvYf8Qmnp2fTj8qa5i9HmF4DL7u0haCOo4u4U8bsrE9wa1Tqg +IiGCB4H4cOStCArZg/wgAWqHeHKyn5+U74hbUnVMwj79zPgySJ/olFtrMptS8Jwe +28zGDua91T7a8y/12HY+a4EGQd/K6S8z3lgnMBFcebI84QJBAKS1wVM0Nu4RZmSS +50GWWui3sdHxe8OxyyiDUdBxajTuIuIH7/A6SOILRGs7cSF3ST9BVk0Lsx+jejvE +rg30E9sCQQCg5KBqp93nZs0ky+DuVK63HYVo9+AF6r7bNXvvX9L0V0FaaUgqdjeL +aonhBQ0VvmtCya+6poyptSbAVEmA09zJAkBI6VhaD6wdOMCd1tXeF8PIbsCdkgta +dpLbLT6DSiFcqunwKtlQ+0wWHCy+V0LeMKLRCIg+dOZnJAPQ/2CZNqmvAkAl2yVT +cwPnOmzyR3Y5HXuuYifNtuTi/4TAlyj9/ZHpI86gszzjoMUY7IxcgY++mfsqz8Gl +LSLTm2fuwOY6hZ7hAkAmww+iGigsQK/qFUenQ1afn9hQxsLrriOgBKNZygqFBHh4 +4u6VK3BHZuYEpMcEzY6JSEKxucN7rZ8CulNO9A0w +-----END RSA PRIVATE KEY----- +``` [![Netlify Status](https://api.netlify.com/api/v1/badges/a7197edc-db66-4a23-b006-657a5868fdbf/deploy-status)](https://app.netlify.com/sites/settle-request-generator/deploys)