Fill in My business, Layout and Google Sheets first. Then download a copy with your URL, logo, signature, bank details, terms, saved items and customers built in. Upload that file to your free host. Do this again whenever you change those settings.
function sh_(n,hd){var s=SpreadsheetApp.getActive(),h=s.getSheetByName(n);if(!h){h=s.insertSheet(n);h.appendRow(hd)}return h}
function up_(h,k,r){var v=h.getDataRange().getValues();for(var i=1;i<v.length;i++)if(v[i][0]==k){h.getRange(i+1,1,1,r.length).setValues([r]);return}h.appendRow(r)}
var KEY=''; // optional secret word; type the same word in the page's Access key box
var DH=['No','Type','Date','Customer','Currency','Total','Status','JSON'],CH=['Name','TIN','Address','Phone'];
function doPost(e){var b=JSON.parse(e.postData.contents);if(KEY&&b.key!=KEY)return ContentService.createTextOutput('denied');var d=b.doc;
up_(sh_('Documents',DH),d.no,[d.no,d.type,d.date,d.cust.name,d.cur,d.total,d.status,JSON.stringify(d)]);
var I=sh_('Items',['DocNo','Description','Unit','Qty','Price','Tax']),v=I.getDataRange().getValues();
for(var i=v.length-1;i>0;i--)if(v[i][0]==d.no)I.deleteRow(i+1);
d.items.forEach(function(x){I.appendRow([d.no,x.d,x.u,x.q,x.p,x.t])});
if(d.cust.name)up_(sh_('Customers',CH),d.cust.name,[d.cust.name,d.cust.tin,d.cust.addr,d.cust.ph]);
return ContentService.createTextOutput('ok')}
function doGet(e){if(KEY&&e.parameter.key!=KEY)return ContentService.createTextOutput('[]');var v=sh_('Documents',DH).getDataRange().getValues().slice(1).map(function(x){return JSON.parse(x[7])});
var c=sh_('Customers',CH).getDataRange().getValues().slice(1).map(function(x){return{name:x[0],tin:x[1],addr:x[2],ph:x[3]}});
return ContentService.createTextOutput(JSON.stringify({docs:v,customers:c})).setMimeType(ContentService.MimeType.JSON)}