springboot接入微信app支付的方法
1.前戲
1.1請(qǐng)先完成微信APP支付接入商戶(hù)服務(wù)中心
1.2詳情請(qǐng)參考微信官方文檔:https://open.weixin.qq.com/
2.application.yml文件的配置如下
#微信支付配置 tenpayconfig: #商戶(hù)APPID appId: asdfg12345 #商戶(hù)號(hào) mchId: 12345678 #商戶(hù)的key(API密匙) key: qwertyuiop #API支付請(qǐng)求地址 payUrl: https://api.mch.weixin.qq.com/pay/unifiedorder #API查詢(xún)請(qǐng)求地址 queryUrl: https://api.mch.weixin.qq.com/pay/orderquery #package packageValue: Sign=WXPay
3.配置文件對(duì)應(yīng)的TenpayConfig,若沒(méi)集成lombok請(qǐng)自行生成get/set方法
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import lombok.Data; /** * @Description: 微信支付配置類(lèi) * @Param: * @return: * @Author: zengXianKang * @Date: 2019/7/28 */ @Data @Component @ConfigurationProperties(prefix = "tenpayconfig") public class TenpayConfig { //appId private String appId; //商戶(hù)號(hào) private String mchId; //商戶(hù)的key(API密匙) private String key; //API支付請(qǐng)求地址 private String payUrl; //API查詢(xún)請(qǐng)求地址 private String queryUrl; //Sign=WXPay private String packageValue; }
3.1新建一個(gè)TenPayVO
import java.math.BigDecimal; import lombok.Data; /** * @description: TenPayVO * @author: zengXianKang * @create: 2019-07-28 **/ @Data public class TenPayVO { //商戶(hù)訂單號(hào) private String outTradeNo; //業(yè)務(wù)結(jié)果 private String resultCode; //簽名方式 private String signType; //簽名 private String sign; //交易類(lèi)型 private String tradeType; //交易狀態(tài) private String tradeState; //商戶(hù)號(hào) private String mchId; //付款銀行 private String bankType; //支付金額 private BigDecimal totalFee; //幣種 private String feeType; //微信支付訂單號(hào) private String transactionId; //支付完成時(shí)間 private String timeEnd; }
3.2由于微信支付和回調(diào)的報(bào)文都是xml,先在maven中添加xstream的jar依賴(lài)
<!--xstream--> <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.7</version> </dependency>
3.3TenPayUtils工具類(lèi),直接拿去用吧,該用到的我基本都寫(xiě)好了,拿走不謝
import com.github.pagehelper.util.StringUtil; import com.huaku.ecom.common.config.TenpayConfig; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.io.xml.DomDriver; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.net.ssl.HttpsURLConnection; import java.io.*; import java.net.URL; import java.security.NoSuchAlgorithmException; import java.util.*; import java.util.Map.Entry; /** * TenPayUtils * @author :zengXianKang */ @Component public class TenPayUtils { private static TenPayUtils tenPayUtils; @Autowired private TenpayConfig tenpayConfig; @PostConstruct public void init(){ tenPayUtils = this; tenPayUtils.tenpayConfig = this.tenpayConfig; } /** * @Description: 微信支付簽名 * * @Param: [paramsMap, charSetName] * @return: java.lang.String * @Author: zengXianKang * @Date: 2019/7/28 */ public String createSign(SortedMap<String, Object> paramsMap, String charSetName) throws UnsupportedEncodingException, NoSuchAlgorithmException { StringBuffer buffer = new StringBuffer(); //參數(shù)按照ACCSII排序(升序) Set set = paramsMap.entrySet(); Iterator iterator = set.iterator(); while (iterator.hasNext()){ Map.Entry entry = (Map.Entry) iterator.next(); String key = (String) entry.getKey(); String value = (String) entry.getValue(); if(!key.equals("sign") && StringUtil.isNotEmpty(value)){ buffer.append(key + "=" + value + "&"); } } buffer.append("key=" + tenPayUtils.tenpayConfig.getKey()); String sign = MDUtils.MD5EncodeForHex(buffer.toString(), charSetName).toUpperCase(); return sign; } /** * @Description: 組裝微信支付請(qǐng)求報(bào)文 * * @Param: [paramsMap] * @return: java.lang.String * @Author: zengXianKang * @Date: 2019/7/28 */ public static String tenPayXmlInfo(SortedMap<String, Object> paramsMap){ StringBuffer buffer = new StringBuffer(); if(paramsMap != null){ buffer.append("<xml>"); for(Map.Entry<String, Object> entry : paramsMap.entrySet()){ buffer.append("<").append(entry.getKey()).append("><![CDATA[").append(entry.getValue()).append("]]></").append(entry.getKey()).append(">"); } buffer.append("</xml>"); } return buffer.toString(); } /** * @Description: 請(qǐng)求調(diào)用URL * * @Param: [requestUrl, requestMethod, output] * @return: java.lang.String * @Author: zengXianKang * @Date: 2019/7/28 */ public static String httpsRequest(String requestUrl, String requestMethod, String output) throws Exception { URL url = new URL(requestUrl); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setUseCaches(false); connection.setRequestMethod(requestMethod); if(StringUtil.isNotEmpty(output)){ OutputStream outputStream = connection.getOutputStream(); outputStream.write(output.getBytes("UTF-8")); outputStream.close(); } InputStream inputStream = connection.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; StringBuffer buffer = new StringBuffer(); while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); inputStream.close(); connection.disconnect(); return buffer.toString(); } /** * @Description: 解析xml * * @Param: [xml, rootName, rowName] * @return: java.lang.Object * @Author: zengXianKang * @Date: 2019/7/28 */ public static Object readXml(String xml, String rootName, String rowName){ XStream xStream = new XStream(new DomDriver()); xStream.alias(rootName, Map.class); xStream.registerConverter(new TenPayUtils.MapEntryConverter(rowName)); Object object = xStream.fromXML(xml); return object; } /** * @Description: 內(nèi)部類(lèi),readXml專(zhuān)用 * * @Param: * @return: * @Author: zengXianKang * @Date: 2019/7/28 */ public static class MapEntryConverter implements Converter { private String rowName; public MapEntryConverter(String rowName) { this.rowName = rowName; } public boolean canConvert(Class clazz) { return Map.class.isAssignableFrom(clazz) || LinkedHashMap.class.isAssignableFrom(clazz); } public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) { this._marshal(value, writer, context); } private void _marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) { Iterator i$; Object object; if (value instanceof Map) { Map map = (Map) value; for (i$ = map.entrySet().iterator(); i$.hasNext(); writer.endNode()) { object = i$.next(); Entry entry = (Entry) object; Object _key = entry.getKey(); Object _value = entry.getValue(); writer.startNode(entry.getKey().toString()); if (_value instanceof Map) { this._marshal(_value, writer, context); } else if (_value instanceof List) { this._marshal(_value, writer, context); } else { writer.setValue(entry.getValue().toString()); } } } else if (value instanceof List) { List list = (List) value; for (i$ = list.iterator(); i$.hasNext(); writer.endNode()) { object = i$.next(); writer.startNode(this.rowName); if (!(object instanceof Map) && !(object instanceof List)) { writer.setValue(object.toString()); } else { this._marshal(object, writer, context); } } } } public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { return this._unmarshal(reader, context); } public Object _unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { Map map = new HashMap(); List list = new ArrayList(); boolean isList; for (isList = false; reader.hasMoreChildren(); reader.moveUp()) { reader.moveDown(); String nodeName = reader.getNodeName(); if (reader.hasMoreChildren()) { if (isList) { list.add(this._unmarshal(reader, context)); } else if (map.containsKey(nodeName)) { isList = true; list.add(map.remove(nodeName)); list.add(this._unmarshal(reader, context)); } else if (this.rowName.equals(nodeName)) { isList = true; list.add(this._unmarshal(reader, context)); } else { map.put(nodeName, this._unmarshal(reader, context)); } } else { String value = reader.getValue(); if (isList) { list.add(value); } else if (map.containsKey(nodeName)) { isList = true; list.add(map.remove(nodeName)); list.add(value); } else if (this.rowName.equals(nodeName)) { isList = true; list.add(value); } else { map.put(nodeName, value); } } } return isList ? list : map; } } }
4.請(qǐng)求微信支付
在很多電商的項(xiàng)目中都有類(lèi)似保存訂單,充值等一系列微信支付場(chǎng)景;我們需要發(fā)起支付返回給前端支付sdk;該篇博文為微信支付的博文,支付寶支付的博文我也已編寫(xiě),若有興趣的話可以去我的博文中看看,希望能幫到你。
4.1發(fā)起支付請(qǐng)求
/** * @Description: 支付請(qǐng)求 * @Param: [payType, outTradeNo, totalAmount] * @return: java.util.Map<java.lang.String,java.lang.String> * @Author: zengXianKang * @Date: 2019/7/28 */ @Override public Map<String, String> payRequest(String payType, String outTradeNo, BigDecimal totalAmount) throws Exception { Map<String, String> map = new HashMap<String, String>(); switch (PayTypeEnum.valueOf(payType)) { case TENPAY://財(cái)付通 SortedMap<String, Object> paramsMap = new TreeMap<String, Object>(); //公眾賬號(hào)ID paramsMap.put("appid", tenpayConfig.getAppId()); //商戶(hù)號(hào) paramsMap.put("mch_id", tenpayConfig.getMchId()); //隨機(jī)字符串 paramsMap.put("nonce_str", Convert.getUUID()); //描述 paramsMap.put("body", "名繪優(yōu)家訂單支付"); //商戶(hù)訂單號(hào)(支付編號(hào)) paramsMap.put("out_trade_no", outTradeNo); //支付金額,金額單位為 分 double price = totalAmount.doubleValue(); int totalFee = (int) (price * 100); paramsMap.put("total_fee", String.valueOf(totalFee)); //回調(diào)地址 paramsMap.put("notify_url", ConstantInfo.TENPAY_ORDER_CALLBACK); //交易類(lèi)型 paramsMap.put("trade_type", "APP"); //用戶(hù)端ip String spbillCreateIp = ""; InetAddress inetAddress = InetAddress.getLocalHost(); if (inetAddress != null) { spbillCreateIp = inetAddress.getHostAddress(); } paramsMap.put("spbill_create_ip", spbillCreateIp); TenPayUtils tenPayUtils = new TenPayUtils(); //sign簽名 String sign = tenPayUtils.createSign(paramsMap, "UTF-8"); paramsMap.put("sign", sign); //請(qǐng)求報(bào)文 String requestXml = TenPayUtils.tenPayXmlInfo(paramsMap); //logger.info("微信支付請(qǐng)求報(bào)文: " + requestXml); //發(fā)送微信支付post請(qǐng)求 String tenPayPost = TenPayUtils.httpsRequest(tenpayConfig.getPayUrl(), "POST", requestXml); //獲取返回 Map<String, String> tenPayMap = (Map<String, String>) TenPayUtils.readXml(tenPayPost, "xml", ""); //微信返回狀態(tài)碼 if (!tenPayMap.get("return_code").equals("SUCCESS")) { logger.error("微信支付請(qǐng)求連接失敗: " + tenPayMap.get("return_msg")); throw new RRException(AppWSConstant.RS_MSG_TENPAY_FALL); } //業(yè)務(wù)結(jié)果 if (!tenPayMap.get("result_code").equals("SUCCESS")) { logger.error("err_code: " + tenPayMap.get("err_code"), "err_code_des: " + tenPayMap.get("err_code_des")); throw new RRException(AppWSConstant.RS_MSG_TENPAY_FALL); } //APPID map.put("appid", tenPayMap.get("appid")); //商戶(hù)號(hào) map.put("partnerid", tenPayMap.get("mch_id")); //預(yù)支付交易會(huì)話ID map.put("prepayid", tenPayMap.get("prepay_id")); //擴(kuò)展字段 map.put("package", tenpayConfig.getPackageValue()); //隨機(jī)字符串 map.put("noncestr", tenPayMap.get("nonce_str")); //時(shí)間戳 map.put("timestamp", String.valueOf(new Date().getTime()).substring(0, 10)); SortedMap<String, Object> signMap = new TreeMap<>(map); String newSign = tenPayUtils.createSign(signMap, "UTF-8"); //簽名 map.put("sign", newSign); break; default: break; } return map; }
4.1.1ConstantInfo中的內(nèi)容為
/** * 常量 */ public class ConstantInfo { //訂單支付財(cái)付通回調(diào)地址 public static String TENPAY_ORDER_CALLBACK = "http://mall.gzmhyj.com:8085/huakuEComBuyer/pay/tenPayOrderCallBack"; }
4.2訂單微信支付回調(diào)
該接口為為微信異步回調(diào)提供的接口
/** * @Description: 訂單微信支付回調(diào) * * @Param: [request] * @return: java.util.Map<java.lang.String,java.lang.String> * @Author: zengXianKang * @Date: 2019/7/28 */ @RequestMapping(value = "/tenPayOrderCallBack", method = RequestMethod.POST) @ResponseBody public Map<String, String> tenPayOrderCallBack(HttpServletRequest request){ Map<String, String> map = new HashMap<String, String>(); try { TenPayVO tenPayVO = payService.tenPayCallBack(request); payService.tenPayOrderCallBack(tenPayVO); map.put("return_code", "SUCCESS"); map.put("return_msg", "OK"); } catch (Exception e) { e.printStackTrace(); } return map; }
4.2.1payService的tenPayCallBack,用于解析回調(diào)的信息,拼接TenPayVO
/** * @Description: 財(cái)付通回調(diào) * @Param: [request] * @return: TenPayVO * @Author: zengXianKang * @Date: 2019/7/28 */ @Override public TenPayVO tenPayCallBack(HttpServletRequest request) throws Exception { InputStream inputStream = request.getInputStream(); StringBuffer resXml = new StringBuffer(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); String str; while ((str = bufferedReader.readLine()) != null) { resXml.append(str); } bufferedReader.close(); inputStream.close(); //logger.info("微信回調(diào)報(bào)文: " + resXml); TenPayVO tenPayVO = this.tenPayCallBackInfo(resXml.toString(), "xml", ""); return tenPayVO; }
4.2.2tenPayCallBackInfo,用于解析微信支付回調(diào)返回結(jié)果,拼接TenPayVO
/** * @Description: 微信支付回調(diào)返回結(jié)果 * @Param: [xml, rootName, rowName] * @return: com.huaku.ecom.system.model.vo.TenPayVO * @Author: zengXianKang * @Date: 2019/7/28 */ private TenPayVO tenPayCallBackInfo(String xml, String rootName, String rowName) throws Exception { Map<String, Object> resHashMap = (Map<String, Object>) TenPayUtils.readXml(xml, "xml", ""); SortedMap<String, Object> resMap = new TreeMap<String, Object>(resHashMap); //微信返回狀態(tài)碼 if (!resMap.get("return_code").equals("SUCCESS")) { logger.error("微信支付回調(diào)連接失敗: " + resMap.get("return_msg")); throw new RRException(AppWSConstant.RS_MSG_TENPAY_FALL); } //業(yè)務(wù)結(jié)果 if (!resMap.get("result_code").equals("SUCCESS")) { logger.error("err_code: " + resMap.get("err_code"), "err_code_des: " + resMap.get("err_code_des")); throw new RRException(AppWSConstant.RS_MSG_TENPAY_FALL); } TenPayUtils tenPayUtils = new TenPayUtils(); //校驗(yàn)簽名 String sign = tenPayUtils.createSign(resMap, "UTF-8"); if (!sign.equals(resMap.get("sign"))) { logger.error("微信支付回調(diào)簽名不正確"); throw new RRException(AppWSConstant.RS_MSG_TENPAY_FALL); } TenPayVO tenPayVO = new TenPayVO(); //商戶(hù)訂單號(hào) tenPayVO.setOutTradeNo((String) resMap.get("out_trade_no")); //業(yè)務(wù)結(jié)果 tenPayVO.setResultCode((String) resMap.get("result_code")); //簽名方式 tenPayVO.setSignType("ASCII"); //簽名 tenPayVO.setSign((String) resMap.get("sign")); //交易類(lèi)型 tenPayVO.setTradeType("APP"); //交易狀態(tài) tenPayVO.setTradeState((String) resMap.get("trade_state")); //商戶(hù)號(hào) tenPayVO.setMchId((String) resMap.get("mch_id")); //付款銀行 tenPayVO.setBankType((String) resMap.get("bank_type")); //交易金額 BigDecimal totalFee = new BigDecimal((String) resMap.get("total_fee")); totalFee = totalFee.divide(new BigDecimal(100)); tenPayVO.setTotalFee(totalFee); //幣種 if (resMap.containsKey("fee_type")) { tenPayVO.setFeeType((String) resMap.get("fee_type")); } //微信支付訂單號(hào) tenPayVO.setTransactionId((String) resMap.get("transaction_id")); //支付完成時(shí)間 tenPayVO.setTimeEnd((String) resMap.get("time_end")); return tenPayVO; }
4.2.3payService的tenPayOrderCallBack,用于自己的回調(diào)完成的業(yè)務(wù)邏輯,如修改訂單狀態(tài),存微信支付交易表等操作
/** * @Description: 微信支付訂單回調(diào) * @Param: [tenPayVO] * @return: void * @Author: zengXianKang * @Date: 2019/7/28 */ @Override public void tenPayOrderCallBack(TenPayVO tenPayVO) throws Exception { if (tenPayVO != null && tenPayVO.getResultCode().equals("SUCCESS") && tenPayVO.getTradeState().equals("SUCCESS")) { //根據(jù)交易編號(hào)加鎖,處理高并發(fā) synchronized (tenPayVO.getOutTradeNo()) { TOrder order = orderMapper.getOneOrderByPayNo(tenPayVO.getOutTradeNo()); if (order.getOrderStatus().equals(OrderStatusEnum.PENDING_PAYMENT.toString())) { //訂單需支付金額總和 BigDecimal payNumSum = this.getPayNumSumByPayNo(tenPayVO.getOutTradeNo()); String orderStatus = ""; //以防萬(wàn)一,再次校驗(yàn)金額 if (payNumSum.compareTo(tenPayVO.getTotalFee()) != 0) { logger.error("***訂單號(hào): " + tenPayVO.getOutTradeNo() + "***微信支付支付金額與訂單需支付金額總和不一致***微信支付金額為:" + tenPayVO.getTotalFee() + " ***訂單需支付金額總為:" + payNumSum + "***日期:" + new Date()); //金額異常,訂單狀態(tài)為支付金額異常 orderStatus = OrderStatusEnum.ABNORMAL_PAYMENT_AMOUNT.toString(); } else { //金額正常,訂單狀態(tài)為已付款(待發(fā)貨) orderStatus = OrderStatusEnum.WAIT_FOR_DELIVERY.toString(); } //修改訂單狀態(tài) int orderFlag = orderMapper.updatePayOrderStatusByPayNo(orderStatus, tenPayVO.getOutTradeNo()); //微信支付交易記錄表 TTenpayTradeLog tenpayTradeLog = new TTenpayTradeLog(); tenpayTradeLog.setTradeLogId(Convert.createUniqueId(idWorker)); //簽名方式 tenpayTradeLog.setSignType(tenPayVO.getSignType()); //交易方式 tenpayTradeLog.setTradeMode(tenPayVO.getTradeType()); //交易狀態(tài) tenpayTradeLog.setTradeStatus(tenPayVO.getResultCode()); //商戶(hù)號(hào) tenpayTradeLog.setPartner(tenPayVO.getMchId()); //銀行類(lèi)型 tenpayTradeLog.setBankType(tenPayVO.getBankType()); //交易金額 tenpayTradeLog.setTotalFee(tenPayVO.getTotalFee()); //幣種 tenpayTradeLog.setFeeType(tenPayVO.getFeeType()); //微信支付訂單號(hào) tenpayTradeLog.setTransactionId(tenPayVO.getTransactionId()); //商戶(hù)訂單號(hào) tenpayTradeLog.setOutTradeNo(tenPayVO.getOutTradeNo()); //支付完成時(shí)間 tenpayTradeLog.setTimeEnd(tenPayVO.getTimeEnd()); int payFlag = tenpayTradeLogMapper.insertSelective(tenpayTradeLog); //若有一個(gè)操作出錯(cuò),拋錯(cuò)回滾 if (!(orderFlag > 0 && payFlag == 1)) { logger.error("微信支付訂單回調(diào)失敗"); throw new RRException(AppWSConstant.RS_MSG_TENPAY_FALL); } } else { logger.info("該訂單已支付處理,交易編號(hào)為: " + tenPayVO.getOutTradeNo()); throw new RRException(AppWSConstant.RS_MSG_ORDER_PAY_ERROR); } } } }
4.3定時(shí)任務(wù)主動(dòng)查詢(xún)微信支付回調(diào),一般微信發(fā)起的異步回調(diào)都是無(wú)序不定時(shí)的,所以一般保險(xiǎn)起見(jiàn)都會(huì)寫(xiě)一個(gè)自己的定時(shí)任務(wù)主動(dòng)查詢(xún)微信支付回調(diào)
/** * 定時(shí)任務(wù):每十五分鐘觸發(fā)一次主動(dòng)調(diào)用訂單支付回調(diào) */ @Scheduled(cron = "0 */15 * * * ?") public void initiativeOrderPayCallBack(){ //主動(dòng)調(diào)用訂單支付回調(diào) try { payService.initiativeOrderPayCallBack(); } catch (Exception e) { logger.error("timer initiativeOrderPayCallBack Error.", e); e.printStackTrace(); } }
4.3.1payService的initiativeOrderPayCallBack,用于主動(dòng)查詢(xún)微信支付回調(diào)與回調(diào)業(yè)務(wù)邏輯處理
/** * 主動(dòng)調(diào)用訂單支付回調(diào) * * @throws Exception */ @Override public void initiativeOrderPayCallBack() throws Exception { //查詢(xún)訂單狀態(tài)為orderStatus的支付編號(hào) List<Map<String, String>> payNoList = orderMapper.getPayNoByStatus(OrderStatusEnum.PENDING_PAYMENT.toString()); for (Map<String, String> map : payNoList) { try { switch (PayTypeEnum.valueOf(map.get("payType"))) { case TENPAY://財(cái)付通 TenPayVO tenPayVO = this.tenPayQueryCallBack(map.get("payNo")); //訂單回調(diào)處理 this.tenPayOrderCallBack(tenPayVO); break; default: break; } } catch (Exception e) { logger.error(e.getMessage()); e.printStackTrace(); } } }
4.3.2payService的tenPayQueryCallBack,用于主動(dòng)查詢(xún)微信支付回調(diào),拼接TenPayVO
/** * @Description: 微信支付主動(dòng)查詢(xún)回調(diào) * @Param: [payNo] * @return: com.huaku.ecom.system.model.vo.TenPayVO * @Author: zengXianKang * @Date: 2019/5/30 */ @Override public TenPayVO tenPayQueryCallBack(String payNo) throws Exception { SortedMap<String, Object> paramsMap = new TreeMap<String, Object>(); //應(yīng)用APPID paramsMap.put("appid", tenpayConfig.getAppId()); //商戶(hù)號(hào) paramsMap.put("mch_id", tenpayConfig.getMchId()); //商戶(hù)訂單號(hào) paramsMap.put("out_trade_no", payNo); //隨機(jī)字符串 paramsMap.put("nonce_str", Convert.getUUID()); TenPayUtils tenPayUtils = new TenPayUtils(); //簽名 String sign = tenPayUtils.createSign(paramsMap, "UTF-8"); paramsMap.put("sign", sign); //請(qǐng)求報(bào)文 String requestXml = TenPayUtils.tenPayXmlInfo(paramsMap); //發(fā)送微信查詢(xún)post請(qǐng)求 String tenQueryPost = TenPayUtils.httpsRequest(tenpayConfig.getQueryUrl(), "POST", requestXml); TenPayVO tenPayVO = this.tenPayCallBackInfo(tenQueryPost, "xml", ""); return tenPayVO; }
到此這篇關(guān)于springboot接入微信app支付的方法的文章就介紹到這了,更多相關(guān)springboot App微信支付內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot整合微信支付sdk過(guò)程解析
- Springboot集成第三方j(luò)ar快速實(shí)現(xiàn)微信、支付寶等支付場(chǎng)景
- SpringBoot微信掃碼支付的實(shí)現(xiàn)示例
- springboot對(duì)接微信支付的完整流程(附前后端代碼)
- SpringBoot實(shí)現(xiàn)整合微信支付方法詳解
- SpringBoot整合Vue實(shí)現(xiàn)微信掃碼支付以及微信退款功能詳解
- Springboot整合微信支付(訂單過(guò)期取消及商戶(hù)主動(dòng)查單)
- SpringBoot集成IJPay實(shí)現(xiàn)微信v3支付的示例代碼
- SpringBoot對(duì)接小程序微信支付的實(shí)現(xiàn)
相關(guān)文章
SpringBoot集成QQ第三方登陸的實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot集成QQ第三方登陸的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Spring中常見(jiàn)的7種BeanDefinition詳解
在?Spring?容器中,我們廣泛使用的是一個(gè)一個(gè)的?Bean,BeanDefinition?從名字上就可以看出是關(guān)于?Bean?的定義,下面就跟隨小編一起深入了解一下常見(jiàn)的7中BeanDefinition吧2023-09-09Java?stream?sorted使用?Comparator?進(jìn)行多字段排序的方法
這篇文章主要介紹了Java?stream?sorted使用?Comparator?進(jìn)行多字段排序,主要講解使用Java?Stream流排序器Comparator對(duì)List集合進(jìn)行多字段排序的方法,包括復(fù)雜實(shí)體對(duì)象多字段升降序排序方法,需要的朋友可以參考下2023-03-03在Java的Hibernate框架中對(duì)數(shù)據(jù)庫(kù)數(shù)據(jù)進(jìn)行查詢(xún)操作
這篇文章主要介紹了Java的Hibernate框架中對(duì)數(shù)據(jù)庫(kù)數(shù)據(jù)進(jìn)行查詢(xún)操作的方法,Hibernate是Java的SSH三大web開(kāi)發(fā)框架之一,需要的朋友可以參考下2015-12-12Java super關(guān)鍵字調(diào)用父類(lèi)過(guò)程解析
這篇文章主要介紹了Java super關(guān)鍵字調(diào)用父類(lèi)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12淺談Java中Spring Boot的優(yōu)勢(shì)
在本篇文章中小編給大家分析了Java中Spring Boot的優(yōu)勢(shì)以及相關(guān)知識(shí)點(diǎn)內(nèi)容,興趣的朋友們可以學(xué)習(xí)參考下。2018-09-09又一波Java專(zhuān)業(yè)人士必備書(shū)籍來(lái)襲
又一波Java專(zhuān)業(yè)人士必備書(shū)籍來(lái)襲,這篇文章主要向大家推薦了Java專(zhuān)業(yè)人士必讀的書(shū),感興趣的小伙伴們不要錯(cuò)過(guò)2016-09-09SpringBoot?Security權(quán)限控制自定義failureHandler實(shí)例
這篇文章主要為大家介紹了SpringBoot?Security權(quán)限控制自定義failureHandler實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11MyBatis?Generator?ORM層面的代碼自動(dòng)生成器(推薦)
Mybatis?Generator是一個(gè)專(zhuān)門(mén)為?MyBatis和?ibatis框架使用者提供的代碼生成器,也可以快速的根據(jù)數(shù)據(jù)表生成對(duì)應(yīng)的pojo類(lèi)、Mapper接口、Mapper文件,甚至生成QBC風(fēng)格的查詢(xún)對(duì)象,這篇文章主要介紹了MyBatis?Generator?ORM層面的代碼自動(dòng)生成器,需要的朋友可以參考下2023-01-01