The B2B Customer Portal plug-in for Shopify enables seamless integration between your webshop and Business Central (BC). It adds a professional self-service environment to the customer ‘Account’ section of your webshop, giving your customers direct access to important Business Central data - securely and in real time.
This plug-in is designed to improve customer experience, reduce manual tasks, and streamline communication. Instead of contacting your support team, customers can log in to their account and immediately view the information they need.
Key Features
Display Business Central data: Show customer-specific information such as orders, invoices, shipments, returns and credit memos.
Customizable content: Choose which sales documents and fields are shown in the account section, based on what’s relevant to your customers. This also includes custom API pages built by your own Business Central developer.
PDF downloads: Allow customers to download documents like invoices, packing slips, and order confirmations as PDF files - directly from their account.
Drag-and-drop menu layout: Determine the order and grouping of the menu items in the account section by dragging them into place.
Automatic data sync: The plug-in retrieves the latest information from Business Central in real time, ensuring accuracy and up-to-date content.
Portal dashboard: Monitor connection status, response times, customer activity and document downloads.
Whether you're looking to improve service levels, reduce support overhead, or provide a more professional B2B experience, the Customer Portal plug-in helps bring Business Central data directly to your customers - where and when they need it.
Step-by-step Configuration Guide
BC: Installation
Install the Tinx Customer Portal extension via AppSource and follow step 1 and 2 (optional) of the step-by-step guide shown above.
BC: Extending Tinx API Pages
The API pages that the Customer Portal uses expose the standard fields of a number of default Dynamics 365 Business Central tables. Many customers and partners have extended those tables with their own fields, or want to display other information in the account section of the webshop.
There are two ways to make that data available to the Customer Portal:
- Custom Info fields: add your own values to the existing Tinx API pages. Suitable when you want to enrich a sales document that the portal already retrieves.
- Custom API pages: create a new API page in Business Central for a table that is not covered by our pages. Suitable when you want to add a completely new menu item to the account section.
Both options are developed in Business Central and require an extension of your own. No changes to the WooCommerce plug-in are needed.
Custom Info Fields
Every Tinx API page contains ten additional customInfo fields. These fields are empty by default and are available on all our pages.
field(customInfo1; CustomInfo[1]) { }
field(customInfo2; CustomInfo[2]) { }
field(customInfo3; CustomInfo[3]) { }
field(customInfo4; CustomInfo[4]) { }
field(customInfo5; CustomInfo[5]) { }| Field | Explanation |
|---|---|
| customInfo1 - customInfo10 | Ten free text fields of Text[100], available on every Tinx API page. The values are assigned in Business Central and are retrieved by the Customer Portal like any other field. |
| orderComment | An additional variable on the Sales Order page with an unlimited size. Suitable for large texts, such as all comments added to the Sales Order Header. |
The fields are populated by creating a subscriber function in a codeunit that subscribes to the GetCustomInfo integration event of the page:
[IntegrationEvent(false, false)] local procedure GetCustomInfo(SalesHeader: Record "Sales Header"; var CustomInfo: array[10] of Text[100]; var orderComment: Text) begin end;
The values that are assigned to the instances of the CustomInfo[x] variable are exposed in the API page. The example below fills the custom info fields of the Sales Order Lines page:
codeunit 50XXX "TINX CPM Sales OrdrLine Subscr"
{
[EventSubscriber(ObjectType::Page, Page::"TINX CPM Sales Order Lines", 'GetCustomInfo', '', true, true)]
local procedure GetCustomInfo(SalesLine: Record "Sales Line"; var CustomInfo: array[10] of Text[100])
var
CustTable: Record "Custom Table";
begin
CustomInfo[1] := SalesLine."Customer Specific Field";
CustomInfo[2] := format(SalesLine."Extension A field 1");
CustomInfo[3] := format(SalesLine."Extension B field 3");
if CustTable.Get(SalesLine."No.") then
CustomInfo[4] := CustTable.Description;
CustomInfo[5] := '';
CustomInfo[6] := '';
CustomInfo[7] := '';
CustomInfo[8] := '';
CustomInfo[9] := '';
CustomInfo[10] := '';
end;
}Order Comment
The Sales Order page contains an extra orderComment variable. This variable has an unlimited size and is therefore suitable for transferring large texts, such as all comments added to the Sales Order Header.
field(orderComment; OrderComment) { }The field is filled in the same way as the custom info fields:
codeunit 50XXX "TINX CPM Sales Orders Subscr"
{
[EventSubscriber(ObjectType::Page, Page::"TINX CPM Sales Orders", 'GetCustomInfo', '', true, true)]
local procedure GetCustomInfo(SalesHeader: Record "Sales Header"; var CustomInfo: array[10] of Text[100]; var ordercomment: Text)
var
SalesCommentLine: Record "Sales Comment Line";
begin
CustomInfo[1] := SalesHeader."FIELD 50123";
CustomInfo[2] := SalesHeader."FIELD 50124";
CustomInfo[3] := format(SalesHeader."Extension A Field 1");
CustomInfo[4] := format(SalesHeader."Extension B Field 2");
SalesCommentLine.SetRange("Document Type", SalesHeader."Document Type");
SalesCommentLine.SetRange("No.", SalesHeader."No.");
if SalesCommentLine.FindSet() then
repeat
ordercomment += SalesCommentLine.Comment + ' ';
until SalesCommentLine.Next() = 0;
end;
}BC: New Custom API Pages
In addition to the API pages created by Tinx, customers and partners can create their own API pages in Business Central. These pages can be used by the Customer Portal as long as the required page properties are configured as described below. Once published, the page appears in the endpoint list in the WordPress back-end and can be added as a menu item like any other entity.
Required fixed properties
If a separate API page is created for the Customer Portal, the following properties must be copied exactly. The Customer Portal uses these values to recognise the page:
PageType = API; APIPublisher = 'tinx'; APIGroup = 'customerPortal'; APIVersion = 'v2.0'; ChangeTrackingAllowed = false; Editable = false;
Page-specific properties
The following properties are filled based on the table and entity that the API page exposes. The example below is for the Customer table:
EntityCaption = 'Customer'; EntitySetCaption = 'Customers'; EntityName = 'customer'; EntitySetName = 'customers'; SourceTable = Customer;
Property overview
| Property | Requirement | Value / example |
|---|---|---|
| PageType | Required fixed value | API |
| APIPublisher | Required fixed value | tinx |
| APIGroup | Required fixed value | customerPortal |
| APIVersion | Required fixed value | v2.0 |
| ChangeTrackingAllowed | Required fixed value | false |
| Editable | Required fixed value | false |
| EntityCaption | Page-specific value | Customer |
| EntitySetCaption | Page-specific value | Customers |
| EntityName | Page-specific value | customer |
| EntitySetName | Page-specific value | customers |
| SourceTable | Page-specific value | Customer |
Note: Use the fixed properties exactly as shown. Change only the page-specific properties, so they match the table and entity that the API page must expose to the Customer Portal.
Line item pages and auto-detection
An entity can consist of two API pages: a header page containing the documents, and a line page containing the line items belonging to a document. When a Header API Endpoint is selected and sales lines are enabled, the plug-in tries to select the matching line page automatically.
Recommendation: when you create your own API pages, name the two pages according to the same convention. End the name of the header page with headers and the name of the line page with lines, for example serviceContractHeaders and serviceContractLines. The plug-in then selects the right combination without any manual configuration.
The detection is based on the name of the header page. The word headers is removed from the end of the name and lines is added instead. The comparison is not case sensitive:
| Header API Endpoint | Line Item API Endpoint selected automatically |
|---|---|
| salesShipmentHeaders | salesShipmentLines |
| salesInvoiceHeaders | salesInvoiceLines |
| returnReceiptHeaders | returnReceiptLines |
If no endpoint with the resulting name exists, the first available line item endpoint is selected. In both cases you can always select a different endpoint manually under Line Item API Endpoint.
Example page
You can use this example as a template:
page 11205894 TINXCPMCustomer
{
PageType = API;
APIPublisher = 'tinx';
APIGroup = 'customerPortal';
APIVersion = 'v2.0';
ChangeTrackingAllowed = false;
Editable = false;
EntityCaption = 'Customer';
EntitySetCaption = 'Customers';
EntityName = 'customer';
EntitySetName = 'customers';
SourceTable = Customer;
layout
{
area(Content)
{
repeater(General)
{
field(no; Rec."No.") { }
field(name; Rec.Name) { }
field(name2; Rec."Name 2") { }
field(address; Rec.Address) { }
field(address2; Rec."Address 2") { }
field(postCode; Rec."Post Code") { }
field(city; Rec.City) { }
field(county; Rec.County) { }
field(countryRegionCode; Rec."Country/Region Code") { }
field(languageCode; Rec."Language Code") { }
field(phoneNo; Rec."Phone No.") { }
field(eMail; Rec."E-Mail") { }
field(faxNo; Rec."Fax No.") { }
field(contact; Rec.Contact) { }
field(mobilePhoneNo; Rec."Mobile Phone No.") { }
field(balanceDueLCY; Rec."Balance Due (LCY)") { }
field(creditLimitLCY; Rec."Credit Limit (LCY)") { }
}
}
}
actions
{
}
}Tip: Use Postman to check which fields your API page returns before you configure the menu item. See the Postman section below.
Shopify: Installation
Install Tinx Customer Portal from the Shopify App Store. On the dashboard, you’ll find a Quick Start guide explaining how to set up the app.
Shopify: Setup Navigation layout
Set up the menu to display Business Central documents in your customers’ accounts. Without this configuration, no Business Central data will appear in their accounts. Follow the step-by-step video below. We recommend using the horizontal menu for the best customer experience.
Horizontal Menu (Top)
Shows only the menu items available to each customer. Customers without a linked Business Central account won't see the Tinx Customer Portal menu items.
Left Sidebar Menu
Uses Shopify's default customer account menu. Customers without a linked Business Central account can still see Tinx Customer Portal menu items. If they open one, they'll see a message explaining that they don't have access.
Shopify: Linking customers to Business Central
The portal uses two additional fields, called metafields, on each Shopify customer to link their account to Business Central:
-
Business Central Customer No. (
tinx.bc_customer_no) links the customer to their company’s customer account. -
Business Central Contact No. (
tinx.bc_contact_no) identifies the individual contact within that company.
The Document Access setting determines which link is used: the Customer No. gives access to company-wide documents, while the Contact No. limits access to the individual’s own documents.
These numbers must match the corresponding records in Business Central. The Tinx Shopify Connector can fill them in automatically through the customer sync.
Shopify: Configuration Reference
In the Wordpress back-end go to Tinx Customer Portal > General Settings. In the configuration you can find the following fields:
Field Explanation API Connection > Tenant ID This variable is included in the request sent by Shopify to obtain the OAuth token and retrieve sales documents from Business Central.
tenantGuid (see screenshot).
API Connection > Company GUID This variable is included in the request sent by Shopify to obtain the OAuth token and retrieve sales documents from Business Central.
Company GUID Go to your Business Central and Search for the company you want to make a connection with. Type in the search bar ‘companies’, click on ‘Companies’, select the company and open the page inspection tool (CRTL+ALT+F1) (see screenshot).
API Connection > Company Name This variable is included in the request sent by Shopify to retrieve sales document PDFs from Business Central.
companyName (see screenshot).
API Connection > Environment Name This variable is included in the request sent by Shopify to obtain the OAuth token and retrieve sales documents from Business Central.
environmentName (see screenshot).
API Connection > Client ID The Client ID is a unique identifier for your application within Microsoft Entra ID. It tells Business Central which application is requesting access. You can find this value in the App registrations section of the Azure portal.
See step 1 of the step-by-step guide.
API Connection > Client Secret The Client Secret acts as a secure password for your application. It proves to Microsoft Entra ID that the request is coming from a trusted and authorized app. You create the Client Secret in the Certificates & secrets section of your app registration in the Azure portal.
See step 1 of the step-by-step guide.
API Connection > Connection Status Displays the current connection status with Business Central, including whether the connection is active, if PDF retrieval is possible, and when the access token expires. Front-end > Amount of Entries per page Defines how many entries are shown per page in the Sales Documents tables. Advanced > Navigation > Horizontal Menu (Top) Shows only the menu items available to each customer. Customers without a linked Business Central account won't see the Tinx Customer Portal menu items. Advanced > Navigation > Left Sidebar Menu Uses Shopify's default customer account menu. Customers without a linked Business Central account can still see Tinx Customer Portal menu items. If they open one, they'll see a message explaining that they don't have access. Advanced > Scheduled Data Refresh (SDR) The plugin regularly checks whether the connection with Business Central is still active. This ensures that data is kept up to date and that the connection remains valid. If the connection is no longer active, the plugin will automatically disable itself on the front-end or deactivate certain components. Advanced > Refresh Interval Defines how often the plugin verifies the connection to Business Central to keep data up to date and ensure system reliability. Advanced > SDR Status Displays the status and timing of the scheduled task that checks the connection to Business Central, including the next run time, interval, and last execution. -
We created the following sales document * API pages in Business Central: Sales Orders, Sales Invoices, Sales Shipment, Sales Credit Memo and Return Receipt Headers. Those pages are used by the Customer Portal extension as a default to retrieve real-time information from Business Central.
Field Explanation General > Enable Determines whether sales documents should be retrieved in real time from Business Central. General > Name Title of the sales entity menu-item in the account section of the customer. General > Display Sales Lines Determines whether sales lines should be retrieved in real time from Business Central. * General > Show PDF Button Allow customers to download Orders as PDF. General > Show Re-order Button Allow customers to re-order the items from a specific sales document. General > Filter Sales Lines by Type Allows you to filter which types of sales lines are retrieved from Business Central, such as items, G/L Accounts, or comments. This helps control which line types are shown in the Customer portal. General > Document Access Choose whether a customer can access all company documents or only their own documents.
Access is based on the Shopify metafields created by our app: tinx.bc_customer_no for company documents and tinx.bc_contact_no for the customer’s own documents.
General > Enable Advanced Filtering Determines whether an additional filter is applied when records are retrieved from Business Central. When enabled, the Filter Expression field becomes available. Refresh Entity Data Manually retrieve new types or fields. This will not affect your current configuration. Field Management > Field Name This field corresponds to the field name in Business Central. Use drag-and-drop to adjust the sort order of fields as they appear. Field Management > Display Label Allows you to customize the display name of the field as shown in the customer's account page. Field Management > Display on Front-end Show or hide this field on the customer's account page.
Shopify: Add Custom Menu Items
Next to the standard sales documents, the plug-in allows you to add your own menu items to the account section. A menu item is based on a Business Central API page and is configured in the same way as a standard sales document, including field management and sales lines.
Any API page that is available in your Business Central environment can be used. This includes the standard Tinx API pages, as well as custom API pages developed by your own Business Central developer. Custom API pages appear in the endpoint list automatically, and no changes to the plug-in are required.
The same API page can be used more than once. This allows you to create, for example, an 'Open Sales Orders' and a 'Released Sales Orders' menu item based on the same Tinx salesOrders API page, each with its own filter expression.
In the WordPress back-end go to Tinx Customer Portal > Add Menu Item. In the configuration you can find the following fields:
Field Explanation Name Title of the menu-item in the account section of the customer. Header API Endpoint The Business Central API page used to retrieve the records for this menu item. Both standard Tinx API pages and custom API pages from your own Business Central environment are listed here. Customer No Field The field from the header endpoint that contains the customer number. This is used to show each customer only their own records. An example value from your Business Central data is shown below the field. Sales Lines Determines whether the entity has line items that should be retrieved. When enabled, a line item endpoint can be selected. Line Item API Endpoint The Business Central API page used to retrieve the line items belonging to a record. Item No Field The field from the line item endpoint that is used as the item number for re-ordering. Display Mode Determines how the data is presented in the account section: as a table containing multiple records, or as field: value pairs for a single record. This option is only available when sales lines are not enabled.
BC: Syncing Metafields (optional)
The Tinx Shopify Connector enables Business Central to communicate with Shopify through the GraphQL Admin API. An access token is required for this connection.
Once you’ve installed the connector in Business Central, activate the relevant default messages in the dashboard job GQL_OUT_CUSTOMERS. These messages sync the Business Central Customer No. and Contact No. to the corresponding customers in Shopify.
Example payload:
mutation {
metafieldsSet
(
metafields: [
{
ownerId: "gid://shopify/Customer/10255702425831"
namespace: "tinx"
key: "bc_contact_no"
type: "single_line_text_field"
value: "CT000031"
}
{
ownerId: "gid://shopify/Customer/10255702425831"
namespace: "tinx"
key: "bc_customer_no"
type: "single_line_text_field"
value: "20000"
}
]
)
{
userErrors{
code
elementIndex
field
message
}
}
} Postman (optional)
Postman is a standalone software testing API (Application Programming Interface) platform to build, test, design, modify, and document APIs. You can use Postman to test and see which field identifiers are available in the API pages. You can download Postman here.
To make life easier for you we prepared a Postman collection. You can download the collection here. This will help you setting up a Postman configuration to make a connection with Business Central. To set this up please follow the steps below:
-
Step 1: Open Postman.
a) Go to your workspace.
b) Click on import and drag-and-drop the 'Example Customer Portal.postman_collection' file in the import-window. -
Step 2: Open the 'Example Customer Portal' collection and navigate to the 'Variables' tab
Replace the dummy information in the 'Initial value' column with your business central data. The 'Initial value' and 'Current value' column should contain the same information. After this has been done save the collection
a) tenantGuid - see screenshot
b) companyGuid - see screenshot
c) clientId - see step 2 in the Business Central section
d) clientSecret - see step 4 in the Business Central section
e) companyName - see screenshot
f) environmentName - see screenshot -
Step 3: Open the 'Example salesOrders' request and navigate to the 'Authorization' tab
a) To retrieve a Business Central token click on the orange button 'Get New Access Token'. If successful click on the orange button 'Use Token'. Now you've a token which is used to make a connection with Business Central (valid for one hour (by default)).
b) Click on the blue button 'Send' to get the sales order information in the Postman response section.
Tip1: This example is for retrieving the sales orders list. To check which API pages are available remove the /salesOrders from the url.
Tip2: You can add filters to your request, here you can find all supported filters. E.g.
../salesOrders?$filter=sellToCustomerNo eq 'XXXX' -
Step 4: Open the 'getPDF' request and navigate to the 'Authorization' tab
a) To retrieve a Business Central token click on the orange button 'Get New Access Token'. If successful click on the orange button 'Use Token'. Now you've a token which is used to make a connection with Business Central (valid for one hour (by default)).
b) Navigate to the 'Body' tab and replace the 'Your documentNo' with a Business Central sales order No.
c) Click on the blue button 'Send' to get the sales order information in the Postman response section.
Tip: To get other PDF documents (not from sales orders). You can replace the 'PrintPDFOrder' element name in the 'Body' tab with: PrintPDFQuote, PrintPDFInvoice, PrintPDFShipment or PrintPDFCredit.
Related to