Skip to content

eCommerce API (B2B / XBG)

The eCommerce API — internally referred to as XBG (the schema files reference C:\XBG\Schemas\...) or B2BSeller — is Prophet 21's original XML message-based integration layer for B2B commerce websites. It predates and is architecturally unrelated to the modern OData, Transaction, Interactive, and Entity APIs documented elsewhere on this site. If you're integrating a storefront, customer portal, or punchout catalog with P21 — rather than building an internal tool or business rule — this is very likely the API your integration already uses or should use.

Source material

This section is reconstructed from two sources: the official eCommerce Services manual (v12.12, Epicor University, 2013) and the actual XSD-backed XML message templates supplied by our eCommerce vendor. The templates are the source of truth for field names — some fields they contain (noted below) postdate the 2013 manual and have no official prose description. Field purposes for those are inferred from naming and context; verify against a live response before relying on them for anything business-critical.


How the API Works

Unlike the REST/UI-server APIs, there is no fixed URL-per-resource pattern here. Each operation is a single XML message type — a root element (e.g. GetItemPrice) containing a <Request>, a <Reply>, and a <ReplyStatus> block:

<GetItemPrice xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:noNamespaceSchemaLocation="C:\XBG\Schemas\XBGGetItemPrice.xsd">
  <Request>
    <!-- fields you populate -->
  </Request>
  <Reply>
    <!-- P21 populates this on response; leave empty in the request -->
  </Reply>
  <ReplyStatus>
    <Result>0</Result>
    <Message />
  </ReplyStatus>
</GetItemPrice>

Your storefront builds the XML string, posts it to Epicor's B2B middleware, and gets the same document back with <Reply> and <ReplyStatus> populated. The transport endpoint/URL and whether it's exposed as SOAP or a raw HTTP POST is not present in the source files we have — that's environment-specific configuration on the middleware side. If you're standing up a new integration, get that from whoever manages the B2BSeller/middleware install (see Internal once we have it documented).

Web Service Groupings

The manual groups the messages into five logical services. The service names below don't always match the XML root element names 1:1 — the mapping is included because it trips people up when cross-referencing the manual against the schema files:

Service Manual's method name Actual XML message (this doc)
ItemServices GetItemLocations GetItemLocations
GetItemPrice GetItemPrice
OrderServices OrderImport OrderImport
CalculateCartInfo GetCartSummary
GetOpenAR GetMyAccountOpenAR
GetOpenOrders GetMyAccountOrders
GetOrderDetail GetMyAccountOrdersDetail
GetOpenAQuote GetMyAccountOpenQuotes / ...Detail
TrackOrder no template provided — likely reuses OrdersDetail/shipment data
PurchaseServices GetPastPurchases GetMyAccountPurchaseHistory
GetPurchaseDetail GetMyAccountPastPurchaseDetail
InvoiceServices GetAccountInvoices GetMyAccountInvoices
GetInvoiceDetail GetMyAccountInvoicesDetail
CustomerServices CustomerImport CustomerImport
GetCustomerInfo GetCustomer
GetCustomerShipToInfo GetCustomerShipTo
GetCustomerControlInfo GetCustomerControl

Also present but not grouped in the manual's service list: ShipToImport (create a ship-to independent of an order), GetPriceBreaks, GetRelatedItems, and the four My Account contract messages (GetMyAccountContracts, GetMyAccountContractDetails).


Common Envelope Fields

Every request carries a version block and a few identity fields. These are consistent across all 21 message types:

Field Purpose
B2BSellerVersion/MajorVersion, MinorVersion, BuildNumber Client version identifier. The 2013 manual says to hardcode 5/11/100; treat that as a starting point, not a hard rule — confirm the expected value with the middleware config, since a mismatch can cause requests to be rejected.
CustomerCode The P21 customer_id placing the order / whose data is being queried. Must exist in P21.
StoreName The P21 company ID (e.g. T), not a literal store name — this is the most common point of confusion for new integrators.
WebReferenceNumber A caller-supplied unique number per request. Used as an idempotency/correlation key and, for OrderImport, echoed back to correlate the import with the resulting order.

Pagination Pattern (all "search" and My Account calls)

GetCustomerShipTo, GetItemLocations, and every GetMyAccount* list operation share one pagination scheme:

Field Direction Purpose
PageSize Request Max rows to return in this call.
StartRowID Request Opaque cursor for the page to start from. Leave blank for page 1.
GetTableOfContents Request Set TRUE on the first call for a given search. P21 walks the full result set once and returns a RowID marker for the start of every page in ListOfRowIDs — the "table of contents."
ListOfSortColumns/SortColumn direction="asc|dsc" Request Sort field, using the Reply-side tag name (e.g. ItemID, OrderDate) as the value. Each operation documents its own valid values.
RowCount Reply Total rows matching the criteria (not just this page).
ListOfRowIDs/RowID Reply One opaque marker per page. Store these — to jump to page 3, resend the original request with StartRowID set to the 3rd RowID value and GetTableOfContents set to False. RowID is not a row number; it's an internal composite cursor (often literally the sort key values pipe-concatenated, e.g. KS|||Leawood|||1011016 for a ship-to sort) and must be treated as opaque.

Don't try to compute RowID yourself

We've seen the KS|||Leawood|||1011016 format tempt people into constructing RowID values by hand for deep-linking. Don't — the format isn't documented as stable across operations or P21 versions. Always get it from a prior response.

Result Codes

ReplyStatus/Result is 0 on success. Non-zero codes fall into ranges by functional area:

Range Area Examples
1–99 System / transport 10 unrecognized document type, 50 unrecognized document, 55 document setup failed, 85 HTTP/SOAP error
1000–1999 Validation 1000 a required field was omitted (message includes the field name), 1010 no records matched the query
2000–2999 Order 2000–2025 import/creation failures (2020 specifically means credit card authorization failed, not a general import error), 2030–2075 "could not find X" lookups (location, order #, quote #, item, shipment #, PO #, UOM) scoped to OrderImport/GetCartSummary
3000–3999 Customer 3000/3025 customer creation failed, 30053035 "could not find X" lookups (contact, customer, customer part number, ship-to)
4000–4999 Item 4000/4005/4015 item not found, 4010 location not found, 4020/4025 UOM not found (GetItemPrice), 4030 invalid AgingBasis
9999 Misc Generic warning

ReplyStatus/Message contains the human-readable detail — it interpolates the actual values from your request (e.g. "Could not find ItemID 1000049 for LocationID 1006840"), so log it in full rather than just the Result code.


Pages in This Section

Page Covers Use for
Item Pricing & Availability GetItemPrice, GetPriceBreaks, GetItemLocations, GetRelatedItems Bulk pricing lookupsGetItemPrice accepts a list of items per call
Orders & Cart OrderImport, ShipToImport, GetCartSummary Submitting orders/quotes, cart pricing/tax preview
Customers CustomerImport, GetCustomer, GetCustomerControl, GetCustomerShipTo Customer/contact/ship-to lookups and self-registration
My Account (Self-Service) The 11 GetMyAccount* read operations Order history, invoices, open AR, quotes, contracts, purchase history for a logged-in customer portal