调第三方接口,首先你需要去看对方的文档,看对方需要你给他哪些参数,有哪些限制,这个是最重要的。我们首先打开微信开放文档,https://pay.weixin.qq.com/partner/public/home 点击进入开放文档,看你需要进行哪些方式支付,比如APP支付,小程序支付,扫描支付等。进入开放文档,去仔细看看支付图,理解这个流程,再去看参数!以下是参数说明: 这个是统一下单接口需要的参数
应用ID appid 这个是登录生成的,可以去看自己的账号
商户号 mch_id 这个是登录账号
子商户应用ID sub_appid 这个填你子商户的ID,没有则不用填
子商户号 sub_mch_id 这个填你子商户的商户号,没有则不用填
设备号 device_info 这个可以不用填
随机字符串 nonce_str 随机生成参数, 推荐32位 自己上网搜索微信生成随机字方法
签名 sign 是 这个签名是你填的所有参数,用Map返回,后面有代码,自己可以去参考
商品描述 body 商品的描述,如购买商品
商品详情 detail 与商品的描述一样
附加数据 attach 可无
商户订单号 out_trade_no 这个是后台下单生成的唯一单号
总金额 total_fee 商品的总金额
终端IP spbill_create_ip 自己写方法,获取当前用户的IP地址
交易起始时间 time_start 时间
交易结束时间 time_expire 时间
订单优惠标记 goods_tag 无
通知地址 notify_url 是 String(256) http://www.weixin.qq.com/wxpay/pay.php 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
交易类型 trade_type 是 String(16) APP 支付类型
指定支付方式 limit_pay 无
本人写的代码
public Object savoLinchpin(int id) {
OrderSupply orderSupply = orderSupplyService.findById(id);
WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();
wxPayUnifiedOrderRequest.setAppid(wxService.getConfig().getAppId());
wxPayUnifiedOrderRequest.setMchId(wxService.getConfig().getMchId());
wxPayUnifiedOrderRequest.setNonceStr(StringUtil.getRandomStr(32));
wxPayUnifiedOrderRequest.setBody(orderSupply.getOrderDetails().get(0).getName() + "商品消费");
wxPayUnifiedOrderRequest.setOutTradeNo(orderSupply.getOrderNumber());
wxPayUnifiedOrderRequest.setTotalFee((int) (orderSupply.getPaymentPrcie() * 100));
wxPayUnifiedOrderRequest.setSpbillCreateIp(StringUtil.getIpAddr(request));
wxPayUnifiedOrderRequest.setNotifyUrl(wxService.getConfig().getNotifyUrl());
wxPayUnifiedOrderRequest.setTradeType(WxPayConstants.TradeType.APP);
SortedMap<String, Object> map = Maps.newTreeMap();
map.put("AppId", wxPayUnifiedOrderRequest.getAppid());
map.put("MchId", wxPayUnifiedOrderRequest.getAppid());
map.put("NonceStr", wxPayUnifiedOrderRequest.getAppid());
map.put("Body", wxPayUnifiedOrderRequest.getAppid());
map.put("OutTradeNo", wxPayUnifiedOrderRequest.getAppid());
map.put("TotalFee", wxPayUnifiedOrderRequest.getAppid());
map.put("SpbillCreateIp", wxPayUnifiedOrderRequest.getAppid());
map.put("NotifyUrl", wxPayUnifiedOrderRequest.getAppid());
map.put("TradeType", wxPayUnifiedOrderRequest.getAppid());
String sign1 = StringUtil.getSign(map);
WxPayUnifiedOrderResult unifiedOrder = this.wxService.unifiedOrder(wxPayUnifiedOrderRequest);
if (unifiedOrder.getResultCode().equals(WxPayConstants.RefundStatus.SUCCESS) && unifiedOrder.getReturnCode().equals(WxPayConstants.RefundStatus.SUCCESS)) {
//签名
String appid = unifiedOrder.getAppid();
String prepayId = unifiedOrder.getPrepayId();
String timeStamp = StringUtil.getTimeStamp();
String nonceStr = StringUtil.getRandomStr(20);
SortedMap<String, Object> signMap = Maps.newTreeMap();
signMap.put("appId", appid);
signMap.put("partnerId", unifiedOrder.getMchId());
signMap.put("prepayId", prepayId);
signMap.put("package", "Sign=WXPay");
signMap.put("nonceStr", nonceStr);
signMap.put("timestamp", timeStamp);
signMap.put("sign", wxService.getConfig().getMchKey());
String sign = StringUtil.getSign(signMap);
signMap.put("sign", sign);
WeiXinOrderVo weiXinOrderVo = (WeiXinOrderVo) StringUtil.mapToObject(signMap, WeiXinOrderVo.class);
weiXinOrderVo.setPackages("Sign=WXPay");
vo.success(weiXinOrderVo);
} else {
vo.fail(ErrorCode.WECHAT_PAY_ERROR, unifiedOrder.getReturnMsg() + "--微信统一下单失败,订单号------" + id);
}
} catch (Exception e) {
log.error(e.toString());
e.printStackTrace();
vo.fail(ErrorCode.WECHAT_PAY_ERROR, "微信统一下单失败,订单号------" + id);
}
}
return vo;
}
仔细看,第一步是set进我的参数,第二步是用map接收我的参数,第三步,把map给支付宝下单接口,形成一个订单!
下单成功,那么前端就用SDK去调微信的微信支付,然后用户进行支付等操作,我们怎么知道是否支付成功?那么就进行回调,看支付是否成功。一样的,去看微信文档,看看回调返回哪些参数。
这个是支付宝回调需要注意的地方:
支付完成后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理,并返回应答。
对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。 (通知频率为15/15/30/180/1800/1800/1800/1800/3600,单位:秒)
这个是回调接口如果成功,返回的正确码,通过这2个参数去判断。
返回状态码 return_code 是 String(16) SUCCESS
请按示例值填写
返回信息 return_msg 是 String(128) OK
请按示例值填写
public String notifyWeiXinPay(HttpServletRequest request) throws Exception {
String xmlStr = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
WxPayOrderNotifyResult notifyResult = wxService.parseOrderNotifyResult(xmlStr);
Map<String, Object> return_data = new HashMap<>(2);
if (!notifyResult.getResultCode().equals(WxPayConstants.RefundStatus.SUCCESS)) {
return_data.put("return_code", "FAIL");
return_data.put("return_msg", "return_code不正确");
log.error("return_code不正确");
} else {
try {
Integer totalFee = notifyResult.getTotalFee();
String outTradeNo = notifyResult.getOutTradeNo();
double total = new BigDecimal(totalFee).divide(new BigDecimal(100)).doubleValue();
OrderSupply orderSupply = orderSupplyService.findOrderByNumber(outTradeNo);
if (orderSupply.getPaymentPrcie() == total) {
return_data.put("return_code", "SUCCESS");
return_data.put("return_msg", "OK");
if (orderSupply.getStatus() > 1) {
return StringUtil.mapToxml(return_data);
} else if (orderSupply.getStatus() == 0) {
notifys(orderSupply);
}
}
} catch (Exception e) {
log.error("回调错误:原因:" + notifyResult.getReturnMsg());
e.printStackTrace();
}
}
return StringUtil.mapToxml(return_data);
}
这接口的含义是:通过WxPayOrderNotifyResult.方法拿到值,去判断结果,再接着做业务逻辑判断,看金额是否匹配,看结果是否正确 !
需要注意的地方:微信金额默认是分,所以需要*100
wxPayUnifiedOrderRequest.setTotalFee((int) (orderSupply.getPaymentPrcie() * 100));
如果说参数错误,签名错误,时间异常等,那么你就要去检查你的密钥,参数是否正确。
作者:技术刘,
来源:CSDN
原文:https://blog.csdn.net/qq_40206199/article/details/84859302
版权声明:本文为博主原创文章,转载请附上博文链接!