Header Ads Widget

Seamless Integration between D365FO (or AX) and D365CE using API (X++)

 In this blog, we’ll explore how to set up an asynchronous integration between D365 Finance and Operations (F&O) and D365 Customer Engagement (CE). This integration will ensure that whenever a customer is created, updated, or deleted in D365 F&O, the corresponding data is reflected in D365 CE. The process involves fetching a new access token for each interaction with CE via its API.

Prerequisites:

Before we start, ensure the following:

  1. D365 CE app must be registered in Azure Active Directory.

  2. Obtain the necessary details such as Client App ID, App Secret, Tenant ID, and CE URL for authentication.


Step-by-Step Guide to Customer Integration

We will define a class CustomerIntegrationHandler in X++ to manage the interaction with D365 CE. Below are methods to create, update, and delete customer records from D365 F&O and push them to D365 CE.

Authentication:

The following method will be used to obtain the OAuth token required for accessing D365 CE’s API.

x++
class CustomerIntegrationHandler { CustTable customer; str ceApiUrl = "https://<your-ce-instance>.crm.dynamics.com/api/data/v9.2"; // D365 CE URL str aadTenantId = "https://login.microsoftonline.com/<your-tenant-id>/oauth2/v2.0/token"; // Azure Tenant str aadResource = "https://<your-ce-instance>.crm.dynamics.com"; // CE Resource URL str aadClientAppId = "<your-client-app-id>"; // Client App ID str aadClientAppSecret = "<your-client-app-secret>"; // Client App Secret str contentType = 'application/json'; // Content Type // Method to assign customer table for processing public CustTable setCustomer(CustTable _customer = customer) { customer = _customer; return customer; } // Method to fetch Access Token from Azure AD public str getAccessToken() { AuthenticationContext authContext = new AuthenticationContext(aadTenantId); ClientCredential clientCredential = new ClientCredential(aadClientAppId, aadClientAppSecret); AuthenticationResult authResult = authContext.AcquireTokenAsync(aadResource, clientCredential).Result; return authResult.AccessToken; } }

Create Customer in D365 CE:

The following method will create a new customer record in D365 CE using a POST request.

x++
public RetailWebResponse createCustomerInCE() { System.IO.StringWriter stringWriter; Newtonsoft.Json.JsonTextWriter jsonWriter; RetailCommonWebAPI webApi; RetailWebResponse response; str data; str postUrl; str header; // Define the URL for CE API to create an account postUrl = ceApiUrl + "/accounts?$select=firstname,lastname,accountnumber,emailaddress"; // Get access token header = strFmt('Authorization: Bearer %1', this.getAccessToken()); // Format JSON data stringWriter = new System.IO.StringWriter(); jsonWriter = new Newtonsoft.Json.JsonTextWriter(stringWriter); DirPartyName partyName = DirPartyName::find(customer.Party); jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName("firstname"); jsonWriter.WriteValue(partyName.FirstName); jsonWriter.WritePropertyName("lastname"); jsonWriter.WriteValue(partyName.LastName); jsonWriter.WritePropertyName("accountnumber"); jsonWriter.WriteValue(customer.AccountNum); jsonWriter.WritePropertyName("emailaddress"); jsonWriter.WriteValue(customer.Email()); jsonWriter.WriteEndObject(); data = stringWriter.ToString(); // Send POST request to create the customer in CE webApi = RetailCommonWebAPI::construct(); response = webApi.makePostRequest(postUrl, data, header, contentType); info("Customer successfully created in D365 CE."); return response; }

Update Customer in D365 CE:

To update an existing customer in D365 CE, we will use a PATCH request as shown below:

x++
public RetailWebResponse updateCustomerInCE() { System.IO.StringWriter stringWriter; Newtonsoft.Json.JsonTextWriter jsonWriter; RetailCommonWebAPI webApi; RetailWebResponse response; str data; str patchUrl; str header; patchUrl = ceApiUrl + "/accounts(accountnumber='" + customer.AccountNum + "')?$select=firstname,lastname,emailaddress"; // Get access token header = strFmt('Authorization: Bearer %1', this.getAccessToken()); // Format JSON data stringWriter = new System.IO.StringWriter(); jsonWriter = new Newtonsoft.Json.JsonTextWriter(stringWriter); DirPartyName partyName = DirPartyName::find(customer.Party); jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName("firstname"); jsonWriter.WriteValue(partyName.FirstName); jsonWriter.WritePropertyName("lastname"); jsonWriter.WriteValue(partyName.LastName); jsonWriter.WritePropertyName("emailaddress"); jsonWriter.WriteValue(customer.Email()); jsonWriter.WriteEndObject(); data = stringWriter.ToString(); // Send PATCH request to update the customer in CE RetailWebRequest request = RetailWebRequest::newUrl(patchUrl); System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); request.parmMethod("PATCH"); request.parmHeader(header); request.parmContentType(contentType); if (strLen(data) > 0) { request.setContentBytes(encoding.GetBytes(data)); } webApi = RetailCommonWebAPI::construct(); response = webApi.getResponse(request); info("Customer updated in D365 CE."); return response; }

Delete Customer from D365 CE:

The following method will delete a customer record from D365 CE using a PATCH request to deactivate the customer.

x++
public RetailWebResponse deleteCustomerFromCE() { System.IO.StringWriter stringWriter; Newtonsoft.Json.JsonTextWriter jsonWriter; RetailCommonWebAPI webApi; RetailWebResponse response; str data; str deleteUrl; str header; deleteUrl = ceApiUrl + "/accounts(accountnumber='" + customer.AccountNum + "')?$select=firstname,lastname,emailaddress,statecode"; // Get access token header = strFmt('Authorization: Bearer %1', this.getAccessToken()); // Format JSON data stringWriter = new System.IO.StringWriter(); jsonWriter = new Newtonsoft.Json.JsonTextWriter(stringWriter); DirPartyName partyName = DirPartyName::find(customer.Party); jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName("firstname"); jsonWriter.WriteValue(partyName.FirstName); jsonWriter.WritePropertyName("lastname"); jsonWriter.WriteValue(partyName.LastName); jsonWriter.WritePropertyName("emailaddress"); jsonWriter.WriteValue(customer.Email()); jsonWriter.WritePropertyName("statecode"); jsonWriter.WriteValue(1); // Deactivate the customer jsonWriter.WriteEndObject(); data = stringWriter.ToString(); // Send PATCH request to deactivate the customer in CE RetailWebRequest request = RetailWebRequest::newUrl(deleteUrl); System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); request.parmMethod("PATCH"); request.parmHeader(header); request.parmContentType(contentType); if (strLen(data) > 0) { request.setContentBytes(encoding.GetBytes(data)); } webApi = RetailCommonWebAPI::construct(); response = webApi.getResponse(request); info("Customer deactivated in D365 CE."); return response; }

Conclusion:

With these methods, you can now integrate D365 F&O with D365 CE to create, update, and delete customer records asynchronously. This process enables seamless data synchronization between the two systems and enhances your enterprise application architecture.

Post a Comment

0 Comments