Platform API Endpoint: Procure And Send Purchase Order To Supplier
Within the SQUIZZ.com Application Programming Interface (API) it contains an endpoint that allows one organisation using 3rd party software to talk to the SQUIZZ.com API, to push up a purchase order and have it be procured by a connected organisation. This allows one organisation to buy products off another supplying organisation, using the API endpoint to automate the ordering process. To use the API endpoint you will need to have knowledge in building software applications, and how to make requests over the internet to call RESTful web services, which the platform's API endpoint is based on.
Before reading on please ensure that you have understood the following topics:
The endpoint is used by a customer organisation to push one or more purchase orders into the platform and have it procured by a designated supplier organisation. "Procure" means for the customer organisation to find and buy goods/services off the supplying organisation. This endpoint allows a customer organisation to automate purchasing off selected supplier organisations registered in the platform. Additionally it helps a supplier organisations to automate selling to existing customer organisations.
The endpoint will look through each purchase order given to it and try to find matching products that the chosen supplying organisation sells. Once all ordered products have been matched then the endpoint will price each product based on the quantities, relationship and customer account that the supplier organisation has assigned to the customer organisation. Only if all products in the purchase orders have been priced will the endpoint then create one or more sales orders for the supplier organisation and have the sales orders be marked as submitted for processing by the supplier organisation. The endpoint will then return each of the sales orders that were created, allowing the customer organisation to know the costs of the sales order and be able to update the purchase order based on the sales order totals.
Optionally the endpoint may also forward on the generated sales order to the supplier's nominated freight provider's ssytem, from where it may create a consignment note or other freight artifacts.
To use this endpoint the following conditions need to be met:
- The customer organisation needs to be connected to the supplier organisation on the SQUIZZ.com platform.
- The supplier organisation's Trading Status must be set to Fully Trading or Selling Only.
- The customer organisation's Trading Status must be set to Fully Trading or Buying Only.
- The supplier organisation needs to have assigned at least one customer account to the customer organisation
- The assigned customer account needs to have an "On Account" payment type set, allowing the customer organisation to pay for the ordered products at a later date, based on agreed terms with the supplier organisation.
- The assigned customer account must be active and allow orders to be created against it (not on hold or outside terms and limits).
- Every product in the purchase orders must match to the supplying organisation's products based on either of the following:
- The customer's product code matches supplier's product code
- The customer's product is assigned to an alternate code that matches the supplier's product code, and the alternate codes have been previously imported into the platform by the customer organisation.
- The customer's product has previously been mapped to the supplier's product based on a previous order being submitted, either through this endpoint, or by a person using the Order Procurement feature within the platform.
- The supplier organisation is able to price all matched products in the purchase orders.
- The supplier organisation has enough trading tokens in the platform for the sales order transaction.
The purchase orders being imported must be placed into the Body of the HTTP request in the form of a conforming Ecommerce Standards Purchase Order Document JSON string. Before using this endpoint we recommend that you understand what the Ecommerce Standards Documents are and how you can convert purchase order data from your system into the standards document. It is highly recommended that any purchase order data uploaded using this endpoint be compressed using the GZIP compression algorithm. Note that there are trading token costs to the supplier organisation to have the sales orders created, of which the supplier organisation must have enough tokens to allow to do. For suppliers see the Trading Tokens and Pricing page for more details.
|api-org-key||Conditional, only set this heading if create_single_request_session parameter is set to Y. Set it to the API key of the organisation sending the purchase order to authentic the request.|
|api-org-pw||Conditional, only set this heading if create_single_request_session parameter is set to Y. Set it to the API password of the organisation sending the purchase order to authentic the request.|
|session_id||STRING||Yes||ID of the API session. Place the session ID within the URL|
|supplier_org_id||STRING||Yes||ID of the organisation in the platform that is to supply the goods and services|
|customer_account_code||STRING||No||Code of the supplying organisation's customer account. The account code is only required if the supplying organisation has assigned multiple customer accounts to the customer organisation calling the endpoint.|
|create_single_request_session||ENUM(Y,N)||No||If set to Y, then indicates that this endpoint is being called without any session being created first, and that api credentials have been passed in the HTTP request headers to authenticate the request. If the correct credentials are given then a session will be created for just the order import then once finished the session will be destroyed. This in effect allows systems to authenticate and send purchase orders in the same request, which may be required when systems have no way of retaining session data between HTTP requests. Note that this option will cause the request to take longer to process due to the additional authentication checks that need to be made. If this parameter is set to Y then the value of the session_id in the URL will be ignored.|
|convert_from_document||ENUM('XCBL3.0')||No||If set to XCBL3.0 then the contents of data placed in the body of the HTTP request will be treated as a purchase order in the XML file format conforming to the xCBL version 3.0 data format. If this parameter is not set then the data in the body must conform to the Purchase Order Ecommerce Standards Document JSON format. Only set this parameter to XCBL3.0 if the system sending the purchase order has no ability to sending purchase orders in the Ecommerce standards, which is preferred data format.|
|response_http_error_code||INTEGER||No||Set to a HTTP response status code that should be returned if any error occurs when calling the endpoint. The system calling this endpoint may require a non 200-OK response code to be returned in the response to identify a failed order procurement attempt. It is preferred for systems to parse the JSON response returned by this endpoint instead of using HTTP response status codes to determine if orders were successfully processed. This allows systems to more accurately report what error occurred. Where that is not possible then set the parameter in the URL.|
|Body||JSON||Yes||Body contains a Purchase Order Ecommerce Standards Document that has one or more purchase order records. The document is serialized into its JSON data string.
If the convert_from_document parameter is set to Y then the body instead should be an XML purchase order conforming to the xCBL3.0 data format (note that is is not preferred due to the limitations of that data standard).
Example Raw HTTP Request
POST https://api.squizz.com/rest/1/org/procure_purchase_order_from_supplier/402934A8234E1B997D51F23974?supplier_org_id=342429EDABC3432498737 HTTP/1.1
"message":"The purchase order data has been successfully obtained.",
"deliveryAddress2":"22 Bourkie Street",
"billingOrgName":"Acme Industries International",
"instructions":"Leave goods at the back entrance",
"productName": "Green tea towel - 30 x 6 centimetres" ,
"productName": "Blue tea towel - 30 x 6 centimetres",
|Response Data Type||JSON|
|result||ENUM (SUCCESS or FAILURE)||Either "SUCCESS" or "FAILURE". If successful then the data was imported into the platform against the organsiation.|
|configs.api_version||DECIMAL||Version of the SQUIZZ.com platform's API used to handle the request|
Status code of trying to import the ESD document data. The following codes could be returned:
|configs.orders_with_unmapped_lines||STRING||Contains a comma delimited list of key value pairs (that each are colon delimited) that specifies the index of the purchase order record and the index of the line within the record that could not be matched to a supplier's product, or the customer organisation does not have permission to purchase.
For example if this value was set to "1:2,1:3,4:0", Then it would specify that the 2nd purchase order record (index 1) within the dataRecords array of the purchase orders uploaded in the endpoint request has lines 3 and 4 that have unmapped products (line indexes 2 and 3), and for the 5th purchase order record (record index 4) the 1st order line has an unmapped product (line index 0).
|configs.orders_with_unpriced_lines||STRING||Contains a comma delimited list of key value pairs (that each are colon delimited) that specifies the index of the purchase order record and the index of the line within the record that could not be priced for a supplier's product. This indicates that supplier products were found for the purchase order lines but that the supplier organisation had not set any pricing of the products, based on the customer account that that the customer organisation was assigned to.
For example if this value was set to "2:1,2:3,5:0", Then it would specify that the 3rd purchase order record (index 2) within the dataRecords array of the purchase orders uploaded in the endpoint request has lines 2 and 4 that have unpriced products (line indexes 1 and 3), and for the 6th purchase order record (record index 5) the 1st order line has an un-priced product (line index 0).
|configs.orders_with_unstocked_lines||STRING||Contains a comma delimited list of key value pairs (that each are colon delimited) that specifies the index of the purchase order record and the index of the line within the record that were out of stock for a supplier's product. This indicates that supplier products were found for the purchase order lines but that the supplier organisation had no stock available for the products listed this attribute.
For example if this value was set to "2:1,2:3,5:0", Then it would specify that the 3rd purchase order record (index 2) within the dataRecords array of the purchase orders uploaded in the endpoint request has lines 2 and 4 that have un-stocked products (line indexes 1 and 3), and for the 6th purchase order record (record index 5) the 1st order line has an un-stocked product (line index 0).
|dataRecords||JSON ARRAY||List of Sales Order Ecommerce Standards Records. Each record contains details of the corresponding supplier's sales order that was generated from each purchase order. These details include sales order number, order line pricing, surcharge prices (such as freight and shipping)|
HTTP Response Example:
Purchase Order Record Fields
When making a HTTP request to the API endpoint, in the body of the HTTP request a Purchase Order Ecommerce Standards Document (ESD) needs to be placed in its serialised JSON form, containing one or more purchase order records within it.
Within the retrieved Purchase Order JSON document, each purchase order record is conforms to the Order Purchase ESD Record format. The following table shows the record fields that this endpoint in the SQUIZZ.com API supports and reads from:
|Data Type||Purchase Order Record|
|Field Name||Data Type||Mandatory||Default Value||Max Length||Description|
|keyPurchaseOrderID||STRING||Yes||[EMPTY STRING]||50||Unique identifier of the purchase order that uniquely identifies the order within the customer organisation's system. The keyPurchaseOrderID may be the same as the purchase order code, or may be based on an different internal unique identifier created in a business system's database, such as an auto-incrementing number, UUID, or GUID identifier.|
|keySupplierAccountID||STRING||No||[EMPTY STRING]||50||The unique identifier of the supplier account that the customer organisation has linked to the purchase order.|
|supplierAccountCode||STRING||Yes||[EMPTY STRING]||60||Code the supplier account that has been linked to the purchase order.|
Number of the purchase order, may or may not be a unique identifier of the order.
The code will be used as a reference in the sales order of the supplier organisation, and may be used find the associated supplier sales order.
Date that the order was created. Date is in the form of a number in milliseconds since the 01-01-1970 12:00am Epoch in UTC time-zone, stored as a long integer.
|instructions||STRING||No||[EMPTY STRING]||21,844||Text describing the instructions on how to handle or deliver the order. May contain comments on the order.|
|deliveryOrgName||STRING||No||[EMPTY STRING]||50||Name of the organisation that the ordered products/goods will be delivered to.|
|deliveryContact||STRING||No||[EMPTY STRING]||50||Contact person at the delivery address where the ordered products/goods will be delivered to.|
|deliveryEmail||STRING||No||[EMPTY STRING]||100||Email address that notifications about the order delivery are to be sent to.|
|deliveryAddress1||STRING||No||[EMPTY STRING]||90||1st address field to deliver the ordered products/goods to. Typically set the unit/apartment number, building name, street number and/or street name.|
|deliveryAddress2||STRING||No||[EMPTY STRING]||90||2nd address field to deliver the ordered products/goods to. Typically set the steet number and name within this field.|
|deliveryAddress3||STRING||No||[EMPTY STRING]||90||3rd address field to deliver the ordered products/goods to. Set the suburb, city or town within this field.|
|deliveryRegionName||STRING||No||[EMPTY STRING]||70||Name of the region, state or province to deliver the ordered products/goods to. If the field is not set then it may be auto filled by the platform based on the delivery post code/zip code.|
Name of the country, state or province to deliver the ordered products/goods to.
|deliveryPostcode||STRING||No||[EMPTY STRING]||20||Postcode or zip code that the ordered products/goods are delivered to.|
|billingContact||STRING||No||[EMPTY STRING]||90||Contact person where the order will be billed to.|
|billingOrgName||STRING||No||[EMPTY STRING]||50||Name of the organisation that the order will be billed to.|
|billingEmail||STRING||No||[EMPTY STRING]||100||Email address that notifications about billing of the order are to be sent to.|
|billingAddress1||STRING||No||[EMPTY STRING]||90||1st address field to bill the order to. Typically set the unit/apartment number, building name, street number and/or street name.|
|billingAddress2||STRING||No||[EMPTY STRING]||90||2nd address field to bill the order to. Typically set the steet number and name within this field.|
|billingAddress3||STRING||No||[EMPTY STRING]||90||3rd address field to bill the order to. Set the suburb, city or town within this field.|
|billingRegionName||STRING||No||[EMPTY STRING]||70||Name of the region, state or province to bill the order to. If the field is not set then it may be auto filled by the platform based on the billing post code/zip code.|
|billingCountryName||STRING||No||[EMPTY STRING]||70||Name of the country, state or province to bill the order to.
If the field is not set then it may be auto filled based on the country that the customer organisation is registered to.
|billingPostcode||STRING||No||[EMPTY STRING]||Postcode or zip code that the billing of the order will be sent to.|
|isDropship||ENUM (Y,N)||No||N||1||Denotes if the order should be delivered direct from the supplier to a specified consumer, as set in the delivery fields. If set to Y then the order is marked as a drop ship order. The supplier may put the organisation's name of who is raising this order onto the packaging to make it look like the ordered products/goods came from the requesting organisation.|
|lines||ARRAY (ESDRecordOrderPurchaseLine)||Yes||[Empty ARRAY]||-||An array of Purchase Order Line ESD Records that specify the products/goods that are to be ordered and purchased.|
Purchase Order Line Records
For each Purchase Order Record in the lines property it may store an array of Purchase Order Line Records, with each record specifying one type of product/goods that is to be ordered and a chosen quantity.
Each purchase order line record is conforms to the Order Purchase Line ESD Record format. The following table shows the line record fields that this endpoint in the SQUIZZ.com API supports and reads from:
|Data Type||Purchase Order Line Record|
|Field Name||Data Type||Mandatory||Default Value||Max Length||Description|
|lineType||ENUM (PRODUCT,TEXT)||Yes||[EMPTY STRING]||-||Specifies the type of entities being ordered. Set to PRODUCT to denote that a physical or non-physical product is being purchased. Set to TEXT to denote a text line that may contain additional details or instructions and is not a product that needs to be purchased.|
|keyProductID||STRING||No||[EMPTY STRING]||50||Unique identifier of the product within the customer organisation's system. The keyProductID may be the same as the productCode, or may be based on an different internal unique identifier created in a business system's database, such as an auto-incrementing number, UUID, or GUID identifier.|
Code that allows the product to be identified within the customer organisation's system. Typically this code is unique to each product that the organisation purchases. The product code may also be known as a Stock Keeping Unit (SKU), item number, product ID, or item code in certain systems.
Name of the purchasing organisation's product. The name typically contains natural words that allow it easily understood by people on what the product is, or does.
|quantity||DECIMAL||Yes||0.0000||14,4||The quantity to be ordered/purchased. Set the quantity based on the base sell unit of the supplier organisation's product. If the quantity is set at 0 or less then the quantity will be changed to 1.|
|priceTotalIncTax||DECIMAL||No||0.0000||14,4||The purchaser's expected total price of the line for all quantities ordered, including taxes.|
|priceTotalExTax||DECIMAL||No||0.0000||14,4||The purchaser's expected total price of the line for all quantities ordered, excluding taxes.|
|priceTotalTax||DECIMAL||No||0.0000||14,4||The purchaser's expected total tax cost of the line for all quantities ordered.|
|salesOrderProductCode||STRING||No||[EMPTY STRING]||60||Set to the product code of the supplier organisation's product.
This code may be used to try to match it to one of the supplier organisation's products where an exact match can be found to the supplier's product code.
Frequently Asked Questions
Can partial quantities be ordered of a supplier's product if not all of the quantities specified in the purchase order are in stock?
Whether partial available quantities of a supplier organisation's products can be ordered through the endpoint is based on if the supplier organisation allows out of stock products to be ordered or not. The endpoint can allow orders to go through even when a supplier's product is out of stock, but this can only happen if the supplier has given permission for out-of-stock products to be ordered, known as back ordering.
If the supplier allows back-ordering for each of its products in an order, then it doesn't matter if the products are in stock or not, the order will still go through. If the supplier does not allow back-ordering for a product, and the quantity of the product within the purchase order is greater than the available stock amount then the endpoint would return an error and not process the order (it would not allow a partial quantity to be ordered).
If this second scenario was enforced by the supplier then it would be recommended to call the "Retrieve Organisation Data" endpoint first and get the available stock quantities for the products you wish to order, that way you could check if there was enough products in stock before sending a purchase order, otherwise advise the purchasing person of the out-of-stock products, and to seek alternative options such as ordering from a different supplier or wait to products are back in stock again.
Supplier organisations can set up the permissions for the products that can be back ordered through the use of Data Sharing Policies. Policies can be set to cover the entire customer base, or be assigned to specific customer organisations and people allowing targeted customers to order out of stocked products or not. These same policies also give permission if products can be ordered at all for targeted customered.
Is there an ability to find out the products in a purchase order sent to the endpoint that had no stock available?
Yes, if the procurement endpoint finds a supplier product that is out of stock then the endpoint will return the SERVER_ERROR_ORDER_MAPPED_PRODUCT_STOCK_NOT_AVAILABLE result code, as well as in the "orders_with_unstocked_lines" attribute the index of the lines in the purchase order that contained the unmapped/out of stock products.
When this error occurs a message could be returned to your user, such as "For purchase order X, lines 2,3 and 5 could not be matched up to the supplier's products because the products are out of stock.". You can determine the purchase orders lines that were out of stock by looking at the "configs.orders_with_unstocked_lines" attribute returned by the endpoint that specifies the index of the purchase orders and lines that were a problem.
When a purchase order is sent to the endpoint if one line in the order is unmapped or unpriced will the order still get processed?
No, the endpoint will not be able to process a purchase order and convert it into a supplier's sales order if one or more product lines in the purchase order cannot be mapped or priced to supplier's product. This ensures that supplier organisations only receive accurate and fully qualified orders, allowing for full automation in receiving the order and dispatching the ordered goods and services.
When calling the endpoint and a Product Not Mapped (matched to a supplier's product) or Product Price Not Found error occurs, what should my software do?
If your software calls the endpoint and it returns either SERVER_ERROR_ORDER_PRODUCT_NOT_MAPPED, SERVER_ERROR_ORDER_MAPPED_PRODUCT_STOCK_NOT_AVAILABLE or SERVER_ERROR_ORDER_MAPPED_PRODUCT_PRICE_NOT_FOUND result codes then it indicates that no product from the supplier organisation was able to found, priced, in stock, or able to be purchased. When this occurs there are a number of options that your software could do. The simplest option would be to raise the error with the person who is in charge of purchasing and advise them of errors with the lines. That person could then do the following:
- Enter a different product code to match the supplier's product.
- Choose a different product to purchase off the supplier.
- Remove the line from the purchase order and choose not to purchase the product.
- For stock issues reduce the quantity of the product requesting to be ordered.
- Contact the supplier organisation and determine why a product cannot be purchased (it could be out of stock, no longer stocked, or the supplier is unwilling to sell the product any more).
Alternatively your software could detect when there's an invalid line and make decisions of its own. It could remove the problematic/unmapped line from the purchase order and try to submit it again. It could put the purchase order aside and raise the issues to a purchasing person to fix up at a later date. It could reassign the problematic purchase order lines to a different supplier (if multiple suppliers exist).
The best option really depends on how a business wishes to handle the exceptional circumstance where the products they want to purchase cannot be found against the supplier, or are unavailable for purchasing.