Map map = new HashMap<>();
String suijishu = WXPayUtil.generateNonceStr();
String dindanhao = GetRandom.getRandomStringByLength(32);
System.out.println("订单号:"+dindanhao);
map.put("appid",payhospital.getAppid());// appid
map.put("mch_id",payhospital.getMchid());// 商户号
map.put("sign_type","MD5");
map.put("nonce_str",suijishu);// 随机字符串
map.put("body","ceshizhifu");// 商品名称
map.put("notify_url","http://wxzf.yiruan01.com/zuul/user/payhospitalbyid/result"); // 回调地址
map.put("out_trade_no",dindanhao);// 订单号
map.put("spbill_create_ip","47.95.245.237");// 终端ip(调用微信支付API的机器IP)//47.95.245.237
map.put("total_fee","1");// 订单金额 现在默认写死,money
map.put("trade_type","JSAPI"); // 交易类型交易类型
map.put("openid",openid);// openid
//生成签名
//将集合M内非空参数值的参数按照参数名ASCII码从小到大排序
String paixu = GroupWeuxin.formatUrlMap(map,false,false);
// 拼接key
String SignTemp = paixu+"&key="+payhospital.getKeyy();
// MD5加密 并且转换为大写
String sign = Md5Util.getMD5String(SignTemp).toUpperCase();
map.put("sign",sign);
// 将map转换为xml
String xml = WXPayUtil.mapToXml(map);
// 判断签名是否正确
Boolean boo = WXPayUtil.isSignatureValid(xml,payhospital.getKeyy());
System.out.println("判断第一次签名是否正确:"+boo);
String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
ResponseEntity responseEntity = restTemplate.postForEntity(url,xml,String.class);
String res1 = responseEntity.getBody();
// 获取返回参数到此后台完成
Map map1 = WXPayUtil.xmlToMap(res1);
// 准备前台需要的参数APPID timestamp nonceStr package signType paySign
Map<String,String> map2 = new HashMap<>();
// 获取之前返回的prepay_id
String prepay_id = (String)map1.get("prepay_id");
map2.put("appId",payhospital.getAppid());
map2.put("nonceStr",suijishu);
map2.put("package","prepay_id="+prepay_id);
map2.put("signType","MD5");
map2.put("timeStamp",String.valueOf(WXPayUtil.getCurrentTimestamp()));
//生成签名
//将集合M内非空参数值的参数按照参数名ASCII码从小到大排序
String paixu2 = GroupWeuxin.formatUrlMap(map2,false,false);
// 拼接key
String SignTemp2 = paixu2+"&key="+payhospital.getKeyy();
// MD5加密 并且转换为大写
String sign2 = Md5Util.getMD5String(SignTemp2).toUpperCase();
map2.put("paySign",sign2);
// 判断签名是否正确
Boolean bool = WXPayUtil.isSignatureValid(map2,payhospital.getKeyy(),WXPayConstants.SignType.MD5);
System.out.println("第二次:"+bool);
第一次成功返回prepay_id第二次签名出错,调用支付JSAPI缺少参数:total_fee
求解答!!!!!!!!!!!!!!
total_fee 应该 是数字吧,不应该字符串
json["nonce_str"] = nonceStr;
json["spbill_create_ip"] = req.headers["x-real-ip"];
json["openid"] = req.body.openid;
json["out_trade_no"] = "HT" + new Date().getTime();
json["attach"] = "video";
json["body"] = "xxxxxx";
json["total_fee"] = req.body.prize * 100;
if (req.body.openid == "o_4cdwLYetpn4sA0_IHp_Cr4Y-GM" || req.body.openid=="o_4cdwIf9ErsXQ03OgYFwv8qj_MU") {
json["total_fee"] = 1;
}
https://blog.csdn.net/ihtml5/article/details/87938992
public Map<String, Object> createUnifiedOrder(UnifiedOrder order) {
HashMap<String, Object> map = new HashMap<>();
map.put("appid", this.appId);// 应用ID
map.put("mch_id", this.mchId);// 商户号
// map.put("device_info", "");//设备号
map.put("nonce_str", getRandamStr());// 随机字符串
if (order.body.length() > 64)
map.put("body", order.body.substring(0, 64));// 商品描述
else
map.put("body", order.body);// 商品描述
// map.put("detail", "");//商品详情
// map.put("attach", "");//附加数据
map.put("out_trade_no", order.out_trade_no);// 商户订单号
// map.put("fee_type", "");//货币类型
map.put("total_fee", order.total_fee);// 总金额(单位分)
map.put("spbill_create_ip", order.spbill_create_ip);// 客户端IP
// map.put("time_start", "");//交易起始时间
// map.put("time_expire", "");//交易结束时间
// map.put("goods_tag", "");//商品标记
map.put("notify_url", this.notifyUrl);// 通知地址
if (order.sub_mch_id != null)
map.put("sub_mch_id", order.sub_mch_id);// 子商户订单号
if (order.openid == null)
map.put("trade_type", "APP");// 交易类型
else {
map.put("trade_type", "JSAPI");// 交易类型
map.put("openid", order.openid);
}
map.put("sign", SignUtils.getSign(map, this.apiKey));// 签名
// map.put("limit_pay", "");// 指定支付方式
// post调取方法
String return_xml = postString(URL_CREATE_UNIFIEDORDER, XMLUtils.toXML(map));
logger.debug("[UnifiedOrder]" + return_xml);
Map<String, Object> result = XMLUtils.doXMLParse(return_xml);
String returnCode = getValue(result, "return_code");
String resultCode = getValue(result, "result_code");
if ("SUCCESS".equals(returnCode) && "SUCCESS".equals(resultCode)) {
String prepayid = getValue(result, "prepay_id");
HashMap<String, Object> maplast = new HashMap<>();
if (order.openid == null) {
maplast.put("appid", this.appId);
maplast.put("noncestr", getRandamStr());
maplast.put("partnerid", this.mchId);
maplast.put("prepayid", prepayid);
maplast.put("timestamp", getTimestamp());
maplast.put("package", "Sign=WXPay");
maplast.put("sign", SignUtils.getSign(maplast, this.apiKey));
} else {
maplast.put("appId", this.appId);
maplast.put("nonceStr", getRandamStr());
maplast.put("package", "prepay_id=" + prepayid);
maplast.put("timeStamp", getTimestamp());
maplast.put("signType", "MD5");
maplast.put("paySign", SignUtils.getSign(maplast, this.apiKey));
}
return maplast;
}
return null;
}
下面是SignUtils的getSign实现
public static String getSign(HashMap<String, Object> map, String apiKey) {
StringBuffer sb = new StringBuffer();
TreeMap<String, Object> sortmap = new TreeMap<>(map);
Object obj;
for (String key : sortmap.keySet()) {
obj = sortmap.get(key);
if (obj == null || "".equals(obj.toString()))
continue;
sb.append(key);
sb.append("=");
sb.append(obj);
sb.append("&");
}
sb.append("key=");
sb.append(apiKey);
return encodeByMD5(sb.toString()).toUpperCase();
}