第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > Java 微信支付接口(统一下单 异步回调 订单退款 取消订单)

Java 微信支付接口(统一下单 异步回调 订单退款 取消订单)

时间:2023-04-06 16:49:54

相关推荐

Java 微信支付接口(统一下单 异步回调 订单退款 取消订单)

一.准备工作

APP绑定微信商户平台获取商户id(mchID)、证书(商户后台下载)、支付签名密钥(商户后台设置api密钥)、退款签名密钥(商户后台设置api密钥ipv3)等

1.导入微信支付SDK

<!--微信支付SDK--><dependency><groupId>com.github.wxpay</groupId><artifactId>wxpay-sdk</artifactId><version>0.0.3</version></dependency>

2.配置微信参数类

@Component@ConfigurationProperties@PropertySource("classpath:config/wxconfig.properties") --需自己创建相应的配置文件@Datapublic class WxConfig implements WXPayConfig {/*** appid*/public String appID;/*** 商户id*/public String mchID;/*** 密钥*/public String key;/*** 退款密钥*/public String refundKey;/*** 连接超时时间*/public int httpConnectTimeoutMs;/*** 读取超时时间*/public int httpReadTimeoutMs;/*** 证书*/public InputStream certStream;/*** 证书路径*/public String certPath;/*** 微信异步通知地址*/public String wxNotifyUrl;public InputStream getCertStream() {byte [] certData=null;InputStream certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(this.getCertPath());try {certData = IOUtils.toByteArray(certStream);certStream.close();} catch (IOException e) {e.printStackTrace();}return new ByteArrayInputStream(certData);}}

二.统一下单

需注入第一步种的配置类

/*微信统一下单接口*/public Map<String, String> wxPayOrder(HashMap param) throws Exception{Double price = Double.valueOf(param.get("price").toString());String paymentDetailNo = param.get("paymentDetailNo").toString();/*转换金额为分*/Map<String, String> respData = null;BigDecimal totalPrice = new BigDecimal(price.toString()); //单位是元String totalFee = totalPrice.multiply(new BigDecimal(100)).toBigInteger().toString();WXPay wxPay = new WXPay(wxconfig, WXPayConstants.SignType.MD5, false);/*调起支付一次签名 得到第一个sign进行下单*/Map<String,String> data = new TreeMap<>();data.put("appid",wxconfig.getAppID());data.put("mch_id",wxconfig.getMchID());//商户号data.put("trade_type","APP");//支付场景 APP 微信app支付 JSAPI 公众号支付 NATIVE 扫码支付data.put("notify_url",wxconfig.getWxNotifyUrl());//回调地址data.put("spbill_create_ip","127.0.0.1"); //终端ipdata.put("total_fee",totalFee); //订单总金额data.put("fee_type","CNY"); //默认人民币data.put("out_trade_no",paymentDetailNo);//交易号data.put("body","**APP-购买业务");//购买显示信息data.put("nonce_str",WXPayUtil.generateNonceStr()); // 随机字符串小于32位String s=WXPayUtil.generateSignature(data, wxconfig.getKey());data.put("sign",s);/** wxPay.unifiedOrder 这个方法中调用微信统一下单接口 */respData = wxPay.unifiedOrder(data);if (respData.get("result_code").equals("SUCCESS")){//返回给APP端的参数并进行签名得到第二个sign,APP端再调起支付接口Map<String,String> repData = new TreeMap<>();repData.put("appid",wxconfig.getAppID());repData.put("partnerid",wxconfig.getMchID());repData.put("prepayid",respData.get("prepay_id"));repData.put("package","Sign=WXPay");repData.put("noncestr",respData.get("nonce_str"));repData.put("timestamp",String.valueOf(System.currentTimeMillis()/1000));String sign = WXPayUtil.generateSignature(repData,wxconfig.getKey()); //调用sdk方法签名respData.put("sign",sign);respData.put("timestamp",repData.get("timestamp"));respData.put("package","Sign=WXPay");}return respData;}

三.异步回调接口

/*微信支付异步回调 支付异常的情况回滚并调用退款接口进行退款*/@Override@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW, rollbackFor=Exception.class)public Boolean wxPayNotifyUrl(Map<String, String> map) throws Exception {log.info(">>>>微信支付回调...<<<<");String out_trade_no = map.get("out_trade_no");String return_code = map.get("return_code");if(return_code.equals("SUCCESS")){log.info(">>>>微信调起成功...<<<<");PaymentDetailVo entity = paymentDao.queryPaymentDetail(out_trade_no);/*微信重复调起-->校验如果已经支付则直接返回*/if(entity.getDetailStatus() == 1){return true;}/*判断sign签名是否一致*/if(WXPayUtil.isSignatureValid(map, wxconfig.getKey())){log.info(">>>>微信签名通过...<<<<");/*校验api返回的金额与流水单的金额是否一致*/if(map.get("total_fee") == null){log.error("API返回无金额!");/*调用退款接口 */wxRefund(out_trade_no,entity.getUserId(), entity.getPaymentStatus());throw new Exception("API返回无金额!");}/*转换金额为元*/BigDecimal totalPrice = new BigDecimal(entity.getPaymentPrice().toString()); //单位是元String paymentPrive = totalPrice.multiply(new BigDecimal(100)).toBigInteger().toString();String total_fee = map.get("total_fee").toString();if(!total_fee.equals(paymentPrive)){log.error("API返回的交易金额与流水单的金额不一致,存在假通知的危险!");wxRefund(out_trade_no,entity.getUserId(), entity.getPaymentStatus());throw new Exception("API返回的交易金额与流水单的金额不一致,存在假通知的危险!");}HashMap param = new HashMap();param.put("no", entity.getPaymentNo());/*异步回调成功,修改订单状态*/...log.info(">>>>微信异步回调完毕...<<<<");}else{log.error("API返回的数据签名验证不通过,有可能被第三方篡改!!!");wxRefund(out_trade_no,entity.getUserId(), Integer.valueOf(map.get("type").toString()));throw new Exception("API返回的数据签名验证不通过,有可能被第三方篡改!!!");}}else {return false;}return true;}

四.退款接口

/*微信退款*/private Boolean wxDoingRefund(HashMap param) {Double price = Double.valueOf(param.get("price").toString());String paymentDetailNo = param.get("paymentDetailNo").toString();String out_trade_no = param.get("out_trade_no").toString();Map<String, String> respData = null;BigDecimal totalPrice = new BigDecimal(price); //此时的单位是元String totalFee = totalPrice.multiply(new BigDecimal(100)).toBigInteger().toString();try {WXPay wxPay = new WXPay(wxconfig, WXPayConstants.SignType.MD5, false);Map<String,String> data = new TreeMap<>();data.put("appid",wxconfig.getAppID());data.put("mch_id",wxconfig.getMchID());//商户号data.put("total_fee",totalFee); //订单总金额data.put("refund_fee",totalFee); //退款总金额data.put("out_trade_no",out_trade_no);//商户订单号data.put("out_refund_no",paymentDetailNo);//商户退款单号data.put("refund_desc","支付异常");data.put("nonce_str",WXPayUtil.generateNonceStr());// 随机字符串小于32位String s=WXPayUtil.generateSignature(data, wxconfig.getRefundKey());data.put("sign",s);/** wxPay.refund 这个方法中调用微信退款接口 */respData = wxPay.refund(data);if (respData.get("return_code").equals("SUCCESS")){log.info(">>>>微信退款成功...>>>>");return true;}} catch (Exception e) {e.printStackTrace();return false;}return false;}

五.关闭订单

关闭订单——以下情况需要调用关单接口:* 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;* 系统下单后,用户支付超时,系统退出不再受理,避免用户继续,请调用关单接口。* 订单生成后不能马上调用关单接口,最短调用时间间隔为5分钟

/*微信关闭订单*/public Boolean cloaseOrder(String out_trade_no) throws Exception{WXPay wxPay = new WXPay(wxconfig, WXPayConstants.SignType.MD5, false);Map<String, String> respData = null;Map<String,String> data = new TreeMap<>();data.put("appid",wxconfig.getAppID());data.put("mch_id",wxconfig.getMchID());//商户号data.put("out_trade_no",out_trade_no);//商户订单号data.put("nonce_str",WXPayUtil.generateNonceStr()); // 随机字符串小于32位String s=WXPayUtil.generateSignature(data, wxconfig.getRefundKey());data.put("sign",s);/** wxPay.cloaseOrder 这个方法中调用微信退款接口 */respData = wxPay.closeOrder(data);if (respData.get("return_code").equals("SUCCESS")){log.info(">>>>微信关闭订单成功...>>>>");return true;}return false;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。