SpringBoot實戰項目精華總結 -- 微信公衆號(三)

SpringBoot實戰項目精華總結 -- 微信公衆號(三)

  注:這裏的總結僅供自己以後參考,遊客還請以微信官方文檔爲主
 一、微信特性
  1.微信授權
    1.1 網頁域名授權配置
    1.2 獲取openid
    手工方式
    利用第三方SDK(github上 => weixin-java-tools)
    1.3 前後端聯調
 二、微信支付
  1.官網文檔
  2.公衆號裏發起支付
  3.第三方SDK
  4.支付時序
    4.1 發起統一下單
    4.2 利用預付單信息+freemarker完成動態參數注入js簽名,喚起前端支付
    4.3 最後通過微信內置對象WeixinJSBridge喚起支付密碼輸入彈窗

  5.處理微信異步通知(API列表=>支付結果通知)
 三、微信退款
  1.基於SDK的方法代碼
  2.退款微信也會調用異步通知(與支付異步通知同一接口)需要處理
 四、其他
  1.基於Gson的Json格式化工具

一、微信特性
 1.微信授權 
  官網文檔:https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html
  1.1 網頁域名授權配置
    -> 本地開發環境使用內網穿透:https://natapp.cn/ 將本地的8080端口映射到購買的可用於微信開發的二級域名,注意要買備案的
    -> 在微信公衆平臺=>功能設置=>網頁授權域名,下載文件存放至 resource/static 目錄下
    -> 啓動natapp.exe(參考natapp1分鐘教程),啓動本地項目(臨時去掉 server.context-path 設置)
    -> 微信公衆平臺填寫買到的二級域名,完成保存。設置後即可刪除txt文件
  1.2 獲取openid
  手工方式
    -> 先調微信授權接口並指定回調地址,用戶端彈出授權框,同意後可獲取code
    -> 回調地址接口接收到微信的回調,帶回code,code只能使用一次,5分鐘有效期
    -> 後端微信回調的接口再使用code+appid+secret獲取access_token+openid+refresh_token
    -> 使用access_token+openid拉取用戶基本信息,但注意拉取得信息編碼是ISO-8859-1編碼
    -> 對用戶信息的轉碼操作 new String(response.getBytes("ISO-8859-1"), "UTF-8")

  利用第三方SDK(github上 => weixin-java-tools)

<dependency>
  <groupId>com.github.binarywang</groupId>
  <artifactId>weixin-java-mp</artifactId>
  <version>2.7.0</version>
</dependency>

    -> 前端發起用戶授權請求,入參爲回調地址(前端接收授權後openid的地址)
  1.3 前後端聯調
    -> 手機網頁抓包工具charles及破解教程:https://www.cnblogs.com/jiayuchn-test/p/8875105.html
    -> 10003 redirect_uri域名與後臺配置不一致:公衆號設置=>功能設置=>網頁授權域名 必須要與 授權鏈接 https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx69fxxxxxxxxed8&redirect_uri=http%3a%2f%2fwww.xxx.com%2fvShop%2fdefault&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect 中redirect_uri一致!
二、微信支付
 1.官網文檔
  https://pay.weixin.qq.com/wiki/doc/api/index.html
 2.公衆號裏發起支付
  https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_4
 3.第三方SDK
  https://github.com/Pay-Group/best-pay-sdk

 4.支付時序
  4.1 發起統一下單
  notifyUrl(異步通知必填)設置爲自己單獨的接口地址給微信支付平臺調用,傳來預付單信息,此時微信端已經記錄下“訂單號+訂單金額”信息(所以只改訂單金額是不行的)

  4.2 利用預付單信息+freemarker完成動態參數注入js簽名,喚起前端支付

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

pay/create.ftl

<script>
  function onBridgeReady(){
  WeixinJSBridge.invoke(
    'getBrandWCPayRequest', {
      "appId":"${payResponse.appId}",   //公衆號名稱,由商戶傳入
      "timeStamp":"${payResponse.timeStamp}",   //時間戳,自1970年以來的秒數
      "nonceStr":"${payResponse.nonceStr}", //隨機串
      "package":"${payResponse.packAge}",
      "signType":"MD5",   //微信簽名方式:
      "paySign":"${payResponse.paySign}" //微信簽名
    },
    function(res){
//      if(res.err_msg == "get_brand_wcpay_request:ok" ) {
//      }   // 使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功後返回  ok,但並不保證它絕對可靠。
      location.href = "${returnUrl}";
    }
  );
  }
  if (typeof WeixinJSBridge == "undefined"){
  if( document.addEventListener ){
    document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
  }else if (document.attachEvent){
    document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
    document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
  }
  }else{
  onBridgeReady();
  }
</script>

  4.3 最後通過微信內置對象WeixinJSBridge喚起支付密碼輸入彈窗

 5.處理微信異步通知(API列表=>支付結果通知)

/**
 * 微信異步通知
 * @param notifyData
 */
@PostMapping("/notify")
public ModelAndView notify(@RequestBody String notifyData) {
  payService.notify(notifyData);
  //返回給微信處理結果
  return new ModelAndView("pay/success");
}

pay/success.ftl 告訴微信訂單處理成功,就不會再收到微信通知支付成功了

<xml>
  <return_code><![CDATA[SUCCESS]]></return_code>
  <return_msg><![CDATA[OK]]></return_msg>
</xml>

三、微信退款
  官方文檔:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
 1.基於SDK的方法代碼
  需要封裝一個退款請求類:RefundRequest(訂單號,訂單金額,支付類型)

/**
 * 退款
 * @param orderDTO
 */
@Override
public RefundResponse refund(OrderDTO orderDTO) {
  RefundRequest refundRequest = new RefundRequest();
  refundRequest.setOrderId(orderDTO.getOrderId());
  refundRequest.setOrderAmount(orderDTO.getOrderAmount().doubleValue());
  refundRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_MP);
  log.info("【微信退款】request={}", JsonUtil.toJson(refundRequest));

  RefundResponse refundResponse = bestPayService.refund(refundRequest);
  log.info("【微信退款】response={}", JsonUtil.toJson(refundResponse));

  return refundResponse;
}

 2.退款微信也會調用異步通知(與支付異步通知同一接口)需要處理
四、其他
 1.基於Gson的Json格式化工具

/**
 * @Description Json格式化處理工具
 * @Date 2020/2/16 12:08
 */
public class JsonUtil {
  public static String toJson(Object object) {
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.setPrettyPrinting();
    Gson gson = gsonBuilder.create();
    return gson.toJson(object);
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章