Dynamics 365 Sales
Dynamics 365 Sales is Microsoft’s sales force automation platform built on Dataverse. It manages opportunities, quotes, sales orders, and invoices. Advanced Form Integration creates these deal records from your WordPress form submissions, with automatic customer resolution that links each deal to the right Account or Contact.
Shared connection with Dynamics 365 CRM
Dynamics 365 Sales runs on the same Dataverse instance as Dynamics 365 CRM. It reuses the connection you configure under AFI → Settings → Dynamics 365 CRM. No separate credentials are needed.
If you have not yet set up the Dynamics 365 CRM connection, follow the steps in the Dynamics 365 & Dataverse doc first.
Create the integration
- Go to AFI → Add New.
- Give the integration a name, for example
Quote request form to Dynamics 365 Sales. - Under Trigger, pick the form plugin and the specific form.
- Under Action → Platform, select Dynamics 365 Sales.
- In Task, choose one of: Create Opportunity, Create Quote, Create Sales Order, or Create Invoice.
- Pick the same Dynamics 365 Account you configured for CRM.
- Map your form fields onto the deal fields listed below.
- Optional: open Conditional Logic to limit which submissions are sent.
- Click Save Integration.
Customer resolution
Every deal entity in Dynamics (Opportunity, Quote, Sales Order, Invoice) requires a customerid lookup. AFI resolves this automatically using a two-step strategy:
- Account by name (preferred): if an Account Name is mapped and an Account with that exact name exists, the deal is linked to it.
- Contact by email (fallback): if no matching Account is found, AFI searches for a Contact by email. If none exists, AFI auto-creates a minimal contact (first name, last name, email) so the deal has a customer to attach to.
The resulting record is bound via a polymorphic OData binding (cu****************@***ta.bind or cu****************@***ta.bind).
Tasks supported
Create Opportunity
Creates an opportunity via POST /opportunities. The Name (Topic) field is required.
| Field | Field key | Required | Notes |
|---|---|---|---|
| Account Name | account_name |
Recommended | Looks up Account by name (preferred customer) |
| Contact Email | contact_email |
Fallback | Looks up or creates a Contact |
| Contact First / Last Name | contact_first, contact_last |
No | Used if contact must be created |
| Opportunity Name (Topic) | name |
Yes | |
| Description | description |
No | |
| Estimated Revenue | estimatedvalue |
No | Decimal |
| Estimated Close Date | estimatedclosedate |
No | YYYY-MM-DD |
| Budget Amount | budgetamount |
No | |
| Probability % | closeprobability |
No | Integer 0-100 |
| Purchase Timeframe | purchasetimeframe |
No | Option set |
| Purchase Process | purchaseprocess |
No | Option set |
| Current Situation | currentsituation |
No | |
| Customer Need | customerneed |
No | |
| Proposed Solution | proposedsolution |
No | |
| Owner ID | ownerid |
No | Systemuser GUID |
Create Quote
Creates a quote via POST /quotes. The Name field is required.
| Field | Field key | Required | Notes |
|---|---|---|---|
| Customer fields | account_name, contact_email, etc. |
See above | Same resolution as Opportunity |
| Quote Name | name |
Yes | |
| Description | description |
No | |
| Effective From / To | effectivefrom, effectiveto |
No | YYYY-MM-DD |
| Requested Delivery By | requestdeliveryby |
No | YYYY-MM-DD |
| Total Amount | totalamount |
No | Decimal |
| Discount Amount | discountamount |
No | |
| Owner ID | ownerid |
No | Systemuser GUID |
Create Sales Order
Creates a sales order via POST /salesorders. The Name field is required. Supports an optional Price List lookup via pricelevelid.
| Field | Field key | Required | Notes |
|---|---|---|---|
| Customer fields | account_name, contact_email, etc. |
See above | |
| Order Name | name |
Yes | |
| Description | description |
No | |
| Requested Delivery By | requestdeliveryby |
No | YYYY-MM-DD |
| Total Amount | totalamount |
No | |
| Discount Amount | discountamount |
No | |
| Price List ID | pricelevelid |
No | Pricelevel GUID, auto-converted to OData bind |
| Owner ID | ownerid |
No | Systemuser GUID |
Create Invoice
Creates an invoice via POST /invoices. The Name field is required.
| Field | Field key | Required | Notes |
|---|---|---|---|
| Customer fields | account_name, contact_email, etc. |
See above | |
| Invoice Name | name |
Yes | |
| Description | description |
No | |
| Due Date | duedate |
No | YYYY-MM-DD |
| Total Amount | totalamount |
No | |
| Discount Amount | discountamount |
No | |
| Price List ID | pricelevelid |
No | Pricelevel GUID |
| Owner ID | ownerid |
No | Systemuser GUID |
Type coercion
AFI automatically coerces monetary fields (estimatedvalue, budgetamount, totalamount, discountamount) to floats, probability to integer, ownerid to an OData bind, and pricelevelid to a pricelevels lookup bind.
Pro features
The Pro integration adds a Custom Fields repeater to every task. Map any custom Dataverse column on Opportunity, Quote, Sales Order, or Invoice using the schema (logical) name as the key, for example new_dealstage or prefix_region.
Feature comparison
| Feature | Free | Pro |
|---|---|---|
| Create opportunity, quote, sales order, invoice | ✅ | ✅ |
| Customer resolution (Account by name, Contact by email) | ✅ | ✅ |
| Auto-create minimal contact if none exists | ✅ | ✅ |
| Standard deal fields + monetary type coercion | ✅ | ✅ |
| Price List lookup binding | ✅ | ✅ |
| Custom Dataverse fields on all four entities | No | ✅ |
Conditional logic example
Only create opportunities for deals above a certain value. Add a condition on deal_value being greater than 10000. Smaller enquiries still create a contact via a separate Dynamics 365 CRM integration but skip deal creation.
Troubleshooting
Deal not created
Open AFI → Log and check the response. Common causes: the Name (Topic) field was not mapped or was empty, or the customer could not be resolved (no matching Account name and no Contact email provided).
Customer not linked
If neither an Account name nor a Contact email is mapped, the deal has no customer and AFI will not send it (Dynamics would reject it). Make sure at least one customer-resolution field is mapped.
Price List not resolved
The pricelevelid must be a valid pricelevel GUID from your Dataverse instance. Find it in Dynamics under Settings → Product Catalog → Price Lists.