Skip to content

§00Order-to-cash

From closed deal to paid invoice.

When a deal closes, the customer and the sales order should exist in your ERP — and sales should see delivery and invoice status without asking finance. PartnerMCP builds that flow from one sentence. The worked example: Salesforce to Priority ERP.

Salesforce → Priority
Production
Opportunity · Closed WonCustomer lookupSchema mappingCreate / update customerCreate sales orderMonitor orderSync fulfillmentSync invoice statusUpdate Opportunity
Order-to-cash plan: Salesforce to Priority ERP. Salesforce to Priority ERP.
  1. Opportunity · Closed Won — Salesforce: Trigger · Change Data Capture
  2. Customer lookup — PartnerMCP: Account ⇄ CUSTOMERS
  3. Schema mapping — PartnerMCP: fields · products · prices
  4. Create / update customer — Priority ERP: CUSTOMERS
  5. Create sales order — Priority ERP: ORDERS + ORDERITEMS_SUBFORM
  6. Monitor order — PartnerMCP: status · delivery · invoice
  7. Sync fulfillment — Priority ERP: DOCUMENTS_D
  8. Sync invoice status — Priority ERP: AINVOICES
  9. Update Opportunity — Salesforce: fulfillment · invoice status
Product preview · sample data
§01—The blueprint

Eight steps, in each system’s own terms.

The Salesforce → Priority flow PartnerMCP plans: who talks to whom, the calls it makes and the rules it follows — taken from Priority’s and Salesforce’s own documentation.

  1. SalesforcePartnerMCP

    The deal closes

    Salesforce Change Data Capture reports the Opportunity change over the Pub/Sub API. PartnerMCP acts on IsWon, not on a stage label — stage names differ from org to org.

    subscribe /data/OpportunityChangeEventfilter IsWon = true
  2. PartnerMCPPriority

    Match the customer

    First by the Priority customer number stored on the Account, then by VAT number, then by name. A match on name alone is never applied without review.

    GET CUSTOMERS('<CUSTNAME>')GET CUSTOMERS?$filter=VATNUM eq '…'GET CUSTOMERS?$filter=contains(CUSTDES,'…')

    VATNUM: confirmed against the tenant's metadata first

  3. PartnerMCPPriority

    Create or update the customer

    Priority assigns or validates the customer number, CUSTNAME. PartnerMCP writes it back to the Account, so the next order matches directly.

    POST CUSTOMERS { CUSTDES, … }PATCH /sobjects/Account/{Id} Priority_Customer_No__c
  4. PartnerMCPPriority

    Guard against duplicates

    Before it creates an order, PartnerMCP looks for one already carrying this Opportunity's reference — kept in a custom column with your four-letter prefix. A replayed event finds it and stops.

    GET ORDERS?$filter=XXXX_SFOPPID eq '<Opportunity.Id>'
  5. PartnerMCPPriority

    Create the sales order

    Lines go into ORDERITEMS_SUBFORM — or through $batch with dependsOn, so a failing line is pinned exactly. Priority prices and taxes the order; PartnerMCP reconciles DISPRICE against Opportunity.Amount instead of overwriting either.

    POST ORDERS { CUSTNAME, ORDERITEMS_SUBFORM: [ … ] }← ORDNAME · ORDSTATUSDES 'Draft'
  6. PrioritySalesforce

    Send fulfillment back

    Shipments are DOCUMENTS_D documents. PartnerMCP polls with $since — or listens to a BPM webhook on shipping status and still reconciles with $since, because webhook retries and ordering aren't documented.

    GET DOCUMENTS_D?$filter=ORDNAME eq '…'GET ORDERS?$since=2026-10-24T07:25:00Z
  7. PrioritySalesforce

    Send invoice status back

    An invoice carries a temporary number until it is finalized; PartnerMCP waits for the permanent IVNUM. In Israel, B2B tax invoices above the threshold also need an allocation number from the Israel Tax Authority.

    GET AINVOICES?$filter=CUSTNAME eq '…'
  8. PartnerMCP

    Keep it running

    Priority Cloud allows 100 API calls a minute per user. PartnerMCP budgets for it, pages every read, holds validation errors for a person and retries only 429 and 5xx.

    429 → back off, resume from the last committed line
§02—Any CRM, any ERP

The same intent, in your ERP’s words.

Not on Priority? Choose your systems. PartnerMCP plans the same flow against each ERP’s own objects, interfaces and limits.

CRM
ERP
Salesforce → Priority
Opportunity · Closed WonCustomer lookupSchema mappingCreate / update customerCreate sales orderMonitor orderSync fulfillmentSync invoice statusUpdate Opportunity
Order-to-cash plan: Salesforce → Priority. Salesforce to Priority ERP.
  1. Opportunity · Closed Won — Salesforce: Trigger · Change Data Capture
  2. Customer lookup — PartnerMCP: Account ⇄ CUSTOMERS
  3. Schema mapping — PartnerMCP: fields · products · prices
  4. Create / update customer — Priority ERP: CUSTOMERS
  5. Create sales order — Priority ERP: ORDERS + ORDERITEMS_SUBFORM
  6. Monitor order — PartnerMCP: status · delivery · invoice
  7. Sync fulfillment — Priority ERP: DOCUMENTS_D
  8. Sync invoice status — Priority ERP: AINVOICES
  9. Update Opportunity — Salesforce: fulfillment · invoice status
Product preview · sample data
The same order-to-cash flow in each ERP's own objects
InterfaceREST (OData v4)Published OData APIsSuiteTalk REST + SuiteQL
CustomerCUSTOMERSA_BusinessPartnercustomer
Sales orderORDERS + ORDERITEMS_SUBFORMA_SalesOrder + A_SalesOrderItemsalesOrder
ShipmentDOCUMENTS_DA_OutbDeliveryHeaderitemFulfillment
InvoiceAINVOICESA_BillingDocumentinvoice
Changes$since polling · BPM webhooksBusiness events (SAP Event Mesh)SuiteScript user events · SuiteQL polling
Rules it respects100 calls/min per API user · $batch ≤ 100, no rollbackCSRF token on writes · ETag in If-MatchAccount-wide concurrency · SOAP gone in 2028.2
§03—Mapping

It maps meaning, not names.

In Priority, CUSTNAME is the customer number and CUSTDES is the name — a string matcher gets it backwards. And some values aren’t written at all: they’re computed by the ERP and reconciled.

Salesforce

Priority ERP

Account.Name
CUSTOMERS.CUSTDESCustomer Name✓ meaning
CUSTOMERS.CUSTNAMECustomer No. — the key, ≤ 16 chars✗ name only

The obvious match is the wrong one. Priority’s own metadata describes CUSTNAME as the Customer Number.

  • Account.WebsiteCUSTOMERS.HOSTNAME
  • OpportunityLineItem.QuantityORDERITEMS_SUBFORM.TQUANT
  • Opportunity.Amountnot written
The full Salesforce → Priority mapping
Order totals
Priority orderOpportunity.AmountORDERS.DISPRICE
  • SO2600041212,400.0012,400.00

    Reconciled · ORDNAME and TOTPRICE written back

  • SO260004159,800.009,310.00

    Held · 5% header discount (PERCENT) set in Priority

Never written into Priority: TOTPRICE. Priority prices and taxes the order itself; PartnerMCP compares the totals, then writes them back to Salesforce.

Product preview · sample data
§04—Details

The details that make or break it.

CRM-to-ERP projects tend to stall on the same things. PartnerMCP plans for them before the first run.

  • 01

    The business logic lives in Priority

    Triggers and BPM run on every write, so an integration has to act like a user. PartnerMCP writes through the REST API — a wrapper around Priority's forms — and never inserts into tables directly.

  • 02

    Every tenant is customised

    Form and column names can be installation-specific. PartnerMCP discovers each tenant from its own metadata, and refreshes after a customisation with ClearEntityMetadata.

  • 03

    Priority assigns the numbers

    ORDNAME and IVNUM come from Priority, and invoice numbers change at finalization. The spec stores both systems' keys and waits for the permanent number.

  • 04

    Someone has to own the price

    Priority price lists or Salesforce price books? PartnerMCP asks — then either sends PRICE or lets Priority price each line from the customer's price list.

  • 05

    Limits and licences are real

    100 calls a minute per API user on Priority Cloud, metered transactions, separate modules for webhooks and ODBC. The plan budgets for the tenant you actually have.

  • 06

    Statuses are tenant-defined

    Order statuses are configured per company — and a Hebrew-language company returns them in Hebrew. PartnerMCP maps them from the tenant's own list instead of hard-coding “Closed”.

  • 07

    Hebrew, direction and time zones

    Hebrew text values, direction tags in text forms, company time-zone offsets. $since cursors use UTC, so daylight saving never skips a change.

  • 08

    Knowledge shouldn't walk out the door

    Older file-drop integrations often depend on the one person who built them. A readable spec and its version history keep the knowledge with the company.

§05—FAQ

Questions

Does this work with Priority on-prem?

Yes, through a path you approve. Priority's REST service is part of its application server, so an on-prem installation can be reached through a reverse proxy or VPN you already run — or through the Edge Agent, an outbound-only architecture concept — instead of publishing the ERP to the internet.

Which Priority modules does it need?

The API module, an API licence for the integration user and transaction packages for writes. The Webhooks module is optional: without it, PartnerMCP detects changes with $since polling on documents.

Does it use Priority's MCP server?

Where it fits. Priority's MCP server runs on Priority Cloud from version 26.0 and is request/response only, without form Actions — so PartnerMCP can use it for lookups and keeps order creation and change tracking on the REST API.

We use HubSpot, or SAP, or NetSuite. Same thing?

Same flow, in each system's own objects and rules — HubSpot deals, SAP business partners and sales orders, NetSuite customers and sales orders. Pick the pair above to see the plan.

Does this replace our Priority partner?

No. Integrators can build with PartnerMCP too — it does the repetitive work and leaves the judgment calls, the review and the client relationship with them.

§06Build

Try it with your Salesforce and your Priority.

Describe the flow in your own words — or start from this one. You’ll see PartnerMCP’s plan and mappings before anything is built.