欧珀莱OMO

欧珀莱OMO


一、POS对外接口技术方案

<h5>对接POS openapi步骤</h5> <ul> <li>1.对接者先向POS申请serviceName和serviceSecret serviceName: 调用接口服务的身份标识,为固定字符串常量 serviceSecret: 调用接口服务的身份密钥,为确保安全,请妥善保管,不可泄露。</li> <li>2.对接者根据API定义编写客户端程序,可以使用任何技术语言编写。</li> <li>3.对接者与POS数据服务端进行接口联调,直至调试通过。</li> </ul> <h5>接口设计</h5> <ul> <li>接口url: /{contextPath}/{version}{requestPath} 其中: 1) contextPath 是被调用服务的名称; 2) version 是被调用服务的版本信息; 3) requestPath是调用服务的请求路径。 示例如下: url: xxxx/openapi/v1/demo/postorder?shopcode=12345678&amp;productcode=12345 contextPath: openapi version: v1 requestPath: /demo/postorder</li> </ul> <h5>公共请求消息头</h5> <ul> <li>1.所有请求头都必须包含 X-Caller-Service、 X-Caller-Timestamp、 X-Caller-Sign、 Content-Type</li> </ul> <table> <thead> <tr> <th style="text-align: left;">请求头(Header)</th> <th style="text-align: left;">说明</th> </tr> </thead> <tbody> <tr> <td style="text-align: left;">X-Caller-Service</td> <td style="text-align: left;">对应上文中的serviceName</td> </tr> <tr> <td style="text-align: left;">X-Caller-Timestamp</td> <td style="text-align: left;">时间戳.格式:yyyy-MM-dd HH:mm:ss,时区为GMT+8.如:2021-04-01 12:20:11</td> </tr> <tr> <td style="text-align: left;">X-Caller-Sign</td> <td style="text-align: left;">签名. 参考sign安全校验机制</td> </tr> <tr> <td style="text-align: left;">Content-Type</td> <td style="text-align: left;">只支持JSON格式. application/json; charset=utf-8</td> </tr> </tbody> </table> <h5>sign安全校验机制</h5> <ul> <li>1.各个服务通过gateway进行调用的时候,需要增加三个自定义的头信息:X-Caller-Service、XCaller-Timestamp、X-Caller-Sign.</li> <li>2.X-CallerSign是通过callerService、timestamp、contextPath、version、serviceSecret、restPath,按首字母排序后,进行md5加密获得的值,只需要将对应的名字做修改即可. Java版本代码如下: <pre><code>import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; public class SignConvertUtil { public static String generateSign(String callerService, String contextPath, String version,String timestamp, String serviceSecret, String requestPath) { String sign = ""; if (callerService == null || callerService.equals("") || contextPath == null ||contextPath.equals("") ||timestamp == null || timestamp.equals("") || serviceSecret == null || serviceSecret.equals("")) { return sign; } Map&lt;String, String&gt; map = new LinkedHashMap&lt;&gt;(); map.put("callerService", callerService); map.put("contextPath", contextPath); try { if (requestPath != null) { StringBuilder sb = new StringBuilder(); for(String part : requestPath.split("/")) { sb.append("/").append(URLEncoder.encode(part,"utf-8")); } map.put("requestPath", sb.toString().substring(1)); } map.put("timestamp", timestamp); map.put("v", version); sign = generateMD5Sign(serviceSecret, map); } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { e.printStackTrace(); return ""; } return sign; } private static String generateMD5Sign(String secret, Map&lt;String, String&gt; parameters) throws NoSuchAlgorithmException, UnsupportedEncodingException { MessageDigest md5 = MessageDigest.getInstance("MD5"); byte[]bytes=md5.digest(generateConcatSign(secret,parameters).getBytes("utf- 8")); return byteToHex(bytes); } private static String generateConcatSign(String secret, Map&lt;String, String&gt;parameters) { StringBuilder sb = new StringBuilder().append(secret); Set&lt;String&gt; keys = parameters.keySet(); for (String key : keys) { sb.append(key).append(parameters.get(key)); } return sb.append(secret).toString(); } private static String byteToHex(byte[] bytesIn) { StringBuilder sb = new StringBuilder(); for (byte byteIn : bytesIn) { String bt = Integer.toHexString(byteIn &amp; 0xff); if (bt.length() == 1) sb.append(0).append(bt); else sb.append(bt); } return sb.toString().toUpperCase(); } }</code></pre></li> </ul> <h5>返回参数</h5> <table> <thead> <tr> <th style="text-align: left;">参数名</th> <th style="text-align: left;">类型</th> <th>说明</th> </tr> </thead> <tbody> <tr> <td style="text-align: left;">result</td> <td style="text-align: left;">string</td> <td>1-成功,0-失败</td> </tr> <tr> <td style="text-align: left;">msg</td> <td style="text-align: left;">string</td> <td>描述信息</td> </tr> <tr> <td style="text-align: left;">totalcount</td> <td style="text-align: left;">int</td> <td>记录总数</td> </tr> <tr> <td style="text-align: left;">data</td> <td style="text-align: left;">array</td> <td>数据信息</td> </tr> </tbody> </table> <h5>返回示例</h5> <pre><code> { "result": 1, "msg": "处理成功", "totalcount": 1, "data": { "ShopCode": "00000000", "ProdCode": "12345", "CounterStock": 5, "DepotStock": 20, "TotalStock": 25 } }</code></pre>

页面列表

ITEM_HTML