{"templateId":"markdown","versions":[{"version":"opendelivery","label":"Open Delivery API","link":"/apis/opendelivery/docs/author","default":true,"active":false,"folderId":"58c9a61d"},{"version":"standard","label":"Standard Keeta API","link":"/apis/standard/docs/author","default":false,"active":false,"folderId":"58c9a61d"},{"version":"grocery","label":"Grocery Keeta API","link":"/apis/grocery/docs/author","default":false,"active":true,"folderId":"58c9a61d"}],"sharedDataIds":{"sidebar":"sidebar-apis/@grocery/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["img"]},"type":"markdown"},"seo":{"title":"Authorization Guide","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"authorization-guide","__idx":0},"children":["Authorization Guide"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"1-overview","__idx":1},"children":["1. Overview"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When developer send requests to Keeta APIs, the request body ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["must include a signature parameter (field name: sig)"]},". Keeta uses this signature to verify request legitimacy and security."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Correspondingly, when Keeta pushes messages (e.g., Webhook notifications) to developer applications, it includes a signature parameter. Developer applications ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["must validate this signature in strict compliance with the signature rules"]}," to ensure message authenticity and integrity, preventing tampering or forgery."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"2-signature-calculation","__idx":2},"children":["2. Signature Calculation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Step 1: Parameter Sorting & Concatenation"]}]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Sort all parameters in ASCII order (lexicographical order)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Concatenate as URL key-value pairs: key1=value1&key2=value2..."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Note:"]}," JSON parameter values (e.g., shopCategory) require no internal sorting."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Step 2: Construct Encryption String"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Concatenate the conponents in this exact order to form the pre-encryption string:"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["URL + String calculated during Step 1 + AppSecret"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Example:"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["AppSecret = abc"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Pre-encryption String = https://open.mykeeta.com/api/open/product/shopcategory/update?accessToken=abc&appId=123&shopCategory={\"id\":123,\"name\":\"test\",\"type\":0,\"description\":null}&shopId=123&timestamp=1682566749abc"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Note:"]}," Chinese characters require no encoding"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Step 3: Generate SHA-256 Signature"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Apply SHA-256 encryption to the Step 2 string to get a 64-character signature, e.g. 48eb6d562bb0673e3db753831f032be237fc19d1e5c33fcb5386d89c0eebca86"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Note"]},": Empty parameters (defined as parameters with no value) must be included for both parameter concatenation and signature calculation."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Step 4: Add the Signature to Request Parameters"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Assign the generated signature to the sig parameter, include sig as a request parameter, and submit the request."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Example (POST request):"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"JSON","header":{"controls":{"copy":{}}},"source":"curl -X POST https://open.mykeeta.com/api/open/product/shopcategory/update\n-H 'Content-Type: application/json'\n-d '{\n    \"appId\": 123,\n    \"shopId\": 123,\n    \"accessToken\": \"abc\",\n    \"shopCategory\": {\n        \"id\": 123,\n        \"name\": \"test\",\n        \"type\": 0,\n        \"description\": null\n    },\n    \"timestamp\": \"1682566749\",\n    \"sig\": \"48eb6d562bb0673e3db753831f032be237fc19d1e5c33fcb5386d89c0eebca86\"\n}'\n","lang":"JSON"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"3-code-implementation-java","__idx":3},"children":["3. Code Implementation (Java)"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"java","header":{"controls":{"copy":{}}},"source":"//demo\npublic static void main(String[] args) {\n        String url = \"https://open.mykeeta.com/api/open/product/shopcategory/update\";\n        Map<String, Object> params = new HashMap<>();\n        params.put(\"appId\", 123);\n        params.put(\"timestamp\", 1682566749);\n        params.put(\"accessToken\", \"abc\");\n        params.put(\"shopId\", \"123\");\n        params.put(\"shopCategory\", \"{\\\"id\\\":123,\\\"name\\\":\\\"test\\\",\\\"type\\\":0,\\\"description\\\":null}\");\n        String sortedParamStr = getSortedParam(params);\n        String secret = \"abc\";\n        String sig = getSig(url, sortedParamStr, secret);\n        System.out.println(\"sig:\" + sig);\n    }\n\npublic static String getSortedParam(Map params) {\n        Object[] key_arr = params.keySet().toArray();\n        Arrays.sort(key_arr);\n        String str = \"\";\n        for (Object key : key_arr) {\n            if (key.equals(\"sig\")) {\n                continue;\n            }\n            Object val = params.get(key);\n            str += \"&\" + key + \"=\" + val;\n        }\n        return str.replaceFirst(\"&\", \"\");\n    }\n\n public static String getSig(String url, String sortedParamStr, String appSecret) {\n        String sigString = digest(url + \"?\" + sortedParamStr + appSecret);\n        log.info(\"getSig(url:{},sortedParamsStr:{}, secret:***},return sig:{})\", url, \n        sortedParamStr, sigString);\n        return sigString;\n }\n\npublic static String digest(String src) {\n        MessageDigest md;\n        try {\n            md = MessageDigest.getInstance(\"SHA-256\");\n        } catch (NoSuchAlgorithmException e) {\n            throw new RuntimeException(\"MessageDigest.getInstance(\\\"SHA-256\\\") exception\", e);\n        }\n        return byte2hex(md.digest(src.getBytes(StandardCharsets.UTF_8)));\n}\n\nprivate static String byte2hex(byte[] hash) {\n        StringBuilder hexString = new StringBuilder(2 * hash.length);\n        for (int i = 0; i < hash.length; i++) {\n            String hex = Integer.toHexString(0xff & hash[i]);\n            if (hex.length() == 1) {\n                hexString.append('0');\n            }\n            hexString.append(hex);\n        }\n        return hexString.toString();\n}\n","lang":"java"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"4faq","__idx":4},"children":["4.FAQ"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"41-image-upload-signature-calculation","__idx":5},"children":["4.1 Image Upload Signature Calculation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Supported Image Formats"]},": JPG / JPEG / PNG / BMP"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Content-Type Requirement"]},": multipart/form-data"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Signature Exclusion:"]}," The imgData parameter (containing image byte array) ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["must be excluded from signature calculation"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Image-to-Byte Conversion Reference"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"java","header":{"controls":{"copy":{}}},"source":"public static byte[] image2byte(String path) throws IOException {\n    FileImageInputStream input = null;\n    ByteArrayOutputStream output = null;\n    try {\n        input = new FileImageInputStream(new File(path));\n        output = new ByteArrayOutputStream();\n        byte[] buf = new byte[1024];\n        int numBytesRead;\n        while ((numBytesRead = input.read(buf)) != -1) {\n            output.write(buf, 0, numBytesRead);\n        }\n        byte[] bytes = output.toByteArray();\n        return bytes;\n    } finally {\n        if (input != null) {\n            input.close();\n        }\n        if (output != null) {\n            output.close();\n        }\n    }\n}\n","lang":"java"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Parameter Location Rules"]},": imgData parameter must be placed in the request body. Other parameters must be placed in request parameters."]},{"$$mdtype":"Tag","name":"Image","attributes":{"src":"/assets/author1.461a7474daa36f6977e89f6dc23e90d9df405608f264cd52f4bf2cf8eda7c3f5.d82da11f.png","alt":"author1.png","framed":false,"withLightbox":true,"width":"","height":""},"children":[]},{"$$mdtype":"Tag","name":"Image","attributes":{"src":"/assets/author2.5713123e5a864b5e53d3d096672b62ae233b7d35c2029a7d566b164cad943579.d82da11f.png","alt":"author2.png","framed":false,"withLightbox":true,"width":"","height":""},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"42-is-strict-parameter-order-enforced","__idx":6},"children":["4.2 Is Strict Parameter Order Enforced?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Yes. All signature parameters ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["must be sorted in ASCII lexicographical order"]},", including:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["All parameters except sig"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Empty parameters (with no value)"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"43-how-to-handle-json-parameters","__idx":7},"children":["4.3 How to Handle JSON Parameters?"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["For parameters containing JSON values:",{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No internal sorting of JSON fields"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Use the original JSON string as-is"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No additional encoding"]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"44-signature-verification-failed---troubleshooting","__idx":8},"children":["4.4 Signature Verification Failed - Troubleshooting"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Perform step-by-step verification:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Parameter concatenation order (ASCII sorted)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Inclusion of empty parameters"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["URL/body consistency"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["AppSecret correctness"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"45-chinese-character-encoding-requirement","__idx":9},"children":["4.5 Chinese Character Encoding Requirement"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["No encoding needed. Use Chinese characters directly in their original form during concatenation."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"46-signature-tools","__idx":10},"children":["4.6 Signature tools"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can easily calculate the correct signature through this tool, helping you quickly verify whether your code implementation is correct. ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://keetatool1.mynocode.host/"},"children":[">>> Click here"]}]}]},"headings":[{"value":"Authorization Guide","id":"authorization-guide","depth":1},{"value":"1. Overview","id":"1-overview","depth":2},{"value":"2. Signature Calculation","id":"2-signature-calculation","depth":2},{"value":"3. Code Implementation (Java)","id":"3-code-implementation-java","depth":2},{"value":"4.FAQ","id":"4faq","depth":2},{"value":"4.1 Image Upload Signature Calculation","id":"41-image-upload-signature-calculation","depth":3},{"value":"4.2 Is Strict Parameter Order Enforced?","id":"42-is-strict-parameter-order-enforced","depth":3},{"value":"4.3 How to Handle JSON Parameters?","id":"43-how-to-handle-json-parameters","depth":3},{"value":"4.4 Signature Verification Failed - Troubleshooting","id":"44-signature-verification-failed---troubleshooting","depth":3},{"value":"4.5 Chinese Character Encoding Requirement","id":"45-chinese-character-encoding-requirement","depth":3},{"value":"4.6 Signature tools","id":"46-signature-tools","depth":3}],"frontmatter":{"seo":{"title":"Authorization Guide"}},"lastModified":"2026-07-15T11:32:09.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/apis/grocery/docs/author","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}