玖零定制问题修复的gravatar头像
玖零定制问题修复 2017-11-09 13:52:57
杂谈:细说JAVA服务端接入支付宝的那些坑点

  最近项目要接入支付环节,由于时间原因没有多余的时间去对接第三方聚合支付平台的产品,所以小编决定了直接对接第三方支付平台官方网站所提供的,小编这里对接了支付宝,微信支付,银联支付,在此浅浅的谈下对接支付宝的时候所遇到的坑点,为以后对接或者有需要的朋友减少些坑点

  先说支付宝大家都不陌生,现在改名叫蚂蚁金服,至于申请的过程小编在这里就不做过多的叙述了,度娘上一大堆,支付宝官网也提供详细的步骤,这里咱们直接说联调的事情。由于小编以前所对接支付宝APP接口所采用的是老版本的,支持的签名验证模式还支持MD5,RSA,现在看支付宝官方网站上采用RSA2进行加密验证签名,头痛了半天,一直以为自己的数据参数都没有问题,经过重重探讨最终发现是RSA2采用的验证机制和RSA,MD5都不一样了,RSA2采用PKCS8进行生成的公钥私钥,而且所采用的必须为秘钥格式:PKCS8,秘钥长度:2048模式的才可以在调用时候验证成功.下面我们一步一步去解释下官方所提供的DEMO吧

  先看下代码

  JAVA服务端SDK生成APP支付订单信息示例

  

//实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody("我是测试数据");
model.setSubject("App支付测试Java");
model.setOutTradeNo(outtradeno);
model.setTimeoutExpress("30m");
model.setTotalAmount("0.01");
model.setProductCode("QUICK_MSECURITY_PAY");
request.setBizModel(model);
request.setNotifyUrl("商户外网可以访问的异步地址");
try {
        //这里和普通的接口调用不同,使用的是sdkExecute
        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
        System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。
    } catch (AlipayApiException e) {
        e.printStackTrace();
}

在上面代码中,需要注意的几点

1.商户外网访问地址如果为域名模式的一定要加上http://拼全面,否则在唤起支付请求的时候就会报错ali40247的错误.

2.subject如果为中文的时候不需要再次进行转码操作,因为在执行sdkExecute的时候默认把中文进行转码了,如果在赋值的时候进行转码则在支付宝那边是接收参数错误

3.app_id为你创建应用时候所提供的一个appid,可在支付宝官方网站你自己创建的应用下面进行查看

4. alipay_public_key:注意是你在生成公钥的时候不是应用公钥,而是要应用公钥所对应的支付宝公钥,否则会在异步回调验证签名的时候验证失败已导致交易失败.支付宝生成公钥可以参考小编整理的支付宝公钥生成步骤

5.支付宝官方网站所提供的最后的System.out.println( responses.getBody());这里仅仅是为了让您看到输出结果,具体操作还要根据您返回的数据,response去写出去返回给调用方,才可以进行接收到

 

JAVA服务端验证异步通知信息参数示例

//获取支付宝POST过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map requestParams = request.getParameterMap();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
    String name = (String) iter.next();
    String[] values = (String[]) requestParams.get(name);
    String valueStr = "";
    for (int i = 0; i < values.length; i++) {
        valueStr = (i == values.length - 1) ? valueStr + values[i]
                    : valueStr + values[i] + ",";
  	}
    //乱码解决,这段代码在出现乱码时使用。
	//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
	params.put(name, valueStr);
}
//切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
boolean flag = AlipaySignature.rsaCheckV1(params, alipaypublicKey, charset,"RSA2")

 

这里再回调的时候主要注意alipaypublickey一定要是支付宝公钥而不能是应用公钥,否则会报验证签名失败

其他的就没有啥可注意的点了,这个是小编在使用支付宝最新app支付的时候所遇到的一些坑点,处理完后感觉确实挺简单的,但是不要被以前的经验所误导,否则可能会吃很多亏。


打赏
最近浏览
做你的景天  LV7 2024年2月22日
80730176  LV7 2024年1月3日
玖零定制问题修复  LV34 2023年9月15日
402452723 2021年3月14日
暂无贡献等级
Yohji Yamamoto 2021年1月25日
暂无贡献等级
laiv77  LV10 2020年9月7日
maiyatang520  LV1 2020年9月2日
wangzilong 2020年7月17日
暂无贡献等级
Sundayhl  LV7 2020年7月1日
lilingling  LV1 2020年5月12日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友