java微信-企業付款api

最近有弄服務號的現金紅包和企業付款,和微信支付 弄完之後發現其實這些基本都差不多.

所有我這裏就把微信企業付款記錄一樣


首先  還是先看一下文檔  https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2  點擊打開鏈接

在文檔中我們可以看到,企業付款需要調用的url和所有參數的說明,這裏的話就需要自己去看去理解了。


如果要使用 現金紅包和企業付款 要先去開通在產品中心裏面 就要 點擊進去開通就行了 ,順便填寫一下機器ip地址


之後我要提一下的是機器ip是外網ip,如果是在本地測試的就要注意一下  然後保持一致就行了 




這裏的話還有個最主要的證書需要下載,我們可以下載到D盤cert目錄下 D:/cert      這個證書的下載 只要登陸微信商戶平臺 API安全  就可以了 看自己是什麼語言就下載什麼證書,這裏文檔有說明 



一些微信的基本配置我都寫在了 #weixin mp config

appID=xxxx
appsecret=xxxx
token=xxxx
#商戶號
partnerId=xxx
#商戶支付密鑰
partnerKey=xxxx
#微信統一支付接口
payUrl=https://api.mch.weixin.qq.com/pay/unifiedorder
#支付結果通知的回調地址
payCallBack= http://域名/wechatPay/wechat_notify
queryOrderUrl=https://api.mch.weixin.qq.com/pay/orderquery

前面的準備工作都ok 之後就是寫代碼了

建一個微信需要的企業付款參數 transfers 類 

public class Transfers {
	
	private String mch_appid;// 公衆賬號
	private String mchid;// 商戶號
	private String nonce_str;// 隨機字符串
	private String sign;// 簽名
	private String partner_trade_no;// 商戶訂單號
	private String openid;// 用戶openid

	//校驗用戶姓名選項  NO_CHECK:不校驗真實姓名 
	private String check_name;
	private int amount;// 付款金額
	private String desc;// 企業付款描述信息
	private String spbill_create_ip;// 調用接口的機器Ip地址
	
	public String getMch_appid() {
		return mch_appid;
	}
	public void setMch_appid(String mch_appid) {
		this.mch_appid = mch_appid;
	}
	public String getMchid() {
		return mchid;
	}
	public void setMchid(String mchid) {
		this.mchid = mchid;
	}
	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 getPartner_trade_no() {
		return partner_trade_no;
	}
	public void setPartner_trade_no(String partner_trade_no) {
		this.partner_trade_no = partner_trade_no;
	}
	public String getOpenid() {
		return openid;
	}
	public void setOpenid(String openid) {
		this.openid = openid;
	}
	public String getCheck_name() {
		return check_name;
	}
	public void setCheck_name(String check_name) {
		this.check_name = check_name;
	}
	public int getAmount() {
		return amount;
	}
	public void setAmount(int amount) {
		this.amount = amount;
	}
	public String getDesc() {
		return desc;
	}
	public void setDesc(String desc) {
		this.desc = desc;
	}
	public String getSpbill_create_ip() {
		return spbill_create_ip;
	}
	public void setSpbill_create_ip(String spbill_create_ip) {
		this.spbill_create_ip = spbill_create_ip;
	}
	
    

}


之後就是給 這些參數賦值 

	@Autowired
	private XMLUtil xmlUtil;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.security.KeyStore;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import javax.net.ssl.SSLContext;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
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.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


上面是導入的包 下面就是給參數配值了

private void redPackets(Integer withdrawId, String openId) throws Exception {
		int total=100;
		int amount = (int) (total*100);
		
		Transfers transfers=new Transfers();
		String nonce = UUID.randomUUID().toString().substring(0, 30);
		
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
		String time = df.format(new Date());
		Random ne=new Random();
		int guid=ne.nextInt(9999-1000+1)+1000;
		
		transfers.setMch_appid(APPID);// 自己的公衆賬號
		transfers.setMchid(partnerId);//自己的 商戶號
		transfers.setNonce_str(nonce);// 隨機字符串
		transfers.setOpenid(openId);// 用戶openId
		transfers.setCheck_name("NO_CHECK");// 校驗用戶姓名選項
		transfers.setAmount(amount);// 付款金額
		transfers.setDesc("微信企業付款");// 企業付款描述信息
		transfers.setSpbill_create_ip("120.236.82.202");// 調用接口的機器Ip地址
		transfers.setPartner_trade_no(WxConfig.partnerId+time+guid);// 商戶訂單號
		String sign = createSendRedPackOrderSign(transfers);
		transfers.setSign(sign);// 簽名
		
		xmlUtil.xstream().alias("xml", transfers.getClass());
		String xml = xmlUtil.xstream().toXML(transfers);
		
		String sendEedPackUrl="https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
		String response = ssl(sendEedPackUrl,xml);
		Map<String, String> responseMap = xmlUtil.parseXml(response);
		
		String return_msg = responseMap.get("return_msg");
		System.out.println(return_msg);
	}


這裏就是根據上面的內容生成簽名 sign 這裏文檔有說明 這裏要注意的是去,簽名要按照 ASCII碼從小到大排序(字典序)

public String createSendRedPackOrderSign(Transfers transfers){
		
        StringBuffer sign = new StringBuffer();
        sign.append("mch_appid=").append(transfers.getMch_appid());
        sign.append("&mchid=").append(transfers.getMchid());
        sign.append("&nonce_str=").append(transfers.getNonce_str());
        sign.append("&partner_trade_no=").append(transfers.getPartner_trade_no());
        sign.append("&openid=").append(transfers.getOpenid());
        sign.append("&check_name=").append(transfers.getCheck_name());
        sign.append("&amount=").append(transfers.getAmount());
        sign.append("&desc=").append(transfers.getDesc());
        sign.append("&spbill_create_ip=").append(transfers.getSpbill_create_ip());
        sign.append("&key=").append(WxConfig.partnerKey);
       
        return  DigestUtils.md5Hex(sign.toString()).toUpperCase();
    }


然後就是xmlutil類了 我是在網上大神博客找的

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.stereotype.Component;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.thoughtworks.xstream.io.xml.XppDriver;

/**
 * XML工具包
 * 
 * XMLUtil
 * 
 * @author zdl
 * @version 1.0.0
 *
 */
@Component
public class XMLUtil {

	/**
	 * 解析字符串(XML)
	 * 
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public Map<String, String> parseXml(String msg) throws Exception {
		// 將解析結果存儲在HashMap中
		Map<String, String> map = new HashMap<String, String>();

		// 從request中取得輸入流
		InputStream inputStream = new ByteArrayInputStream(
				msg.getBytes("UTF-8"));

		// 讀取輸入流
		SAXReader reader = new SAXReader();
		Document document = reader.read(inputStream);
		// 得到xml根元素
		Element root = document.getRootElement();
		// 得到根元素的所有子節點
		List<Element> elementList = root.elements();

		// 遍歷所有子節點
		for (Element e : elementList)
			map.put(e.getName(), e.getText());

		// 釋放資源
		inputStream.close();
		inputStream = null;

		return map;
	}

	/**
	 * 擴展xstream,使其支持CDATA塊
	 */
	private XStream xstream = new XStream(new XppDriver(new NoNameCoder()) {

		@Override
		public HierarchicalStreamWriter createWriter(Writer out) {
			return new PrettyPrintWriter(out) {
				// 對所有xml節點的轉換都增加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;
	}

}


如何就是ssl方法 

private String ssl(String url,String data){
        StringBuffer message = new StringBuffer();
        try {
            KeyStore keyStore  = KeyStore.getInstance("PKCS12");
            FileInputStream instream = new FileInputStream(new File("D:/cert/apiclient_cert.p12"));
            keyStore.load(instream, WxConfig.partnerId.toCharArray());
            // Trust own CA and all self-signed certs
            SSLContext sslcontext = SSLContexts.custom()
                    .loadKeyMaterial(keyStore, WxConfig.partnerId.toCharArray())
                    .build();
            // Allow TLSv1 protocol only
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    sslcontext,
                    new String[] { "TLSv1" },
                    null,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .build();
            HttpPost httpost = new HttpPost(url);

            httpost.addHeader("Connection", "keep-alive");
            httpost.addHeader("Accept", "*/*");
            httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            httpost.addHeader("Host", "api.mch.weixin.qq.com");
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");
            httpost.addHeader("Cache-Control", "max-age=0");
            httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
            httpost.setEntity(new StringEntity(data, "UTF-8"));
            //System.out.println("executing request" + httpost.getRequestLine());

            CloseableHttpResponse response = httpclient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();

                //System.out.println("----------------------------------------");
                //System.out.println(response.getStatusLine());
                if (entity != null) {
                    //System.out.println("Response content length: " + entity.getContentLength());
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(),"UTF-8"));
                    String text;
                    while ((text = bufferedReader.readLine()) != null) {
                        message.append(text);
                    }
                }
                EntityUtils.consume(entity);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                response.close();
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        } 

        return message.toString();
    }
	

如果還有什麼不懂的可以去看 這位大師的博客,我也是根據他的來寫的 ,順便說一下是java微信紅包的!   

http://blog.csdn.net/jrainbow/article/details/50266391



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