微信支付之app支付服务器端的开发与扫码支付的处理过程类似,区别的地方在于,统一下单过程,需要将返回的参数进行签名处理后再次返回给app端做处理,由app端调起支付完成支付流程后,回调服务器端处理方法,下边是统一下单方法中的处理
public RespData weixin_pay(String out_trade_no) throws Exception {
// 账号信息 // appid
String appid = PayConfigUtil.getAppid();
// 商业号
String mch_id = PayConfigUtil.getMchid();
// key
String key = PayConfigUtil.getKey();
String currTime = PayCommonUtil.getCurrTime();
String strTime = currTime.substring(8, currTime.length());
String strRandom = PayCommonUtil.buildRandom(4) + "";
//随机字符串
String nonce_str = strTime + strRandom;
// 价格 注意:价格的单位是分
//查询订单数据表获取订单信息
PayOrder payOrder = payOrderDao.get(PayOrder.class,out_trade_no);
// 获取发起电脑 ip
String spbill_create_ip = PayConfigUtil.getIP();
// 回调接口
String notify_url = PayConfigUtil.NOTIFY_URL;
String trade_type = "APP";
String time_start = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
Calendar ca = Calendar.getInstance();
ca.setTime(new Date());
ca.add(Calendar.DATE, 1);
String time_expire = new SimpleDateFormat("yyyyMMddHHmmss").format(ca.getTime());
SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();
packageParams.put("appid", appid);
packageParams.put("mch_id", mch_id);
packageParams.put("nonce_str", nonce_str);
packageParams.put("body",payOrder.getBody());
packageParams.put("out_trade_no", out_trade_no);
//packageParams.put("total_fee", "1");
packageParams.put("total_fee", payOrder.getTotalFee());
packageParams.put("spbill_create_ip", spbill_create_ip);
packageParams.put("notify_url", notify_url);
packageParams.put("trade_type", trade_type);
packageParams.put("time_start", time_start);
packageParams.put("time_expire", time_expire);
String sign = PayCommonUtil.createSign("UTF-8", packageParams,key);
packageParams.put("sign", sign);
String requestXML = PayCommonUtil.getRequestXml(packageParams);
System.out.println("请求xml::::"+requestXML);
String resXml = HttpUtil.postData(PayConfigUtil.PAY_API, requestXML);
System.out.println("返回xml::::"+resXml);
Map map = new HashMap<String, String>();
map = XMLUtil.doXMLParse(resXml);
//过滤空 设置 TreeMap
SortedMap<Object,Object> respackageParams = new TreeMap<Object,Object>();
SortedMap<Object,Object> clientParamsMap = new TreeMap<Object,Object>();
Iterator it = map.keySet().iterator();
while (it.hasNext()) {
String parameter = (String) it.next();
String parameterValue = (String)map.get(parameter);
String v = "";
if(null != parameterValue) {
v = parameterValue.trim();
}
respackageParams.put(parameter, v);
}
//判断签名是否正确
if( "SUCCESS".equals(map.get("return_code"))&&PayCommonUtil.isTenpaySign("UTF-8", respackageParams,key)){
//签名验证通过,将获取的预支付ID返回给app端,需要重新签名,返回的数据做了加密处理
clientParamsMap.put("appid",appid);
clientParamsMap.put("partnerid",mch_id);
clientParamsMap.put("prepayid",(String)map.get("prepay_id"));
clientParamsMap.put("package","Sign=WXPay");
String currTimeclient = PayCommonUtil.getCurrTime();
String strTimeclient = currTimeclient.substring(8, currTimeclient.length());
String strRandomclient = PayCommonUtil.buildRandom(4) + "";
String nonce_strclient = strTimeclient + strRandomclient;
clientParamsMap.put("noncestr",nonce_strclient);
clientParamsMap.put("timestamp",(System.currentTimeMillis()+"").subSequence(0, 10));
String signclient = PayCommonUtil.createSign("UTF-8", clientParamsMap,key);
clientParamsMap.put("sign",signclient);
return RespCode.getRespData(RespCode.SUCESS,clientParamsMap);
}else{
System.out.println("返回app端信息时,判断签名错误");
return RespCode.getRespData(RespCode.ERROR);
}
}
与扫码支付的区别,把 trade_type 写死为“APP”,返回值中遍历map重新组织所有参数放入respackageParams中使用 PayCommonUtil.isTenpaySign方法验证签名是否正确,以及返回值中的return_code是否为Success,验证通过后,重新将参数签名返回至app端,其中package 暂时写死为 Sign=WXPay,传递时间戳时需要取出10位,否则app端会调用支付出错,将这些信息放入clientParamsMap中做签名处理,返回给app端做处理
其余工具类可参看上一篇文章中内容,不在重复粘贴
欢迎大家指正。