網(wǎng)上有很多關(guān)于移動pos機使用教程刷微信,一步一步教你在SpringBoot中集成微信掃碼支付的知識,也有很多人為大家解答關(guān)于移動pos機使用教程刷微信的問題,今天pos機之家(www.dsth100338.com)為大家整理了關(guān)于這方面的知識,讓我們一起來看下吧!
本文目錄一覽:
移動pos機使用教程刷微信
一:準(zhǔn)備工作
使用微信支付需要先開通服務(wù)號,然后還要開通微信支付,最后還要配置一些開發(fā)參數(shù),過程比較多。
申請服務(wù)號(企業(yè))開通微信支付開發(fā)配置 \x08 具體準(zhǔn)備工作請參考Spring Boot入門教程(三十九):微信支付集成-申請服務(wù)號和微信支付二:開發(fā)文檔掃碼支付有兩種模式,分為模式一、模式二,模式二與模式一相比,流程更為簡單,不依賴設(shè)置的回調(diào)支付URL。商戶后臺系統(tǒng)先調(diào)用微信支付的統(tǒng)一下單接口,微信后臺系統(tǒng)返回鏈接參數(shù)codeurl,商戶后臺系統(tǒng)將codeurl值生成二維碼圖片,用戶使用微信客戶端掃碼后發(fā)起支付。注意:code_url有效期為2小時,過期后掃碼不能再發(fā)起支付。
業(yè)務(wù)流程說明:
(1)商戶后臺系統(tǒng)根據(jù)用戶選購的商品生成訂單。
(2)用戶確認(rèn)支付后調(diào)用微信支付【統(tǒng)一下單API】生成預(yù)支付交易;
(3)微信支付系統(tǒng)收到請求后生成預(yù)支付交易單,并返回交易會話的二維碼鏈接code_url。
(4)商戶后臺系統(tǒng)根據(jù)返回的code_url生成二維碼。
(5)用戶打開微信“掃一掃”掃描二維碼,微信客戶端將掃碼內(nèi)容發(fā)送到微信支付系統(tǒng)。
(6)微信支付系統(tǒng)收到客戶端請求,驗證鏈接有效性后發(fā)起用戶支付,要求用戶授權(quán)。
(7)用戶在微信客戶端輸入密碼,確認(rèn)支付后,微信客戶端提交授權(quán)。
(8)微信支付系統(tǒng)根據(jù)用戶授權(quán)完成支付交易。
(9)微信支付系統(tǒng)完成支付交易后給微信客戶端返回交易結(jié)果,并將交易結(jié)果通過短信、微信消息提示用戶。微信客戶端展示支付交易結(jié)果頁面。
(10)微信支付系統(tǒng)通過發(fā)送異步消息通知商戶后臺系統(tǒng)支付結(jié)果。商戶后臺系統(tǒng)需回復(fù)接收情況,通知微信后臺系統(tǒng)不再發(fā)送該單的支付通知。
(11)未收到支付通知的情況,商戶后臺系統(tǒng)調(diào)用【查詢訂單API】。
(12)商戶確認(rèn)訂單已支付后給用戶發(fā)貨。
掃碼支付文檔
三:集成步驟1. 引入依賴<dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.2.1</version></dependency><dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId> <version>0.0.3</version></dependency>2. application.yml
pay: wxpay: appID: xxx mchID: xxx key: xxx sandboxKey: xxx certPath: /var/local/cert/apiclient_cert.p12 useSandbox: false3. MyWXPayconfig
/** * 微信支付的參數(shù)配置 * * @author mengday zhang */@Data@Slf4j@ConfigurationProperties(prefix = "pay.wxpay")public class MyWXPayConfig implements WXPayConfig{ /** 公眾賬號ID */ private String appID; /** 商戶號 */ private String mchID; /** API 密鑰 */ private String key; /** API 沙箱環(huán)境密鑰 */ private String sandboxKey; /** API證書絕對路徑 */ private String certPath; /** 退款異步通知地址 */ private String notifyUrl; private Boolean useSandbox; /** HTTP(S) 連接超時時間,單位毫秒 */ private int httpConnectTimeoutMs = 8000; /** HTTP(S) 讀數(shù)據(jù)超時時間,單位毫秒 */ private int httpReadTimeoutMs = 10000; /** * 獲取商戶證書內(nèi)容 * * @return 商戶證書內(nèi)容 */ @Override public inputStream getCertStream() { File certFile = new File(certPath); InputStream inputStream = null; try { inputStream = new FileInputStream(certFile); } catch (FileNotFoundException e) { log.error("cert file not found, path={}, exception is:{}", certPath, e); } return inputStream; } @Override public String getKey(){ if (useSandbox) { return sandboxKey; } return key; }}4. WXPayClient
/** * WXPayClient * <p> * 對WXPay的簡單封裝,處理支付密切相關(guān)的邏輯. * * @author Mengday Zhang * @version 1.0 * @since 2018/6/16 */@Slf4jpublic class WXPayClient extends WXPay { /** 密鑰算法 */ private static final String ALGORITHM = "AES"; /** 加解密算法/工作模式/填充方式 */ private static final String ALGORITHM_MODE_PADDING = "AES/ECB/PKCS5Padding"; /** 用戶支付中,需要輸入密碼 */ private static final String ERR_CODE_USERPAYING = "USERPAYING"; private static final String ERR_CODE_AUTHCODEEXPIRE = "AUTHCODEEXPIRE"; /** 交易狀態(tài): 未支付 */ private static final String TRADE_STATE_NOTPAY = "NOTPAY"; /** 用戶輸入密碼,嘗試30秒內(nèi)去查詢支付結(jié)果 */ private static Integer remainingTimeMs = 10000; private WXPayConfig config; public WXPayClient(WXPayConfig config, WXPayConstants.SignType signType, boolean useSandbox) { super(config, signType, useSandbox); this.config = config; } /** * * 刷卡支付 * * 對WXPay#microPay(Map)增加了當(dāng)支付結(jié)果為USERPAYING時去輪詢查詢支付結(jié)果的邏輯處理 * * 注意:該方法沒有處理return_code=FAIL的情況,暫時不考慮網(wǎng)絡(luò)問題,這種情況直接返回錯誤 * * @param reqData * @return * @throws Exception */ public Map<String, String> microPayWithPOS(Map<String, String> reqData) throws Exception { // 開始時間(毫秒) long startTimestampMs = System.currentTimeMillis(); Map<String, String> responseMapForPay = super.microPay(reqData); log.info(responseMapForPay.toString()); // // 先判斷 協(xié)議字段返回(return_code),再判斷 業(yè)務(wù)返回,最后判斷 交易狀態(tài)(trade_state) // 通信標(biāo)識,非交易標(biāo)識 String returnCode = responseMapForPay.get("return_code"); if (WXPayConstants.SUCCESS.equals(returnCode)) { String errCode = responseMapForPay.get("err_code"); // 余額不足,信用卡失效 if (ERR_CODE_USERPAYING.equals(errCode) || "SYSTEMERROR".equals(errCode) || "BANKERROR".equals(errCode)) { Map<String, String> orderQueryMap = null; Map<String, String> requestData = new HashMap<>(); requestData.put("out_trade_no", reqData.get("out_trade_no")); // 用戶支付中,需要輸入密碼或系統(tǒng)錯誤則去重新查詢訂單API err_code, result_code, err_code_des // 每次循環(huán)時的當(dāng)前系統(tǒng)時間 - 開始時記錄的時間 > 設(shè)定的30秒時間就退出 while (System.currentTimeMillis() - startTimestampMs < remainingTimeMs) { // 商戶收銀臺得到USERPAYING狀態(tài)后,經(jīng)過商戶后臺系統(tǒng)調(diào)用【查詢訂單API】查詢實際支付結(jié)果。 orderQueryMap = super.orderQuery(requestData); String returnCodeForQuery = orderQueryMap.get("return_code"); if (WXPayConstants.SUCCESS.equals(returnCodeForQuery)) { // 通訊成功 String tradeState = orderQueryMap.get("trade_state"); if (WXPayConstants.SUCCESS.equals(tradeState)) { // 如果成功了直接將查詢結(jié)果返回 return orderQueryMap; } // 如果支付結(jié)果仍為USERPAYING,則每隔5秒循環(huán)調(diào)用【查詢訂單API】判斷實際支付結(jié)果 Thread.sleep(1000); } } // 如果用戶取消支付或累計30秒用戶都未支付,商戶收銀臺退出查詢流程后繼續(xù)調(diào)用【撤銷訂單API】撤銷支付交易。 String tradeState = orderQueryMap.get("trade_state"); if (TRADE_STATE_NOTPAY.equals(tradeState) || ERR_CODE_USERPAYING.equals(tradeState) || ERR_CODE_AUTHCODEEXPIRE.equals(tradeState)) { Map<String, String> reverseMap = this.reverse(requestData); String returnCodeForReverse = reverseMap.get("return_code"); String resultCode = reverseMap.get("result_code"); if (WXPayConstants.SUCCESS.equals(returnCodeForReverse) && WXPayConstants.SUCCESS.equals(resultCode)) { // 如果撤銷成功,需要告訴客戶端已經(jīng)撤銷訂單了 responseMapForPay.put("err_code_des", "用戶取消支付或尚未支付,后臺已經(jīng)撤銷該訂單,請重新支付!"); } } } } return responseMapForPay; } /** * 從request的inputStream中獲取參數(shù) * @param request * @return * @throws Exception */ public Map<String, String> getNotifyParameter(HttpServletRequest request) throws Exception { InputStream inputStream = request.getInputStream(); ByteArrayOutputStream outSteam = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length = 0; while ((length = inputStream.read(buffer)) != -1) { outSteam.write(buffer, 0, length); } outSteam.close(); inputStream.close(); // 獲取微信調(diào)用我們notify_url的返回信息 String resultXml = new String(outSteam.toByteArray(), "utf-8"); Map<String, String> notifyMap = WXPayUtil.xmlToMap(resultXml); return notifyMap; } /** * 解密退款通知 * * <a href="https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_16&index=11>退款結(jié)果通知文檔</a> * @return * @throws Exception */ public Map<String, String> decodeRefundNotify(HttpServletRequest request) throws Exception { // 從request的流中獲取參數(shù) Map<String, String> notifyMap = this.getNotifyParameter(request); log.info(notifyMap.toString()); String reqInfo = notifyMap.get("req_info"); //(1)對加密串A做base64解碼,得到加密串B byte[] bytes = new BASE64Decoder().decodeBuffer(reqInfo); //(2)對商戶key做md5,得到32位小寫key* ( key設(shè)置路徑:微信商戶平臺(pay.weixin.qq.com)-->賬戶設(shè)置-->API安全-->密鑰設(shè)置 ) Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING); SecretKeySpec key = new SecretKeySpec(WXPayUtil.MD5(config.getKey()).toLowerCase().getBytes(), ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, key); //(3)用key*對加密串B做AES-256-ECB解密(PKCS7Padding) // java.security.InvalidKeyException: Illegal key size or default parameters // https://www.cnblogs.com/yaks/p/5608358.html String responseXml = new String(cipher.doFinal(bytes),"UTF-8"); Map<String, String> responseMap = WXPayUtil.xmlToMap(responseXml); return responseMap; } /** * 獲取沙箱環(huán)境驗簽秘鑰API * <a href="https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=23_1">獲取驗簽秘鑰API文檔</a> * @return * @throws Exception */ public Map<String, String> getSignKey() throws Exception { Map<String, String> reqData = new HashMap<>(); reqData.put("mch_id", config.getMchID()); reqData.put("nonce_str", WXPayUtil.generateNonceStr()); String sign = WXPayUtil.generateSignature(reqData, config.getKey(), WXPayConstants.SignType.MD5); reqData.put("sign", sign); String responseXml = this.requestWithoutCert("https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey", reqData, config.getHttpConnectTimeoutMs(), config.getHttpReadTimeoutMs()); Map<String, String> responseMap = WXPayUtil.xmlToMap(responseXml); return responseMap; }}5. WXPayConfiguration
@Configuration@EnableConfigurationProperties(MyWXPayConfig.class)public class WXPayConfiguration { @Autowired private MyWXPayConfig wxPayConfig; /** * useSandbox 沙盒環(huán)境 * @return */ @Bean public WXPay wxPay() { return new WXPay(wxPayConfig, WXPayConstants.SignType.MD5, wxPayConfig.getUseSandbox() ); } @Bean public WXPayClient wxPayClient() { return new WXPayClient(wxPayConfig, WXPayConstants.SignType.MD5, wxPayConfig.getUseSandbox()); }}6. PayUtil
public class PayUtil { /** * 根據(jù)url生成二位圖片對象 * * @param codeUrl * @return * @throws WriterException */ public static BufferedImage getQRCodeImge(String codeUrl) throws WriterException { Map<EncodeHintType, Object> hints = new Hashtable(); hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); hints.put(EncodeHintType.CHARACTER_SET, "UTF8"); int width="360px",height="auto" />
7. WXPayPrecreateController/** * 微信支付-掃碼支付. * <p> * detailed description * * @author Mengday Zhang * @version 1.0 * @since 2018/6/18 */@Slf4j@RestController@RequestMapping("/wxpay/precreate")public class WXPayPrecreateController { @Autowired private WXPay wxPay; @Autowired private WXPayClient wxPayClient; /** * 掃碼支付 - 統(tǒng)一下單 * 相當(dāng)于支付不的電腦網(wǎng)站支付 * * <a href="https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1">掃碼支付API</a> */ @PostMapping("") public void precreate(HttpServletRequest request, HttpServletResponse response) throws Exception { Map<String, String> reqData = new HashMap<>(); reqData.put("out_trade_no", String.valueOf(System.nanoTime())); reqData.put("trade_type", "NATIVE"); reqData.put("product_id", "1"); reqData.put("body", "商戶下單"); // 訂單總金額,單位為分 reqData.put("total_fee", "2"); // APP和網(wǎng)頁支付提交用戶端ip,Native支付填調(diào)用微信支付API的機器IP。 reqData.put("spbill_create_ip", "14.23.150.211"); // 異步接收微信支付結(jié)果通知的回調(diào)地址,通知url必須為外網(wǎng)可訪問的url,不能攜帶參數(shù)。 reqData.put("notify_url", "http://3sbqi7.natappfree.cc/wxpay/precreate/notify"); // 自定義參數(shù), 可以為終端設(shè)備號(門店號或收銀設(shè)備ID),PC網(wǎng)頁或公眾號內(nèi)支付可以傳"WEB" reqData.put("device_info", ""); // 附加數(shù)據(jù),在查詢API和支付通知中原樣返回,可作為自定義參數(shù)使用。 reqData.put("attach", ""); /** * { * code_url=weixin://wxpay/bizpayurl?pr=vvz4xwC, * trade_type=NATIVE, * return_msg=OK, * result_code=SUCCESS, * return_code=SUCCESS, * prepay_id=wx18111952823301d9fa53ab8e1414642725 * } */ Map<String, String> responseMap = wxPay.unifiedOrder(reqData); log.info(responseMap.toString()); String returnCode = responseMap.get("return_code"); String resultCode = responseMap.get("result_code"); if (WXPayConstants.SUCCESS.equals(returnCode) && WXPayConstants.SUCCESS.equals(resultCode)) { String prepayId = responseMap.get("prepay_id"); String codeUrl = responseMap.get("code_url"); BufferedImage image = PayUtil.getQRCodeImge(codeUrl); response.setContentType("image/jpeg"); response.setHeader("Pragma","no-cache"); response.setHeader("Cache-Control","no-cache"); response.setIntHeader("Expires",-1); ImageIO.write(image, "JPEG", response.getOutputStream()); } } /** * * @param request * @return * @throws Exception */ @RequestMapping("/notify") public void precreateNotify(HttpServletRequest request, HttpServletResponse response) throws Exception { Map<String, String> reqData = wxPayClient.getNotifyParameter(request); /** * { * transaction_id=4200000138201806180751222945, * nonce_str=aaaf3fe4d3aa44d8b245bc6c97bda7a8, * bank_type=CFT, * openid=xxx, * sign=821A5F42F5E180ED9EF3743499FBCF13, * fee_type=CNY, * mch_id=xxx, * cash_fee=1, * out_trade_no=186873223426017, * appid=xxx, * total_fee=1, * trade_type=NATIVE, * result_code=SUCCESS, * time_end=20180618131247, * is_subscribe=N, * return_code=SUCCESS * } */ log.info(reqData.toString()); // 特別提醒:商戶系統(tǒng)對于支付結(jié)果通知的內(nèi)容一定要做簽名驗證,并校驗返回的訂單金額是否與商戶側(cè)的訂單金額一致,防止數(shù)據(jù)泄漏導(dǎo)致出現(xiàn)“假通知”,造成資金損失。 boolean signatureValid = wxPay.isPayResultNotifySignatureValid(reqData); if (signatureValid) { /** * 注意:同樣的通知可能會多次發(fā)送給商戶系統(tǒng)。商戶系統(tǒng)必須能夠正確處理重復(fù)的通知。 * 推薦的做法是,當(dāng)收到通知進行處理時,首先檢查對應(yīng)業(yè)務(wù)數(shù)據(jù)的狀態(tài), * 判斷該通知是否已經(jīng)處理過,如果沒有處理過再進行處理,如果處理過直接返回結(jié)果成功。 * 在對業(yè)務(wù)數(shù)據(jù)進行狀態(tài)檢查和處理之前,要采用數(shù)據(jù)鎖進行并發(fā)控制,以避免函數(shù)重入造成的數(shù)據(jù)混亂。 */ Map<String, String> responseMap = new HashMap<>(2); responseMap.put("return_code", "SUCCESS"); responseMap.put("return_msg", "OK"); String responseXml = WXPayUtil.mapToXml(responseMap); response.setContentType("text/xml"); response.getWriter().write(responseXml); response.flushBuffer(); } }}8. WXPayController
/** * 微信支付 - 通用API. * * <p> * 類似支付寶中的條碼支付. * * @author Mengday Zhang * @version 1.0 * @since 2018/6/15 */@Slf4j@RestController@RequestMapping("/wxpay")public class WXPayController { @Autowired private WXPay wxPay; @Autowired private WXPayClient wxPayClient; @Autowired private MyWXPayConfig wxPayConfig; /** * 訂單查詢 * @param orderNo * @return * @throws Exception */ @GetMapping("/orderQuery") public Object orderQuery(String orderNo) throws Exception { Map<String, String> data = new HashMap<>(); data.put("out_trade_no", orderNo); Map<String, String> result = wxPay.orderQuery(data); return result; } /** * 退款 * 注意:調(diào)用申請退款、撤銷訂單接口需要商戶證書 * 注意:沙箱環(huán)境響應(yīng)結(jié)果可能會是"沙箱支付金額不正確,請確認(rèn)驗收case",但是正式環(huán)境不會報這個錯誤 * 微信支付的最小金額是0.1元,所以在測試支付時金額必須大于0.1元,否則會提示微信支付配置錯誤,可以將microPay的total_fee大于1再退款 */ @PostMapping("/refund") public Object refund(String orderNo) throws Exception { Map<String, String> reqData = new HashMap<>(); // 商戶訂單號 reqData.put("out_trade_no", orderNo); // 授權(quán)碼 reqData.put("out_refund_no", orderNo); // 訂單總金額,單位為分,只能為整數(shù) reqData.put("total_fee", "2"); //退款金額 reqData.put("refund_fee", "2"); // 退款異步通知地址 reqData.put("notify_url", wxPayConfig.getNotifyUrl()); reqData.put("refund_fee_type", "CNY"); reqData.put("op_user_id", wxPayConfig.getMchID()); Map<String, String> resultMap = wxPay.refund(reqData); log.info(resultMap.toString()); return resultMap; } /** * 退款結(jié)果通知 * * 特別說明:退款結(jié)果對重要的數(shù)據(jù)進行了加密,商戶需要用商戶秘鑰進行解密后才能獲得結(jié)果通知的內(nèi)容 * @param request * @throws Exception */ @RequestMapping("/refund/notify") public String refundNotify(HttpServletRequest request) throws Exception {// Map<String, String> notifyMap = new HashMap<>();// notifyMap.put("nonce_str", "9b4e428ae262d5dca96178027e849fa9");// notifyMap.put("req_info", "VKGj8c81RwQ45LcyWEVBE9/HsNfADGbgmbIAQZ2ydcbIFhIIcJFKFQwGfcSGgFGtQlWvg6KDNsRjmCjN+PvipJ3roynJ7cME0LOFG50VGtk4EYHqdjFzUVANI7GpT+i6Ok+ZWivH0MwoGK2fsz3WG+bYs2XJBwav/K89tKjFhZGitCKKBeGqcP99fa/gAL0swNXXNQHmL806Zi+QcACzL3E89BtP9FlXM2Gi+wPQafvPr+/iE+LrPdMlNUa5LiZnenZXUF24kMdhaTafczcKL4sZjRXQHEfEyc/pIZPbIjcNIETvHsskyzKuHVr/SAFkxaM6RR1Kl9pyWZGUjkH5SOeqsT8uL7YQmTlDXrnXmno3AvZdnepTGL5w69yIOmQNPeMqsd01ES9WX36GZYOigfi2+BJ9RRXjIffmpB/MFF+zryyvLTaJE2obCwFSHrmOD8YbaJqrZXOUvWZQrn7wIQgaCypo8V57cD3w5d2RSgIHNrdnEDYlbRcLNYgKuL+T9+1HPhU/frowZgwPN9IB53OahZV3p1Yvos23kvhqPCLn3BYgUihRbey6QhEtL2QyifiQ9e8WVLzWpRZ+DOa8VrhYvSuTfjRdjoNanqHFvXGP6uEsEa+DETqnexpB7xOS9m/CdmlNCwbdUplPEVzNQQdzYT4kybi00Y8A+EdairxfVyK9A7MAYAMtAO9yxV2ht0bn3SofFyZe/YSzdJgxdtcxBf1CVYN6x+yHcSueCSgq4cM/2VCwh4J1+pUVmNpEm0OVcdKbV5USkaxJR0h7Yd+n5FTz5Q2S/qvyDo202cUzLFPI5UqQm5X+FOrWDAkmmr5yVcDQIm3dAdb31jkz0X2TPYt5g7ciQ1h9heyVxJ67FexKvEM4pKCCubtWx6nyxcOUghHMrh8DSoBtewtNjbnwGVIbLsSb6X9MIYAkWIDbqNVP1f63GiZU+cJlhBmvcb8aeQUdTTj7EX5pOTIVSVv5D6SkKmpGU4FGvV+WjufuGX4ZRZo+01p6xl0sfZVmucG1UtxhX6bMCJb06yDwxpv7tGwkwS4TCK4SQp40Xe0=");// notifyMap.put("appid", "xxx");// notifyMap.put("mch_id", "xxx");// notifyMap.put("return_code", "SUCCESS"); // 注意:同樣的通知可能會多次發(fā)送給商戶系統(tǒng)。商戶系統(tǒng)必須能夠正確處理重復(fù)的通知。 // 推薦的做法是,當(dāng)收到通知進行處理時,首先檢查對應(yīng)業(yè)務(wù)數(shù)據(jù)的狀態(tài),判斷該通知是否已經(jīng)處理過,如果沒有處理過再進行處理,如果處理過直接返回結(jié)果成功。 // 在對業(yè)務(wù)數(shù)據(jù)進行狀態(tài)檢查和處理之前,要采用數(shù)據(jù)鎖進行并發(fā)控制,以避免函數(shù)重入造成的數(shù)據(jù)混亂。 // TODO 處理業(yè)務(wù) Map<String, String> requstInfoMap = wxPayClient.decodeRefundNotify(request); // 商戶處理退款通知參數(shù)后同步返回給微信參數(shù) Map<String, String> responseMap = new HashMap<>(); responseMap.put("return_code", "SUCCESS"); responseMap.put("return_msg", "OK"); String responseXml = WXPayUtil.mapToXml(responseMap); return responseXml; } /** * 退款查詢 * @param orderNo * @return * @throws Exception */ @GetMapping("/refundQuery") public Object refundQuery(String orderNo) throws Exception { Map<String, String> reqData = new HashMap<>(); reqData.put("out_trade_no", orderNo); Map<String, String> result = wxPay.refundQuery(reqData); return result; } /** * 下載對賬單 * 注意: * 微信在次日9點啟動生成前一天的對賬單,建議商戶10點后再獲??; * 對賬單接口只能下載三個月以內(nèi)的賬單。 * @throws Exception */ @PostMapping("/downloadBill") public Object downloadBill(String billDate) throws Exception { Map<String, String> reqData = new HashMap<>(); reqData.put("bill_date", billDate); reqData.put("bill_type", "ALL"); Map<String, String> resultMap = wxPay.downloadBill(reqData); return resultMap; } /** * 獲取沙箱環(huán)境API秘鑰, * * 這里只是為了獲取,可以放在main方法下運行,這里作為api來運行的,實際情況下不應(yīng)該暴露出來 * @return * @throws Exception */ @GetMapping("/sandbox/getSignKey") public Object getSignKey() throws Exception { Map<String, String> signKey = wxPayClient.getSignKey(); log.info(signKey.toString()); return signKey; }}獲取源碼
關(guān)注并私信“微信掃碼支付”獲取源碼。
以上就是關(guān)于移動pos機使用教程刷微信,一步一步教你在SpringBoot中集成微信掃碼支付的知識,后面我們會繼續(xù)為大家整理關(guān)于移動pos機使用教程刷微信的知識,希望能夠幫助到大家!
