简述

微信支付也早已提供了代付功能,支持企业向用户付款,分别未付款到零钱和付款到银行卡两种方式。在我们平常开发的项目中一般都会用到微信支付功能,相应的项目中也会提供提现功能。企业付款到零钱和企业付款到银行卡是两个接口,功能不一样,Api限制也不一样,本篇博文主要讲述开发微信企业付款到银行卡的步骤详解,关于企业付款到零钱等下篇再进行讲述。

这里还是主要说付款至用户银行卡,微信上线的企业付款至银行卡功能,商户可以将商户号余额付款至指定的收款银行账户,通过指定收款银行账户户名、卡号,以及收款银行信息就可以实现付款功能。目前企业付款到银行卡仅支持17家银行,更多银行在逐步开放中,但是看着常用的银行基本都有,这个不影响使用。

步骤

第一步、开通微信付款到个人银行卡这个功能产品

企业微信付款到个人微信java代码实现 企业微信付款流程图_开发微信企业付款到银行卡步骤详解

第二步、下载API安全证书

企业微信付款到个人微信java代码实现 企业微信付款流程图_微信企业付款_02

微信企业付款到零钱要求必传证书,需要到https://pay.weixin.qq.com 账户中心->账户设置->API安全->下载证书,下载下来的证书文件一共有三个,还有一个证书使用说明文档,这里就不进行解释了。然后保存,配置好代码中的证书路径。

第三步、获取RSA加密公钥

调用获取RSA公钥API获取RSA公钥,落地成本地文件,假设为public.pem,确定public.pem文件的存放路径,同时修改代码中文件的输入路径,加载RSA公钥,用标准的RSA加密库对敏感信息进行加密,选择RSA_PKCS1_OAEP_PADDING填充模式, 得到进行rsa加密并转base64之后的密文,将密文传给微信侧相应字段,如付款接口(enc_bank_no/enc_true_name)

下面代码默认输出PKCS#1格式的公钥,我们需要这个,所以先写一个接口去请求一下,然后将证书文件保存一下。请求下面这个接口方法会返回证书信息。

/**
     * 获得RSA加密公钥
     */
    public function GetRsa()
    {
        $data = [
            'mch_id' => $this->mch_id,
            'nonce_str' => self::CreateNonceStr(32),
            'sign_type' => 'MD5',
        ];
        $data['sign'] = self::MakeSign($data, $this->api_key);

        $xml = self::ArrayToXml($data);
        $url = 'https://fraud.mch.weixin.qq.com/risk/getpublickey';
        $arr = self::CurlPostSsl($url, $xml, $this->certificate_path);
        var_dump(self::XmlToArray(strstr($arr, '<xml>')));
        exit;
    }

第四步、RSA密钥PKCS#1转PKCS#8

PKCS#1 转 PKCS#8:
openssl rsa -RSAPublicKey_in -in  -pubout
PKCS#8 转 PKCS#1:
openssl rsa -pubin -in  -RSAPublicKey_out

这个命令需要在服务器执行,如果报错的话,说明你姿势不对,亲重新查找原因再次尝试。

openssl rsa -RSAPublicKey_in -in pkcs1.pem -pubout > pkcs8.pem

企业微信付款到个人微信java代码实现 企业微信付款流程图_微信企业付款_03

这样提示writing RSA key就说明成功了,当然敲这个命令的时候要进入你放证书以及上面的公钥的目录,放在一个不可直接访问的目录!

第五步、进行代码配置

准备工作到此就做完了,下面可以进行代码配置。

/**
     * 构造函数
     * @desc 用于设置基本信息
     * 1、设置APP ID(应用id)
     * 2、设置MCH ID(商户id)
     * 3、设置API KEY(API接口密钥)
     * 4、设置Certificate Path(证书路径地址)
     * @other 这些数据也可以直接从数据库中获取,然后赋值;或者从配置文件中获取、赋值;根据个人习惯。
     */
    public function __construct($parameter = array())
    {
        $this->mch_appid = !empty($parameter['mch_appid']) ? $parameter['mch_appid'] : '';
        $this->mch_id = !empty($parameter['mch_id']) ? $parameter['mch_id'] : '';
        $this->api_key = !empty($parameter['api_key']) ? $parameter['api_key'] : '';
        $this->certificate_path = !empty($parameter['certificate_path']) ? $parameter['certificate_path'] : '';

        if (empty($this->mch_appid)) {
            throw new Exception("App Id has not been set up!");
        }
        if (empty($this->mch_id)) {
            throw new Exception("Mch Id has not been set up!");
        }
        if (empty($this->api_key)) {
            throw new Exception("Api Key has not been set up!");
        }
        if (empty($this->certificate_path)) {
            throw new Exception("Certificate Path has not been set up!");
        }
    }

第六步、调用代付提交

企业付款到个人银行卡API的请求参数以及返回结果等具体可查看微信开发文档:企业付款待银行卡API。

/**
     * 企业付款到银行卡
     * @param $bank_no string 银行卡号
     * @param $true_name string 真实姓名
     * @param $bank_code string 银行代码(可在开发文档中查看)
     * @param $amount float 金额数值(元) 
     * @param $partner_trade_no string 代付单号
     * @return mixed
     */
    public function WxPayToBank($bank_no, $true_name, $bank_code, $amount, $partner_trade_no)
    {        
        $paybank = [
            'mch_id' => $this->mch_id,
            'partner_trade_no' => $partner_trade_no,
            'nonce_str' => self::CreateNonceStr(),
            'enc_bank_no' => self::RSAEncrypt($bank_no, $this->certificate_path),
            'enc_true_name' => self::RSAEncrypt($true_name, $this->certificate_path),
            'bank_code' => $bank_code,
            'amount' => intval($amount) * 100,
            'desc' => "提现处理!"
        ];

        $paybank['sign'] = self::MakeSign($paybank, $this->api_key);
        $xml = self::ArrayToXml($paybank);
        $url = "https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank";
        $data = self::CurlPostSsl($url, $xml, $this->certificate_path);
        return self::XmlToArray(strstr($data, '<xml>'));
    }

第七步、查询代付结果

由于微信代付到账是T+1,并不是实时到账且没有异步通知,所以就需要我们进行结果查询。

/**
     * 代付结果查询
     * @param $partner_trade_no string 代付单号
     * @return mixed
     */
    public function QueryPayResult($partner_trade_no)
    {
        $paybank = [
            'mch_id' => $this->mch_id,
            'partner_trade_no' => $partner_trade_no,
            'nonce_str' => self::CreateNonceStr(),
        ];
        $paybank['sign'] = self::MakeSign($paybank, $this->api_key);
        $xml = self::ArrayToXml($paybank);
        $url = "https://api.mch.weixin.qq.com/mmpaysptrans/query_bank";
        $data = self::CurlPostSsl($url, $xml, $this->certificate_path);
        return self::XmlToArray(strstr($data, '<xml>'));
    }