java 企业付款到零钱 微信提现功能讲解

从微信支付平台中我们要下载证书,设置秘钥,确保appid一致,获取商户号,

微信api说明,请求需要双向证书。 所以需要去商户管理后台下载api证书  微信支付平台 (https://pay.weixin.qq.com/index.php/core/home/login?return_url=%2F)

在支付平台->账户中心->api安全 下载证书   并设置秘钥   

然后在营销中心->支付后配置  查看发起提现公众号的appid  此appid一定要和获取用户openid的appid一致

以下是代码:

-----------------------------------------WeixinpayUtil------------------------------------------------

package com.xxx.utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.company.user.bean.EnterprisesPayment;

/**
 * 
 * @author 作者 ldh:
 * 
 * @version 创建时间:2019年10月15日 下午1:57:29
 * 
 *          类说明 微信提现 xml数据 签名等
 * 
 */

public class WeixinpayUtil {
    static Logger log = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

    public static String createDocumentForEnterprisesPayment(EnterprisesPayment enterprisesPayment) {
        final StringBuffer result = new StringBuffer();
        result.append("");
        result.append("" + enterprisesPayment.getMch_appid() + "");
        result.append("" + enterprisesPayment.getMchid() + "");
        result.append("" + enterprisesPayment.getNonce_str() + "");
        result.append("" + enterprisesPayment.getPartner_trade_no() + "");
        result.append("" + enterprisesPayment.getOpenid() + "");
        result.append("" + enterprisesPayment.getCheck_name() + "");
        result.append("" + enterprisesPayment.getRe_user_name() + "");
        result.append("" + enterprisesPayment.getAmount() + "");
        result.append("" + enterprisesPayment.getDesc() + "");
        result.append("" + enterprisesPayment.getSpbill_create_ip() + "");
        result.append("" + enterprisesPayment.getSign() + "");
        result.append("
");
        return result.toString();
    }

    public static String getSignCode(Map map, String keyValue) {
        String result = "";
        try {
            List> infoIds = new ArrayList>(map.entrySet());
            // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)
            Collections.sort(infoIds, new Comparator>() {

                public int compare(Map.Entry o1, Map.Entry o2) {
                    return (o1.getKey()).toString().compareTo(o2.getKey());
                }
            });
            // 构造签名键值对的格式
            StringBuilder sb = new StringBuilder();
            for (Map.Entry item : infoIds) {
                if (item.getKey() != null || item.getKey() != "") {
                    String key = item.getKey();
                    String val = item.getValue();
                    if (!(val == "" || val == null)) {
                        sb.append(key + "=" + val + "&");
                    }
                }
            }
            sb.append("key=" + keyValue);
            result = sb.toString();

            // 进行MD5加密
            result = WeixinpayUtil.md5(result).toUpperCase();
        } catch (Exception e) {
            return null;
        }
        return result;
    }

    /**
     * 生成32位编码
     * 
     * @return string
     */
    public static String getUUID() {
        String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
        return uuid;
    }

    /**
     * 生成提现订单号
     * 
     * @return string
     */
    public static String getOrderId() {
        int machineId = 1;// 最大支持1-9个集群机器部署
        int hashCodeV = UUID.randomUUID().toString().hashCode();
        if (hashCodeV < 0) {// 有可能是负数
            hashCodeV = -hashCodeV;
        }
        return machineId + String.format("%015d", hashCodeV);
    }

    /**
     * md5加密
     * 
     * @param text
     * @return
     */
    public static String md5(final String text) {
        return EncryptionUtil.encodeByMD5(text).toUpperCase();
        // return Md5Encrypt.md5(text).toUpperCase();
    }

}

-------------------------------------------ClientCustomSSLController-----------------------------------------------------------------

package com.xxx.controller;

import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import javax.net.ssl.SSLContext;
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.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

/**
 * 
 * @author 作者 ldh:
 * 
 * @version 创建时间:2019年10月15日 下午1:50:03
 * 
 *          类说明 加载证书 发送请求
 * 
 */

public class ClientCustomSSLController {

    public static String doRefund(String url, String xmlData) throws Exception {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        FileInputStream instream = new FileInputStream(new File(""));// P12文件目录
                                                                        // 写证书的项目路径
        try {
            keyStore.load(instream, "xxxx".toCharArray());// 这里写密码..默认是你的MCHID
                                                            // 证书密码
        } finally {
            instream.close();
        }
        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, "xxxx".toCharArray())// 这里也是写密码的
                .build();

        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        try {
            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("", "UTF-8"));
            CloseableHttpResponse response = httpclient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();

                String returnMessage = EntityUtils.toString(response.getEntity(), "UTF-8");
                EntityUtils.consume(entity);
                return returnMessage; // 返回后自己解析结果
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }

}
-------------------------------------------------------TestWeixin------------------------------------------------------------------

package com.xxx.test;

import java.util.SortedMap;
import java.util.TreeMap;
import com.company.controller.ClientCustomSSLController;
import com.company.user.bean.EnterprisesPayment;
import com.company.utils.WeixinpayUtil;
/**
 * 
 * @author 作者 ldh:
 * 
 * @version 创建时间:2019年10月15日 下午2:10:06
 * 
 *          类说明 测试微信提现
 * 
 */

public class TestWeixin {

    private static SortedMap sortedMap = new TreeMap();

    public static void main(String[] args) throws Exception {

        String openid = null;
        Integer amount = null;
        String sginCode = getSgin(openid, amount);// 获取用户openid 和 用户要提现的金额 拿到签名
        EnterprisesPayment enterprisesPayment = addEnterprisesPayment(openid, amount, sginCode);// 拿到签名后加密得到要发送到对象数据
        String enterprisesPaymentXML = WeixinpayUtil.createDocumentForEnterprisesPayment(enterprisesPayment); // 封装xml
                                                                                                                // 数据发送
        String returnXmlData = ClientCustomSSLController.doRefund("url地址", enterprisesPaymentXML);
        System.out.println("returnXmlData:" + returnXmlData);
    }

    public static EnterprisesPayment addEnterprisesPayment(String openid, Integer amount, String sginCode) {
        EnterprisesPayment enterprisesPayment = new EnterprisesPayment();
        enterprisesPayment.setMch_appid("appid");// 商户号appid
        enterprisesPayment.setMchid("商户号");// 商户号
        // enterprisesPayment.setDevice_info(null);//设备号 非必填
        enterprisesPayment.setNonce_str(sortedMap.get("nonce_str"));// 随机字符串
        enterprisesPayment.setSign(sginCode);// 签名
        enterprisesPayment.setPartner_trade_no(sortedMap.get("partner_trade_no"));// 商户订单号
        enterprisesPayment.setOpenid(openid);
        enterprisesPayment.setCheck_name("NO_CHECK");
        enterprisesPayment.setRe_user_name(null); // 根据checkName字段判断是否需要
        enterprisesPayment.setAmount(amount);// 金额
        enterprisesPayment.setDesc("desc");// 描述
        enterprisesPayment.setSpbill_create_ip("ip");// ip地址
        return enterprisesPayment;
    }

    public static String getSgin(String openid, Integer amount) {
        sortedMap.put("mch_appid", "appid");
        sortedMap.put("mchid", "商户号");
        sortedMap.put("nonce_str", WeixinpayUtil.getUUID());
        sortedMap.put("partner_trade_no", WeixinpayUtil.getOrderId());
        sortedMap.put("openid", openid);
        sortedMap.put("check_name", "NO_CHECK");
        sortedMap.put("amount", amount.toString());
        sortedMap.put("desc", "desc");
        sortedMap.put("spbill_create_ip", "ip");
        sortedMap.put("re_user_name", "null");
        return WeixinpayUtil.getSignCode(sortedMap, "api秘钥");
    }
}
 

你可能感兴趣的:(JAVA,IT)