微信開發官方文檔:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5php
有關微信支付的流程圖微信官方已經說的很清楚了,這裏也無需其它解釋。這邊採用微信支付掃碼模式二(不依賴商戶平臺設置回調url),因此在生成二維碼以前git
要先調用微信統一下單支付接口,得到code_url,再經過谷歌二維碼工具將code_url生成二維碼圖片。github
在微信掃碼支付功能開發以前,首先要得到微信認證而獲得的一些信息以下:算法
開發者帳戶信息spring
公衆號 appid: wx0pi2m4x6we76140w數據庫
公衆號 appsecret: x82552d8w0y1i161lp9o7821s5d7osryapi
商戶號 mer_id: 5731202714安全
支付 key: PL9wT9n9Ljav4zSN66J0bmzT1Yl54429微信
三、和微信支付交互方式微信開發
(1)、post方式提交
(2)、xml格式的協議
(3)、簽名算法MD5
(4)、接口交易單位爲 分
(5)、交易類型:JSAPI--公衆號支付、NATIVE--原生掃碼支付、APP--app支付
(6)、商戶訂單號規則:
商戶支付的訂單號由商戶自定義生成,僅支持使用字母、數字、中劃線-、下劃線_、豎線|、星號*這些英文半角字符的組合,請勿使用漢字或全角等特殊字符,
微信支付要求商戶訂單號保持惟一性
(7)、安全規範:
簽名算法:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=4_3
校驗工具:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=20_1
(8)、採用微信支付掃碼模式二(不依賴商戶平臺設置回調url)
接口須要接收購買商品ID,用戶ID,返回的就是二維碼圖片供用戶掃碼支付。
/** * 訂單接口 */ @RestController @RequestMapping("/api/v1/order") public class OrderController { @Autowired private VideoOrderService videoOrderService; /** * 用戶點擊購買下單接口 */ @GetMapping("buy") public void saveOrder(@RequestParam(value = "video_id",required = true)int videoId, HttpServletRequest request, HttpServletResponse response) throws Exception { /** * 實際開發須要獲取用戶id和用戶當前ip,這裏臨時寫死的配置 * String ip = IpUtils.getIpAddr(request); * int userId = request.getAttribute("user_id"); */ int userId = 1; String ip = "120.25.1.43"; //一、根據用戶id和商品id生成訂單 VideoOrderDto videoOrderDto = new VideoOrderDto(); videoOrderDto.setUserId(userId); videoOrderDto.setVideoId(videoId); videoOrderDto.setIp(ip); //二、保存訂單同時返回codeUrl String codeUrl = videoOrderService.save(videoOrderDto); if(codeUrl == null) { throw new NullPointerException(); } //三、經過google工具生成二維碼供用戶掃碼支付 try{ //三、1生成二維碼配置 Map<EncodeHintType,Object> hints = new HashMap<>(); //三、2設置糾錯等級 hints.put(EncodeHintType.ERROR_CORRECTION,ErrorCorrectionLevel.L); //三、3編碼類型 hints.put(EncodeHintType.CHARACTER_SET,"UTF-8"); BitMatrix bitMatrix = new MultiFormatWriter().encode(codeUrl,BarcodeFormat.QR_CODE,400,400,hints); OutputStream out = response.getOutputStream(); MatrixToImageWriter.writeToStream(bitMatrix,"png",out); }catch (Exception e){ e.printStackTrace(); } } }
該類的主要業務邏輯是:
(1)經過商品ID查詢是否有該商品信息
(2)經過用戶ID查詢是否存在該用戶
(3)若是上面兩步沒有問題,則生成用戶訂單信息保存到數據庫中
@Override @Transactional(propagation = Propagation.REQUIRED) public String save(VideoOrderDto videoOrderDto) throws Exception { //一、查找商品信息(這裏商品指的是視頻課程) Video video = videoMapper.findById(videoOrderDto.getVideoId()); //二、查找用戶信息 User user = userMapper.findByid(videoOrderDto.getUserId()); //三、生成訂單,插入數據庫 VideoOrder videoOrder = new VideoOrder(); videoOrder.setTotalFee(video.getPrice()); videoOrder.setVideoImg(video.getCoverImg()); videoOrder.setVideoTitle(video.getTitle()); videoOrder.setCreateTime(new Date()); videoOrder.setVideoId(video.getId()); videoOrder.setState(0); videoOrder.setUserId(user.getId()); videoOrder.setHeadImg(user.getHeadImg()); videoOrder.setNickname(user.getName()); videoOrder.setDel(0); videoOrder.setIp(videoOrderDto.getIp()); videoOrder.setOutTradeNo(CommonUtils.generateUUID()); videoOrderMapper.insert(videoOrder); //四、獲取codeurl String codeUrl = unifiedOrder(videoOrder); return codeUrl; }
微信官方統一下單接口文檔說明: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1
(1) 根據接口需求添加所需參數:好比appid,mch_id,body等等......
(2)sign簽名獲取:具體獲取規則官方已經說明: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=4_3
(3) 經過工具類將map集合轉爲xml格式字符串
(4)回調微信統一下單接口,接口地址:https://api.mch.weixin.qq.com/pay/unifiedorder
(5)若是上一步成功(成功標誌返回SUSSCUSS),則將返回成功的xml格式再經過工具類轉爲map
(6)經過key=code_url,獲取value字符串,這也是最終生成二維碼的字符串。code_url格式大體爲:weixin://wxpay/s/An4baqw
接下來只要將code_url值變成二維碼就能夠供用戶掃碼付款了。
調用http://localhost:8081/api/v1/order/buy?video_id=1接口
成功返回二維碼:code_url有效期是兩個小時
微信掃碼以後:看到具體信息
再看數據庫該商品信息:
github: https://github.com/yudiandemingzi/spring-boot-wechat-pay
我只是偶爾安靜下來,對過去的種種思忖一番。那些曾經的舊時光裏即使有過天真愚鈍,也不值得譴責。畢竟,日後的日子,還很長。不斷鼓勵本身,
天一亮,又是嶄新的起點,又是未知的征程(上校16)