syncProduct

POST /v2/pos/syncProduct

The syncProduct API is called by the POS provider to synchronize with D-Store the product information of a specific store. You can call this API in the following scenarios:

  • Synchronize full product information when creating or updating products. Note that:
    • For each request, pass the latest information for all products in the store because new requests overwrite previous data.
    • Pass only actual products in the store because all synchronized products appear in D-Store Console for merchants to set up their store menu.
  • Update the statuses of single items and modifiers (identified by the value SINGLE or MODIFIER in the products.type field). In this scenario, you can pass only the products that need to be updated. Note that:
    • Specify the required parameters only. Including optional parameters results in D-Store processing the request as a full product information synchronization.
    • If any specified product (identified by products.posProductId) is reused, then the updated product status applies to any groups, combos, or bundles that include this product.

Structure

A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see:

Request parameters

Field

Data type

Required

Description

requestId

String

Yes

The unique ID that is assigned by the POS provider to identify a product synchronization request.

Maximum length: 255 characters

Note: This field is an idempotency key field. For the syncProduct requests that are initiated with the same requestId value, D-Store must return the same result. For details about API idempotency, see the Idempotency chapter.

posAccountId

String

Yes

The unique ID that is assigned by the POS provider to identify a merchant account. This identifier also marks a single digital store that can include multiple store locations.

Maximum length: 255 characters

store

Store

Yes

The store whose product information is to be synchronized or updated.

products

Array<Product>

Yes

The product list of the store. The product quantity must adhere to the following restrictions:

  • Up to 1,500 products for full product information synchronization.
  • Up to 10 products for updating product statuses.

extendInfo

Object

No

An extended attribute that is used to provide additional information if necessary.

Maximum length: 4096 characters

Response parameters

Field

Data type

Required

Description

result

Result

Yes

The result of the API call.

More information

How to handle the result

You might receive different results from D-Store. Follow the instructions in this table to handle the result.

result.resultStatus

result.resultCode

Synchronization status

Actions

S

SUCCESS

Successful

N/A

F

Multiple possible values exist, such as

PROCESS_FAIL,

PARAM_ILLEGAL, etc.

Failed

Take actions according to the result message (specified in the result.resultMessage parameter). For more information, see Result codes.

U

UNKNOWN_EXCEPTION

Unknown

Use the same parameters to retry the syncProduct request. If you keep receiving the same result indicating the unknown status, contact overseas_support@service.alibaba.com.

No result received

Unknown

Use the same parameters to retry the syncProduct request. If you keep receiving no results, contact overseas_support@service.alibaba.com.

Result codes

Result code

Result status

Result message

Further action

SUCCESS

S

success

N/A

PROCESS_FAIL

F

A general business failure occurred. Do not retry.

Contact overseas_support@service.alibaba.com to troubleshoot the issue.

PARAM_ILLEGAL

F

Parameter names or values do not meet the specified requirements. The result message can vary according to the specific error encountered.

Check whether the request parameters, including the header parameters and body parameters, are correct and valid. For more information about the parameters of this API, see the Structure section.

INVALID_API

F

The called API is invalid or not active.

Check whether the correct API name is used when making the API call.

INVALID_SIGNATURE

F

Signature is invalid.

Check whether the public key, signed message, and signature algorithm are as expected.

ACCESS_DENIED

F

Access is denied

Contact overseas_support@service.alibaba.com to troubleshoot the issue.

REQUEST_TRAFFIC_EXCEED_LIMIT

F

The request traffic exceeds the limit.

Reduce the API calling frequency.

UNKNOWN_EXCEPTION

U

An API calling is failed, which is caused by unknown reasons.

Recall the API.

Request examples

Sync full product information

The following sections show how to construct request bodies for synchronizing full product information according to the product types:

Basic example

The following figure shows the structure of a basic example where the product includes a single item (chicken burger) without any modifiers.

image.png

Then, the request example is shown below.

copy
{
  "requestId":"20231220bsefibb334",
  "posAccountId": "bk001",
  "store": {
    "posStoreId": "s1",
    "name": "s1-name"
  },
  "products": [
    {
      "posProductId": "p1",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "chicken burger",
      "price": {"currency": "SGD", "value": 1000}
    }
  ]
}

Modifier group

The following figure shows the data structure of an example where the product includes a single item (cola) with a modifier (with ice or without ice).

image.png

Then, the request example is shown below.

copy
{
  "requestId":"20231220bsefibb334",
  "posAccountId": "bk001",
  "store": {
    "posStoreId": "s1",
    "name": "s1-name"
  },
  "products": [
    {
      "posProductId": "p1",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "cola",
      "price": {"currency": "SGD", "value": 1000},
      "subProducts": ["g1"]
    },
    {
      "posProductId": "g1",
      "type": "GROUP",
      "status": "AVAILABLE",
      "name": "ice",
      "quantityRule": {"min": 0, "max": 1},
      "subProducts": ["p2", "p3"]
    },
    {
      "posProductId": "p2",
      "type": "MODIFIER",
      "status": "AVAILABLE",
      "name": "with ice",
      "price": {"currency": "SGD", "value": 0},
      "quantityRule": {"min": 0, "max": 1}
    },
    {
      "posProductId": "p3",
      "type": "MODIFIER",
      "status": "AVAILABLE",
      "name": "without ice",
      "price": {"currency": "SGD", "value": 0},
      "quantityRule": {"min": 0, "max": 1}
    }
  ]
}

Nested modifiers

The following figure shows the data structure of an example where the product includes a single item (coffee) with one modifier added to another, which is also called nested modifiers. In this example, one modifier of coffee is hot/cold (hot or cold) and another modifier (with ice or without ice) is added to cold.

image.png

Then, the request example is shown below.

copy
{
  "requestId":"20231220bsefibb334",
  "posAccountId": "bk001",
  "store": {
    "posStoreId": "s1",
    "name": "s1-name"
  },
  "products": [
    {
      "posProductId": "p1",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "coffee",
      "price": {"currency": "SGD", "value": 0},
      "subProducts": ["g1"]
    },
    {
      "posProductId": "g1",
      "type": "GROUP",
      "status": "AVAILABLE",
      "name": "hot/cold",
        "quantityRule": {"min": 0, "max": 1},
      "subProducts": ["p1-1", "p1-2"]
    },
    {
      "posProductId": "p1-1",
      "type": "MODIFIER",
      "status": "AVAILABLE",
      "name": "hot",
        "price": {"currency": "SGD", "value": 500},
      "quantityRule": {"min": 0, "max": 1}
    },
    {
      "posProductId": "p1-2",
      "type": "MODIFIER",
      "status": "AVAILABLE",
      "name": "cold",
        "price": {"currency": "SGD", "value": 700},
      "quantityRule": {"min": 0, "max": 1},
      "subProducts": ["g2"]
    },
    {
      "posProductId": "g2",
      "type": "GROUP",
      "status": "AVAILABLE",
      "name": "ice",
      "quantityRule": {"min": 0, "max": 1},
      "subProducts": ["p5", "p6"]
    },
    {
      "posProductId": "p5",
      "type": "MODIFIER",
      "status": "AVAILABLE",
      "name": "with ice",
      "price": {"currency": "SGD", "value": 0},
      "quantityRule": {"min": 0, "max": 1}
    },
    {
      "posProductId": "p6",
      "type": "MODIFIER",
      "status": "AVAILABLE",
      "name": "without ice",
      "price": {"currency": "SGD", "value": 0},
      "quantityRule": {"min": 0, "max": 1}
    }
  ]
}

Variant product

The following figure shows the data structure of an example where the product includes single items (short coffee, tall coffee, and grande coffee) that share a common modifier (with ice or without ice). This kind of product is also called a variant product.


image.png

Then, the request example is shown below.

copy
{
  "requestId":"20231220bsefibb334",
  "posAccountId": "bk001",
  "store": {
    "posStoreId": "s1",
    "name": "s1-name"
  },
  "products": [
    {
      "posProductId": "p1",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "coffee",
      "price": {"currency": "SGD", "value": 0},
      "subProducts": ["g1"]
    },
    {
      "posProductId": "g1",
      "type": "GROUP",
      "status": "AVAILABLE",
      "name": "size",
      "quantityRule": {"min": 1, "max": 1},
      "subProducts": ["p1-1", "p1-2", "p1-3"]
    },
    {
      "posProductId": "p1-1",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "short",
      "price": {"currency": "SGD", "value": 500},
      "quantityRule": {"min": 0, "max": 1000},
      "overloads": [
        {
          "posProductIds": ["g1"],
          "quantityRule": {"min": 0, "max": 1}
        }
      ],
      "subProducts": ["g2"]
    },
    {
      "posProductId": "p1-2",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "tall",
      "price": {"currency": "SGD", "value": 700},
      "quantityRule": {"min": 0, "max": 1000},
      "overloads": [
        {
          "posProductIds": ["g1"],
          "quantityRule": {"min": 0, "max": 1}
        }
      ],
      "subProducts": ["g2"]
    },
    {
      "posProductId": "p1-3",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "grande",
      "price": {"currency": "SGD", "value": 900},
      "quantityRule": {"min": 0, "max": 1000},
      "overloads": [
        {
          "posProductIds": ["g1"],
          "quantityRule": {"min": 0, "max": 1}
        }
      ],
      "subProducts": ["g2"]
    },
    {
      "posProductId": "g2",
      "type": "GROUP",
      "status": "AVAILABLE",
      "name": "ice",
      "quantityRule": {"min": 0, "max": 1},
      "subProducts": ["p5", "p6"]
    },
    {
      "posProductId": "p5",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "with ice",
      "price": {"currency": "SGD", "value": 0},
      "quantityRule": {"min": 0, "max": 1}
    },
    {
      "posProductId": "p6",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "without ice",
      "price": {"currency": "SGD", "value": 0},
      "quantityRule": {"min": 0, "max": 1}
    }
  ]
}

Combo meal

The following figure shows the data structure of an example where the product includes combination items (burger and beverage). This kind of product is also called a combo meal.

image.png

In this example, ensure to specify the following request parameters correctly:

  • products.overloads.price.value: Set to the price of the specific single item in the combo meal, which is always lower than the price of the single item. For example, the price of a chicken burger is 1000 while that in the combo meal is 0.
  • products.overloads.quantityRule: Set the quantity rule for the bundle, which is always different from that of the single item.

Then, the request example is shown below.

copy
{
  "requestId":"20231220bsefibb334",
  "posAccountId": "bk001",
  "store": {
    "posStoreId": "s1",
    "name": "s1-name"
  },
  "products": [
    {
      "posProductId": "p1",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "burger set meal",
      "price": {"currency": "SGD", "value": 2000},
      "subProducts": ["g1", "g2"]
    },
    {
      "posProductId": "g1",
      "type": "GROUP",
      "status": "AVAILABLE",
      "name": "burger",
      "quantityRule": {"min": 1, "max": 2},
      "subProducts": ["p2", "p3"]
    },
    {
      "posProductId": "p2",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "chicken burger",
      "price": {"currency": "SGD", "value": 1000},
      "quantityRule": {"min": 0, "max": 1000},
      "overloads": [
        {
          "posProductIds": ["g1"],
          "price": {"currency": "SGD", "value": 0},
          "quantityRule": {"min": 1, "max": 2}
        }
      ]
    },
    {
      "posProductId": "p3",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "cheese burger",
      "price": {"currency": "SGD", "value": 1500},
      "quantityRule": {"min": 0, "max": 1000},
      "overloads": [
        {
          "posProductIds": ["g1"],
          "price": {"currency": "SGD", "value": 500},
          "quantityRule": {"min": 0, "max": 1}
        }
      ]
    },
    {
      "posProductId": "g2",
      "type": "GROUP",
      "status": "AVAILABLE",
      "name": "beverage",
      "quantityRule": {"min": 0, "max": 1},
      "subProducts": ["p4", "p5"]
    },
    {
      "posProductId": "p4",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "cola",
      "price": {"currency": "SGD", "value": 1500},
      "quantityRule": {"min": 0, "max": 1000},
      "overloads": [
        {
          "posProductIds": ["g2"],
          "price": {"currency": "SGD", "value": 0},
          "quantityRule": {"min": 0, "max": 1}
        }
      ]
    },
    {
      "posProductId": "p5",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "blank tea",
      "price": {"currency": "SGD", "value": 2000},
      "quantityRule": {"min": 0, "max": 1000},
      "overloads": [
        {
          "posProductIds": ["g2"],
          "price": {"currency": "SGD", "value": 500},
          "quantityRule": {"min": 0, "max": 1}
        }
      ]
    }
  ]
}

Bundle

The following figure shows the data structure of an example where the product includes a bundle of single items (different types of coffee).

image.png

In this example, ensure to specify the following request parameters correctly:

  • products.overloads.price.value: Set to the price of a cup of coffee in the bundle, which is always lower than the price of the single item.
  • products.overloads.quantityRule: Set the quantity rule for the bundle, which is always different from that of the single item.

Then, the request example is shown below.

copy
{
  "requestId":"20231220bsefibb334",
  "posAccountId": "bk001",
  "store": {
    "posStoreId": "s1",
    "name": "s1-name"
  },
  "products": [
    {
      "posProductId": "p1",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "two cups of coffee",
      "price": {"currency": "SGD", "value": 1500},
      "subProducts": ["g1"]
    },
    {
      "posProductId": "g1",
      "type": "GROUP",
      "status": "AVAILABLE",
      "name": "beverage",
      "quantityRule": {"min": 2, "max": 2},
      "subProducts": ["p2"]
    },
    {
      "posProductId": "p2",
      "type": "SINGLE",
      "status": "AVAILABLE",
      "name": "coffee",
      "price": {"currency": "SGD", "value": 1000},
      "quantityRule": {"min": 0, "max": 1000},
      "overloads": [
        {
          "posProductIds": ["g1"],
          "price": {"currency": "SGD", "value": 0},
          "quantityRule": {"min": 2, "max": 2}
        }
      ]
    }
  ]
}

Update product status

The following sections show how to construct request bodies for updating product statuses for single items and modifiers respectively:

Single items

The following figure shows an example of a single item (chicken burger) that is included in both the chicken burger combo meal and the burger combo meal. If you update its status from AVAILABLE to SOLDOUT, this update affects the chicken burger within both combo meals.

image.png

The product status update request for this example is shown as follows:

copy
{
  "requestId":"20231220bsefibb334",
  "posAccountId": "bk001",
  "store": {
    "posStoreId": "s1"
  },
  "products": [
    {
      "posProductId": "p1",
      "status": "SOLDOUT"
    }
  ]
}

Modifiers

The following figure shows an example of a modifier (with ice) that is available for both cola and sprite. If you update its status from AVAILABLE to SOLDOUT, this update affects the with ice modifier within both beverages.

image.png

The product status update request for this example is shown as follows:

copy
{
  "requestId":"20231220bsefibb334",
  "posAccountId": "bk001",
  "store": {
    "posStoreId": "s1",
    "name": "s1-name"
  },
  "products": [
    {
      "posProductId": "M1",
      "status": "SOLDOUT",
    }
  ]

Sample codes

The following sections provide sample codes for different syncProduct request scenarios:

Sync full product information

To speed up your development and testing, D-Store offers full sample codes of the syncProduct API for synchronizing full product information. You can directly copy and paste the sample codes into your local codes and customize them if necessary.

Request body

Use the following code to construct a request body.

copy
{"requestId":"20231220bsefibb334","posAccountId":"bk001","store":{"posStoreId":"s1","name":"s1-name"},"products":[{"posProductId":"p1","type":"SINGLE","status":"AVAILABLE","name":"green tea","price":{"currency":"SGD","value":1000}}]}

Request signing

To sign a syncProduct request, put the following signature in the request header.

copy
EVCRST9tbtIaCqYvozPbVhi7d0D5rfdIHUUh6fIjx7nf9%2FeCbkRFrxoCOzzp3ac%2FcMhQnxtmvYZFOQDLAmhzUjhB68Z3bMm0O03wqPExowRlDHGFPWJL8bmgUQMGyblViAfCaSjCcpCa1C%2Fk6A6CCaAAh9MRMNQZ8X36lS5f64Db07IIKIJ53aqDl40y4MNUcJiY3nDmOZeVxATUubKc8HnZgm2IkgxEOqRpodP%2FWAyZq8iHR4rID%2B4xeQDGdPTlRg3Z3G15lebb38yuukgcYE337rYjMgENTDol3rWz1ZTMJ5pwPxWkT5rlqE%2FG55tyDf6dfy%2BxK3bt9JLvL3bb8A%3D%3D

The signature above is generated according to the common private key obtained in the Exchange sandbox resources step and the request body above If you use your own private key or customize the request body, refer to Sign a request to generate a new signature.

Request calling

After signing a request, use the following code to call a syncProduct request.

copy
curl --location 'https://open-region-pre.alipayplus.com/v2/pos/syncProduct' \
--header 'content-type: application/json' \
--header 'client-id: 375Y903U2Y45KE00600' \
--header 'request-time: 2022-10-10T23:00:56+08:00' \
--header 'signature: algorithm=RSA256,keyVersion=1,signature=EVCRST9tbtIaCqYvozPbVhi7d0D5rfdIHUUh6fIjx7nf9%2FeCbkRFrxoCOzzp3ac%2FcMhQnxtmvYZFOQDLAmhzUjhB68Z3bMm0O03wqPExowRlDHGFPWJL8bmgUQMGyblViAfCaSjCcpCa1C%2Fk6A6CCaAAh9MRMNQZ8X36lS5f64Db07IIKIJ53aqDl40y4MNUcJiY3nDmOZeVxATUubKc8HnZgm2IkgxEOqRpodP%2FWAyZq8iHR4rID%2B4xeQDGdPTlRg3Z3G15lebb38yuukgcYE337rYjMgENTDol3rWz1ZTMJ5pwPxWkT5rlqE%2FG55tyDf6dfy%2BxK3bt9JLvL3bb8A%3D%3D' \
--data '{"requestId":"20231220bsefibb334","posAccountId":"bk001","store":{"posStoreId":"s1","name":"s1-name"},"products":[{"posProductId":"p1","type":"SINGLE","status":"AVAILABLE","name":"green tea","price":{"currency":"SGD","value":1000}}]}'

If you customize the request body and the signature, replace <requestBody> and <generatedSignature> in the following code with the customized ones.

copy
curl --location 'https://open-region-pre.alipayplus.com/v2/pds/store/syncProduct' \
--header 'content-type: application/json' \
--header 'client-id: 375Y903U2Y45KE00600' \
--header 'request-time: 2022-10-10T23:00:56+08:00' \
--header 'signature: algorithm=RSA256,keyVersion=1,signature=<generatedSignature>' \
--data '<requestBody>'

Response body

If the API call succeeds, the syncProduct response body is returned as the following code.

copy
{"result":{"resultCode":"PARAM_ILLEGAL","resultMessage":"Illegal parameters. For example, non-numeric input, invalid date.","resultStatus":"F"}}

Update product status

Request body

The following sample code shows that the POS provider updates the status of a product to AVAILABLE:

copy
{
    "requestId":"20231220bsefibb334",
    "posAccountId":"bk001",
    "store":{
        "posStoreId":"s1"
    },
    "products":[
        {
            "posProductId":"p1",
            "status":"AVAILABLE"
        }
    ]
}

Response body

The following sample code shows that D-Store handles the update request successfully:

copy
{
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success",
    "resultStatus": "S"
  }
}