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



  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 29
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值