NW Pre Customer + ApiConnectBC
Portal de autoservicio para Microsoft Dynamics 365 Business Central — niccoweb.com
Sin entrar a BC
El cliente potencial nunca necesita usuario, licencia ni sesión de Business Central.
Token de un solo uso
Cada invitación incluye un Guid Token que se invalida automáticamente tras la primera actualización correcta.
Caducidad configurable
El campo Token Time define cuánto tiempo sigue siendo válido el enlace enviado.
Validación en la propia API
El trigger OnModifyRecord rechaza cualquier PATCH con token incorrecto o caducado.
Autenticación app-only
ApiConnectBC se autentica con OAuth2 client credentials: no usa ni expone credenciales del prospecto.
Vista previa del correo
La acción Send Email (Preview Mode) abre el email en el editor de BC antes de enviarlo.
Adjuntos documentales
Cada Pre Customer admite archivos adjuntos (DNI, justificante, etc.) desde la ficha de BC.
API estándar reutilizable
La página API (OData v4) puede integrarse con cualquier sistema externo, no solo con ApiConnectBC.
- 1Registra una aplicación Azure AD (client credentials) con permiso sobre la API de Business Central; guarda el Tenant ID, Client ID y genera un Client Secret.
- 2Da de alta esa aplicación en BC (Microsoft Entra Applications) con permiso sobre los objetos de Pre Customer.
- 3Configura el .env de ApiConnectBC: TENANT_ID, CLIENT_ID, CLIENT_SECRET, BASE_URL, ENVIRONMENT, API_VERSION, COMPANY_ID, RESOURCE_TYPE, PORT.
- 4Despliega/arranca el servicio: npm install && npm start, y anota su URL pública.
- 5En BC, abre Pre Customer Setup e indica esa Url, el Subject, el Body Text del correo y el Token Time de validez.
- 1El usuario de BC crea un registro Pre Customer con Name, E-mail, Address, City, County y Post Code.
- 2Pulsa Send Email (o la versión en modo vista previa).
- 3El codeunit genera un nuevo Guid Token, calcula su caducidad y envía un correo HTML con un botón hacia {Url}/{Id}/{GuidToken}.
- 4ApiConnectBC obtiene un token OAuth2 y hace GET a la API de BC para traer los datos actuales del prospecto.
- 5El prospecto ve el formulario pre-rellenado (E-mail de solo lectura) y corrige Name/Address/City/County/Post Code.
- 6Al enviar, ApiConnectBC hace PATCH a la API incluyendo el guidToken recibido en el enlace.
- 7La página API valida el token: si es correcto y no ha caducado, aplica los cambios y lo borra (un solo uso); si no, devuelve error.
- 8El prospecto ve la pantalla de confirmación, sin haber accedido nunca a Business Central.
| Tipo | ID | Nombre | Descripción |
|---|---|---|---|
| Tabla | 50140 | Pre Customer | Tabla intermedia con los datos del prospecto y su token de seguridad |
| Tabla | 50141 | Pre Customer Setup | Configuración singleton: URL del formulario, asunto, cuerpo del correo y caducidad del token |
| Página | 50140 | Pre Customer | Lista para gestionar prospectos y disparar el envío de invitaciones |
| Página | 50141 | Pre Customer Setup | Ficha de configuración (singleton, sin alta ni baja) |
| Página API | 50142 | API Pre Customer | Endpoint OData consumido por ApiConnectBC (y cualquier otro sistema externo) |
| Codeunit | 50140 | Pre Customer Mgt. | Generación del token, envío del correo e integración con adjuntos documentales |
| EnumExt | 50140 | NW Attachment Document Type | Añade "Pre Customer" como tipo de documento adjunto |
| Campo | Tipo | Descripción |
|---|---|---|
No. (1) | Code[20] | Clave primaria, expuesta como id en la API |
E-mail (2) | Text[80] | Correo del prospecto; solo lectura en el formulario web |
Name (3) | Text[100] | Nombre del prospecto |
Address (4) | Text[100] | Dirección |
City (5) | Text[30] | Ciudad |
County (6) | Text[30] | Provincia / condado |
Post Code (7) | Code[20] | Código postal |
Guid Token (50000) | Guid | Token de un solo uso para autorizar la actualización |
Guid Token Expires At (50001) | DateTime | Caducidad del token |
| Campo | Tipo | Descripción |
|---|---|---|
Url | Text[150] | URL base del formulario (servidor ApiConnectBC) |
Subject | Text[80] | Asunto del correo de invitación |
Body Text | Text[500] | Cuerpo del correo, insertado en la plantilla HTML |
Token Time | Duration | Tiempo de validez del enlace enviado |
| Campo API | Campo BC | Acceso |
|---|---|---|
systemId | SystemId | Clave OData (lectura) |
id | No. | Lectura |
eMail | Lectura/escritura | |
name | Name | Lectura/escritura |
address | Address | Lectura/escritura |
city | City | Lectura/escritura |
county | County | Lectura/escritura |
postCode | Post Code | Lectura/escritura |
guidToken | Guid Token | Escritura (token de la invitación) |
documentAttachments (basada en la página estándar "APIV2 - Document Attachments" de BC), enlazada por Document Id = SystemId.
🔐 Seguridad del token (trigger OnModifyRecord): antes de aplicar cualquier modificación, compara el Guid Token recibido con el que ya tenía el registro y comprueba que no haya superado su fecha de caducidad. Si algo no coincide, rechaza la petición con error; si todo es correcto, aplica los cambios y borra ambos campos de token, de modo que el enlace deja de funcionar tras el primer uso.
| Método | Ruta | Descripción |
|---|---|---|
| GET | / | Sirve form.html: formulario para introducir manualmente Id y token |
| GET | /api/update-precustomer/:id/:guid | Obtiene token OAuth2, hace GET a la API de BC y renderiza el formulario pre-rellenado |
| POST | /api/update-precustomer/:id/:guid | Hace PATCH a la API de BC con los campos editados y el guidToken; renderiza éxito o error |
server.js (arranque Express) · auth/oauth.js (token client-credentials) · routes/bc.js (rutas GET/POST) · views/update-precustomer.ejs + views/success.ejs · public/form.html + public/css/style.css
📦 Dependencias: express, ejs, axios, dotenv, express-session.
- ✓OAuth2 client credentials: ApiConnectBC se autentica como aplicación (app-only) contra login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token con el scope https://api.businesscentral.dynamics.com/.default; el prospecto nunca ve ni necesita credenciales de BC.
- ✓El Client Secret vive solo en el .env del servidor, nunca llega al navegador del prospecto.
- ✓El Guid Token es de un solo uso y caduca según Token Time; tras una actualización válida se borra y el enlace deja de servir.
- ✓El campo E-mail es de solo lectura en el formulario, para evitar que alguien redirija la prospección a otra bandeja de entrada.
- ✓Business Central con la extensión Pre Customer instalada y publicada (probado en v26.0).
- ✓Una app registration de Azure AD con permiso de API sobre Business Central y un Client Secret vigente.
- ✓Un entorno Node.js donde alojar ApiConnectBC, idealmente detrás de HTTPS para los enlaces enviados por correo.
- ✓El conector de correo saliente de Business Central configurado (Email Setup) para que el codeunit pueda enviar las invitaciones.
NW Pre Customer + ApiConnectBC
Self-service portal for Microsoft Dynamics 365 Business Central — niccoweb.com
No BC login required
The prospect never needs a Business Central user, license, or session.
Single-use token
Every invitation carries a Guid Token that is automatically invalidated after the first successful update.
Configurable expiry
The Token Time field controls how long the emailed link stays valid.
Validated at the API itself
The OnModifyRecord trigger rejects any PATCH with a wrong or expired token.
App-only authentication
ApiConnectBC authenticates with OAuth2 client credentials — no prospect credentials are ever used or exposed.
Email preview mode
The Send Email (Preview Mode) action opens the email in BC's editor before sending.
Document attachments
Each Pre Customer supports file attachments (ID, proof of address, etc.) from the BC card.
Reusable standard API
The OData v4 API page can be integrated with any external system, not just ApiConnectBC.
-
1Register an Azure AD application (client credentials) with permission to call the Business Central API; note the Tenant ID, Client ID and generate a Client Secret.
-
2Register that application in BC (Microsoft Entra Applications) with permission over the Pre Customer objects.
-
3Fill in ApiConnectBC's .env: TENANT_ID, CLIENT_ID, CLIENT_SECRET, BASE_URL, ENVIRONMENT, API_VERSION, COMPANY_ID, RESOURCE_TYPE, PORT.
-
4Deploy/run the service: npm install && npm start, and note its public URL.
-
5In BC, open Pre Customer Setup and enter that Url, the Subject, the email Body Text, and the Token Time validity window.
- 1The BC user creates a Pre Customer record with Name, E-mail, Address, City, County and Post Code.
- 2They click Send Email (or the preview-mode variant).
- 3The codeunit generates a new Guid Token, computes its expiry, and sends an HTML email with a button linking to {Url}/{Id}/{GuidToken}.
- 4ApiConnectBC obtains an OAuth2 token and issues a GET to the BC API to fetch the prospect's current data.
- 5The prospect sees a pre-filled form (E-mail read-only) and corrects Name/Address/City/County/Post Code.
- 6On submit, ApiConnectBC issues a PATCH to the API including the guidToken received in the link.
- 7The API page validates the token: if correct and not expired, it applies the changes and clears it (single use); otherwise it returns an error.
- 8The prospect sees a confirmation screen — having never accessed Business Central.
| Type | ID | Name | Description |
|---|---|---|---|
| Table | 50140 | Pre Customer | Staging table holding the prospect's data and security token |
| Table | 50141 | Pre Customer Setup | Singleton config: form URL, email subject/body and token expiry |
| Page | 50140 | Pre Customer | List page to manage prospects and trigger invitation emails |
| Page | 50141 | Pre Customer Setup | Card page for configuration (singleton, no insert/delete) |
| API Page | 50142 | API Pre Customer | OData endpoint consumed by ApiConnectBC (or any external system) |
| Codeunit | 50140 | Pre Customer Mgt. | Token generation, email sending, document attachment integration |
| EnumExt | 50140 | NW Attachment Document Type | Adds "Pre Customer" as a valid attachment document type |
| Field | Type | Description |
|---|---|---|
No. (1) | Code[20] | Primary key, exposed as id in the API |
E-mail (2) | Text[80] | Prospect's email; read-only in the web form |
Name (3) | Text[100] | Prospect's name |
Address (4) | Text[100] | Street address |
City (5) | Text[30] | City |
County (6) | Text[30] | County / state |
Post Code (7) | Code[20] | Postal code |
Guid Token (50000) | Guid | Single-use token authorising the update |
Guid Token Expires At (50001) | DateTime | Token expiry timestamp |
| Field | Type | Description |
|---|---|---|
Url | Text[150] | Base URL of the form (ApiConnectBC server) |
Subject | Text[80] | Invitation email subject |
Body Text | Text[500] | Email body, inserted into the HTML template |
Token Time | Duration | Validity window of the emailed link |
| API Field | BC Field | Access |
|---|---|---|
systemId | SystemId | OData key (read) |
id | No. | Read |
eMail | Read/write | |
name | Name | Read/write |
address | Address | Read/write |
city | City | Read/write |
county | County | Read/write |
postCode | Post Code | Read/write |
guidToken | Guid Token | Write (invitation token) |
documentAttachments (based on BC's standard "APIV2 - Document Attachments" page), linked via Document Id = SystemId.
🔐 Token security (OnModifyRecord trigger): before applying any change, it compares the incoming Guid Token against the one already stored on the record and checks that its expiry has not passed. If anything doesn't match, the request is rejected with an error; if it checks out, the change is applied and both token fields are cleared, so the link stops working after its first use.
| Method | Route | Description |
|---|---|---|
| GET | / | Serves form.html: manual entry form for Id and token |
| GET | /api/update-precustomer/:id/:guid | Gets an OAuth2 token, issues a GET to the BC API and renders the pre-filled form |
| POST | /api/update-precustomer/:id/:guid | Issues a PATCH to the BC API with the edited fields and guidToken; renders success or error |
server.js (Express bootstrap) · auth/oauth.js (client-credentials token) · routes/bc.js (GET/POST routes) · views/update-precustomer.ejs + views/success.ejs · public/form.html + public/css/style.css
📦 Dependencies: express, ejs, axios, dotenv, express-session.
- ✓OAuth2 client credentials: ApiConnectBC authenticates app-only against login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token with scope https://api.businesscentral.dynamics.com/.default; the prospect never sees or needs BC credentials.
- ✓The Client Secret lives only in the server's .env file and never reaches the prospect's browser.
- ✓The Guid Token is single-use and expires per Token Time; after a valid update it is cleared and the link stops working.
- ✓The E-mail field is read-only in the form, preventing a prospect from redirecting their record to a different inbox.
- ✓Business Central with the Pre Customer extension installed and published (tested on v26.0).
- ✓An Azure AD app registration with API permission over Business Central and a valid Client Secret.
- ✓A Node.js environment to host ApiConnectBC, ideally behind HTTPS for the emailed links.
- ✓Business Central's outgoing email connector configured (Email Setup) so the codeunit can send invitations.
Comentarios
Publicar un comentario