Naar inhoud springen
Van Oosten Advies B.V.

Laatst bijgewerkt: 19 september 2026

CustomerGate 365: naslag webservices

Voor ontwikkelaars die een website op CustomerGate 365 bouwen. Deze pagina beschrijft het aanmelden, de vorm van de endpoints, elke service en procedure, de JSON-sleutels en vaste waarden, en de beveiligingsregels erachter. Ze beschrijft appversie 1.0. Namen zijn hoofdlettergevoelig, en de AL-broncode van de app is doorslaggevend.

De services

CustomerGate 365 publiceert acht webservices. De app publiceert ze zelf bij de installatie en bij elke update: een ontbrekende service wordt aangemaakt, en een service die onder die naam al bestaat, wordt nooit gewijzigd, ook niet als iemand hem met de hand heeft ongepubliceerd of aangepast. De drie services van iFacto bestaan alleen waar Steel 365 geïnstalleerd is.

ServiceSoortWaarvoorAangeroepen door
voaItemspagina, alleen lezenArtikelen voor de catalogussynchronisatietoepassing
voaVariantspagina, alleen lezenArtikelvarianten (afmetingen)synchronisatietoepassing
voaCategoriespagina, alleen lezenArtikelcategorieënsynchronisatietoepassing
voaProfilespagina (iFacto DXSteel)Staalprofielensynchronisatietoepassing
voaGradespagina (iFacto DXSteel)Staalkwaliteitensynchronisatietoepassing
voaItemTypespagina (iFacto DXSteel)Staalartikelsoortensynchronisatietoepassing
voaRequestscodeunit, unbound actionsEen offerteaanvraag of accountaanvraag aannemenwebsitetoepassing
voaPortalcodeunit, unbound actionsAanmelden en alles wat een aangemelde klant ziet of doetwebsitetoepassing

Aanmelden

De website praat met Business Central als twee Microsoft Entra-toepassingen. Hun client-ID's staan op CustomerGate-instellingen, en Machtigingen herstellen registreert ze daar in Business Central en wijst hun machtigingssets toe.

Veld in de instellingenWaarvoorMag aanroepen
Client-ID websiteOfferte- en accountaanvragen, het klantenportaalvoaRequests, voaPortal
Client-ID synchronisatieDe synchronisatie van de catalogus. Laat leeg als de catalogus niet wordt gesynchroniseerd.voaItems, voaVariants, voaCategories, voaProfiles, voaGrades, voaItemTypes

Geen van beide toepassingen kan de services van de ander gebruiken: de websitetoepassing heeft geen uitvoerrecht op de cataloguspagina's, en de synchronisatietoepassing geen op voaPortal of voaRequests.

Machtigingssets

SetToegewezen aanWat hij toestaat
VOA WEB APIwebsite, alle bedrijvenvoaRequests uitvoeren. Alleen indirect invoegen op de aanvraagtabellen, geen leesrecht.
VOA WEB PORTALwebsite, alle bedrijvenvoaPortal en de codeunits die hij aanroept uitvoeren. Alleen indirecte tabelrechten.
VOA WEB BASELINEwebsite, alle bedrijvenDe vloer die een webservicesessie nodig heeft, in plaats van D365 BASIC, dat klant- en verkoopgegevens zou blootleggen.
VOA CG EXECUTEwebsite, tenant-setUitvoerrechten op de objecten die het mail-, schrijf- en pdf-pad raken.
VOA CG MAILwebsite, tenant-setWat de e-mailconnectors nodig hebben om mail te versturen, zoals de aanmeldcode.
VOA CG S365 ARCHIVEwebsite, alleen met DXSteel Doc ArchiveDe archieftabellen lezen, met een beveiligingsfilter op de toegestane archiefrubrieken.
VOA CG DOCUMENTSwebsite, alleen zonder dat archief en met Portaaldocumenten uit rapporten aanLezen wat de standaard verkooprapporten lezen, en die rapporten draaien, zodat Document pdf's kan afdrukken.
CDC BASICwebsite, alleen met Continia Document CaptureContinia hangt aan de triggers van de tabellen waar de website in schrijft.
VOA WEB SYNCsynchronisatie, per bedrijfDe drie cataloguspagina's en hun brontabellen, plus leesrecht op artikelposten voor de restvoorraad.
VOA CG S365 SYNCsynchronisatie, alleen met Steel 365De drie DXSteel-pagina's en de tabellen erachter.

Een token ophalen

Beide toepassingen gebruiken de OAuth 2.0-clientreferentiestroom:

POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token

grant_type=client_credentials
client_id={client id}
client_secret={secret}
scope=https://api.businesscentral.dynamics.com/.default

Stuur het toegangstoken bij elke aanroep mee als Authorization: Bearer {token}.

Endpoints en afspraken

Alle services zijn standaard OData v4-endpoints van Business Central onder https://api.businesscentral.dynamics.com/v2.0/{tenant}/{environment}/ODataV4.

Paginaservices

De cataloguspagina's leest u met GET. De referentiewebsite spreekt het bedrijf op naam aan:

GET .../ODataV4/Company('{company name}')/voaItems?$select=No,Description&$filter=...

Een bedrijfsnaam met een apostrof krijgt die dubbel (O''Brien), zoals OData voorschrijft. Grote resultaten komen in pagina's: volg @odata.nextLink tot die er niet meer is. De records staan in value.

Codeunitservices

voaRequests en voaPortal bieden elke openbare procedure aan als unbound action met de naam {service}_{Procedure}. Roep die aan met POST en geef de parameters op naam mee in een JSON-body. De referentiewebsite spreekt het bedrijf aan met zijn GUID, de id van het bedrijf in de standaard companies-API:

POST https://api.businesscentral.dynamics.com/v2.0/{tenant}/{environment}/ODataV4/voaPortal_ReadSession?company={company id}
Authorization: Bearer {access token}
Content-Type: application/json
Accept: application/json
Accept-Language: en-US

{"token": "<session token>"}

De teruggave komt in de OData-envelop onder value:

{"@odata.context": "…", "value": "{\"email\":\"buyer@example.com\",\"customerNo\":\"C00010\", …}"}

Afspraken

  • Namen zijn hoofdlettergevoelig en worden op naam gebonden. voaPortal_readSession bestaat niet, en een parameter die emailAddress heet in plaats van email levert een 400 op zonder verdere uitleg.
  • Elke parameter is een tekenreeks: alle procedureparameters zijn AL-Text.
  • Een JSON-resultaat komt terug als tekenreeks binnen value, omdat een unbound action geen genest object kan teruggeven. Ontleed value een tweede keer. Een booleaanse uitkomst is een JSON-true of false in value.
  • Een lege tekenreeks is een antwoord. Bij de meeste procedures van voaPortal betekent "": geen geldige sessie, of hier is niets voor u.
  • Optionele sleutels worden weggelaten, niet als null verstuurd. Behandel een ontbrekende sleutel als null.
  • Datums zijn YYYY-MM-DD, tijdstempels zijn ISO 8601 in UTC (2026-09-19T14:30:00.000Z). Een lege datum of tijdstempel is "".
  • Getallen en booleans zijn JSON-getallen en JSON-booleans.
  • Accept-Language bepaalt de taal van de Business Central-sessie. Dat raakt foutmeldingen en de optiebijschriften in de catalogus, nooit de vaste waarden hieronder. De referentiewebsite stuurt nl-NL.

Statuscodes en opnieuw proberen

StatusWat het hier betekent
200De procedure is gelopen. Kijk in value naar de uitkomst.
400Er is een AL-fout opgeworpen, bijvoorbeeld een geweigerde aanvraag (de melding staat in de body), of de parameternamen kloppen niet.
401 / 403Token of machtigingssets kloppen niet. De body noemt het object dat ontbreekt.
404De service is niet onder die naam gepubliceerd, of het bedrijf klopt niet.
409Gelijktijdige aanroepen met hetzelfde sessietoken wilden dezelfde sessierij bijwerken.
429Business Central knijpt af. Er is niets verwerkt; houd u aan Retry-After.
5xxServerfout. Bij een aanroep die iets wijzigt, weet u niet of hij is uitgevoerd.

Na een 429 opnieuw proberen kan altijd. Na een netwerkfout, een time-out, een 409 of een 5xx probeert u alleen de lezende procedures opnieuw (ReadSession, MyDetails, MyDeliveryAddresses, MyRequests, MyQuotes, MyOrders, MyShipments, DocumentLines, MyDocuments, Document). Probeer RequestCode, SignIn, SignOut, LinkRequest en AcceptQuote niet uit uzelf opnieuw; bij CreateQuoteRequest en CreateAccountRequest is opnieuw proberen alleen veilig met dezelfde requestId.

Het beveiligingsmodel

Er zijn twee lagen. De Entra-toepassing bewijst dat de aanroeper de website is; ze wijst nooit een klant aan. Het sessietoken van het portaal wijst de aangemelde persoon aan, en Business Central leidt daar de klant uit af. Het klantnummer reist nooit van de website naar Business Central: geen enkele procedure neemt een klantnummer, een e-mailfilter of een andere parameter aan die bepaalt wiens gegevens er terugkomen.

Portaalgebruikers

  • Iemand mag het portaal gebruiken zodra de binnendienst zijn accountaanvraag heeft goedgekeurd. Daarmee ontstaat een portaalgebruiker: een e-mailadres gekoppeld aan één klant, met een rol. De website kan geen portaalgebruikers aanmaken.
  • E-mailadressen worden in kleine letters vergeleken, zonder spaties eromheen.
  • Is één adres aan meer klanten gekoppeld, dan krijgt de sessie het laagste klantnummer dat in het portaal mag. De interface kan klanten niet opsommen of wisselen.
  • De portaalgebruiker moet actief en niet geanonimiseerd zijn, en de klant moet bestaan, niet voor privacy geblokkeerd zijn en niet volledig geblokkeerd. Klanten die alleen voor verzenden of factureren geblokkeerd zijn, houden toegang.

Aanmelden met een eenmalige code

  1. De bezoeker vult zijn e-mailadres in; de website roept RequestCode(email, ipHash) aan.
  2. Business Central maakt een code, bewaart daar alleen een gezouten hash van en mailt de code naar het adres als het bij een actieve portaalgebruiker hoort.
  3. De bezoeker vult de code in; de website roept SignIn(email, code, ipHash) aan en krijgt een sessietoken, of "".
  4. De website bewaart het token, bijvoorbeeld in een HttpOnly-cookie, en geeft het als token mee aan elke andere procedure van voaPortal.
  5. SignOut(token) beëindigt de sessie.

De code bestaat uit tien tekens uit het alfabet 0123456789ABCDEFGHJKMNPQRSTVWXYZ (geen I, L, O of U) en staat in de e-mail als twee groepen van vijf met een koppelteken. Voor de vergelijking wordt hij genormaliseerd: spaties en koppeltekens weg, hoofdletters, O gelezen als 0, I en L als 1. Pas dezelfde regels toe als u de invoer op de website controleert.

  • Een code is geldig gedurende Geldigheid aanmeldcode (min.), standaard 15 minuten, en werkt één keer. Na een geslaagde aanmelding verlopen alle andere open codes voor dat adres.
  • Fout gokken sluit niemand buiten. Foute pogingen worden geteld op de nieuwste open code, tot Maximum codepogingen, als spoor om misbruik te herkennen.
  • Er kunnen meer codes tegelijk leven: een nieuwe code maakt eerdere niet ongeldig.
  • RequestCode antwoordt altijd true, of het adres nu bekend, gekoppeld of geblokkeerd is of de mail mislukte, en duurt altijd minstens 1,5 seconde. Zo verklapt het endpoint niemand welke adressen klant zijn.
  • Tussen twee codes voor hetzelfde adres geldt een minimale wachttijd van Wachttijd aanmeldcode (sec.), standaard 60 seconden. Een verzoek binnen die tijd krijgt true en doet niets.
  • De mail met de code gaat meteen vanuit de aanroep van RequestCode weg, niet via de taakwachtrij, in de taal van de accountaanvraag waar de portaalgebruiker uit voortkwam, anders de taal van de klant, anders de taal van de binnendienst.

Sessietokens

  • Een token bestaat uit 64 tekens, twee GUID's als hoofdletterhex. Behandel het als ondoorzichtig; Business Central bewaart alleen de SHA-256-hash ervan. Spaties voor en na token worden genegeerd.
  • Schuivende vervaltijd: een sessie verloopt na Sessieduur (min.), standaard 480, zonder gebruik. Elke geslaagde aanroep verlengt hem, hooguit één keer per minuut weggeschreven, dus een sessie kan tot een minuut eerder eindigen dan de genoemde tijd.
  • Absolute grens: geen sessie leeft langer dan Maximale sessieleeftijd (uren), standaard 168, na het aanmelden, hoe actief hij ook wordt gebruikt.
  • Bij elke aanroep wordt gecontroleerd of het token bestaat, niet is ingetrokken, niet is verlopen en binnen de maximale leeftijd valt, of de portaalgebruiker nog bestaat en actief is, en of de klant nog in het portaal mag. Faalt de controle op de portaalgebruiker of de klant, dan wordt de sessie meteen ingetrokken.
  • De rol wordt bij elke aanroep van de portaalgebruiker gelezen, niet uit de sessie, dus een wijziging van Inkoper naar Meekijker geldt meteen.
  • ReadSession geeft expiresAt terug. Gebruik dat voor de levensduur van de cookie.
  • Meer aanroepen met hetzelfde token op hetzelfde moment kunnen Business Central bij één ervan 409 laten antwoorden. De lezende procedures kunt u één keer opnieuw proberen.

Het klantslot

Alles wat voaPortal teruggeeft, is gefilterd op de klant van de sessie, en geen enkele parameter kan dat filter weghalen:

GegevensGefilterd op
WebaanvragenKlantnr. van de aanvraag
Verkoopoffertes en -orders, actueel en gearchiveerdVerkoop-aan klantnr.
Geboekte verzendingen, facturen, creditnota'sVerkoop-aan klantnr.
LeveradressenKlantnr.
DXSteel Doc Archivede relatie is deze klant, het relatietype is Klant, en de rubriek is toegestaan

Een documentnummer is een parameter in DocumentLines, Document en AcceptQuote. Het zegt wat er wordt gevraagd, nooit van wie het is. Documentnummers worden getrimd en omgezet naar hoofdletters; een nummer langer dan 20 tekens geldt als niet gevonden, niet als afgekapt.

Overal hetzelfde lege antwoord

Een document dat niet bestaat en een document van een andere klant geven precies hetzelfde antwoord. Anders zou een lijst nummers genoeg zijn om af te tasten wat er bestaat.

ProcedureGeen geldige sessieNiet gevonden, niet van u, niet toegestaan
RequestCodeniet van toepassingtrue (altijd)
SignInniet van toepassing"" (verkeerde, verlopen of gebruikte code, inactieve gebruiker)
SignOuttruetrue
ReadSession, MyDetails, MyRequests, MyQuotes, MyOrders, MyShipments, MyDocuments""niet van toepassing: een lijst mag leeg zijn
MyDeliveryAddresses"""" voor een Meekijker
LinkRequestfalsefalse
DocumentLines""""; een bestaand document van uzelf zonder artikelregels geeft {"lines":[]}
Document"""", ook als er geen rapport is ingesteld, of met het archief van Steel 365
AcceptQuote{"outcome":"refused",…}{"outcome":"refused",…}

Rollen

Een nieuwe portaalgebruiker is Meekijker, tenzij de binnendienst Inkoper kiest, en een onbekende rolwaarde wordt gemeld als Viewer. Een Inkoper mag alles wat een Meekijker mag, plus LinkRequest, MyDeliveryAddresses en AcceptQuote. Voor een Meekijker antwoorden die drie false, "" en refused. Een Meekijker kan wel een offerteaanvraag versturen via voaRequests; die wordt dan niet aan de klant gekoppeld, en de binnendienst behandelt hem als een aanvraag van een anonieme bezoeker. MyDetails geeft role terug, zodat het formulier dat kan melden.

IP-hash

Verschillende aanroepen nemen een ipHash aan. Business Central krijgt het IP-adres van de bezoeker nooit te zien: de website rekent een hash met sleutel uit. De referentiewebsite gebruikt HMAC-SHA256 met een geheime sleutel uit haar eigen configuratie, als 64 hexadecimale tekens in kleine letters. Business Central slaat de waarde op zoals ze binnenkomt, tot 64 tekens, bij de aanmeldcode, de sessie, het akkoord op een offerte en de aanvragen, gebruikt ze alleen om misbruik te herkennen, en de opruimtaak wist ze na de bewaartermijn. Houd de sleutel geheim en stabiel: zonder sleutel is een IPv4-hash terug te rekenen.

Portaalinstellingen

Per bedrijf, op CustomerGate-instellingen:

InstellingStandaardToegestaanEffect
Geldigheid aanmeldcode (min.)151 tot 1440Hoe lang een code werkt.
Maximum codepogingen51 tot 20Hoeveel foute pogingen per code worden geteld. Geen blokkade.
Wachttijd aanmeldcode (sec.)600 tot 3600Minimale tijd tussen twee codes voor één adres. 0 haalt de wachttijd weg.
Sessieduur (min.)4805 tot 20160Schuivende vervaltijd.
Maximale sessieleeftijd (uren)1681 tot 480Absolute einde van een sessie.
Portaaldocumenten uit rapportenaanZie MyDocuments en Document.
Aanvragen weigerenuitLaat CreateQuoteRequest en CreateAccountRequest met een fout mislukken. Raakt het portaal niet.

Catalogusservices

De catalogusservices zijn alleen-lezen lijstpagina's, bedoeld voor een nachtelijke synchronisatie en niet voor live paginaweergaven. Gebruik $select om alleen de eigenschappen op te halen die u nodig hebt. De OData-eigenschapsnamen zijn de namen van de paginabesturingselementen hieronder en horen bij het contract. De waarden komen live uit de tabellen, ook de DXSteel-velden, die de app op veldnaam leest zodat hij niet van de DXSteel-app afhangt: zonder Steel 365 geeft een DXSteel-tekstveld "" terug en een DXSteel-getal 0.

voaItems

Brontabel: Artikel. Er komen geen prijzen, kosten of voorraadwaarden uit.

EigenschapTypeBron
NotekstNr.
DescriptiontekstOmschrijving
Description2tekstOmschrijving 2
BaseUnitofMeasuretekstBasiseenheid
DXPriceUOMSalesDMXtekstDXSteel Price UOM (Sales) DMX
ItemCategoryCodetekstArtikelcategoriecode
DXItemProfileCodeDMXtekstDXSteel Item Profile Code DMX
DXQualityCodeDMXtekstDXSteel Quality Code DMX, de kwaliteit
BlockedbooleanGeblokkeerd
SalesBlockedbooleanVerkoop geblokkeerd

voaVariants

Brontabel: Artikelvariant.

EigenschapTypeBron
ItemNotekstArtikelnr.
CodetekstCode
DescriptiontekstOmschrijving
Description2tekstOmschrijving 2
DXLengthgetalDXSteel Length DMX
DXWidthgetalDXSteel Width DMX
DXThicknessgetalDXSteel Thickness DMX
DXExtraLengthgetalDXSteel Extra Length DMX
DXFormatTypetekstDXSteel Format Type DMX, als bijschrift in de taal van de sessie. Stuur een vaste Accept-Language mee als u deze bijschriften vertaalt naar uw eigen model.
BlockedbooleanGeblokkeerd
DXRemainingInventorygetalDXSteel Remaining Inventory DMX, opgeteld over alle locaties

voaCategories

Brontabel: Artikelcategorie, met de eigenschappen Code en Description. Er is geen veld voor de bovenliggende categorie; de referentiewebsite leidt de boom af uit de code (BALK-IPE hoort onder BALK).

voaProfiles, voaGrades, voaItemTypes

Deze drie wijzen naar pagina's van iFacto Steel 365 (DXSteel), niet naar pagina's van deze app. Hun eigenschappen liggen bij iFacto en kunnen met een update van iFacto veranderen; deze naslag legt ze niet vast. Ze bestaan alleen waar Steel 365 geïnstalleerd is.

voaRequests: offerte- en accountaanvragen

Twee acties, die elk de hele aanvraag als één tekstparameter payload met JSON aannemen en elk {"number":"…"} als tekst teruggeven. Het websiteaccount kan aanvragen aanmaken, maar ze niet teruglezen: er is geen service die aanvragen opsomt of een klant op e-mailadres opzoekt.

ActieParameterGeeft terug
voaRequests_CreateQuoteRequestpayloadtekst: {"number":"WEB000123"}
voaRequests_CreateAccountRequestpayloadtekst: {"number":"ACC000045"}

Hoe de payload wordt gelezen: een ontbrekende sleutel en een JSON-null betekenen allebei leeg ("", 0 of false); tekstwaarden worden stilzwijgend afgekapt op de veldlengte; Code-velden worden in hoofdletters opgeslagen; de aanroep loopt in één transactie, dus mislukt er iets, dan wordt er niets opgeslagen. Business Central zet zelf het aanvraagnummer, de status New, het tijdstip van ontvangst, de gekoppelde klant en bij accountaanvragen de beoordelaar en de reden van afwijzing; de payload doet dat nooit.

CreateQuoteRequest: sleutels in de kop

SleutelTypeVerplichtMaxToelichting
requestIdtekstaanbevolen64Sleutel tegen dubbele verwerking, in hoofdletters. Ook de enige manier waarop LinkRequest de aanvraag kan vinden.
privacyAcceptedbooleanja, trueZonder deze sleutel wordt de aanvraag geweigerd.
privacyConsentVersiontekstja20Welke privacyverklaring is geaccepteerd. In hoofdletters.
contactNametekst100Contactpersoon.
emailtekst100Waar de aanvrager de offerte verwacht.
companyNametekst100
vatRegistrationNotekst20Wordt niet gecontroleerd.
phoneNotekst30
customerReferencetekst35De eigen referentie van de klant. Wordt Extern documentnr. op de offerte.
languageCodetekst10Een taalcode van Business Central, bijvoorbeeld NLB of FRB. De bevestigingsmail wordt in die taal geschreven.
address, address2, postCode, city, countryCodetekst100 / 50 / 20 / 30 / 10Het factuuradres van de aanvrager. Het land is een ISO-code, bijvoorbeeld BE.
deliveryMethodtekstPickup of Delivery. Iets anders wordt Pickup.
shipToCodetekst10Een geregistreerd leveradres van de klant, uit MyDeliveryAddresses. Telt pas mee nadat LinkRequest het heeft gecontroleerd.
useShipToAddressbooleanHet leveradres wijkt af van het factuuradres.
shipToName, shipToAddress, shipToAddress2, shipToPostCode, shipToCity, shipToCountryCodetekst100 / 100 / 50 / 20 / 30 / 10Het leveradres als tekst. Een ander land van levering kan de btw-behandeling van de offerte veranderen.
requestedDeliveryDatetekstYYYY-MM-DD. Een waarde die geen geldige datum is, laat de aanroep mislukken.
remarkstekst2048Vrije tekst van de aanvrager.
ipHashtekst64Zie IP-hash hierboven.
sourcetekst50Het kanaal of de pagina. counterVisit heeft een bijzondere betekenis; zie hieronder.
assistedBytekst50De medewerker aan de balie. Alleen bij een baliebezoek.
quoteRequestLinesarrayRegelobjecten. Ontbreekt de sleutel of is het geen array, dan heeft de aanvraag geen regels. Elementen die geen object zijn, worden overgeslagen.

CreateQuoteRequest: sleutels per regel

Objecten in quoteRequestLines, genummerd 10000, 20000, … in de volgorde van de array:

SleutelTypeMaxToelichting
itemNotekst20Wordt bij het invoegen niet gecontroleerd, wel als de binnendienst de aanvraag omzet. Leeg bij een regel met vrije tekst.
variantCodetekst10De afmeting.
profileCodetekst30Profiel uit Steel 365.
qualityCodetekst20Kwaliteit uit Steel 365.
descriptiontekst100Zoals op de website getoond, of vrije tekst.
quantitygetalHet gevraagde aantal.
unitOfMeasureCodetekst10Bijvoorbeeld PCS, M of KG. Wordt bij de omzetting gecontroleerd.
lengthMmgetal0 betekent de standaardlengte van de afmeting.
widthMmgetalAlleen platen en strip.
thicknessMmgetalAlleen platen en strip.
lineRemarkstekst250Bijvoorbeeld een zaaginstructie.

Een voorbeeldpayload, voordat die in payload wordt geserialiseerd:

{
  "requestId": "3F2C9A1E7B0D4C5E",
  "languageCode": "NLB",
  "contactName": "Jan Example",
  "companyName": "Example Ltd",
  "email": "jan@example.com",
  "customerReference": "Site 12",
  "address": "Example Street 1",
  "postCode": "2000",
  "city": "Antwerp",
  "countryCode": "BE",
  "deliveryMethod": "Delivery",
  "useShipToAddress": true,
  "shipToName": "Example Ltd",
  "shipToAddress": "Yard Road 5",
  "shipToPostCode": "2100",
  "shipToCity": "Deurne",
  "shipToCountryCode": "BE",
  "requestedDeliveryDate": "2026-10-01",
  "remarks": "Please call before delivery.",
  "privacyAccepted": true,
  "privacyConsentVersion": "2026-09",
  "ipHash": "<64 hex characters>",
  "source": "shop/en/quote-request",
  "quoteRequestLines": [
    {
      "itemNo": "1000",
      "variantCode": "6000",
      "quantity": 4,
      "unitOfMeasureCode": "PCS",
      "lineRemarks": "Cut to 3 m"
    }
  ]
}

Wat er daarna gebeurt:

  • De aanvraag komt in een eigen tabel terecht, niet in een verkoopofferte. De binnendienst zet hem met één actie om, alleen vanuit de Business Central-client.
  • De mailtaak stuurt de aanvrager een bevestiging en de binnendienst een melding, afhankelijk van de schakelaars in de instellingen.
  • source = counterVisit markeert een aanvraag die aan de balie is ingevoerd. Die wordt omgezet naar een verkooporder in plaats van een offerte, en er gaat geen bevestiging of melding uit. Bij afhalen krijgt de order een tekstregel met de medewerker uit assistedBy.
  • Is de bezoeker aangemeld, roep dan meteen na deze aanroep LinkRequest aan om de klant van de sessie op de aanvraag te zetten. Het klantnummer zit nooit in de payload.
  • shipToCode telt pas mee nadat LinkRequest hem tegen de klant van de sessie heeft gecontroleerd. Bij een aanvraag die zo niet is gekoppeld, weigert de omzetting de code tot de binnendienst hem met de hand bevestigt; stuur het adres daarom ook als tekst mee.

CreateAccountRequest

Een aanvraag voor een portaalaccount. De binnendienst koppelt hem aan een klant en een rol, of wijst hem af.

SleutelTypeVerplichtMaxToelichting
requestIdtekstaanbevolen64Sleutel tegen dubbele verwerking, in hoofdletters.
privacyAcceptedbooleanja, true
privacyConsentVersiontekstja20In hoofdletters.
emailtekstja100Het adres waarmee de persoon zich zal aanmelden.
contactNametekst100
jobTitletekst50Helpt de binnendienst kiezen tussen Inkoper en Meekijker.
companyNametekst100Wordt niet gecontroleerd.
vatRegistrationNotekst20
phoneNotekst30
address, address2, postCode, city, countryCodetekst100 / 50 / 20 / 30 / 10
existingCustomertekstYes, No of Unknown. Iets anders wordt Unknown.
statedCustomerNotekst20Het klantnummer dat de persoon opgeeft. Een aanwijzing voor de binnendienst, nooit een koppeling.
languageCodetekst10Wordt gebruikt voor de mails aan deze persoon, ook voor latere aanmeldcodes.
remarkstekst2048
ipHashtekst64
sourcetekst50De pagina waar de aanvraag vandaan kwam.

Dubbele verwerking voorkomen: requestId

Maak per formulierverzending één requestId en stuur dezelfde waarde mee als u die verzending opnieuw probeert. Een tweede aanvraag met een requestId die al bestaat, wordt geweigerd met HTTP 400, en de foutmelding bevat het merkteken [VOA-DUBBEL] en het nummer van de aanvraag die al is opgeslagen. Beschouw dat als geslaagd: de aanvraag staat in Business Central, alleen niet uit deze aanroep. De tekst van de melding wordt vertaald, dus herken het merkteken en nooit de zin. De vergelijking is in de praktijk ongevoelig voor hoofdletters, omdat de waarde in hoofdletters wordt opgeslagen; zonder requestId is er geen controle op dubbele verzendingen. De regel geldt voor beide acties, elk in de eigen tabel.

Fouten

Alle fouten zijn AL-fouten, dus de aanroep mislukt met HTTP 400 en de melding in de body. De aanvraag wordt niet opgeslagen.

VoorwaardeGeldt voorDe melding begint met
payload is geen geldige JSONallebeiThe request is not valid JSON.
Aanvragen weigeren staat aanallebeiCustomerGate is not accepting requests at the moment.
privacyAccepted is niet trueallebeiA request cannot be accepted without agreement…
privacyConsentVersion is leegallebeiInclude in privacyConsentVersion…
email is leegaccountaanvragenAn account request without an e-mail address is not possible…
requestId is al gebruiktallebeiThis submission has already been accepted under number… (bevat [VOA-DUBBEL])
requestedDeliveryDate is geen geldige datumofferteaanvragende eigen datumfout van Business Central

voaPortal: het klantenportaal

Elke actie is POST .../ODataV4/voaPortal_{Procedure}?company={company id}. Deze vijftien procedures zijn de enige die aanroepbaar zijn; elke andere procedure in de codeunit is lokaal.

ProcedureParametersGeeft terugRolWijzigt gegevens
RequestCodeemail, ipHashbooleaniedereenmaakt een code, verstuurt een mail
SignInemail, code, ipHashtekst: token of ""iedereengebruikt de code, maakt een sessie
ReadSessiontokenJSON-tekst of ""allebeiverlengt de sessie
SignOuttokenboolean (altijd true)allebeitrekt de sessie in
MyDetailstokenJSON-tekst of ""allebeiverlengt de sessie
MyDeliveryAddressestokenJSON-tekst of ""Inkoperverlengt de sessie
LinkRequesttoken, requestIdbooleanInkoperkoppelt een aanvraag aan de klant
MyRequeststokenJSON-tekst of ""allebeiverlengt de sessie
MyQuotestokenJSON-tekst of ""allebeiverlengt de sessie
MyOrderstokenJSON-tekst of ""allebeiverlengt de sessie
MyShipmentstokenJSON-tekst of ""allebeiverlengt de sessie
DocumentLinestoken, documentType, documentNoJSON-tekst of ""allebeiverlengt de sessie
AcceptQuotetoken, quoteNo, ipHashJSON-tekstInkoperlegt een akkoord vast
MyDocumentstokenJSON-tekst of ""allebeiverlengt de sessie
Documenttoken, documentType, documentNoJSON-tekst of ""allebeiverlengt de sessie

Harde grenzen

LijstMaximum
MyRequests200 aanvragen
MyQuotes, MyOrders, MyShipmentselk 100 rijen, actueel en gearchiveerd samen; truncated zegt of er meer waren
MyDeliveryAddresses100 adressen
DocumentLines500 regels
MyDocuments, archief van Steel 365200 documenten, uit hooguit 1.000 bekeken archiefrijen
MyDocuments, uit rapporten100 per documentsoort

RequestCode, SignIn, SignOut

RequestCode geeft altijd true terug, na minstens 1,5 seconde; roep hem niet automatisch opnieuw aan, want elke aanroep kan een mail versturen. SignIn geeft het sessietoken van 64 tekens terug, of "" als de code verkeerd, verlopen of al gebruikt is, of als de portaalgebruiker of de klant niet meer mag; het antwoord zegt nooit welke van die gevallen het is. Een juiste code voor een gebruiker die intussen is gedeactiveerd, wordt opgebruikt en geeft "". SignOut trekt de sessie in als het token bestaat en geeft altijd true, ook bij een onbekend token; gooi de cookie hoe dan ook weg.

ReadSession

Wie er achter het token zit. Roep het aan bij elke paginaweergave van het portaal: het controleert de sessie, de portaalgebruiker en de klant, en verlengt de sessie.

SleutelTypeToelichting
emailtekstHet adres van de portaalgebruiker.
customerNotekstDe klant van deze sessie. Business Central zegt het tegen de website; de website nooit tegen Business Central.
customerNametekstKlantnaam, of "".
roletekstBuyer of Viewer.
weightTypetekstHet gewichtstype uit Steel 365 van de klant (Theoretical, Trade, GermanTrade), of "" zonder Steel 365 of als het niet is ingevuld.
expiresAttekstTijdstip waarop de sessie verloopt als hij niet meer wordt gebruikt.

MyDetails

De bedrijfsgegevens van de klant van de sessie, om het offerteformulier voor in te vullen. Elk veld is tekst en kan "" zijn. Het klantnummer zit er bewust niet in, en er zijn geen prijzen, kortingen of kredietgegevens. De sleutels zijn company, vatRegistrationNo, address, address2, postCode, city, country, phoneNo, email (het adres van de portaalgebruiker, niet dat van de klantenkaart) en role.

MyDeliveryAddresses

De geregistreerde leveradressen van de klant van de sessie, alleen voor een Inkoper: {"addresses": [{"code", "name", "address", "address2", "postCode", "city", "country"}]}, allemaal tekst. Een Meekijker krijgt "", net als bij een ongeldige sessie. Het factuuradres staat niet in deze lijst, dat staat in MyDetails. Stuur de gekozen code als shipToCode mee in CreateQuoteRequest.

LinkRequest

Zet de klant van de sessie op een offerteaanvraag die net is verstuurd, dus roep het meteen na CreateQuoteRequest aan, met dezelfde requestId. Het geeft alleen true als de sessie geldig is, de rol Inkoper is, requestId (getrimd, in hoofdletters, hooguit 64 tekens) niet leeg is, en er een offerteaanvraag met dat Verzoek-id bestaat die nog geen klant heeft. Daarna zet het de klant op de aanvraag, houdt het shipToCode alleen als dat een leveradres van die klant is en wist het anders (de adrestekst blijft staan), en zet het de Bron van de aanvraag op portal. Een false is geen fout: de aanvraag bestaat sowieso, en de binnendienst pakt hem op als elke andere.

MyRequests

De offerteaanvragen die aan de klant van de sessie zijn gekoppeld, de nieuwste eerst, hooguit 200. Geanonimiseerde aanvragen en aanvragen die als spam zijn gemarkeerd, blijven erbuiten.

SleutelTypeToelichting
notekstAanvraagnummer.
receivedAttekstTijdstip.
statustekstNew, InProgress, Converted, Rejected, of "" voor een status die deze versie niet kent.
quoteNotekstOptioneel. Het verkoopdocument dat uit de aanvraag is gemaakt; bij een baliebezoek een ordernummer.
quoteNoStatustekstAanwezig bij quoteNo. active bij een actuele offerte van deze klant, completed bij een vrijgegeven offerte in het offertearchief, anders "".
linesgetalAantal aanvraagregels.

MyQuotes

De verkoopoffertes van de klant van de sessie: eerst de actuele offertes, het hoogste nummer eerst, daarna offertes die alleen nog in het offertearchief bestaan (omgezet of verwijderd), alleen vrijgegeven versies, per nummer de hoogste gearchiveerde versie. Samen hooguit 100 rijen. Het antwoord is {"quotes": [ … ], "truncated": <boolean>}.

SleutelTypeToelichting
notekstOffertenummer.
documentDatetekstDatum.
validUntiltekstDe geldigheidsdatum van de offerte, anders de vervaldatum uit Steel 365, anders "".
yourReferencetekstDe referentie van de klant: Extern documentnr.
requestNotekstHet veld Uw referentie. Bij offertes uit een webaanvraag staat daar het aanvraagnummer; bij andere offertes kan er van alles staan.
statustekstOpen, Released, of "" bij elke andere status.
linesgetalAantal artikelregels.
totalWeightKggetalOptioneel, alleen met Steel 365. Totaalgewicht in kg.
hasDocumentbooleantrue alleen als Document deze offerte kan afdrukken. Bij gearchiveerde rijen altijd false.
acceptedbooleanEr is via het portaal een akkoord vastgelegd.
commenttekstAlleen bij actuele rijen: de opmerking die de binnendienst voor de klant schreef. Nooit de interne werkbeschrijving.
orderNo, orderNoStatustekstBij gearchiveerde rijen, optioneel: de order waar deze offerte in is overgegaan, uit het documentarchief van Steel 365, met active, completed of "". Verwijs alleen naar de order als dit niet "" is.

MyOrders

De verkooporders van de klant van de sessie: actuele orders, het hoogste nummer eerst, daarna orders die alleen nog in het orderarchief bestaan, per nummer de hoogste gearchiveerde versie, elke status. Samen hooguit 100 rijen, als {"orders": [ … ], "truncated": <boolean>}.

SleutelTypeToelichting
notekstOrdernummer.
quoteNo, quoteNoStatustekstDe offerte waar de order uit voortkwam, met active, completed of "". Gearchiveerde rijen halen die uit het documentarchief van Steel 365.
orderDate, requestedDeliveryDate, promisedDeliveryDatetekstDatums.
yourReferencetekstDe referentie van de klant (Extern documentnr.).
statustekstOpen, Released of "".
completelyShippedbooleanActueel: het eigen veld van de order. Gearchiveerd: per regel herrekend uit geboekte verzendregels.
linesgetalAantal artikelregels.
hasDocumentbooleanZoals bij MyQuotes.
commenttekstAlleen bij actuele rijen: de opmerking voor de klant.

MyShipments

De geboekte verkoopverzendingen van de klant van de sessie, de nieuwste eerst, hooguit 100, als {"shipments": [ … ], "truncated": <boolean>}.

SleutelTypeToelichting
notekstVerzendnummer.
deliveryDatetekstBoekingsdatum van de verzending.
orderNo, orderNoStatustekstDe order waar de verzending bij hoort, met active, completed of "".
yourReferencetekstDe referentie van de klant (Extern documentnr.).
shipToAddressobject{"name", "postCode", "city"}. Straat en huisnummer komen er niet uit.
linesgetalAantal artikelregels.
hasDocumentbooleanZoals bij MyQuotes.

DocumentLines

Parameters: documentType is quote, order of shipment (ongevoelig voor hoofdletters; iets anders geeft ""), en documentNo is het documentnummer. Het eigendom wordt gecontroleerd voordat er ook maar één regel wordt gelezen. Bij quote en order wordt eerst het actuele document geprobeerd; bestaat dat niet, dan de hoogste versie in het archief, bij offertes alleen vrijgegeven versies. Alleen regels van het type Artikel komen terug, hooguit 500; tekst- en opmerkingsregels blijven erbuiten. Het antwoord is {"lines": [ … ]}.

SleutelTypeWanneerToelichting
lineNogetalaltijdRegelnr.
itemNotekstaltijdArtikelnummer.
descriptiontekstaltijd
formattekstaltijdVariantcode: de afmeting.
quantitygetalzonder Steel 365Aantal.
unitOfMeasureCodetekstzonder Steel 365Eenheid van quantity.
outstandingQuantity, quantityShippedgetalzonder Steel 365, actuele orderregels
profile, grade, formatDescriptiontekstSteel 365, optioneelItem Profile Code DMX, Quality Code DMX, Item Variant Description DMX.
unittekstSteel 365, optioneelDoc. Unit of Measure Code DMX, de onvertaalde optienaam. Zegt welk van de drie aantallen leidend is; de referentiewebsite verwacht PCS, KG of MTR.
quantityPieces, quantityMeters, quantityKggetalSteel 365Quantity Pieces DMX, Quantity Length DMX, Quantity Weight DMX.
weightTypetekstSteel 365, optioneelTheoretical, Trade of GermanTrade.
outstandingPieces, outstandingMeters, outstandingKg, shippedPieces, shippedMeters, shippedKggetalSteel 365, actuele orderregelsOpenstaande en verzonden aantallen.

Regels voor het lezen van regels: tekstsleutels van Steel 365 blijven weg als ze leeg zijn, terwijl getalsleutels van Steel 365 er zijn zodra het veld bestaat, dus 0 betekent nul en een ontbrekende sleutel betekent onbekend (toon dan een streepje, geen 0). Met Steel 365 zijn stuks, meters en kilo's drie aparte aantallen: tel ze nooit op en kies er zelf geen, unit zegt welk aantal leidend is. Openstaande en verzonden waarden bestaan alleen bij actuele orderregels; reken ze niet zelf uit. Er komt nooit een prijs, korting, marge of bedrag terug.

{
  "lines": [
    {"lineNo": 10000, "itemNo": "1000", "description": "HEA 200 S235JR", "format": "12000",
     "profile": "HEA200", "grade": "S235JR", "unit": "PCS", "quantityPieces": 4,
     "quantityMeters": 48, "quantityKg": 2035.2, "weightType": "Theoretical"}
  ]
}

AcceptQuote

Legt vast dat de klant een vrijgegeven verkoopofferte accepteert. Alleen voor een Inkoper. Er wordt in Business Central niets omgezet of vrijgegeven: het akkoord is een signaal voor de binnendienst, die de offerte met de hand omzet. Het geeft altijd een object terug met outcome (recorded, already, expired of refused) en acceptedAt (een tijdstip, of ""). De controles, op volgorde:

ControleUitkomst
Sessie niet geldigrefused
De rol is geen Inkoperrefused
quoteNo is leeg of langer dan 20 tekensrefused
Geen actuele offerte met dat nummer voor deze klantrefused
De status van de offerte is niet Vrijgegevenrefused
Er bestaat al een akkoord voor deze offertealready, met de oorspronkelijke acceptedAt
De geldigheidsdatum is ingevuld en ligt voor vandaagexpired
Een andere aanroep legt op hetzelfde moment een akkoord voor deze offerte vastalready, acceptedAt = ""
Verderrecorded, acceptedAt = nu

refused zegt nooit waarom, en already is geen fout: toon dan dat het akkoord binnen is. Probeer deze aanroep niet automatisch opnieuw. Het vastgelegde akkoord bewaart het offertenummer, de klant, het e-mailadres van de portaalgebruiker, het moment, de IP-hash, de documentdatum, het bedrag inclusief btw, de valuta, het aantal regels, de laatste archiefversie en een vingerafdruk van de regels, zodat duidelijk blijft waarmee is ingestemd als de offerte later verandert. De mailtaak stuurt daarna de klant een bevestiging en de binnendienst een melding.

MyDocuments

De pdf's die de klant van de sessie kan krijgen, als {"documents": [ … ]}, zonder truncated. De bron is er één van twee, nooit allebei: het documentarchief van Steel 365 als DXSteel Doc Archive geïnstalleerd is, anders de rapporten als Portaaldocumenten uit rapporten aan staat. Staat het archief er niet en staat die instelling uit, dan is de lijst altijd leeg. Gaat er bij het lezen van het archief iets mis, dan is de lijst leeg in plaats van een fout, en de instellingenkaart toont waarom.

Archiefrijen. Een document staat alleen in de lijst als het aan het nummer van deze klant hangt, het relatietype Klant is, en de rubriek op Archiefrubrieken staat met een andere soort dan geen. De nieuwste eerst.

SleutelTypeToelichting
idtekstSystemId van het archiefrecord, in kleine letters met koppeltekens. De sleutel om te downloaden.
fileNametekstZoals opgeslagen in het archief. Kan spaties en accenten bevatten; maak de naam schoon voordat u hem in een header zet.
contentTypetekstapplication/pdf bij .pdf, anders application/octet-stream.
categorytekstDe soort: SalesQuote, SalesOrder, SalesInvoice, SalesCreditMemo, Proforma, Waybill of WarehouseShipment. Niet uw eigen rubrieknaam.
documentNotekstHet nummer van het brondocument, of "".
documentTypetekstquote, order, shipment of "". Pas ingevuld nadat Business Central heeft bevestigd dat documentNo zo'n document van deze klant is. Facturen, creditnota's en proforma's krijgen altijd "".
documentNoStatustekstAlleen als documentType order is: active of completed.
datetekstDe aanmaakdatum uit het archief, anders de datum waarop het record is aangemaakt, anders "".
orderNo, orderNoStatus, invoiceNo, creditMemoNotekstOptioneel. Nummers van bijbehorende documenten, met active, completed of "" voor de order.

Een archiefdocument downloaden. Business Central kan de bytes niet via deze codeunit teruggeven zonder afhankelijkheid van de app van iFacto, dus de website haalt ze met de id bij de API van iFacto op:

POST https://api.businesscentral.dynamics.com/v2.0/{tenant}/{environment}/api/ifacto/dxsteel/v1.0/companies({company id})/documentArchives({id})/Microsoft.NAV.Download
{}

-> {"value": "<base64>"}

Download alleen een id die voorkomt in de lijst van MyDocuments die u net voor diezelfde sessie hebt opgehaald. Neem nooit een id uit de browser en geef dat ongecontroleerd door: het account van de website heeft leesrecht op het archief nodig om te downloaden, en in hetzelfde archief zitten inkoopfacturen en interne correspondentie. VOA CG S365 ARCHIVE beperkt die toegang met een beveiligingsfilter tot de toegestane rubrieken, maar de eigendomscontrole is MyDocuments. Een lege value betekent dat er geen bestand bij het archiefrecord zit.

Rapportrijen. Alleen documentsoorten waarvoor een rapport is ingesteld (een documentindeling op de klantenkaart, anders de rapportselecties): actuele offertes en orders, geboekte verzendingen, facturen en creditnota's, in die volgorde, elk het hoogste nummer eerst en hooguit 100 per soort.

SleutelTypeToelichting
idtekstSystemId van het document in Business Central. Ter informatie; downloaden doet u met Document.
sourcetekstAltijd report. Ontbreekt bij archiefrijen: zo houdt u de twee uit elkaar.
reportTypetekstquote, order, shipment, invoice of creditMemo. Geef dit mee als documentType aan Document.
fileNametekst{category} {document number}.pdf, bijvoorbeeld SalesInvoice 103001.pdf.
contentTypetekstapplication/pdf.
categorytekstSalesQuote, SalesOrder, Waybill (verzendingen), SalesInvoice of SalesCreditMemo.
documentNotekstDocumentnummer. Geef dit mee als documentNo aan Document.
documentTypetekstquote, order of shipment; "" bij facturen en creditnota's.
documentNoStatustekstAlleen bij orders: active.
datetekstOfferte: documentdatum. Order: orderdatum. Verzending, factuur, creditnota: boekingsdatum.
orderNo, orderNoStatus, invoiceNo, creditMemoNotekstOptioneel. Nummers van bijbehorende documenten.

Document

De pdf van één document, afgedrukt met het rapport dat Business Central daarvoor gebruikt, en alleen bij de bron rapporten: waar het archief van Steel 365 staat, geeft dit altijd "" en gebruikt u de download uit het archief hierboven. documentType is quote, order, shipment, invoice of creditMemo (ongevoelig voor hoofdletters) en documentNo is het nummer. Het geeft "" bij een ongeldige sessie, een onbekend type, een document dat niet bestaat of niet van deze klant is, een documentsoort zonder rapport, of een lege afdruk. Offertes en orders moeten actueel zijn; gearchiveerde versies zijn niet af te drukken. Verder komen fileName, contentType en base64 terug, de pdf zelf.

Het rapport draait met de rechten van het websiteaccount (tenant-set VOA CG DOCUMENTS). Mislukt het rapport, meestal doordat een eigen indeling een tabel leest die de set niet dekt, dan mislukt de aanroep met een fout die het object noemt; zet die tabel in de set. Een download archiveert de offerte of order niet, maar de standaardrapporten verhogen wel Aantal afgedrukt. hasDocument in MyQuotes, MyOrders en MyShipments is precies dan true als de bron rapporten actief is en er voor die documentsoort een rapport voor deze klant is ingesteld.

Vaste waarden

Deze waarden zijn vaste merktekens. Ze worden nooit vertaald en hangen nooit van de taal van de sessie af. Vergelijk ze exact.

WaarSleutel of parameterWaarden
ReadSession, MyDetailsroleBuyer, Viewer
MyRequestsstatusNew, InProgress, Converted, Rejected, ""
MyQuotes, MyOrdersstatusOpen, Released, ""
MyRequests, MyOrdersquoteNoStatusactive, completed, ""
MyQuotes, MyShipments, MyDocumentsorderNoStatusactive, completed, ""
MyDocumentsdocumentNoStatusactive, completed
AcceptQuoteoutcomerecorded, already, expired, refused
DocumentLinesparameter documentTypequote, order, shipment
Documentparameter documentTypequote, order, shipment, invoice, creditMemo
MyDocumentsdocumentTypequote, order, shipment, ""
MyDocumentscategorySalesQuote, SalesOrder, SalesInvoice, SalesCreditMemo, Proforma, Waybill, WarehouseShipment
MyDocumentssourcereport (alleen rapportrijen)
MyDocumentsreportTypequote, order, shipment, invoice, creditMemo
MyDocuments, DocumentcontentTypeapplication/pdf, application/octet-stream
ReadSession, DocumentLinesweightTypeTheoretical, Trade, GermanTrade, ""
DocumentLinesunitOnvertaalde optienamen van het Steel 365-veld; de referentiewebsite kent PCS, KG, MTR
CreateQuoteRequestdeliveryMethodPickup, Delivery (iets anders: Pickup)
CreateQuoteRequestsourceVrije tekst tot 50 tekens. counterVisit maakt er een baliebezoek van; LinkRequest zet portal.
CreateAccountRequestexistingCustomerYes, No, Unknown (iets anders: Unknown)
Fouten van voaRequestsmelding[VOA-DUBBEL] markeert een dubbele requestId
Aanmeldcodealfabet0123456789ABCDEFGHJKMNPQRSTVWXYZ, 10 tekens

Aanvraagnummers komen uit nummerreeksen in de instellingen. Bij de installatie staan die standaard op WEB000001 tot WEB999999 voor offerteaanvragen en ACC000001 tot ACC999999 voor accountaanvragen, maar elk bedrijf kan ze wijzigen: vertrouw niet op het patroon.

Verschillen met Steel 365

CustomerGate 365 is één app. Hij kijkt zelf naar de omgeving en heeft daar geen instelling voor nodig: Steel 365 is actief zodra het veld Quantity Pieces DMX op de verkoopregel bestaat, en het documentarchief van Steel 365 zodra de tabel Document Archive DADMX bestaat.

OnderdeelMet Steel 365Zonder Steel 365
CatalogusservicesvoaProfiles, voaGrades en voaItemTypes zijn gepubliceerd, en de DX…-eigenschappen zijn gevuldAlleen voaItems, voaVariants, voaCategories; DX…-tekst is "" en getallen zijn 0
Machtigingen synchronisatieVOA WEB SYNC en VOA CG S365 SYNCAlleen VOA WEB SYNC
Aantallen in DocumentLinesquantityPieces, quantityMeters, quantityKg plus unit; quantity komt nooit voorquantity plus unitOfMeasureCode
DocumentLines bij actuele orderregelsoutstandingPieces/Meters/Kg, shippedPieces/Meters/KgoutstandingQuantity, quantityShipped
Extra sleutels in DocumentLinesprofile, grade, formatDescription, weightType als ze gevuld zijngeen
MyQuotes.totalWeightKgaanwezigafwezig
ReadSession.weightTypehet gewichtstype van de klant, of """"
Geldigheid van een offertevalt terug op de vervaldatum uit Steel 365alleen de geldigheidsdatum van de offerte

Het documentarchief is een aparte schakelaar:

OnderdeelMet het archiefZonder archief
MyDocumentsArchiefrijen, gefilterd op de toegestane rubriekenRapportrijen als Portaaldocumenten uit rapporten aan staat, anders leeg
Pdf downloadenDe bound action van de iFacto-API met de idDocument geeft base64 terug
Documentaltijd ""drukt de pdf af
hasDocumentaltijd falsetrue als er een rapport is ingesteld
Offertes en orders die alleen nog gearchiveerd zijnorderNo- en quoteNo-verwijzingen uit het archiefgeen verwijzingen
Tenant-set van de websiteVOA CG S365 ARCHIVEVOA CG DOCUMENTS als de instelling aan staat

Versies en compatibiliteit

De namen zijn het contract. Websites roepen ze letterlijk aan, dus dit hoort er allemaal bij: de namen van de services, de namen van procedures en parameters inclusief hoofdletters, de namen van de cataloguseigenschappen, de JSON-sleutels in payloads en antwoorden, en elke vaste waarde hierboven. Eén ervan hernoemen breekt elke website die op de app is gebouwd, in veel gevallen stilzwijgend: een hernoemde cataloguseigenschap laat gewoon een kolom leeg, en een hernoemde JSON-sleutel leest als null. Er zijn geen aliassen voor eerdere namen.

Voor wie de services gebruikt:

  • Negeer sleutels die u niet kent. In een compatibele release kunnen er sleutels bij komen.
  • Behandel een ontbrekende optionele sleutel als null, en "" als geen waarde.
  • Behandel een onbekende waarde als onbekend. Vertaal haar niet naar een standaard die iets beweert, bijvoorbeeld door een onbekende outcome als recorded te lezen.
  • Houd het sessietoken, de requestId en de sleutel voor de IP-hash aan de serverkant.

Een sleutel, een procedure of een cataloguseigenschap toevoegen is een compatibele wijziging; er een weghalen of hernoemen niet. De installatie en updates maken ontbrekende services aan, maar wijzigen nooit een bestaande: een hernoemde service zou naast de oude komen te staan, terwijl de oude blijft wijzen waar hij wees.

Verder in de documentatie