Acumatica CRM Integration
March 10, 2024
•
13 min read
Introduction
Integrating Acumatica with CRM systems enables bidirectional synchronization of customers, contacts, opportunities, and sales data. This creates a unified view of customer relationships and sales pipeline.
Data Synchronization
The integration handles synchronization of:
- Accounts and Customers
- Contacts
- Leads and Opportunities
- Sales Orders and Quotes
- Activities and Tasks
Contact Sync
async function syncContactToAcumatica(contact) {
const customerData = {
CustomerID: { value: contact.accountId },
CustomerName: { value: contact.accountName },
Email: { value: contact.email },
Phone1: { value: contact.phone },
Address: {
AddressLine1: { value: contact.street },
City: { value: contact.city },
State: { value: contact.state },
PostalCode: { value: contact.zip }
}
};
const result = await createOrUpdateCustomer(
baseUrl,
token,
'AR303000',
customerData
);
await updateCRMMapping('contact', contact.id, result.CustomerID);
}
Opportunity Management
async function syncOpportunity(opportunity) {
const opportunityData = {
OpportunityID: { value: opportunity.id },
Subject: { value: opportunity.name },
Stage: { value: mapCRMStage(opportunity.stage) },
CustomerID: { value: opportunity.accountId },
CloseDate: { value: opportunity.closeDate },
Amount: { value: opportunity.amount },
Probability: { value: opportunity.probability }
};
return await createOpportunity(
baseUrl,
token,
'CR304000',
opportunityData
);
}
function mapCRMStage(crmStage) {
const stageMap = {
'Prospecting': '01',
'Qualification': '02',
'Proposal': '03',
'Negotiation': '04',
'Closed Won': '05'
};
return stageMap[crmStage] || '01';
}
Sales Order Sync
async function createSalesOrderFromOpportunity(opportunity) {
const products = await getOpportunityProducts(opportunity.id);
const orderData = {
CustomerID: { value: opportunity.accountId },
OrderType: { value: 'SO' },
Description: { value: `Opportunity: ${opportunity.name}` },
Details: products.map(product => ({
InventoryCD: { value: product.sku },
Qty: { value: product.quantity },
UnitPrice: { value: product.unitPrice }
}))
};
const order = await createSalesOrder(
baseUrl,
token,
'SO301000',
orderData
);
await updateOpportunityField(opportunity.id, 'acumaticaOrder', order.OrderNbr);
}
Webhooks
// Handle CRM webhook events
app.post('/webhooks/crm', async (req, res) => {
const event = req.body;
switch (event.type) {
case 'contact.created':
case 'contact.updated':
await syncContactToAcumatica(event.data);
break;
case 'opportunity.stage_changed':
await updateOpportunityStage(event.data);
break;
case 'opportunity.closed_won':
await createSalesOrderFromOpportunity(event.data);
break;
}
res.status(200).send('OK');
});
Complete Integration Class
class AcumaticaCRMIntegration {
constructor(acumaticaConfig, crmConfig) {
this.acumatica = acumaticaConfig;
this.crm = crmConfig;
}
async syncAllData() {
await this.syncContacts();
await this.syncOpportunities();
await this.syncSalesOrders();
}
async syncContacts() {
const contacts = await this.crm.getContacts();
for (const contact of contacts) {
await this.syncContactToAcumatica(contact);
}
}
async handleWebhook(event) {
const handlers = {
'contact.created': this.syncContactToAcumatica,
'opportunity.closed_won': this.createSalesOrderFromOpportunity,
'account.updated': this.syncAccountToAcumatica
};
const handler = handlers[event.type];
if (handler) {
await handler.call(this, event.data);
}
}
}
Summary
Integrating Acumatica with CRM systems creates a seamless flow of customer and sales data between platforms. By implementing the patterns in this guide, you can synchronize contacts, opportunities, and sales orders automatically.
For more information, check out our other tutorials on Payment Gateway Integration and Shopify Integration.