欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java微信公眾號支付開發(fā)之現(xiàn)金紅包

 更新時間:2020年11月23日 16:15:38   作者:GCS隨心  
這篇文章主要為大家詳細介紹了java微信公眾號支付開發(fā)之現(xiàn)金紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

我們先來看看公眾號發(fā)放現(xiàn)金紅包的效果:

需要調(diào)用商戶平臺的接口,接口發(fā)放規(guī)則如下:

1.發(fā)送頻率限制——默認1800/min
2.發(fā)送個數(shù)上限——按照默認1800/min算
3.金額上限——根據(jù)傳入場景id不同默認上限不同,可以在商戶平臺產(chǎn)品設置進行設置和申請,最大不大于4999元/個
4.其他的“量”上的限制還有哪些?——用戶當天的領取上限次數(shù),默認是10
5.如果量上滿足不了我們的需求,如何提高各個上限?——金額上限和用戶當天領取次數(shù)上限可以在商戶平臺進行設置
注意-紅包金額大于200時,請求參數(shù)scene_id必傳,參數(shù)說明見下文。
注意2-根據(jù)監(jiān)管要求,新申請商戶號使用現(xiàn)金紅包需要滿足兩個條件:1、入駐時間超過90天 2、連續(xù)正常交易30天。

請求Url https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack
是否需要證書 是(證書及使用說明詳見商戶證書)
請求方式 POST

請求數(shù)據(jù)示例:

<xml>

<sign><![CDATA[E1EE61A91C8E90F299DE6AE075D60A2D]]></sign>

<mch_billno><![CDATA[0010010404201411170000046545]]></mch_billno>

<mch_id><![CDATA[888]]></mch_id>

<wxappid><![CDATA[wxcbda96de0b165486]]></wxappid>
<send_name><![CDATA[send_name]]></send_name>
<re_openid><![CDATA[onqOjjmM1tad-3ROpncN-yUfa6uI]]></re_openid>
<total_amount><![CDATA[200]]></total_amount>
<total_num><![CDATA[1]]></total_num>
<wishing><![CDATA[恭喜發(fā)財]]></wishing>

<client_ip><![CDATA[127.0.0.1]]></client_ip>
<act_name><![CDATA[新年紅包]]></act_name>
<remark><![CDATA[新年紅包]]></remark>
<scene_id><![CDATA[PRODUCT_2]]></scene_id>
<consume_mch_id><![CDATA[10000097]]></consume_mch_id>
<nonce_str><![CDATA[50780e0cca98c8c8e814883e5caa672e]]></nonce_str>

<risk_info>posttime%3d123123412%26clientversion%3d234134%26mobile%3d122344545%26deviceid%3dIOS</risk_info>

</xml>

接口需要調(diào)用商戶平臺的證書,證書需要去商戶平臺下載:

然后在接口中使用證書,首先我們新建一個WeixinSSL 類

@Component
public class WeiXinSSL {

 /**
  * 證書類型
  */
 @Value("${werchant.storekey}")
 private String storekey;

 /**
  * 文件路徑
  */
 @Value("${werchant.ssLfile}")
 private String ssLfile;

 /**
  * 商戶號
  */
 @Value("${werchant.merchantNumber}")
 private String merchantNumber;


 public String getStorekey() {
  return storekey;
 }

 public void setStorekey(String storekey) {
  this.storekey = storekey;
 }

 public String getSsLfile() {
  return ssLfile;
 }

 public void setSsLfile(String ssLfile) {
  this.ssLfile = ssLfile;
 }

 public String getMerchantNumber() {
  return merchantNumber;
 }

 public void setMerchantNumber(String merchantNumber) {
  this.merchantNumber = merchantNumber;
 } 
}

封裝HttpClientSSL 類實現(xiàn) https 請求加證書:

@Component
public class HttpClientSSL {

 @Autowired
 private WeiXinSSL weiXinSSL;

 // 請求超時時間(毫秒) 5秒
 public static RequestConfig requestConfig;

 // 響應超時時間(毫秒) 60秒
 public static int HTTP_RESPONSE_TIMEOUT = 60 * 1000;

 // httpClient字符編碼
 public static String encoding = "UTF-8";


 public static RequestConfig getRequestConfig() {
  return RequestConfig.custom().setConnectTimeout(5 * 1000)
    .setConnectionRequestTimeout(HTTP_RESPONSE_TIMEOUT).build();
 }


 public static void setRequestConfig(RequestConfig requestConfig) {
  HttpClientSSL.requestConfig = requestConfig;
 }

 /**
  * https請求偽造證書
  * @return
  */
 public CloseableHttpClient defaultSSLClient() {
  SSLContext sslContext = null;
  try {
   new SSLContextBuilder().loadTrustMaterial(null,new TrustStrategy(){
    @Override
    public boolean isTrusted(X509Certificate[] chain, String authType)
      throws java.security.cert.CertificateException {
     return false;
    }
   });
  } catch (NoSuchAlgorithmException | KeyStoreException e) {
   e.printStackTrace();
  }
  SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslContext);
  return HttpClients.custom().setSSLSocketFactory(factory).build();
 }


 /**
  * https請求加證書
  * @return
  */
 public CloseableHttpClient defaultSSLClientFile() {
  if (this.weiXinSSL == null){
   return this.defaultSSLClient();
  }
  FileInputStream inputStream = null;
  KeyStore keyStore = null;
  try {
   // ssl類型
   keyStore = KeyStore.getInstance(weiXinSSL.getStorekey());
   // ssl文件
   inputStream = new FileInputStream(weiXinSSL.getSsLfile());
   // 設置ssl密碼
   keyStore.load(inputStream,weiXinSSL.getMerchantNumber().toCharArray());
  } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e1) {
   e1.printStackTrace();
  } finally {
   try {
    inputStream.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
  SSLContext sslContext = null;
  try {
   sslContext = SSLContexts.custom().loadKeyMaterial(keyStore,weiXinSSL.getMerchantNumber().toCharArray()).build();
  } catch (UnrecoverableKeyException | NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
   e.printStackTrace();
  }

  SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1" }, null,
    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
  return HttpClients.custom().setSSLSocketFactory(factory).build();
 }

 /**
  * 封裝發(fā)送請求的方法
  * @throws UnsupportedEncodingException
  */
 public String send(String url, String data, CloseableHttpClient closeableHttpClient)
   throws UnsupportedEncodingException {

  CloseableHttpClient client = closeableHttpClient;
  HttpPost httpPost = new HttpPost(URLDecoder.decode(url, encoding));
  httpPost.addHeader("Connection", "keep-alive");
  httpPost.addHeader("Accept", "*/*");
  httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
  httpPost.addHeader("Host", "api.mch.weixin.qq.com");
  httpPost.addHeader("X-Requested-With", "XMLHttpRequest");
  httpPost.addHeader("Cache-Control", "max-age=0");
  httpPost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
  httpPost.setConfig(this.getRequestConfig());// 設置超時時間
  CloseableHttpResponse response = null;

  // 參數(shù)放入
  StringEntity entity = new StringEntity(data, encoding);
  entity.setContentEncoding(encoding);
  entity.setContentType("application/xml");
  httpPost.setEntity(entity);

  try {
   response = client.execute(httpPost);
   if (response.getStatusLine().getStatusCode() == 200) {
    HttpEntity httpEntity = (HttpEntity) response.getEntity();
    if (response != null) {
     return EntityUtils.toString(httpEntity,encoding);
    }
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
  return null;
 }


} 

這樣我們就封裝了一個https請求加證書的實體類,接下來我們生成請求微信紅包接口:
https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack 的參數(shù)簽名:

/**
* 紅包參數(shù)實體類
 * @throws UnsupportedEncodingException
 */
@Component
public class SendRedPack implements Serializable{

 /**
  * 
  */
 private static final long serialVersionUID = -1000489228099916099L;

 private String nonce_str;// 隨機字符串
 private String sign;// 簽名
 private String mch_billno;// 商戶訂單號
 private String mch_id;// 商戶號
 private String wxappid;// 公眾賬號
 private String send_name;// 商戶名稱
 private String re_openid;// 用戶
 private int total_amount;// 付款金額 單位:分
 private int total_num;// 紅包發(fā)放總?cè)藬?shù)
 private String wishing;// 紅包祝福語
 private String client_ip;// Ip地址
 private String act_name;// 活動名稱
 private String remark;// 備注
 public String getNonce_str() {
  return nonce_str;
 }
 public void setNonce_str(String nonce_str) {
  this.nonce_str = nonce_str;
 }
 public String getSign() {
  return sign;
 }
 public void setSign(String sign) {
  this.sign = sign;
 }
 public String getMch_billno() {
  return mch_billno;
 }
 public void setMch_billno(String mch_billno) {
  this.mch_billno = mch_billno;
 }
 public String getMch_id() {
  return mch_id;
 }
 public void setMch_id(String mch_id) {
  this.mch_id = mch_id;
 }
 public String getWxappid() {
  return wxappid;
 }
 public void setWxappid(String wxappid) {
  this.wxappid = wxappid;
 }
 public String getSend_name() {
  return send_name;
 }
 public void setSend_name(String send_name) {
  this.send_name = send_name;
 }
 public String getRe_openid() {
  return re_openid;
 }
 public void setRe_openid(String re_openid) {
  this.re_openid = re_openid;
 }
 public int getTotal_amount() {
  return total_amount;
 }
 public void setTotal_amount(int total_amount) {
  this.total_amount = total_amount;
 }
 public int getTotal_num() {
  return total_num;
 }
 public void setTotal_num(int total_num) {
  this.total_num = total_num;
 }
 public String getWishing() {
  return wishing;
 }
 public void setWishing(String wishing) {
  this.wishing = wishing;
 }
 public String getClient_ip() {
  return client_ip;
 }
 public void setClient_ip(String client_ip) {
  this.client_ip = client_ip;
 }
 public String getAct_name() {
  return act_name;
 }
 public void setAct_name(String act_name) {
  this.act_name = act_name;
 }
 public String getRemark() {
  return remark;
 }
 public void setRemark(String remark) {
  this.remark = remark;
 }
}

接下來是發(fā)送紅包的控制器:

/**
 * 領紅包控制器
 * @author zengliang
 */
@Controller
@RequestMapping(value="/redenveLopesReceive")
public class RedEnvelopesReceiveController {

 //微信唯一標識
 @Value("${weixin.appid}")
 private String appid;

 //微信開發(fā)者密碼標識
 @Value("${weixin.appsecret}")
 public String appsecret;

 @Autowired
 private SendRedPack sendredpack;

 @Autowired
 private HttpClientSSL httpclientssl;

 /**
  * 發(fā)送XML參數(shù)
  * @author zengliang
  */
 @ResponseBody
 @RequestMapping(value="/sendXml")
 public String sendXml(String openid,Long redenveLopes_id
   ,String mch_billno){
  RedenveLopes redenve = redenveLopesService.findOne(redenveLopes_id);

  XMLUtil xmlUtil= new XMLUtil();
  sendredpack.setAct_name(redenve.getAct_name());
  sendredpack.setNonce_str(xmlUtil.random());
  sendredpack.setRe_openid(openid);
  sendredpack.setClient_ip(redenve.getClient_ip());
  sendredpack.setMch_billno(mch_billno);
  sendredpack.setMch_id(redenve.getMch_id());
  String xx = redenve.getRemark();
  sendredpack.setRemark(StringUtils.isEmpty(xx) == false?xx:"空");
  sendredpack.setSend_name(redenve.getSend_name());
  sendredpack.setTotal_amount(redenve.getTotal_amount());
  sendredpack.setTotal_num(redenve.getTotal_num());
  sendredpack.setWishing(redenve.getWishing());
  sendredpack.setWxappid(redenve.getWxappidxx());
  //生成簽名
  String params = this.createSendRedPackOrderSign(sendredpack,redenve.getStore_key());
  sendredpack.setSign(params);

  xmlUtil.xstream().alias("xml",sendredpack.getClass());
  //擴展xstream,使其支持CDATA塊
  String requestXml = xmlUtil.xstream().toXML(sendredpack);

  String result;
  try {
   result = httpclientssl.send("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack",requestXml,httpclientssl.defaultSSLClientFile());
   System.out.println("成功返回值"+result);
   return result;
  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
  }
  return null;
 }

/**
  * 生成簽名
  * @param redPack
  * @return
  */
 public String createSendRedPackOrderSign(SendRedPack redPack,String storekey){
  StringBuffer sign = new StringBuffer();
  sign.append("act_name=").append(redPack.getAct_name());
  sign.append("&client_ip=").append(redPack.getClient_ip());
  sign.append("&mch_billno=").append(redPack.getMch_billno());
  sign.append("&mch_id=").append(redPack.getMch_id());
  sign.append("&nonce_str=").append(redPack.getNonce_str());
  sign.append("&re_openid=").append(redPack.getRe_openid());
  sign.append("&remark=").append(redPack.getRemark());
  sign.append("&send_name=").append(redPack.getSend_name());
  sign.append("&total_amount=").append(redPack.getTotal_amount());
  sign.append("&total_num=").append(redPack.getTotal_num());
  sign.append("&wishing=").append(redPack.getWishing());
  sign.append("&wxappid=").append(redPack.getWxappid());
  sign.append("&key=").append(storekey);
  return DigestUtils.md5Hex(sign.toString()).toUpperCase();
 }

}

然后我們需要用一個解析XML的工具類實現(xiàn)解析微信返回的XML

/**
 * 解析XML工具類
 * @author zengliang
 */
@Component
public class XMLUtil {

 /**
  * 解析微信返回的XML
  * @param xml
  * @return
  * @throws Exception
  */
 @SuppressWarnings("unchecked")
 public Map<String, String> parseXml(String xml)throws Exception {
  Map<String,String> map = new HashMap<String,String>(); 
  Document doc = null; 
  try { 
   doc = DocumentHelper.parseText(xml); // 將字符串轉(zhuǎn)為XML 
   Element rootElt = doc.getRootElement(); // 獲取根節(jié)點 
   List<Element> list = rootElt.elements();//獲取根節(jié)點下所有節(jié)點 
   for (Element element : list) { //遍歷節(jié)點 
    map.put(element.getName(), element.getText()); //節(jié)點的name為map的key,text為map的value 
   } 
  } catch (DocumentException e) { 
   e.printStackTrace(); 
  } catch (Exception e) { 
   e.printStackTrace(); 
  }
  return map; 
 }

 /**
  * 擴展xstream,使其支持CDATA塊
  */
  private XStream xstream = new XStream(new XppDriver(new NoNameCoder()) {
   @Override
   public HierarchicalStreamWriter createWriter(Writer out) {
     return new PrettyPrintWriter(out) {
     // 對所有xml節(jié)點的轉(zhuǎn)換都增加CDATA標記
     boolean cdata = true;
     @Override
     @SuppressWarnings("rawtypes")
     public void startNode(String name, Class clazz) {
      super.startNode(name, clazz);
     }
     @Override
     public String encodeNode(String name) {
      return name;
     }
     @Override
     protected void writeText(QuickWriter writer, String text) {
      if (cdata) {
       writer.write("<![CDATA[");
       writer.write(text);
       writer.write("]]>");
      } else {
       writer.write(text);
      }
     }
     };
   }
  });
  private XStream inclueUnderlineXstream = new XStream(new DomDriver(null,new XmlFriendlyNameCoder("_-", "_")));
  public XStream getXstreamInclueUnderline() {
   return inclueUnderlineXstream;
  }

  public XStream xstream() {
   return xstream;
  }

  /**
  * 生成隨機數(shù)
  * @return
  */
 public String random(){
  String random = UUID.randomUUID().toString().replace("-", "");
  return random;
 }
}

然后我們調(diào)用 sendXML 方法公眾號就能向用戶發(fā)送紅包了。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 為spring get請求添加自定義的參數(shù)處理操作(如下劃線轉(zhuǎn)駝峰)

    為spring get請求添加自定義的參數(shù)處理操作(如下劃線轉(zhuǎn)駝峰)

    這篇文章主要介紹了為spring get請求添加自定義的參數(shù)處理操作(如下劃線轉(zhuǎn)駝峰),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Mybatis執(zhí)行SQL時多了一個limit的問題及解決方法

    Mybatis執(zhí)行SQL時多了一個limit的問題及解決方法

    這篇文章主要介紹了Mybatis執(zhí)行SQL時多了一個limit的問題及解決方法,Mybatis攔截器方法識別到配置中參數(shù)supportMethodsArguments 為ture時會分頁處理,本文結(jié)合示例代碼給大家講解的非常詳細,需要的朋友可以參考下
    2022-10-10
  • Java時間復雜度、空間復雜度的深入詳解

    Java時間復雜度、空間復雜度的深入詳解

    對于一個算法,其時間復雜度和空間復雜度往往是相互影響的,當追求一個較好的時間復雜度時,可能會使空間復雜度的性能變差,即可能導致占用較多的存儲空間,這篇文章主要給大家介紹了關于Java時間復雜度、空間復雜度的相關資料,需要的朋友可以參考下
    2021-11-11
  • 如何使用mybatis-plus實現(xiàn)分頁查詢功能

    如何使用mybatis-plus實現(xiàn)分頁查詢功能

    最近在研究mybatis,然后就去找簡化mybatis開發(fā)的工具,發(fā)現(xiàn)就有通用Mapper和mybatis-plus兩個比較好的可是使用,可是經(jīng)過對比發(fā)現(xiàn)還是mybatis-plus比較好,下面這篇文章主要給大家介紹了關于如何使用mybatis-plus實現(xiàn)分頁查詢功能的相關資料,需要的朋友可以參考下
    2022-06-06
  • 深入理解Spring的事務傳播行為

    深入理解Spring的事務傳播行為

    spring特有的事務傳播行為,spring支持7種事務傳播行為,確定客戶端和被調(diào)用端的事務邊界(說得通俗一點就是多個具有事務控制的service的相互調(diào)用時所形成的復雜的事務邊界控制),這篇文章主要給大家介紹了關于Spring事務傳播行為的相關資料,需要的朋友可以參考下。
    2018-02-02
  • [Java]詳解Socket和ServerSocket學習筆記

    [Java]詳解Socket和ServerSocket學習筆記

    即時類應用或者即時類的游戲,HTTP協(xié)議很多時候無法滿足于我們的需求,這會,Socket對于我們來說就非常實用了。本篇文章主要介紹了Socket和ServerSocket,有興趣的可以了解一下。
    2016-12-12
  • SpringCloud Feign多參數(shù)傳遞及需要注意的問題

    SpringCloud Feign多參數(shù)傳遞及需要注意的問題

    這篇文章主要介紹了SpringCloud Feign多參數(shù)傳遞及需要注意的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java?Zookeeper分布式分片算法超詳細講解流程

    Java?Zookeeper分布式分片算法超詳細講解流程

    ZooKeeper是一個分布式的,開放源碼的分布式應用程序協(xié)調(diào)服務,是Google的Chubby一個開源的實現(xiàn),是Hadoop和Hbase的重要組件。它是一個為分布式應用提供一致性的軟件,提供的功能包括:配置維護、域名服務、分布式同步、組服務等
    2023-03-03
  • Java代碼實現(xiàn)循環(huán)隊列的示例代碼

    Java代碼實現(xiàn)循環(huán)隊列的示例代碼

    隊列作為基礎的數(shù)據(jù)結(jié)構,是程序員的入門課。也是所有程序員必須掌握的一種數(shù)據(jù)結(jié)構,隊列在程序中廣泛應用,因此我們應該對隊列有深入的了解,接下來我們通過代碼來對隊列這種數(shù)據(jù)結(jié)構進行深度解析,感興趣的朋友一起看看吧
    2021-09-09
  • Java生成10個1000以內(nèi)的隨機數(shù)并用消息框顯示數(shù)組內(nèi)容然后求和輸出

    Java生成10個1000以內(nèi)的隨機數(shù)并用消息框顯示數(shù)組內(nèi)容然后求和輸出

    這篇文章主要介紹了Java生成10個1000以內(nèi)的隨機數(shù)并用消息框顯示數(shù)組內(nèi)容然后求和輸出,需要的朋友可以參考下
    2015-10-10

最新評論