小程序支付SDK,刚开始做,网上找了很多,下载了三个demo,最后发现都有不同的实际问题,无法运行或各种报错,这玩意还是需要个干货!

讲重点:

1.下载微信官方的SDK

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

选择下载java版本最佳实践。

2.将以下文件拷到你的后台项目中

3.在同文件夹下创建此继承类

package com.***.utils.wx;import java.io.ByteArrayInputStream;
import java.io.InputStream;/*** @Description: 微信支付配置类* @Author: hm* @CreateDate: 2018/12/10 17:19.* @UpdateDate: 2018/12/10 17:19.* @Version: 1.0*/
public class MyConfig extends WXPayConfig {private byte[] certData;public MyConfig() throws Exception {
//        String certPath = "classpath:apiclient_cert.p12";
//        File file = new File(certPath);
//        InputStream certStream = new FileInputStream(file);
//        this.certData = new byte[(int) file.length()];
//        certStream.read(this.certData);
//        certStream.close();}@Overridepublic String getAppID() {return "你的appid";}@Overridepublic String getMchID() {return "你的商户id";}@Overridepublic String getKey() {return "你的商户api安全key,在商户平台api安全目录下可设置";}@Overridepublic InputStream getCertStream() {ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);return certBis;}@Overridepublic int getHttpConnectTimeoutMs() {return 8000;}@Overridepublic int getHttpReadTimeoutMs() {return 10000;}@OverrideIWXPayDomain getWXPayDomain() {return new IWXPayDomain() {@Overridepublic void report(String domain, long elapsedTimeMillis, Exception ex) {}@Overridepublic DomainInfo getDomain(WXPayConfig config) {return new DomainInfo("api.mch.weixin.qq.com", false);}};}
}

4.java后台的调用统一下单接口类

/*** 微信统一下单接口* @return*/@RequestMapping(value = "/doUnifiedOrder", method = RequestMethod.POST)public BaseResponse<Map> doUnifiedOrder(@RequestBody BaesRequest<> baseRequest) {BaseResponse<Map> response = new BaseResponse<>();Map resultMap=new HashMap();String openid = baseRequest.getRequestData().getOpenId();MyConfig config = null;WXPay wxpay =null;try {config = new MyConfig();wxpay= new WXPay(config);} catch (Exception e) {e.printStackTrace();}//生成的随机字符串String nonce_str = WXPayUtil.generateNonceStr();//获取客户端的ip地址//获取本机的ip地址InetAddress addr = null;try {addr = InetAddress.getLocalHost();} catch (UnknownHostException e) {e.printStackTrace();}String spbill_create_ip = addr.getHostAddress();//支付金额,需要转成字符串类型,否则后面的签名会失败int  total_fee=1;//商品描述String body = "车费支付";//商户订单号String out_trade_no= WXPayUtil.generateNonceStr();//统一下单接口参数HashMap<String, String> data = new HashMap<String, String>();data.put("appid", appid);data.put("mch_id", mch_id);data.put("nonce_str", nonce_str);data.put("body", body);data.put("out_trade_no",out_trade_no);data.put("total_fee", String.valueOf(total_fee));data.put("spbill_create_ip", spbill_create_ip);data.put("notify_url", notify_url);data.put("trade_type",TRADETYPE);data.put("openid", openid);try {Map<String, String> rMap = wxpay.unifiedOrder(data);System.out.println("统一下单接口返回: " + rMap);String return_code = (String) rMap.get("return_code");String result_code = (String) rMap.get("result_code");String nonceStr = WXPayUtil.generateNonceStr();resultMap.put("nonceStr", nonceStr);Long timeStamp = System.currentTimeMillis() / 1000;if ("SUCCESS".equals(return_code) && return_code.equals(result_code)) {String prepayid = rMap.get("prepay_id");resultMap.put("package", "prepay_id="+prepayid);resultMap.put("signType", "MD5");//这边要将返回的时间戳转化成字符串,不然小程序端调用wx.requestPayment方法会报签名错误resultMap.put("timeStamp", timeStamp + "");//再次签名,这个签名用于小程序端调用wx.requesetPayment方法resultMap.put("appId",appid);String sign = WXPayUtil.generateSignature(resultMap, key);resultMap.put("paySign", sign);System.out.println("生成的签名paySign : "+ sign);response.setData(resultMap);return response;}else{return  response;}} catch (Exception e) {e.printStackTrace();return  response;}}

5.小程序端的支付请求

payNow: function() {var that = this;wx.request({url: app.data.requestUrl + 'weChatPay/doUnifiedOrder',header: {"Content-Type": "application/json;charset=UTF-8"},data: {requestData: {openId: app.globalData.openId}},method: 'POST',dataType: 'json',responseType: 'text',success: function(res) {console.log("服务端返回订单号");var c=res.data;wx.requestPayment({timeStamp: res.data.data.timeStamp,nonceStr: res.data.data.nonceStr,package: res.data.data.package,signType: 'MD5',paySign: res.data.data.paySign,success(res) {console.log("统一下单接口成功");},fail(res) {console.log("统一下单接口失败");}});},fail: function(res) {},complete: function(res) {},});}

6.超简单支付过程,只需要修改配置文件中你自己的appid等信息就可以使用了。文中没有java后台的业务逻辑,可以自己添加,这里主要实现支付功能。(为了隐私,截图中屏蔽了主体信息。)

补充:有人问BaseResponse类,只是项目中封装的一个请求响应父类,你们在自己项目里可以不用管的。但还是把这两个类贴在这里吧。

BaseResponse类


public class BaseResponse<T> {/*** 状态码 200是成功,300是失败,301是超时*/private String statusCode = "200";/*** 错误信息, example = "error"*/private String message;/*** 返回前台的数据*/private T data;public BaseResponse() {super();}public BaseResponse(String statusCode, String message) {super();this.statusCode = statusCode;this.message = message;}public BaseResponse failure() {this.statusCode = "300";this.message = "Response exception";return this;}public BaseResponse failure(String massage) {this.statusCode = "300";this.message = massage;return this;}public String getStatusCode() {return statusCode;}public void setStatusCode(String statusCode) {this.statusCode = statusCode;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public T getData() {return data;}public void setData(T data) {this.data = data;}
}

BaseRequest类

public class BaesRequest<T> {/***  请求对象*/T requestData;public BaesRequest(){super();}public T getRequestData(){return requestData;}public void setRequestData(T requestData) {this.requestData = requestData;}}

统一回复下评论的问题:签名那块会报错,原因是微信SDK中设置正式环境的加密方式不对,将加密方式改为与沙箱环境一样的 MD5加密方式即可。如果你使用以上代码没有出现签名错误,说明微信SDK已经修改过来了。如果出现签名错误,请确认其它参数无误后按照以下方式修改:

1.找到上面复制到项目中的这个类 WXPay

2.打开找到这个位置

3.修改else中的内容如下

this.signType = SignType.MD5;

如果你懒得找,可以直接复制此类替换你项目中的该类

package com.github.wxpay.sdk;import com.github.wxpay.sdk.WXPayConstants.SignType;import java.util.HashMap;
import java.util.Map;public class WXPay {private WXPayConfig config;private SignType signType;private boolean autoReport;private boolean useSandbox;private String notifyUrl;private WXPayRequest wxPayRequest;public WXPay(final WXPayConfig config) throws Exception {this(config, null, true, false);}public WXPay(final WXPayConfig config, final boolean autoReport) throws Exception {this(config, null, autoReport, false);}public WXPay(final WXPayConfig config, final boolean autoReport, final boolean useSandbox) throws Exception{this(config, null, autoReport, useSandbox);}public WXPay(final WXPayConfig config, final String notifyUrl) throws Exception {this(config, notifyUrl, true, false);}public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport) throws Exception {this(config, notifyUrl, autoReport, false);}public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport, final boolean useSandbox) throws Exception {this.config = config;this.notifyUrl = notifyUrl;this.autoReport = autoReport;this.useSandbox = useSandbox;if (useSandbox) {this.signType = SignType.MD5; // 沙箱环境}else {this.signType = SignType.MD5;}this.wxPayRequest = new WXPayRequest(config);}private void checkWXPayConfig() throws Exception {if (this.config == null) {throw new Exception("config is null");}if (this.config.getAppID() == null || this.config.getAppID().trim().length() == 0) {throw new Exception("appid in config is empty");}if (this.config.getMchID() == null || this.config.getMchID().trim().length() == 0) {throw new Exception("appid in config is empty");}if (this.config.getCertStream() == null) {throw new Exception("cert stream in config is empty");}if (this.config.getWXPayDomain() == null){throw new Exception("config.getWXPayDomain() is null");}if (this.config.getHttpConnectTimeoutMs() < 10) {throw new Exception("http connect timeout is too small");}if (this.config.getHttpReadTimeoutMs() < 10) {throw new Exception("http read timeout is too small");}}/*** 向 Map 中添加 appid、mch_id、nonce_str、sign_type、sign <br>* 该函数适用于商户适用于统一下单等接口,不适用于红包、代金券接口** @param reqData* @return* @throws Exception*/public Map<String, String> fillRequestData(Map<String, String> reqData) throws Exception {reqData.put("appid", config.getAppID());reqData.put("mch_id", config.getMchID());reqData.put("nonce_str", WXPayUtil.generateNonceStr());if (SignType.MD5.equals(this.signType)) {reqData.put("sign_type", WXPayConstants.MD5);}else if (SignType.HMACSHA256.equals(this.signType)) {reqData.put("sign_type", WXPayConstants.HMACSHA256);}reqData.put("sign", WXPayUtil.generateSignature(reqData, config.getKey(), this.signType));return reqData;}/*** 判断xml数据的sign是否有效,必须包含sign字段,否则返回false。** @param reqData 向wxpay post的请求数据* @return 签名是否有效* @throws Exception*/public boolean isResponseSignatureValid(Map<String, String> reqData) throws Exception {// 返回数据的签名方式和请求中给定的签名方式是一致的return WXPayUtil.isSignatureValid(reqData, this.config.getKey(), this.signType);}/*** 判断支付结果通知中的sign是否有效** @param reqData 向wxpay post的请求数据* @return 签名是否有效* @throws Exception*/public boolean isPayResultNotifySignatureValid(Map<String, String> reqData) throws Exception {String signTypeInData = reqData.get(WXPayConstants.FIELD_SIGN_TYPE);SignType signType;if (signTypeInData == null) {signType = SignType.MD5;}else {signTypeInData = signTypeInData.trim();if (signTypeInData.length() == 0) {signType = SignType.MD5;}else if (WXPayConstants.MD5.equals(signTypeInData)) {signType = SignType.MD5;}else if (WXPayConstants.HMACSHA256.equals(signTypeInData)) {signType = SignType.HMACSHA256;}else {throw new Exception(String.format("Unsupported sign_type: %s", signTypeInData));}}return WXPayUtil.isSignatureValid(reqData, this.config.getKey(), signType);}/*** 不需要证书的请求* @param urlSuffix String* @param reqData 向wxpay post的请求数据* @param connectTimeoutMs 超时时间,单位是毫秒* @param readTimeoutMs 超时时间,单位是毫秒* @return API返回数据* @throws Exception*/public String requestWithoutCert(String urlSuffix, Map<String, String> reqData,int connectTimeoutMs, int readTimeoutMs) throws Exception {String msgUUID = reqData.get("nonce_str");String reqBody = WXPayUtil.mapToXml(reqData);String resp = this.wxPayRequest.requestWithoutCert(urlSuffix, msgUUID, reqBody, connectTimeoutMs, readTimeoutMs, autoReport);return resp;}/*** 需要证书的请求* @param urlSuffix String* @param reqData 向wxpay post的请求数据  Map* @param connectTimeoutMs 超时时间,单位是毫秒* @param readTimeoutMs 超时时间,单位是毫秒* @return API返回数据* @throws Exception*/public String requestWithCert(String urlSuffix, Map<String, String> reqData,int connectTimeoutMs, int readTimeoutMs) throws Exception {String msgUUID= reqData.get("nonce_str");String reqBody = WXPayUtil.mapToXml(reqData);String resp = this.wxPayRequest.requestWithCert(urlSuffix, msgUUID, reqBody, connectTimeoutMs, readTimeoutMs, this.autoReport);return resp;}/*** 处理 HTTPS API返回数据,转换成Map对象。return_code为SUCCESS时,验证签名。* @param xmlStr API返回的XML格式数据* @return Map类型数据* @throws Exception*/public Map<String, String> processResponseXml(String xmlStr) throws Exception {String RETURN_CODE = "return_code";String return_code;Map<String, String> respData = WXPayUtil.xmlToMap(xmlStr);if (respData.containsKey(RETURN_CODE)) {return_code = respData.get(RETURN_CODE);}else {throw new Exception(String.format("No `return_code` in XML: %s", xmlStr));}if (return_code.equals(WXPayConstants.FAIL)) {return respData;}else if (return_code.equals(WXPayConstants.SUCCESS)) {if (this.isResponseSignatureValid(respData)) {return respData;}else {throw new Exception(String.format("Invalid sign value in XML: %s", xmlStr));}}else {throw new Exception(String.format("return_code value %s is invalid in XML: %s", return_code, xmlStr));}}/*** 作用:提交刷卡支付<br>* 场景:刷卡支付* @param reqData 向wxpay post的请求数据* @return API返回数据* @throws Exception*/public Map<String, String> microPay(Map<String, String> reqData) throws Exception {return this.microPay(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());}/*** 作用:提交刷卡支付<br>* 场景:刷卡支付* @param reqData 向wxpay post的请求数据* @param connectTimeoutMs 连接超时时间,单位是毫秒* @param readTimeoutMs 读超时时间,单位是毫秒* @return API返回数据* @throws Exception*/public Map<String, String> microPay(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {String url;if (this.useSandbox) {url = WXPayConstants.SANDBOX_MICROPAY_URL_SUFFIX;}else {url = WXPayConstants.MICROPAY_URL_SUFFIX;}String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);return this.processResponseXml(respXml);}/*** 提交刷卡支付,针对软POS,尽可能做成功* 内置重试机制,最多60s* @param reqData* @return* @throws Exception*/public Map<String, String> microPayWithPos(Map<String, String> reqData) throws Exception {return this.microPayWithPos(reqData, this.config.getHttpConnectTimeoutMs());}/*** 提交刷卡支付,针对软POS,尽可能做成功* 内置重试机制,最多60s* @param reqData* @param connectTimeoutMs* @return* @throws Exception*/public Map<String, String> microPayWithPos(Map<String, String> reqData, int connectTimeoutMs) throws Exception {int remainingTimeMs = 60*1000;long startTimestampMs = 0;Map<String, String> lastResult = null;Exception lastException = null;while (true) {startTimestampMs = WXPayUtil.getCurrentTimestampMs();int readTimeoutMs = remainingTimeMs - connectTimeoutMs;if (readTimeoutMs > 1000) {try {lastResult = this.microPay(reqData, connectTimeoutMs, readTimeoutMs);String returnCode = lastResult.get("return_code");if (returnCode.equals("SUCCESS")) {String resultCode = lastResult.get("result_code");String errCode = lastResult.get("err_code");if (resultCode.equals("SUCCESS")) {break;}else {// 看错误码,若支付结果未知,则重试提交刷卡支付if (errCode.equals("SYSTEMERROR") || errCode.equals("BANKERROR") || errCode.equals("USERPAYING")) {remainingTimeMs = remainingTimeMs - (int)(WXPayUtil.getCurrentTimestampMs() - startTimestampMs);if (remainingTimeMs <= 100) {break;}else {WXPayUtil.getLogger().info("microPayWithPos: try micropay again");if (remainingTimeMs > 5*1000) {Thread.sleep(5*1000);}else {Thread.sleep(1*1000);}continue;}}else {break;}}}else {break;}}catch (Exception ex) {lastResult = null;lastException = ex;}}else {break;}}if (lastResult == null) {throw lastException;}else {return lastResult;}}/*** 作用:统一下单<br>* 场景:公共号支付、扫码支付、APP支付* @param reqData 向wxpay post的请求数据* @return API返回数据* @throws Exception*/public Map<String, String> unifiedOrder(Map<String, String> reqData) throws Exception {return this.unifiedOrder(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());}/*** 作用:统一下单<br>* 场景:公共号支付、扫码支付、APP支付* @param reqData 向wxpay post的请求数据* @param connectTimeoutMs 连接超时时间,单位是毫秒* @param readTimeoutMs 读超时时间,单位是毫秒* @return API返回数据* @throws Exception*/public Map<String, String> unifiedOrder(Map<String, String> reqData,  int connectTimeoutMs, int readTimeoutMs) throws Exception {String url;if (this.useSandbox) {url = WXPayConstants.SANDBOX_UNIFIEDORDER_URL_SUFFIX;}else {url = WXPayConstants.UNIFIEDORDER_URL_SUFFIX;}if(this.notifyUrl != null) {reqData.put("notify_url", this.notifyUrl);}String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);return this.processResponseXml(respXml);}/*** 作用:查询订单<br>* 场景:刷卡支付、公共号支付、扫码支付、APP支付* @param reqData 向wxpay post的请求数据* @return API返回数据* @throws Exception*/public Map<String, String> orderQuery(Map<String, String> reqData) throws Exception {return this.orderQuery(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());}/*** 作用:查询订单<br>* 场景:刷卡支付、公共号支付、扫码支付、APP支付* @param reqData 向wxpay post的请求数据 int* @param connectTimeoutMs 连接超时时间,单位是毫秒* @param readTimeoutMs 读超时时间,单位是毫秒* @return API返回数据* @throws Exception*/public Map<String, String> orderQuery(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {String url;if (this.useSandbox) {url = WXPayConstants.SANDBOX_ORDERQUERY_URL_SUFFIX;}else {url = WXPayConstants.ORDERQUERY_URL_SUFFIX;}String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);return this.processResponseXml(respXml);}/*** 作用:撤销订单<br>* 场景:刷卡支付* @param reqData 向wxpay post的请求数据* @return API返回数据* @throws Exception*/public Map<String, String> reverse(Map<String, String> reqData) throws Exception {return this.reverse(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());}/*** 作用:撤销订单<br>* 场景:刷卡支付<br>* 其他:需要证书* @param reqData 向wxpay post的请求数据* @param connectTimeoutMs 连接超时时间,单位是毫秒* @param readTimeoutMs 读超时时间,单位是毫秒* @return API返回数据* @throws Exception*/public Map<String, String> reverse(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {String url;if (this.useSandbox) {url = WXPayConstants.SANDBOX_REVERSE_URL_SUFFIX;}else {url = WXPayConstants.REVERSE_URL_SUFFIX;}String respXml = this.requestWithCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);return this.processResponseXml(respXml);}/*** 作用:关闭订单<br>* 场景:公共号支付、扫码支付、APP支付* @param reqData 向wxpay post的请求数据* @return API返回数据* @throws Exception*/public Map<String, String> closeOrder(Map<String, String> reqData) throws Exception {return this.closeOrder(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());}/*** 作用:关闭订单<br>* 场景:公共号支付、扫码支付、APP支付* @param reqData 向wxpay post的请求数据* @param connectTimeoutMs 连接超时时间,单位是毫秒* @param readTimeoutMs 读超时时间,单位是毫秒* @return API返回数据* @throws Exception*/public Map<String, String> closeOrder(Map<String, String> reqData,  int connectTimeoutMs, int readTimeoutMs) throws Exception {String url;if (this.useSandbox) {url = WXPayConstants.SANDBOX_CLOSEORDER_URL_SUFFIX;}else {url = WXPayConstants.CLOSEORDER_URL_SUFFIX;}String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);return this.processResponseXml(respXml);}/*** 作用:申请退款<br>* 场景:刷卡支付、公共号支付、扫码支付、APP支付* @param reqData 向wxpay post的请求数据* @return API返回数据* @throws Exception*/public Map<String, String> refund(Map<String, String> reqData) throws Exception {return this.refund(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());}/*** 作用:申请退款<br>* 场景:刷卡支付、公共号支付、扫码支付、APP支付<br>* 其他:需要证书* @param reqData 向wxpay post的请求数据* @param connectTimeoutMs 连接超时时间,单位是毫秒* @param readTimeoutMs 读超时时间,单位是毫秒* @return API返回数据* @throws Exception*/public Map<String, String> refund(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {String url;if (this.useSandbox) {url = WXPayConstants.SANDBOX_REFUND_URL_SUFFIX;}else {url = WXPayConstants.REFUND_URL_SUFFIX;}String respXml = this.requestWithCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);return this.processResponseXml(respXml);}/*** 作用:退款查询<br>* 场景:刷卡支付、公共号支付、扫码支付、APP支付* @param reqData 向wxpay post的请求数据* @return API返回数据* @throws Exception*/public Map<String, String> refundQuery(Map<String, String> reqData) throws Exception {return this.refundQuery(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());}/*** 作用:退款查询<br>* 场景:刷卡支付、公共号支付、扫码支付、APP支付* @param reqData 向wxpay post的请求数据* @param connectTimeoutMs 连接超时时间,单位是毫秒* @param readTimeoutMs 读超时时间,单位是毫秒* @return API返回数据* @throws Exception*/public Map<String, String> refundQuery(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {String url;if (this.useSandbox) {url = WXPayConstants.SANDBOX_REFUNDQUERY_URL_SUFFIX;}else {url = WXPayConstants.REFUNDQUERY_URL_SUFFIX;}String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);return this.processResponseXml(respXml);}/*** 作用:对账单下载(成功时返回对账单数据,失败时返回XML格式数据)<br>* 场景:刷卡支付、公共号支付、扫码支付、APP支付* @param reqData 向wxpay post的请求数据* @return API返回数据* @throws Exception*/public Map<String, String> downloadBill(Map<String, String> reqData) throws Exception {return this.downloadBill(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());}/*** 作用:对账单下载<br>* 场景:刷卡支付、公共号支付、扫码支付、APP支付<br>* 其他:无论是否成功都返回Map。若成功,返回的Map中含有return_code、return_msg、data,*      其中return_code为`SUCCESS`,data为对账单数据。* @param reqData 向wxpay post的请求数据* @param connectTimeoutMs 连接超时时间,单位是毫秒* @param readTimeoutMs 读超时时间,单位是毫秒* @return 经过封装的API返回数据* @throws Exception*/public Map<String, String> downloadBill(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {String url;if (this.useSandbox) {url = WXPayConstants.SANDBOX_DOWNLOADBILL_URL_SUFFIX;}else {url = WXPayConstants.DOWNLOADBILL_URL_SUFFIX;}String respStr = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs).trim();Map<String, String> ret;// 出现错误,返回XML数据if (respStr.indexOf("<") == 0) {ret = WXPayUtil.xmlToMap(respStr);}else {// 正常返回csv数据ret = new HashMap<String, String>();ret.put("return_code", WXPayConstants.SUCCESS);ret.put("return_msg", "ok");ret.put("data", respStr);}return ret;}/*** 作用:交易保障<br>* 场景:刷卡支付、公共号支付、扫码支付、APP支付* @param reqData 向wxpay post的请求数据* @return API返回数据* @throws Exception*/public Map<String, String> report(Map<String, String> reqData) throws Exception {return this.report(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());}/*** 作用:交易保障<br>* 场景:刷卡支付、公共号支付、扫码支付、APP支付* @param reqData 向wxpay post的请求数据* @param connectTimeoutMs 连接超时时间,单位是毫秒* @param readTimeoutMs 读超时时间,单位是毫秒* @return API返回数据* @throws Exception*/public Map<String, String> report(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {String url;if (this.useSandbox) {url = WXPayConstants.SANDBOX_REPORT_URL_SUFFIX;}else {url = WXPayConstants.REPORT_URL_SUFFIX;}String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);return WXPayUtil.xmlToMap(respXml);}/*** 作用:转换短链接<br>* 场景:刷卡支付、扫码支付* @param reqData 向wxpay post的请求数据* @return API返回数据* @throws Exception*/public Map<String, String> shortUrl(Map<String, String> reqData) throws Exception {return this.shortUrl(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());}/*** 作用:转换短链接<br>* 场景:刷卡支付、扫码支付* @param reqData 向wxpay post的请求数据* @return API返回数据* @throws Exception*/public Map<String, String> shortUrl(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {String url;if (this.useSandbox) {url = WXPayConstants.SANDBOX_SHORTURL_URL_SUFFIX;}else {url = WXPayConstants.SHORTURL_URL_SUFFIX;}String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);return this.processResponseXml(respXml);}/*** 作用:授权码查询OPENID接口<br>* 场景:刷卡支付* @param reqData 向wxpay post的请求数据* @return API返回数据* @throws Exception*/public Map<String, String> authCodeToOpenid(Map<String, String> reqData) throws Exception {return this.authCodeToOpenid(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());}/*** 作用:授权码查询OPENID接口<br>* 场景:刷卡支付* @param reqData 向wxpay post的请求数据* @param connectTimeoutMs 连接超时时间,单位是毫秒* @param readTimeoutMs 读超时时间,单位是毫秒* @return API返回数据* @throws Exception*/public Map<String, String> authCodeToOpenid(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {String url;if (this.useSandbox) {url = WXPayConstants.SANDBOX_AUTHCODETOOPENID_URL_SUFFIX;}else {url = WXPayConstants.AUTHCODETOOPENID_URL_SUFFIX;}String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);return this.processResponseXml(respXml);}} // end class

微信小程序支付SDK集成springboot相关推荐

  1. 如何处理微信小程序支付下载下来的对账单以及证书读取

    在网上稍微搜了一下,有一篇介绍了如何处理,但那时候的对账单数据与我现在下载下来的似乎有点误差,在这里我不谈论对方的方法对错,我只写下自己的处理过程. 首先,先看下获取的对账单数据: 2019-03-1 ...

  2. 【问题排查与解决】ios调起微信小程序支付失败

    ios调起微信小程序支付SDK失败 场景 排查方向(1. 支付规范导致2. 参数缺少导致3. sdk版本问题) 微信小程序支付规范 解决方式 调起微信小程序参数问题(需要传入当前小程序的appId) ...

  3. 微信小程序、app集成微信支付

    一.微信小程序支付 开发文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_11&index=2 申请小程序 ...

  4. 微信小程序支付java服务端集成采坑总结

    先上个微信小程序支付官方文档地址: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_7&index=8 重点看 ...

  5. SpringBoot对接微信小程序支付功能开发(一,下单功能)

    1,接入前准备: 接入模式选择直连模式: 申请小程序,得到APPID,并开通微信支付: 申请微信商户号,得到mchid,并绑定APPID: 配置商户API key,下载并配置商户证书,根据微信官方文档 ...

  6. SpringBoot 搭建微信小程序支付(JSAPI) 纯后端

    一.支付流程 PS:做这个之前  ,先去下载官方的SDK吧  https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 1.首先要拿到 ...

  7. 基于springboot微信小程序支付功能实现

    基于springboot微信小程序支付功能实现 简单的封装微信小程序支付功能,支付工具类所依赖的fastjson.lombok.wagegger, 1.添加maven依赖: 版本号可根据自己项目的实际 ...

  8. SpringBoot对接微信小程序支付功能开发(二,支付回调功能)

    接着上一篇: SpringBoot对接微信小程序支付功能开发(一,下单功能) 在上一篇下单功能中我们有传支付结果回调地址. 下面是回调接口实现 package com.office.miniapp.c ...

  9. SpringBoot实现微信小程序支付

    本文给大家讲解微信小程序支付全流程,以及相关功能源代码,项目不开放,带来不便尽请谅解.小程序支付主要 包含如下几步骤,1.预下单-调用微信统一下单接口进行预下单.2.小程序拿到支付参数唤醒支付.3.支 ...

最新文章

  1. 在Ubuntu 14.04 64bit上升级安装ATS 5.3.2/6.1.1实录
  2. 各小组对于自己产品的预期“软件下载/用户人数”
  3. html多级折叠菜单表单,JS实战篇之收缩菜单表单布局
  4. SIAMATIC S7-1200 中通过 Modbus RTU 如何读取地址范围 9999 到 65535 的输入字
  5. 本田电动SUV Prologue拟2024年上市销售 初始年销售目标7万辆
  6. win7下,令人头疼的 classpnp.sys (附带:安装系统时蓝屏;0x0000007b)。
  7. MySQL删除s表命令_SQL语句中删除表数据drop、truncate和delete的用法
  8. 【oracle】查看当前用户各个表的记录数
  9. CC呼叫中心系统源码注册机cccloud
  10. URL转换成IP的过程
  11. Kettle使用 js 文件生成节假日表文件 附带2019-2020节假日文件
  12. 自己动手编写CSDN博客备份工具-blogspider之源码分析(2)
  13. 开始编写寄几的 CSS 基础库
  14. Unity3D 制作游戏简单“跑马灯”功能
  15. 基于PaddleOCR银行卡识别实现(一)
  16. 【面试题】1383- 面试官问:Vue3 对比 Vue2 有哪些变化?
  17. 【SQL】练习题184道
  18. 如何在word中粘贴美观工整的代码段(planetB/notepad++)
  19. 2022(招聘季)linux面试高频题
  20. 学者爱当官--学界官本位阴魂不散?

热门文章

  1. 人际交往类的书籍推荐
  2. 欧拉角计算xy轴与水平面夹角
  3. Kaggle - 图片脏文档清洗-python
  4. 翻译工作必备,英文标点符号使用规则
  5. acdream1197 Points In Cuboid
  6. 【Unity3D基础概念】给初学者看的Unity概览(一):GameObject,Compoent,Time,Input,Physics...
  7. HFirst解读和复现心得
  8. I4mc-deep: 利用具有化学特性的深度学习方法,对 n4- 甲基胞嘧啶位点进行智能预测
  9. 导出Word几种方法
  10. mac 上如何安装及切换输入法