{"id":949,"date":"2023-05-02T10:28:50","date_gmt":"2023-05-02T02:28:50","guid":{"rendered":"https:\/\/open-doc.jkos.com\/?docs=%e7%b7%9a%e4%b8%8b%e4%ba%a4%e6%98%93pos\/%e9%a9%97%e7%b0%bd%e5%b7%a5%e5%85%b7\/%e6%9f%a5%e8%a9%a2-api"},"modified":"2023-05-02T10:44:32","modified_gmt":"2023-05-02T02:44:32","slug":"%e6%9f%a5%e8%a9%a2-api","status":"publish","type":"docs","link":"https:\/\/open-doc.jkos.com\/?docs=%e7%b7%9a%e4%b8%8b%e4%ba%a4%e6%98%93pos\/%e9%a9%97%e7%b0%bd%e5%b7%a5%e5%85%b7\/%e6%9f%a5%e8%a9%a2-api","title":{"rendered":"\u67e5\u8a62 API"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<head>\n  <script\n    type=\"text\/javascript\"\n    src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/crypto-js\/3.1.2\/rollups\/hmac-sha256.js\"\n  ><\/script>\n<\/head>\n\n<body>\n  <body>\n    <div class=\"w-75\">\n      <div class=\"mb-3\">\n        <div class=\"mb-1\">\u8acb\u6c42\u53c3\u6578\uff1a<\/div>\n        <textarea id=\"msg\" class=\"form-control\" rows=\"7\" cols=\"5\"><\/textarea>\n      <\/div>\n      <div class=\"mb-3\">\n        <div class=\"mb-1\">MerchantKey\uff1a<\/div>\n        <input\n          id=\"mercantKey\"\n          type=\"text\"\n          class=\"form-control\"\n          placeholder=\"secret\"\n        \/>\n      <\/div>\n\n      <button type=\"button\" class=\"btn btn-info mb-2 p-2\" onclick=\"getSign()\">\n        \u8a08\u7b97\u7c3d\u540d\n      <\/button>\n\n      <div class=\"mb-3\">\n        <div id=\"error\"><\/div>\n      <\/div>\n      <div class=\"mb-3\">\n        <div class=\"mb-1\">\u7c3d\u540d\u7d50\u679c<\/div>\n        <textarea\n          id=\"output\"\n          type=\"text\"\n          class=\"form-control\"\n          rows=\"3\"\n          cols=\"5\"\n        ><\/textarea>\n      <\/div>\n    <\/div>\n  <\/body>\n<\/body>\n<script>\n  const msg = document.getElementById(\"msg\");\n  msg.placeholder = String(\n    '{\"GatewayTradeNo\":\"\",\"InquiryType\":\"P\",\"MerchantID\":\"9999999\",\"MerchantTradeNo\":\"2343565453423421\",\"PosID\":\"1\",\"PosTradeTime\":\"2016\/05\/08 12:01:01\",\"SendTime\":\"20160805120103\",\"StoreID\":\"000000000000001\",\"Sign\":\"7d931cc96fa989e69a6054c29eedd97008e3ee370eb34c603a50919c66801806\"}'\n  );\n  const getSign = () => {\n    let errorArr = [];\n    let correctObj = {};\n    let sortedResult = {};\n\n    const msg = document.getElementById(\"msg\").value.toString();\n    const mercantKey = document.getElementById(\"mercantKey\").value.toString();\n\n    const setErrorMsg = errorMsg => {\n      errorArr.push(errorMsg);\n      showError();\n    };\n\n    const showError = () => {\n      document.getElementById(\"error\").style.color = \"red\";\n      document.getElementById(\"error\").innerHTML = errorArr\n        .toString()\n        .replaceAll(\",\", \"<br>\");\n    };\n\n    if (\/\\n\/g.test(msg)) return setErrorMsg(\"\u8acb\u52ff\u63db\u884c\");\n\n    const getParams = () => {\n      try {\n        return JSON.parse(msg);\n      } catch (e) {\n        return setErrorMsg(\"\u8acb\u8f38\u5165\u6b63\u78ba\u7684 JSON \u683c\u5f0f\");\n      }\n    };\n    const params = getParams();\n    const paramsKeys = Object.keys(params);\n    const ignoreKeyMap = [\"Sign\"];\n\n    const hasWhiteSpace = {\n      checkFunction: value => \/\\s\/g.test(value),\n      errorMsg: \"\u4e0d\u80fd\u6709\u7a7a\u683c\",\n    };\n\n    const checkRegex = regex => {\n      return {\n        checkFunction: value => !regex.test(value),\n        errorMsg: \"\u932f\u8aa4\u683c\u5f0f\",\n      };\n    };\n\n    const checkLength = num => {\n      return {\n        checkFunction: value => value.length > num,\n        errorMsg: `\u9577\u5ea6\u4e0d\u53ef\u5927\u65bc ${num}`,\n      };\n    };\n\n    const isString = {\n      checkFunction: value => typeof value !== \"string\",\n      errorMsg: \"\u9808\u70ba string\",\n    };\n\n    const isNumber = {\n      checkFunction: value => typeof value !== \"number\",\n      errorMsg: \"\u9808\u70ba int\uff0c\u82e5\u7121\u8acb\u653e 0\",\n    };\n\n    const checkByElement = () => {\n      const validations = {\n        InquiryType: [\n          hasWhiteSpace,\n          isString,\n          checkLength(1),\n          checkRegex(\/P|R\/),\n        ],\n        MerchantID: [hasWhiteSpace, isString, checkLength(10)],\n        StoreID: [hasWhiteSpace, isString, checkLength(20)],\n        GatewayTradeNo: [hasWhiteSpace, isString, checkLength(20)],\n        MerchantTradeNo: [hasWhiteSpace, isString, checkLength(60)],\n        PosID: [hasWhiteSpace, isString, checkLength(20)],\n        PosTradeTime: [\n          isString,\n          checkLength(19),\n          checkRegex(\n            \/^[0-9]{4}\\\/(0[1-9]|1[0-2])\\\/(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9]$\/im\n          ),\n        ],\n        SendTime: [\n          hasWhiteSpace,\n          isString,\n          checkLength(14),\n          checkRegex(\n            \/^[0-9]{4}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])(2[0-3]|[01][0-9])[0-5][0-9][0-5][0-9]$\/im\n          ),\n        ],\n        Sign: [hasWhiteSpace, isString],\n      };\n\n      const requiredKeys = Object.keys(validations);\n      requiredKeys.map(key => {\n        if (!paramsKeys.includes(key)) errorArr.push(`\u7f3a\u5c11 ${key} \u6b04\u4f4d`);\n      });\n\n      paramsKeys.map(key => {\n        if (!validations[key]) errorArr.push(`\u672a\u77e5\u53c3\u6578 ${key} `);\n\n        validations[key]?.map(check => {\n          if (check.checkFunction(params[key])) {\n            errorArr.push(key + \" \" + check.errorMsg);\n          } else {\n            ignoreKeyMap.map(\n              ignoreKey => key !== ignoreKey && (correctObj[key] = params[key])\n            );\n          }\n        });\n      });\n    };\n\n    const checkSignPosition = () => {\n      const lastElement = paramsKeys.slice(-1).pop();\n      if (lastElement !== \"Sign\") errorArr.push(`Sign \u6b04\u4f4d\u8981\u653e\u5728\u6700\u5f8c\u4e00\u500b\u6b04\u4f4d`);\n    };\n\n    const checkSorting = () => {\n      const OriKey = Object.keys(params).filter(\n        key => !ignoreKeyMap.includes(key)\n      );\n\n      const SortedKey = Object.keys(params)\n        .filter(key => !ignoreKeyMap.includes(key))\n        .sort();\n\n      if (JSON.stringify(OriKey) !== JSON.stringify(SortedKey))\n        errorArr.push(`\u6392\u5e8f\u6709\u8aa4\uff0c\u8acb\u78ba\u8a8d\u9032\u884c\u5b57\u6bcd\u6392\u5e8f`);\n\n      SortedKey.forEach(key => {\n        sortedResult[key] = params[key];\n      });\n    };\n\n    const checkIsEqual = () => {\n      const ignoreKeyValue = {};\n      ignoreKeyMap.map(ignoreKey => {\n        ignoreKeyValue[ignoreKey] = params[ignoreKey];\n      });\n\n      const correctOuput = JSON.stringify({ ...correctObj, ...ignoreKeyValue });\n\n      if (correctOuput !== msg) errorArr.push(`\u8acb\u52ff\u52a0\u5165\u7a7a\u767d\u4ee5\u53ca\u63db\u884c`);\n    };\n\n    function validate() {\n      checkByElement();\n      checkSignPosition();\n      checkSorting();\n      checkIsEqual();\n\n      showError();\n    }\n    validate();\n\n    if (errorArr.length) return (document.getElementById(\"output\").value = \"\");\n\n    const finalSignString = JSON.stringify(sortedResult) + mercantKey;\n    const sign256 = CryptoJS.SHA256(finalSignString).toString(CryptoJS.enc.Hex);\n\n    document.getElementById(\"output\").value = sign256;\n  };\n<\/script>\n\n","protected":false},"featured_media":0,"parent":947,"menu_order":1,"comment_status":"open","ping_status":"closed","template":"","doc_tag":[],"class_list":["post-949","docs","type-docs","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/open-doc.jkos.com\/index.php?rest_route=\/wp\/v2\/docs\/949","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/open-doc.jkos.com\/index.php?rest_route=\/wp\/v2\/docs"}],"about":[{"href":"https:\/\/open-doc.jkos.com\/index.php?rest_route=\/wp\/v2\/types\/docs"}],"replies":[{"embeddable":true,"href":"https:\/\/open-doc.jkos.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=949"}],"version-history":[{"count":2,"href":"https:\/\/open-doc.jkos.com\/index.php?rest_route=\/wp\/v2\/docs\/949\/revisions"}],"predecessor-version":[{"id":954,"href":"https:\/\/open-doc.jkos.com\/index.php?rest_route=\/wp\/v2\/docs\/949\/revisions\/954"}],"up":[{"embeddable":true,"href":"https:\/\/open-doc.jkos.com\/index.php?rest_route=\/wp\/v2\/docs\/947"}],"next":[{"title":"\u9000\u6b3e API","link":"https:\/\/open-doc.jkos.com\/?docs=%e7%b7%9a%e4%b8%8b%e4%ba%a4%e6%98%93pos\/%e9%a9%97%e7%b0%bd%e5%b7%a5%e5%85%b7\/%e9%80%80%e6%ac%be-api","href":"https:\/\/open-doc.jkos.com\/index.php?rest_route=\/wp\/v2\/docs\/950"}],"prev":[{"title":"\u4ed8\u6b3e\/\u53d6\u6d88 API","link":"https:\/\/open-doc.jkos.com\/?docs=%e7%b7%9a%e4%b8%8b%e4%ba%a4%e6%98%93pos\/%e9%a9%97%e7%b0%bd%e5%b7%a5%e5%85%b7\/%e4%bb%98%e6%ac%be-%e5%8f%96%e6%b6%88-api","href":"https:\/\/open-doc.jkos.com\/index.php?rest_route=\/wp\/v2\/docs\/948"}],"wp:attachment":[{"href":"https:\/\/open-doc.jkos.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=949"}],"wp:term":[{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/open-doc.jkos.com\/index.php?rest_route=%2Fwp%2Fv2%2Fdoc_tag&post=949"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}