<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      微信商家紅包發(fā)放接入

      微信紅包

      準備工作

      微信商家開通支付功能、微信公眾號、開通紅包功能

      相關網站

      需要資料

      • API證書(apiclient_cert.p12):微信商戶平臺(pay.weixin.qq.com)-->賬戶中心-->賬戶設置-->API安全
      • API支付秘鑰:商戶平臺設置的密鑰key 32 位
      • openId:用戶微信公眾授權獲取到得 openId

      注意事項

      1. 現(xiàn)金紅包接口目前微信還沒升級,使用的v2版本,所以提交數(shù)據(jù)和返回數(shù)據(jù)采用的是xml格式
      2. 付款金額,單位分
      3. 紅包發(fā)放成功,會發(fā)放到公眾號中,需要用戶主動點擊領取
      4. 測試過程中保證商戶運營賬號有余額
      5. 微信紅包-產品設置-添加測試地址ip白名單,不知道自己外網ip地址 百度搜索 ip 即可

      代碼示例

      import lombok.extern.slf4j.Slf4j;
      import org.apache.commons.lang3.StringUtils;
      import org.apache.http.client.methods.CloseableHttpResponse;
      import org.apache.http.client.methods.HttpPost;
      import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
      import org.apache.http.entity.StringEntity;
      import org.apache.http.impl.client.CloseableHttpClient;
      import org.apache.http.impl.client.HttpClientBuilder;
      import org.apache.http.ssl.SSLContexts;
      import org.jeecg.common.util.Md5Util;
      import org.jeecg.modules.video.utitls.Constants;
      import org.springframework.core.io.ClassPathResource;
      import org.w3c.dom.Document;
      import org.w3c.dom.Element;
      import org.w3c.dom.Node;
      import org.w3c.dom.NodeList;
      import org.xml.sax.SAXException;
      
      import javax.net.ssl.SSLContext;
      import javax.xml.parsers.DocumentBuilder;
      import javax.xml.parsers.DocumentBuilderFactory;
      import javax.xml.parsers.ParserConfigurationException;
      import java.io.IOException;
      import java.io.InputStream;
      import java.security.*;
      import java.util.*;
      
      /**
       * @description:
       * @author: Mr.Fang
       * @create: 2023-05-26 
       **/
      @Slf4j
      public class WxTest {
          public static void main(String[] args) throws Exception {
              // 1、參數(shù)封裝
              TreeMap<String, Object> map = new TreeMap<>();
              map.put("nonce_str", UUID.randomUUID().toString().replaceAll("-", "")); // 隨機字符串
              map.put("mch_billno", "202302260000001");// "商家訂單編號"
              map.put("mch_id", Constants.WX_MERCHANT_ID); // 商戶號
              map.put("wxappid", Constants.WX_APP_ID); // 公眾號 APPID
              map.put("send_name", "我發(fā)的");
              map.put("re_openid", "123456"); // openid
              map.put("total_amount", "100"); // 金額
              map.put("total_num", 1); // 數(shù)量
              map.put("wishing", "恭喜發(fā)財");
              map.put("client_ip", "127.0.0.1");
              map.put("act_name", "任務分傭");
              map.put("remark", "無");
      
              // 2、參數(shù)拼接 k=v 格式
              List<String> list = new ArrayList<>();
              for (Map.Entry<String, Object> entry : map.entrySet()) {
                  String key = entry.getKey();
                  Object value = entry.getValue();
                  list.add(String.format("%s=%s", key, value.toString()));
              }
              String join = String.join("&", list);
              log.debug("拼接參數(shù)結果:{}", join);
              // 3、參數(shù)+&key=API支付秘鑰 md5 簽名
              String sign = Md5Util.md5Encode(join + "&key=" + Constants.WX_MERCHANT_API_SECRET, "UTF-8");
              log.debug("拼接參數(shù)md5:{}", sign.toUpperCase(Locale.ROOT));
              map.put("sign", sign.toUpperCase(Locale.ROOT));
              log.debug("請求參數(shù)Map:{}", map);
              // 4、獲取 API 證書,當前證書是放在 resource 下的
              ClassPathResource resource = new ClassPathResource("apiclient_cert.p12");
              InputStream inputStream = null;
              try {
                  inputStream = resource.getInputStream();
              } catch (IOException e) {
                  e.printStackTrace();
              }
              // FIXME: 2023/5/26 也可以這樣
      //        inputStream = new FileInputStream("證書路徑");
              // 5、加載 SSL 證書
              String pass =Constants.WX_MERCHANT_ID; // 密碼商戶號
              KeyStore keyStore = KeyStore.getInstance("PKCS12");
              keyStore.load(inputStream, pass.toCharArray()); // 證書默認密碼是商戶號碼
              SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial((chain, authType) -> true).loadKeyMaterial(keyStore, pass.toCharArray()).build();
              SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
              // 6、創(chuàng)建 httpClient 客戶端 并設置 ssl 對象
              HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
              httpClientBuilder.setSSLSocketFactory(sslConnectionSocketFactory);
              CloseableHttpClient build = httpClientBuilder.build();
      
              // 7、創(chuàng)建 post 請求
              HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack");
              String xml = parseMapToXml(map);
              log.debug("請求體xml:{}", xml);
              StringEntity stringEntity = new StringEntity(xml, "UTF-8");
              stringEntity.setContentEncoding("UTF-8");
              httpPost.setEntity(stringEntity);
      
              // 8、發(fā)起請求
              CloseableHttpResponse response = build.execute(httpPost);
              Map<String, Object> toMap = parseXMLToMap(response.getEntity().getContent());
              log.info("mchRedEnvelope:{}", toMap);
          }
      
          /**
           * 解析 xml
           *
           * @param map
           * @return
           */
          public static String parseMapToXml(Map<String, ? extends Object> map) {
              StringBuilder sb = new StringBuilder("<xml>");
              if (null != map && map.size() > 0) {
                  Set<? extends Map.Entry<String, ?>> entries = map.entrySet();
      
                  String key;
                  for (Iterator iterator = entries.iterator(); iterator.hasNext(); sb.append("</" + key + ">")) {
                      Map.Entry next = (Map.Entry) iterator.next();
                      key = (String) next.getKey();
                      Object value = next.getValue();
                      sb.append("<" + key + ">");
                      if (Objects.nonNull(value)) {
                          sb.append("<![CDATA[" + value + "]]>");
                      }
                  }
              }
      
              sb.append("</xml>");
              return sb.toString();
          }
      
          /**
           * xml 轉 map
           * @param inputStream
           * @return
           */
          public static Map<String, Object> parseXMLToMap(InputStream inputStream) {
              DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      
              try {
                  DocumentBuilder builder = factory.newDocumentBuilder();
                  Document document = builder.parse(inputStream);
                  Element documentElement = document.getDocumentElement();
                  Map<String, Object> map = recursiveFindXmlElement(documentElement);
                  return map;
              } catch (ParserConfigurationException | SAXException | IOException e) {
                  e.printStackTrace();
              }
      
              return null;
          }
      
          private static Map<String, Object> recursiveFindXmlElement(Element element) {
              if (Objects.nonNull(element)) {
                  HashMap<String, Object> map = new HashMap();
                  NodeList childNodes = element.getChildNodes();
      
                  for(int i = 0; i < childNodes.getLength(); ++i) {
                      Node item = childNodes.item(i);
                      short nodeType = item.getNodeType();
                      if (Objects.equals(nodeType, (short) 1)) {
                          String nodeName = item.getNodeName();
                          Element childElement = (Element)item;
                          Map<String, Object> childMap = recursiveFindXmlElement(childElement);
                          if (null != childMap && childMap.size() > 0) {
                              map.put(nodeName, childMap);
                          } else {
                              String nodeValue = StringUtils.isBlank(item.getTextContent()) ? null : item.getTextContent().trim();
                              map.put(nodeName, nodeValue);
                          }
                      }
                  }
                  if (map.size() > 0) {
                      return map;
                  }
              }
      
              return null;
          }
      }
      
      

      響應結果

      展示參數(shù)進行處理,不代表真實發(fā)送數(shù)據(jù)內容

      拼接參數(shù)結果:

      act_name=任務分傭&client_ip=127.0.0.1&mch_billno=202302260000001&mch_id=1299535101&nonce_str=c3dad56d4bc74f9d910a6210edaddd0a&re_openid=1111111&remark=無&send_name=我發(fā)的&total_amount=100&total_num=1&wishing=恭喜發(fā)財&wxappid=1111111
      

      拼接參數(shù)md5:

      426a84083ea5adc67398a7918490adeb
      

      請求參數(shù)Map:

      {act_name=任務分傭, client_ip=127.0.0.1, mch_billno=202302260000001, mch_id=1111111, nonce_str=c3dad56d4bc74f9d910a6210edaddd0a, re_openid=1111111, remark=無, send_name=恭喜發(fā)財, sign=426a84083eadadc67398a7918490adeb, total_amount=100, total_num=1, wishing=恭喜發(fā)財, wxappid=1111111}
      

      請求體xml

      <xml>
          <act_name><![CDATA[任務分傭]]></act_name>
          <client_ip><![CDATA[127.0.0.1]]></client_ip>
          <mch_billno><![CDATA[202302260000001]]></mch_billno>
          <mch_id><![CDATA[1111111]]></mch_id>
          <nonce_str><![CDATA[c3dad56d4bc74f9d910a6210edaddd0a]]></nonce_str>
          <re_openid><![CDATA[1111111]]></re_openid>
          <remark><![CDATA[無]]></remark>
          <send_name><![CDATA[33333]]></send_name>
          <sign><![CDATA[426a84083eadadc67398a7918490adeb]]></sign>
          <total_amount><![CDATA[100]]></total_amount>
          <total_num><![CDATA[1]]></total_num>
          <wishing><![CDATA[恭喜發(fā)財]]></wishing>
          <wxappid><![CDATA[1111111]]></wxappid>
      </xml>
      
      posted @ 2023-05-26 10:02  天葬  閱讀(135)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 自拍偷自拍亚洲精品熟妇人| 亚洲色一区二区三区四区| 国产精品va无码一区二区| 免费A级毛片樱桃视频| 老色鬼在线精品视频在线观看| AV人摸人人人澡人人超碰| 亚洲香蕉av一区二区蜜桃| 狠狠爱五月丁香亚洲综| 熟妇人妻av无码一区二区三区| 亚洲精品成人一二三专区| 青青草成人免费自拍视频| 国产香蕉尹人综合在线观看| 久久男人av资源网站| 日韩精品专区在线影院重磅| 九九热在线视频免费观看| 免费99视频| 一区二区三区国产亚洲网站| 国产一区二区三区色老头| 欧美久久精品一级c片免费| 中文字幕精品人妻丝袜| 国内熟妇与亚洲洲熟妇妇| 日韩av片无码一区二区不卡| 波多野结衣的av一区二区三区| 国产av无码专区亚洲草草| 九九热视频在线免费观看| 久久精品熟女亚洲av艳妇| 亚洲国产色婷婷久久99精品91| 亚洲精品码中文在线观看| 亚洲VA久久久噜噜噜久久无码| 国产午夜福利在线视频| 亚洲中文字幕无码一久久区| 亚洲V天堂V手机在线| 措美县| 色一伊人区二区亚洲最大| 亚洲成人av综合一区| 国产成人无码www免费视频播放| 精品国产午夜理论片不卡| 国产成人精品无码播放| 337p粉嫩大胆噜噜噜| 国产福利微视频一区二区| 成人无码潮喷在线观看|