springboot集成微信app支付
生活随笔
收集整理的這篇文章主要介紹了
springboot集成微信app支付
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、準(zhǔn)備工作(以下信息需要自行開(kāi)通和申請(qǐng)):
public static final String APP_ID = "";//app的id 需要app應(yīng)用public static final String KEY = "";//api密鑰 商戶賬戶信息里面去獲取public static final String MCH_ID = "";//商戶的id,需要開(kāi)通商戶maven項(xiàng)目添加依賴:
<!-- 微信支付 --><dependency><groupId>com.github.wxpay</groupId><artifactId>wxpay-sdk</artifactId><version>0.0.3</version></dependency>二、開(kāi)發(fā)流程:
整個(gè)流程我們只需要兩個(gè)接口即可:
1.微信支付的統(tǒng)一下單接口(本地項(xiàng)目請(qǐng)求微信):
接口api請(qǐng)點(diǎn)擊這里
URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder2.微信支付后的通知接口,是我們向外提供的(微信請(qǐng)求本地項(xiàng)目):接口地址自行定義
?
三、代碼:我使用的springboot restful接口方式,詳解請(qǐng)看注釋
service層:
import java.util.Map;/*** * @類名稱 WeixinService.java* @類描述 <pre>微信相關(guān)</pre>* @作者 yw xingsfdz@163.com* @創(chuàng)建時(shí)間 2020年4月29日 下午4:25:10* @版本 5.0.0** @修改記錄* <pre>* 版本 修改人 修改日期 修改內(nèi)容描述* ----------------------------------------------* 5.0.0 yw 2020年4月29日 * ----------------------------------------------* </pre>*/ public interface WeixinService {/*** * @方法名稱 payBack* @功能描述 <pre>回調(diào)接口</pre>* @作者 yw* @創(chuàng)建時(shí)間 2020年5月22日 下午12:50:15* @param resXml* @return*/String payBack(String resXml);/*** * @param order * @方法名稱 doUnifiedOrder* @功能描述 <pre>統(tǒng)一下單</pre>* @作者 yw* @創(chuàng)建時(shí)間 2020年5月22日 下午12:50:26* @return* @throws Exception*/Map<String, String> doUnifiedOrder(Order order) throws Exception;}service層實(shí)現(xiàn)(以下代碼已刪除了業(yè)務(wù)處理部分,需要自己添加自己項(xiàng)目的業(yè)務(wù)處理):
import com.github.wxpay.sdk.WXPay; import com.github.wxpay.sdk.WXPayConstants; import com.github.wxpay.sdk.WXPayUtil;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.util.HashMap; import java.util.Map;/*** * @類名稱 WeixinServiceImpl.java* @類描述 <pre>微信 支付</pre>* @作者 yw xingsfdz@163.com* @創(chuàng)建時(shí)間 2020年5月22日 下午12:51:13* @版本 5.0.0** @修改記錄* <pre>* 版本 修改人 修改日期 修改內(nèi)容描述* ----------------------------------------------* 5.0.0 yw 2020年5月22日 * ----------------------------------------------* </pre>*/ @Service @Slf4j public class WeixinServiceImpl implements WeixinService {public static final String HOST_IP = "";//回調(diào)的服務(wù)器ippublic static final String NOTIFY_URL = "";//回調(diào)的地址,注意:外網(wǎng)可以訪問(wèn)public static final String TRADE_TYPE_APP = "APP";@AutowiredOrderService orderService;//自己業(yè)務(wù)的處理服務(wù)@Overridepublic String payBack(String resXml) {WXConfigUtil config = null;try {config = new WXConfigUtil();} catch (Exception e) {e.printStackTrace();}WXPay wxpay = new WXPay(config);String xmlBack = "";Map<String, String> notifyMap = null;try {notifyMap = WXPayUtil.xmlToMap(resXml); // 調(diào)用官方SDK轉(zhuǎn)換成map類型數(shù)據(jù)if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {//驗(yàn)證簽名是否有效,有效則進(jìn)一步處理String return_code = notifyMap.get("return_code");//狀態(tài)String out_trade_no = notifyMap.get("out_trade_no");//商戶訂單號(hào)if (return_code.equals("SUCCESS")) {if (out_trade_no != null) {// 注意特殊情況:訂單已經(jīng)退款,但收到了支付結(jié)果成功的通知,不應(yīng)把商戶的訂單狀態(tài)從退款改成支付成功// 注意特殊情況:微信服務(wù)端同樣的通知可能會(huì)多次發(fā)送給商戶系統(tǒng),所以數(shù)據(jù)持久化之前需要檢查是否已經(jīng)處理過(guò)了,處理了直接返回成功標(biāo)志//業(yè)務(wù)處理 以下進(jìn)行業(yè)務(wù)處理(比如修改訂單狀態(tài)信息等)log.info("微信手機(jī)支付回調(diào)成功訂單號(hào):{}", out_trade_no);xmlBack = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";} else {log.info("微信手機(jī)支付回調(diào)失敗訂單號(hào):{}", out_trade_no);xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[報(bào)文為空]]></return_msg>" + "</xml> ";}}return xmlBack;} else {// 簽名錯(cuò)誤,如果數(shù)據(jù)里沒(méi)有sign字段,也認(rèn)為是簽名錯(cuò)誤//失敗的數(shù)據(jù)要不要存儲(chǔ)?log.error("手機(jī)支付回調(diào)通知簽名錯(cuò)誤");xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[報(bào)文為空]]></return_msg>" + "</xml> ";return xmlBack;}} catch (Exception e) {log.error("手機(jī)支付回調(diào)通知失敗", e);xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[報(bào)文為空]]></return_msg>" + "</xml> ";}return xmlBack;}/*** * @方法名稱 doUnifiedOrder* @功能描述 <pre>統(tǒng)一下單接口具體實(shí)現(xiàn)</pre>* @作者 yw* @創(chuàng)建時(shí)間 2020年5月22日 下午4:30:44* @param order 參數(shù)可以根據(jù)自己定義* @return* @throws Exception*/@Overridepublic Map<String, String> doUnifiedOrder(Order order) throws Exception {try {WXConfigUtil config = new WXConfigUtil();WXPay wxpay = new WXPay(config);Map<String, String> data = new HashMap<>();//生成商戶訂單號(hào),不可重復(fù)data.put("appid", WXConfigUtil.APP_ID);data.put("mch_id", WXConfigUtil.MCH_ID);data.put("nonce_str", WXPayUtil.generateNonceStr());String body = "手機(jī)支付";data.put("body", body);data.put("out_trade_no", order.getOrderNo());//訂單號(hào)data.put("total_fee", "1");//設(shè)置金額1分//自己的服務(wù)器IP地址data.put("spbill_create_ip", HOST_IP);//異步通知地址(請(qǐng)注意必須是外網(wǎng))data.put("notify_url", NOTIFY_URL);//交易類型data.put("trade_type", TRADE_TYPE_APP);//附加數(shù)據(jù),在查詢API和支付通知中原樣返回,該字段主要用于商戶攜帶訂單的自定義數(shù)據(jù)data.put("attach", "");data.put("sign", WXPayUtil.generateSignature(data, WXConfigUtil.KEY,WXPayConstants.SignType.MD5));//使用官方API請(qǐng)求預(yù)付訂單Map<String, String> response = wxpay.unifiedOrder(data);if ("SUCCESS".equals(response.get("return_code"))) {//主要返回以下5個(gè)參數(shù)Map<String, String> param = new HashMap<>();param.put("appid", WXConfigUtil.APP_ID);param.put("partnerid",response.get("mch_id"));param.put("prepayid",response.get("prepay_id"));param.put("package","Sign=WXPay");param.put("noncestr",WXPayUtil.generateNonceStr());param.put("timestamp",System.currentTimeMillis()/1000+"");param.put("sign",WXPayUtil.generateSignature(param, WXConfigUtil.KEY,WXPayConstants.SignType.MD5));return param;}} catch (Exception e) {e.printStackTrace();throw new Exception("下單失敗");}throw new Exception("下單失敗");} }controller層:
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader;import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j;/*** * @類名稱 WeixinRestController.java* @類描述 <pre>微信app支付</pre>* @作者 yw xingsfdz@163.com* @創(chuàng)建時(shí)間 2020年5月22日 下午4:04:19* @版本 5.0.0** @修改記錄* <pre>* 版本 修改人 修改日期 修改內(nèi)容描述* ----------------------------------------------* 5.0.0 yw 2020年5月22日 * ----------------------------------------------* </pre>*/ @Slf4j @Api(value="微信",tags={"微信"}) @RequestMapping("/weixin/") @RestController public class WeixinRestController{@AutowiredWeixinService weixinService;/*** * @方法名稱 wxAdd* @功能描述 <pre>微信統(tǒng)一下單- 前端發(fā)起下單 比如web ios android</pre>* @作者 yw* @創(chuàng)建時(shí)間 2020年5月22日 下午12:56:59* @return* @throws Exception*/@RequestMapping(value={"app/wxpay"}, method={RequestMethod.POST})public ResponseMsg wxpay(HttpServletRequest request, Order order) throws Exception {return new ResponseMsg(weixinService.doUnifiedOrder(order));}/*** * @方法名稱 wxPayNotify* @功能描述 <pre>給微信回調(diào)的接口</pre>* @作者 yw* @創(chuàng)建時(shí)間 2020年5月22日 下午4:04:55* @param request* @return*/@PostMapping("order/wxnotify")@ApiOperation("微信回調(diào)")public String wxPayNotify(HttpServletRequest request) {String resXml = "";try {InputStream inputStream = request.getInputStream();//將InputStream轉(zhuǎn)換成xmlStringBufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));StringBuilder sb = new StringBuilder();String line = null;try {while ((line = reader.readLine()) != null) {sb.append(line + "\n");}} catch (IOException e) {log.info(e.getMessage());} finally {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}resXml = sb.toString();String result = weixinService.payBack(resXml);return result;} catch (Exception e) {log.info("微信手機(jī)支付失敗:" + e.getMessage());String result = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[報(bào)文為空]]></return_msg>" + "</xml> ";return result;}} }四、測(cè)試:
安卓端發(fā)起請(qǐng)求,并請(qǐng)求支付成功:
總結(jié)
以上是生活随笔為你收集整理的springboot集成微信app支付的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 浅析几种常见RAID模式。DVI接口种类
- 下一篇: 每天一个linux命令(lsof)