Visma.NET Connector - Customer Creation/Update
Overview
This document details how the App4Sales Visma.NET connector creates or updates customer records in the Visma.NET ERP system. The process is triggered when a new customer is created in App4Sales or an existing customer is modified. The connector determines if a customer is new or existing based on the presence of a Visma.NET Customer Code and performs either a POST (create) or PUT (update) operation against the Visma.NET API.
Trigger & Permissions
The customer creation/update flow is typically initiated from the App4Sales mobile application (for new customers) or via backoffice synchronization processes. The connector requires the EditCustomer permission (Constants.ConnectorInfoInternalIds.EditCustomer) to execute this command.
Authentication with Visma.NET is handled via OAuth 2.0. The connector can use "Visma Connect" authentication or an older flow with username/password configured in the App4Sales CMS. Access tokens are automatically managed and refreshed by the connector.
Data Source Configuration
The primary data source for customer creation/update is the App4Sales internal Customer object. This object contains all the necessary information for mapping to the Visma.NET customer structure. Connector-specific settings within the App4Sales CMS also influence how certain fields are mapped and defaulted.
Visma.NET API Base URL: Configured to
VismaNETConstants.ApiRoutes.Apim.Customer Creation Endpoint (POST):
[Base URL]/v1/customerCustomer Update Endpoint (PUT):
[Base URL]/v1/customer/{CustomerCode}
Payload Mapping - Visma.NET Customer
The App4Sales Customer object is transformed into a VismaNetPostCustomer object before being sent to the Visma.NET API.
App4Sales Field | Source Field (API/Excel/DB) | Logic/Notes |
CustomerName |
| Directly mapped. |
ChamberOfCommerceCode |
| Directly mapped. |
VatCode |
| Directly mapped. |
PaymentConditionCode |
| Mapped to the ID of the credit terms. Empty values are sent as null. |
Price List (derived from |
| Determined from |
Price List Currency (derived from |
| Determined from |
DynamicFreeFields (for Customer Class) |
| If |
VatLiable |
| If |
CustomerCode |
| For new customer creation, this field is explicitly set to null as Visma.NET assigns the customer number. For updates, the customer code is used in the URL route parameter. |
Payload Mapping - Main Contact Person
The App4Sales MainContactPerson is mapped to the MainContact of the Visma.NET customer.
App4Sales Field | Source Field (API/Excel/DB) | Logic/Notes |
MainContactPerson.FullName |
| Directly mapped. |
Name |
| Mapped from the main App4Sales Customer's |
MainContactPerson.Email |
| Directly mapped. |
MainContactPerson.Phonenumber |
| Directly mapped. |
MainContactPerson.MobileNumber |
| Directly mapped. |
Payload Mapping - Visit Address (to Main Address)
The App4Sales address with AddressType "Visit" is mapped to the MainAddress of the Visma.NET customer. Mapping only occurs if AddressLine1 is not empty.
App4Sales Field | Source Field (API/Excel/DB) | Logic/Notes |
Addresses (Type: Visit).AddressLine1 |
| Directly mapped. |
Addresses (Type: Visit).AddressLine2 |
| Directly mapped. |
Addresses (Type: Visit).AddressLine3 |
| Directly mapped. |
Addresses (Type: Visit).PostCode |
| Directly mapped. |
Addresses (Type: Visit).City |
| Directly mapped. |
Addresses (Type: Visit).Iso2 |
| Mapped to the 2-letter ISO country code. Empty values are sent as null. |
Payload Mapping - Delivery Address
The App4Sales address with AddressType "Delivery" is mapped to the DeliveryAddress of the Visma.NET customer. Mapping only occurs if AddressLine1 is not empty.
App4Sales Field | Source Field (API/Excel/DB) | Logic/Notes |
Addresses (Type: Delivery).AddressLine1 |
| Directly mapped. |
Addresses (Type: Delivery).AddressLine2 |
| Directly mapped. |
Addresses (Type: Delivery).AddressLine3 |
| Directly mapped. |
Addresses (Type: Delivery).PostCode |
| Directly mapped. |
Addresses (Type: Delivery).City |
| Directly mapped. |
Addresses (Type: Delivery).Iso2 |
| Mapped to the 2-letter ISO country code. Empty values are sent as null. |
Validation & Defaults
For new customers,
VismaNetPostCustomer.Statusdefaults toActive.Customer codes (
VismaNetPostCustomer.Number) are not sent during creation/update, as Visma.NET assigns them.CreditTermsId,CurrencyId,CustomerClassId,VatZoneId, andCountryIdfor addresses are sent as null if their corresponding App4Sales values are empty.If
customer.DynamicFreeFieldsdoes not contain a "CustomerClass" field, theCustomerClassIddefaults to the value specified in the connector settingCustomerClassForNewCustomers.If a price list's currency cannot be determined from
customer.UsesPriceField, theCurrencyIddefaults tosettings.DefaultCurrencyForNewCustomers.For addresses, mapping only occurs if
AddressLine1is not empty.
Response & Error Handling
Successful Creation (POST): Upon successful creation, the Visma.NET API returns a
Locationheader containing the URI of the newly created customer. The connector extracts the customer's new code from this URI and assigns it tocustomer.CustomerCodein App4Sales. The updated customer record is then persisted in the App4Sales database viaCustomerUpdateHandler().Update(customer).Successful Update (PUT): Visma.NET PUT requests do not return a
Locationheader. The connector assumes success if no error is returned.Error Handling: If the Visma.NET API returns an error, a
RestExceptionis caught. The connector attempts to deserialize the error response to extract details such asExceptionType,ExceptionMessage, andExceptionFaultCode, logging these details. A generic "Unknown error occurred" or "Fatal exception occurred" message is used if specific error details cannot be retrieved. In case of an error, anExceptionis thrown, halting the process.Duplicate Detection: The connector detects existing customers by attempting to retrieve a
VismaNetCustomerusingcustomer.CustomerCodebefore attempting to create a new one. If a customer with the code is found, an update operation (PUT) is performed instead of a creation (POST).
Known Limitations
The
InvoiceAddress,InvoiceContact, andDeliveryContactfields ofVismaNetPostCustomerare not directly mapped from the App4Sales Customer object during a new customer creation; they appear to be populated only during an update if an existing Visma.NET customer record is provided.The
CreditLimitfield ofVismaNetPostCustomeris not explicitly mapped from the App4Sales Customer object. It is likely preserved from an existing Visma.NET customer during an update.