参考网上博客:https://blog.csdn.net/shaomiaojava/article/details/50562550
import java.io.*; import java.math.BigDecimal; import java.security.KeyStore; import java.util.Map; import java.util.UUID; import javax.net.ssl.SSLContext; import com.dingyi.common.base.CommonConstant; import com.dingyi.common.model.member.PlatformWeixinCheckTransfer; import com.dingyi.common.model.member.PlatformWeixinMoneyRecord; import com.dingyi.common.model.member.PlatformWeixinTransfer; import com.dingyi.common.util.MD5Util; import com.dingyi.common.util.XMLUtil; 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.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Component; @Component public class RedPacketUtil { @Value("${weixin.mch_appid}") private String APPID; @Value("${weixin.mchid}") private String partnerId; //商户号 @Value("${weixin.mchkey}") private String partnerKey; //支付key @Autowired private XMLUtil xmlUtil; @Autowired private AlipayUtil alipayUtil; /*进行付款*/ public MapsendRed(PlatformWeixinMoneyRecord record) { PlatformWeixinTransfer transfers = new PlatformWeixinTransfer(); //把以元为单位的金额改成以分为单位 BigDecimal total = record.getAmount(); int amount = total.multiply(new BigDecimal("100")).intValue(); String nonce = UUID.randomUUID().toString().substring(0, 30); String partnerTradeNo = alipayUtil.getTradeNo(CommonConstant.WEIXIN_REDPACKET);//生成唯一订单号,可以用随机数+时间戳替代 transfers.setMch_appid(APPID);// 自己的公众账号 transfers.setMchid(partnerId);//自己的 商户号 transfers.setNonce_str(nonce);// 随机字符串 transfers.setOpenid(record.getOpenid());// 用户openId transfers.setCheck_name("NO_CHECK");// 校验用户姓名选项 transfers.setAmount(amount);// 付款金额 transfers.setDesc(record.getDesc());// 企业付款描述信息 transfers.setSpbill_create_ip("116.62.61.25");// 调用接口的机器Ip地址 transfers.setPartner_trade_no(partnerTradeNo);// 商户订单号 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 responseMap = null; try { responseMap = xmlUtil.parseXml(response); } catch (Exception e) { e.printStackTrace(); } String return_msg = responseMap.get("return_msg"); System.out.println(return_msg); return responseMap; } /* 查询付款结果*/ public Map checkSuccess(PlatformWeixinMoneyRecord record) { PlatformWeixinCheckTransfer checkTransfer = new PlatformWeixinCheckTransfer(); String nonce = UUID.randomUUID().toString().substring(0, 30); checkTransfer.setAppid(APPID);// 自己的公众账号 checkTransfer.setMch_id(partnerId);//自己的 商户号 checkTransfer.setNonce_str(nonce);// 随机字符串 checkTransfer.setPartner_trade_no(record.getPartnerTradeNo());// 商户订单号 String sign = createCheckOrderSign(checkTransfer); checkTransfer.setSign(sign);// 签名 xmlUtil.xstream().alias("xml", checkTransfer.getClass()); String xml = xmlUtil.xstream().toXML(checkTransfer); System.out.println(xml); String sendEedPackUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo"; String response = ssl(sendEedPackUrl, xml); Map responseMap = null; try { responseMap = xmlUtil.parseXml(response); } catch (Exception e) { e.printStackTrace(); } String return_msg = responseMap.get("return_msg"); System.out.println(return_msg); return responseMap; } /*查询付款结果的签名*/ private String createCheckOrderSign(PlatformWeixinCheckTransfer checkTransfer) { StringBuffer sign = new StringBuffer(); sign.append("appid=").append(checkTransfer.getAppid()); sign.append("&mch_id=").append(checkTransfer.getMch_id()); sign.append("&nonce_str=").append(checkTransfer.getNonce_str()); sign.append("&partner_trade_no=").append(checkTransfer.getPartner_trade_no()); sign.append("&key=").append(partnerKey); System.out.println(sign.toString()); return MD5Util.MD5Encode(sign.toString(), null).toUpperCase(); } /*付款的签名*/ public String createSendRedPackOrderSign(PlatformWeixinTransfer transfers){ StringBuffer sign = new StringBuffer(); sign.append("amount=").append(transfers.getAmount()); sign.append("&check_name=").append(transfers.getCheck_name()); sign.append("&desc=").append(transfers.getDesc()); sign.append("&mch_appid=").append(transfers.getMch_appid()); sign.append("&mchid=").append(transfers.getMchid()); sign.append("&nonce_str=").append(transfers.getNonce_str()); sign.append("&openid=").append(transfers.getOpenid()); sign.append("&partner_trade_no=").append(transfers.getPartner_trade_no()); sign.append("&spbill_create_ip=").append(transfers.getSpbill_create_ip()); sign.append("&key=").append(partnerKey); System.out.println(sign.toString()); return MD5Util.MD5Encode(sign.toString(), null).toUpperCase(); } private String ssl(String url,String data){ StringBuffer message = new StringBuffer(); try { KeyStore keyStore = KeyStore.getInstance("PKCS12"); ClassPathResource classPathResource = new ClassPathResource("apiclient_cert.p12"); InputStream instream = classPathResource.getInputStream(); keyStore.load(instream, partnerId.toCharArray()); // Trust own CA and all self-signed certs SSLContext sslcontext = SSLContexts.custom() .loadKeyMaterial(keyStore, 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(); } }
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) * * @return * @throws Exception */ @SuppressWarnings("unchecked") public MapparseXml(String msg) throws Exception { // 将解析结果存储在HashMap中 Map map = new HashMap (); // 从request中取得输入流 InputStream inputStream = new ByteArrayInputStream( msg.getBytes("UTF-8")); // 读取输入流 SAXReader reader = new SAXReader(); Document document = reader.read(inputStream); // 得到xml根元素 Element root = document.getRootElement(); // 得到根元素的所有子节点 List 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("); 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; } }
注意事项:
1. 小程序需要开通微信支付,此处appid既为小程序appid。
2.商户号,是商户平台中的商户号。在小程序开通微信支付的时候,这些信息会被以邮件的形式发送给用户
3.支付key和安全证书(“apiclient_cert.p12”)都是在商户平台-账户中心-API安全 中设置和获取