Last active
December 7, 2025 19:39
-
-
Save mrts/abaf4b3ebc235fdac93a22fc561265fc to your computer and use it in GitHub Desktop.
Merit Aktiva API quick example rewritten for Google Script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function testGetAllCustomers() { | |
| const ApiId = '...'; | |
| const ApiKey = '...'; | |
| function pad2(n) { | |
| return n > 9 ? '' + n : '0' + n; | |
| } | |
| function getTimestamp() { | |
| var d = new Date(); | |
| var yyyy = d.getFullYear(); | |
| var MM = pad2(d.getMonth() + 1); | |
| var dd = pad2(d.getDate()); | |
| var HH = pad2(d.getHours()); | |
| var mm = pad2(d.getMinutes()); | |
| var ss = pad2(d.getSeconds()); | |
| return '' + yyyy + MM + dd + HH + mm + ss; // YYYYMMDDHHmmss | |
| } | |
| // Empty filter, ask for all customers. | |
| // Merit docs warn this can be very large and may fail for big accounts. | |
| var queryPayload = {}; | |
| var timestamp = getTimestamp(); | |
| var dataString = ApiId + timestamp + JSON.stringify(queryPayload); | |
| var hashBytes = Utilities.computeHmacSha256Signature( | |
| dataString, | |
| ApiKey, | |
| Utilities.Charset.UTF_8 | |
| ); | |
| var signature = Utilities.base64Encode(hashBytes); | |
| Logger.log('dataString: %s', dataString); | |
| Logger.log('signature (Base64 HMAC-SHA256): %s', signature); | |
| var baseUrl = 'https://aktiva.merit.ee/api/v1/getcustomers'; | |
| var url = | |
| baseUrl + | |
| '?ApiId=' + encodeURIComponent(ApiId) + | |
| '×tamp=' + encodeURIComponent(timestamp) + | |
| '&signature=' + encodeURIComponent(signature); | |
| var options = { | |
| method: 'post', | |
| contentType: 'application/json', | |
| payload: JSON.stringify(queryPayload), | |
| muteHttpExceptions: true, // let us read non-200 responses | |
| }; | |
| var response = UrlFetchApp.fetch(url, options); | |
| Logger.log('Status code: %s', response.getResponseCode()); | |
| Logger.log('Headers: %s', JSON.stringify(response.getAllHeaders())); | |
| var contentType = response.getHeaders()['Content-Type'] || ''; | |
| var bodyText = response.getContentText(); | |
| if (contentType.indexOf('application/json') !== -1) { | |
| try { | |
| var data = JSON.parse(bodyText); | |
| if (Array.isArray(data)) { | |
| Logger.log('Received %s customers', data.length); | |
| Logger.log('Customers: %s', data); | |
| } else { | |
| Logger.log('JSON response (not an array): %s', JSON.stringify(data, null, 2)); | |
| } | |
| } catch (e) { | |
| Logger.log('Body (text, JSON parse failed): %s', bodyText); | |
| } | |
| } else { | |
| Logger.log('Body (text): %s', bodyText); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function testMeritAktivaSendInvoice() { | |
| const ApiId = '...'; | |
| const ApiKey = '...'; | |
| const KM24_ID = '...'; | |
| const DOCDATE = '20250113131239'; | |
| var reqJson = { | |
| Customer: { | |
| // Id: null, | |
| Name: 'FirstCustomer Inc', | |
| RegNo: '1122334455', | |
| NotTDCustomer: false, | |
| VatRegNo: '11223344', | |
| CurrencyCode: 'EUR', | |
| PaymentDeadLine: 7, | |
| OverDueCharge: 0, | |
| RefNoBase: 1, | |
| Address: 'Merimiehenkatu 31', | |
| CountryCode: 'FI', | |
| County: 'Finland', | |
| City: 'Helsinki', | |
| PostalCode: '', | |
| PhoneNo: '6548765', | |
| PhoneNo2: '', | |
| HomePage: '', | |
| Email: '[email protected]', | |
| }, | |
| DocDate: DOCDATE, | |
| DueDate: DOCDATE, | |
| InvoiceNo: '123', | |
| RefNo: '1232', | |
| DepartmentCode: '', | |
| ProjectCode: '', | |
| InvoiceRow: [ | |
| { | |
| Item: { | |
| Code: 1234567, | |
| Description: 'Bag of goldflakes', | |
| Type: 3, | |
| UOMName: 'kg', | |
| }, | |
| Quantity: '2', | |
| Price: '1000', | |
| DiscountPct: 0, | |
| DiscountAmount: 0, | |
| TaxId: KM24_ID, | |
| LocationCode: 1, | |
| }, | |
| ], | |
| TotalAmount: 2000, | |
| RoundingAmount: 0, | |
| TaxAmount: [{ TaxId: KM24_ID, Amount: 400 }], | |
| HComment: '', | |
| FComment: '', | |
| }; | |
| function pad2(n) { | |
| return n > 9 ? '' + n : '0' + n; | |
| } | |
| function getTimestamp() { | |
| var d = new Date(); | |
| var yyyy = d.getFullYear(); | |
| var MM = pad2(d.getMonth() + 1); | |
| var dd = pad2(d.getDate()); | |
| var HH = pad2(d.getHours()); | |
| var mm = pad2(d.getMinutes()); | |
| var ss = pad2(d.getSeconds()); | |
| return '' + yyyy + MM + dd + HH + mm + ss; | |
| } | |
| var timestamp = getTimestamp(); | |
| var dataString = ApiId + timestamp + JSON.stringify(reqJson); | |
| var hashBytes = Utilities.computeHmacSha256Signature( | |
| dataString, | |
| ApiKey, | |
| Utilities.Charset.UTF_8 | |
| ); | |
| var signature = Utilities.base64Encode(hashBytes); | |
| Logger.log('dataString: %s', dataString); | |
| Logger.log('signature (Base64 HMAC-SHA256): %s', signature); | |
| var baseUrl = 'https://aktiva.merit.ee/api/v1/sendinvoice'; | |
| var url = | |
| baseUrl + | |
| '?ApiId=' + encodeURIComponent(ApiId) + | |
| '×tamp=' + encodeURIComponent(timestamp) + | |
| '&signature=' + encodeURIComponent(signature); | |
| var options = { | |
| method: 'post', | |
| contentType: 'application/json', | |
| payload: JSON.stringify(reqJson), | |
| muteHttpExceptions: true, // let us read non-200 responses | |
| }; | |
| var response = UrlFetchApp.fetch(url, options); | |
| Logger.log('Status code: %s', response.getResponseCode()); | |
| Logger.log('Headers: %s', JSON.stringify(response.getAllHeaders())); | |
| var contentType = response.getHeaders()['Content-Type'] || ''; | |
| var body = response.getContentText(); | |
| if (contentType.indexOf('application/json') !== -1) { | |
| try { | |
| var jsonBody = JSON.parse(body); | |
| Logger.log('Body (JSON): %s', JSON.stringify(jsonBody, null, 2)); | |
| } catch (e) { | |
| Logger.log('Body (text, JSON parse failed): %s', body); | |
| } | |
| } else { | |
| Logger.log('Body (text): %s', body); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment