一次性开发,线上线下全渠道对接所有主流移动支付方式

所有请求格式均采用JSON格式,请求字符集采用UTF-8编码

1、收钱吧官方文档地址:https://doc.shouqianba.com/LitePos/

2、通用请求体样式

{"request": {"head": {"version": "1.0.0","sign_type": "SHA1","appid": "28lp61847655","request_time": "2001-07-04T12:08:56+05:30","reserve": "{}"},"body": {"subject": "this is request business body"}},"signature":"blmSaxUF6/N2XOcz7UWRRVQ5XsVCEz1BpZl6R9Rc6TA3+IfWhJtmCsUZjtw72w1QQ8rEV6+uMh3GWbyzH02Y9dJQCW"
}

3、上干货

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;public class ShouqianbaPush {private static Logger logger = LoggerFactory.getLogger(ShouqianbaPush.class);/**私钥*/private static String privateKeyStr = "收钱吧提供的私钥";/**公钥*/private static String publicKeyStr = "收钱吧提供的公钥";/**轻POS接口地址*/private static final String API_DOMAIN = "https://vapi.shouqianba.com/";/**APPID*/private static final String APP_ID = "你的APPID";/**品牌编号,系统对接前由"收钱吧"分配并提供*/private static final String BRAND_CODE = "收钱吧提供的品牌编号";/**商户内部使用的门店编号*/private static final String STORE_SN = "收钱吧提供的门店编号";/*** 收钱吧 推送支付订单信息* @param url 接口地址* @param orderSn 商户订单号,在商户系统中唯一* @param createTime 商户订单创建时间* @param price 订单价格,精确到分* @param subject 订单简短描述,建议传8个字内* @param operator 操作员,可以传入收款的收银员或导购员。例如"张三"* @param customer 可以传入需要备注顾客的信息* @param posInfo 传入商户系统的产品名称、系统编号等信息,便于帮助商户调查问题* @return* @author lan* @since 2020-7-17*/public static boolean shouqianbaOrderPush(String url,String orderSn,Date createTime,String price,String subject,String operator,String customer,String posInfo) {boolean result = false;try {String timestr = getTime(createTime);//请求接口参数Map<String,Object> param = new HashMap<String,Object>();param.put("request_id", UUID.randomUUID());//请求编号,每次请求必须唯一param.put("brand_code", BRAND_CODE);//品牌编号,系统对接前由"收钱吧"分配并提供param.put("store_sn", STORE_SN);//商户内部使用的门店编号param.put("workstation_sn", "0");//门店收银机编号,如果没有请传入"0"param.put("check_sn", orderSn);param.put("scene", "1");//场景值:1-智能终端,2-H5,4-PCparam.put("sales_time", timestr);param.put("amount", price);param.put("currency", "156");//币种param.put("subject", subject);param.put("operator", operator);param.put("customer", customer);param.put("industry_code", "0");//行业代码, 0=零售;1:酒店; 2:餐饮; 3:文娱; 4:教育;param.put("pos_info", posInfo);param.put("notify_url", "接口调用成功后的回调地址");//eg:http://127.0.0.1:8080/projectName/payNotify.json//传入参数 生成对应签名体//注意:完整的请求内容,如步骤1(不包含"request"字段,仅包括request的值)使用RSA私钥签名,并转换为BASE64编码。即:/*{"head": {"version": "1.0.0","sign_type": "SHA1","appid": "你的APPID","request_time": "2001-07-04T12:08:56+05:30"},"body": {"request_id": UUID.randomUUID(),"brand_code": BRAND_CODE,"store_sn": STORE_SN,......(请求接口参数全部内容)}}*/String signBody = createSignatureBody(timestr,param);//将生成的签名体使用私钥加密,生成签名String sign = getSignature(signBody);//将参数及签名组装成对应的通用请求体格式String paramStr = createParamBody(param,sign,timestr);//进行http post请求String responseStr = sendPost(API_DOMAIN+url,paramStr);Map map = getResponseData(responseStr);if(null != map && null != map.get("result_code") && Integer.parseInt(map.get("result_code").toString()) == 200 ){Map bizResponse = JSONObject.parseObject(map.get("biz_response").toString(),Map.class);if(null != bizResponse && null != bizResponse.get("result_code") && Integer.parseInt(bizResponse.get("result_code").toString()) == 200){result = true;}}} catch (Exception e) {logger.error("收钱吧 推送支付订单失败",e);return false;}return result;}/*** 获取 YYYY-MM-DDThh:mm:ssTZD 格式时间(时间格式请参考官方文档)* @return* @author lan* @since 2020-6-28*/private static String getTime(Date date){SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");if(date == null){return sdf.format(new Date());}return sdf.format(date);}/*** 生成签名体* @param appId 轻POS应用编号,商户入网后由收钱吧技术支持提供* @param storeSn 商户内部使用的门店编号* @param brandCode 品牌编号,系统对接前由"收钱吧"分配并提供* @param checkSn 商户订单号,在商户系统中唯一* @param workstationSn 门店收银机编号,如果没有请传入"0"* @return* @author lan* @since 2020-6-28*/private static String createSignatureBody(String timestr,Map<String,Object> param){String result = null;try {JSONObject head = new JSONObject();head.put("sign_type", "SHA1");head.put("appid", APP_ID);head.put("request_time", timestr);head.put("version", "1.0.0");JSONObject body = new JSONObject();for (String key : param.keySet()) {body.put(key, param.get(key));}JSONObject res = new JSONObject();res.put("head", head);res.put("body", body);result = res.toJSONString();} catch (Exception e) {return null;}return result;}/*** 获取签名* @param signBody* @return* @author lan* @since 2020-7-17*/public static String getSignature(String signBody){try {KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");gen.initialize(2048);PrivateKey privateKey = getPrivateKey(privateKeyStr);// SHA1withRSA算法进行签名Signature sign = Signature.getInstance("SHA1withRSA");sign.initSign(privateKey);byte[] data = signBody.getBytes();// 更新用于签名的数据sign.update(data);byte[] signature = sign.sign();String res = new String(Base64.encodeBase64(signature));return res;} catch (Exception e) {e.printStackTrace();}return null;}/*** 获取私钥* @param privateKey 私钥字符串* @return*/public static PrivateKey getPrivateKey(String privateKey) throws Exception {KeyFactory keyFactory = KeyFactory.getInstance("RSA");byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes());PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);return keyFactory.generatePrivate(keySpec);}/*** 获取公钥* @param publicKey 公钥字符串* @return*/public static PublicKey getPublicKey(String publicKey) throws Exception {KeyFactory keyFactory = KeyFactory.getInstance("RSA");byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes());X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);return keyFactory.generatePublic(keySpec);}/*** 组建参数体* @param appId* @param storeSn* @param brandCode* @param checkSn* @param workstationSn* @return*/private static String createParamBody(Map<String,Object> param,String signature,String timestr){String result = null;try {JSONObject head = new JSONObject();head.put("sign_type", "SHA1");head.put("appid", APP_ID);head.put("request_time", timestr);head.put("version", "1.0.0");JSONObject body = new JSONObject();for (String key : param.keySet()) {body.put(key, param.get(key));}JSONObject request = new JSONObject();request.put("head", head);request.put("body", body);JSONObject res = new JSONObject();res.put("request", request);res.put("signature", signature);result = res.toJSONString();} catch (Exception e) {return null;}return result;}/*** 向指定 URL 发送POST方法的请求* @param url 发送请求的 URL* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。* @return 所代表远程资源的响应结果*/public static String sendPost(String url, String param) {PrintWriter out = null;BufferedReader in = null;String result = "";try {URL realUrl = new URL(url);// 打开和URL之间的连接URLConnection conn = realUrl.openConnection();// 设置通用的请求属性conn.setRequestProperty("accept", "application/json");conn.setRequestProperty("Charset", "UTF-8");conn.setRequestProperty("Content-Type","application/json");conn.setRequestProperty("connection", "Keep-Alive");conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");// 发送POST请求必须设置如下两行conn.setDoOutput(true);conn.setDoInput(true);// 获取URLConnection对象对应的输出流out = new PrintWriter(conn.getOutputStream());// 发送请求参数out.print(param);// flush输出流的缓冲out.flush();// 定义BufferedReader输入流来读取URL的响应in = new BufferedReader(new InputStreamReader(conn.getInputStream()));String line;while ((line = in.readLine()) != null) {result += line;}} catch (Exception e) {System.out.println("发送 POST 请求出现异常!"+e);e.printStackTrace();}//使用finally块来关闭输出流、输入流finally{try{if(out!=null){out.close();}if(in!=null){in.close();}}catch(IOException ex){ex.printStackTrace();}}return result;}  /*** 获取返回参数 (返回内容格式请参考官方文档-“响应通用定义”)* @param result* @return* @author lan* @since 2020-7-17*/private static Map<String,Object> getResponseData(String result){if(result != null){JSONObject res = JSONObject.parseObject(result);if(res != null && res.get("response") != null){String resp = res.get("response").toString();JSONObject response = JSONObject.parseObject(resp);if(response != null && response.get("body") != null){Map map = JSONObject.parseObject(response.get("body").toString(), Map.class);return map;}else{return null;}}else{return null;}}else{return null;}}}

4、需要注意下的是签名体的格式问题及时间格式问题,走了些许弯路。另外,所有接口地址全部是小写地址,如果收钱吧技术人员提供的文档上写的是大写地址,请改为小写地址试一试。截止编写此篇文章之时,官方API已更新,处理了以上较为明显的问题。

仅作留存备忘,提供参考之用。

收钱吧-轻POS接口相关推荐

  1. 如何帮用户管好云账本?阿里云数据库助力收钱吧!

    简介:"收钱吧到账100万"成为普通商家最想听到的声音. 你有多久没摸过现金了? 中国互联网络信息中心发布的第47次<中国互联网络发展状况统计报告>数据显示,截至202 ...

  2. 如何帮用户管好云账本?阿里云数据库助力收钱吧 | 甲子光年

    简介: "收钱吧到账100万"成为普通商家最想听到的声音. 你有多久没摸过现金了? 中国互联网络信息中心发布的第47次<中国互联网络发展状况统计报告>数据显示,截至20 ...

  3. 你还在为“收钱”发愁吗?BeeCloud打造支付平台

    移动互联网产业高速发展,据工信部相关数据统计,移动互联网用户已经超过4亿,相关产业规模更是超过9000亿元.中国,已经成为了第一大智能手机和平板市场,其中安卓与IOS系统占据了移动设备系统的主流市场. ...

  4. 路由器重温——POS接口配置管理——SDH

    POS(Packet Over SONET/SDH)接口可利用SONET(Synchronous Optical Network,同步光纤网)或SDH(Synchronous Digital Hier ...

  5. 收钱吧的 Python 高效自动化测试实践

    1. 背景 收钱吧业务服务千万级商家,业务庞大,产品背后有复杂的应用支撑.我们采用了微服务架构,有成百上千个不同类型的后端服务,使用了包括Node.js.Java.Go.Python等后端语言,还有M ...

  6. 快来被子里 看看我的夜光收钱码!

    6月23日消息,根据支付宝发布的数据:截至6月22日,全国已超过600万家小店夜间收入超过去年同期,平均每天十多万人新开通收钱码做生意. 为了小店主在夜间更便捷的收钱,昨晚,支付宝紧急上线" ...

  7. jssdk 获取微信收货地址_微信收货地址共享开发接口讲解

    写在前面的话:微信开发者文档写的比较清楚,也不容易出错,可是偏偏收货地址共享那儿写的比较绕,同时也会有很多坑,这里总结一下. ======正文开始====== 微信收货地址共享开发接口基本使用场景是: ...

  8. 如何打造一个让粉丝一见就能收钱的朋友圈

    做微营销的人都知道打造朋友圈非常重要! 但也有人不这么认为,说现在形势变了,朋友圈都成了广告,都是垃圾,没人看朋友圈了,发朋友圈没有用了,果然是这样吗?对这个问题我通过对五行赚钱术的学习明白了,我们赚 ...

  9. 躺着收钱月入过万,怎样才能做到?

    躺着收钱月入过万.怎样才能做到? 其实有很多方法. 比如今天举一个例子.你有资源.别人想要的商品,市场畅销的货,你能用低于大多数销售商的价格进到货,然后卖给销售商,其实基本就是躺着赚钱了.别说月入过万 ...

最新文章

  1. bireme数据源同步工具--debezium+kafka+bireme
  2. 应用开发者必须了解的Kubernetes网络二三事
  3. 电脑怎么打印文件步骤_电脑中毒后怎么办 电脑中毒后解决方法【详细步骤】...
  4. json 转换 java odl_JSON与JAVA数据的转换
  5. java取linux本地xml,java-使用apache poi读取.xlsx文件会在Linux机器...
  6. 浅谈CIVIL 3D
  7. java tree 表格_00030-layui+java 树形表格treeTable
  8. MapTask工作机制图解
  9. 华为悦盒EC6109u线刷救砖文件fastboot.bin bootargs.bin recovery
  10. VMware网络配置基础
  11. 命令提示符怎么以管理员方式打开
  12. Spark CASE WHEN 写法案例
  13. Modbus从站读写数据
  14. MFC CListCtrl修改表头字体、字体颜色、背景颜色、字体垂直居中、表头高度
  15. 写给那些进步缓慢却全然不知的IT人
  16. win7怎么修改服务器端口,教你在Win7中如何轻松修改3389远程桌面端口
  17. 小白学习Excel VBA (一)
  18. 利用组策略进行的一次Windows主机安全整改
  19. typedef 简介
  20. 网站部署详细流程(包括域名,服务器的配置等)

热门文章

  1. 综述:目标检测2001-2021
  2. 吐血整理!14个编写Spring MVC控制器的实用小技巧
  3. 计算机切换管理员用户,切换为Administrator,完全掌握电脑
  4. IDES翻译—采购流程中的Enjoy界面
  5. 岁末忆今朝,辞旧话新潮——心灵与技术的聚合
  6. 海康威视秋招正式开始,快来和我做同事~
  7. python中的ideavim有什么作用_【进击的Vimmer】为什么选择vim
  8. 【ROS小车8】_小车硬件组成
  9. 计算机软件工程大学排名(2015)
  10. windows下整合UCenter、ECShop、Discus