Customers¶
Covers CustomerImport, GetCustomer, GetCustomerControl, and GetCustomerShipTo — the CustomerServices messages. These handle self-registration/updates and the lookups a storefront needs before a customer can check out (billing address, ship-tos, credit/contract eligibility).
See eCommerce API overview for the shared envelope fields, pagination pattern, and result codes.
CustomerImport¶
Creates a new customer, or updates an existing one if CustomerCode is populated with an existing ID. If CustomerCode is omitted, P21 assigns one and returns it.
File-based import pipeline
Per the manual, the request gets written to a flat file named CustomerCode.lock, renamed to CustomerCode.cust once complete, imported into P21, then renamed to CustomerCode.cust.comp on success or CustomerCode.cerror on failure. This is background/internal detail — you don't interact with the files directly — but it explains why customer creation, like OrderImport, is not necessarily synchronous.
Request Fields¶
| Field | Required | Notes |
|---|---|---|
CustomerCode | No | Omit to have P21 generate one. |
CompanyName | No | Present in current schema, not in the 2013 manual. |
TemplateCustomerCode | No | An existing customer code to use as a template — P21 copies its defaults (terms, territory, etc.) onto the new customer. |
StateTaxExemptionNumber | No | |
StateTaxFlag | No | Set N to exempt the customer from state tax. |
PackingBasis | No | Default packing basis for the new customer. |
CustomerBillTo/BillToAddress/*, BillToContactFirstName/LastName/Salutation/Title/Phone/Fax/Email | Yes | Bill-to address and primary contact. BillToState is a 2-character code. |
BillToContactEmail | No | Present in current schema alongside BillToEmail — appears redundant; unclear which one P21 actually persists to. Verify before relying on either. |
ListOfCustomerShipTos/CustomerShipTo/ShipToAddress/*, contact fields | No | Default ship-to(s) for the new customer. |
ListOfOptionalElements/OptionalElement/id,value | No | Generic key/value extension mechanism — populate if your P21 install has custom fields wired to accept import data this way. |
Reply¶
GetCustomer¶
Returns the customer's bill-to information. The simplest of the four customer messages — no pagination, single record.
Request Fields¶
CustomerCode, StoreName, WebReferenceNumber — no operation-specific fields.
Reply¶
<CustomerBillTo>
<BillToAddress>
<BillToCompanyName /><BillToAddress1 /><BillToAddress2 /><BillToAddress3 />
<BillToCity /><BillToState /><BillToZip /><BillToCountry />
</BillToAddress>
<BillToContactFirstName /><BillToContactLastName />
<BillToContactSalutation /><BillToContactTitle />
<BillToPhone /><BillToFax /><BillToEmail />
</CustomerBillTo>
GetCustomerControl¶
Returns customer-level checkout controls and account status — the call a storefront makes right after login to decide what the customer is allowed to do (contract-only ordering? PO required? prepayment required? merchandise credit available?).
Request Fields¶
| Field | Required | Notes |
|---|---|---|
ContactID | No | If populated, contact-specific Element (payment token) accounts are included in the reply. |
GetContracts | No | TRUE to check for active contracts and populate HasContracts. |
ShipToID | No | If populated, P21 also uses it to check for ship-to–specific contracts and to derive SourceLocation. |
CheckForMerchandiseCredits | No | TRUE to populate AvailableCreditAmount / MerchandiseCreditsAvailable. |
OrderTotalStartDate / OrderTotalEndDate | No | Both must be populated together to get a total order amount for that date range back in OrderTotal. |
PriceColumnID | No | Requires B2BSeller / a specific custom feature. |
AllowRestrictedItems | No | Requires B2BSeller. |
Reply — CustomerControl¶
| Field | Notes |
|---|---|
SourceLocation | Derived from ShipToID if given, else from a ship-to matching the customer code, else blank. |
Taxable | |
PORequired | TRUE if the customer must supply a PO # with every order. |
CompanyID | Populated if StoreName was blank in the request; if the customer spans multiple companies, this is the first alphabetically — don't rely on it to mean "the only company." |
HasContracts | Only meaningful if GetContracts=TRUE was requested. |
ContractRequired | TRUE if the customer is configured to require a contract on every order. |
AllowNonContractItems | TRUE if non-contract items are still allowed alongside contract items. |
UseAllContracts | TRUE if line-item-level contracts are allowed (vs. one contract per order). |
AvailableCreditAmount | Only populated if CheckForMerchandiseCredits=TRUE. |
MerchandiseCreditsAvailable | Same condition. |
PrimarySalesRep/FirstName,LastName | |
PrepaymentRequired | TRUE when the validate_pymt_req_for_web_pymt system setting is on and the customer's req_pymt_upon_release_of_items flag is Y — if TRUE, force credit card checkout for this customer. |
ResaleCertificate | TRUE if a resale certificate is on file. |
CustomerName | |
ListOfElementAccounts/ElementAccount/ElementAccountSource,ElementAccountID,ElementMaskedCreditCard,ElementCreditCardExp,ElementPaymentType | Stored payment tokens. ElementAccountSource is CUSTOMER or CONTACT — contact-level tokens only appear if ContactID was in the request. |
CustomerActive | INACTIVE when credit_status.order_entry_action = 'E' (customer blocked from ordering online); ACTIVE otherwise. |
OrderTotal | Only populated if OrderTotalStartDate/EndDate were both set. |
SalesLocation | |
Password, PreferredCustomer, UseAccount, ListOfCommonIDs, PriceMultiplier, MaximumNumberOfOrdersAction | Present in schema but not supported by P21 — these exist for a different ERP the same B2B platform also targets. Expect them blank/unused on a P21 install. |
ListOfEFTInformation/EFTInformation/* | ACH/EFT accounts, undocumented in the 2013 manual. |
Call this before rendering checkout, not just after login
PrepaymentRequired, ContractRequired, and PORequired all change what the checkout UI needs to demand from the customer. If your storefront caches GetCustomerControl at login only, a mid-session change to any of these (e.g. credit hold triggering PrepaymentRequired) won't be reflected until next login — call it again at checkout if that risk matters for your flow.
GetCustomerShipTo¶
Returns the customer's ship-to addresses. Paginated — see the pagination pattern.
Request Fields¶
| Field | Required | Notes |
|---|---|---|
ContractUID | No | If populated, only ship-tos associated with that contract are returned. |
GetDefaultShipToOnly | No | Requires B2BSeller — hardcode False unless you specifically need only the default ship-to. |
DefaultShipToID | No | Requires B2BSeller. |
SearchText / SearchColumns | No | Present in current schema, undocumented — filter ship-tos by free-text search against specified columns. |
ListOfSortColumns/SortColumn | No | Valid values: ShipToId, ShipToCompanyName, ShipToAddress1, ShipToCity, ShipToState. |
Reply — ListOfCustomerShipTos/CustomerShipTo¶
| Field | Notes |
|---|---|
ShipToID | |
ShipToAddress/* | Standard address block. |
ShipToEMail, ShipToFax, ShipToPhone | |
ShipToContactFirstName/LastName/Salutation/Title, ShipInstructions, SalesLocation | Not supported by P21 per the manual — always blank on a P21 install. |
SourceLocation | Default source location for orders shipped to this address. |
FreightCode | |
FreeIncomingFreightMinimum / FreeOutgoingFreightMinimum | Order minimums for free freight, incoming/outgoing. |
DefaultShipToID also appears at the reply root (in addition to per-ship-to), plus the standard RowCount / ListOfRowIDs pagination fields.
Example¶
<GetCustomerShipTo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="C:\XBG\Schemas\XBGGetShipTo.xsd">
<Request>
<B2BSellerVersion><MajorVersion>5</MajorVersion><MinorVersion>11</MinorVersion><BuildNumber>100</BuildNumber></B2BSellerVersion>
<CustomerCode>100000</CustomerCode>
<StoreName>COS</StoreName>
<WebReferenceNumber>1</WebReferenceNumber>
<PageSize>10</PageSize>
<GetTableOfContents>True</GetTableOfContents>
<ListOfSortColumns>
<SortColumn direction="dsc">ShipToId</SortColumn>
</ListOfSortColumns>
</Request>
<Reply />
<ReplyStatus><Result>0</Result><Message /></ReplyStatus>
</GetCustomerShipTo>