您的位置:首页 > 移动开发 > 微信开发

微信企业付款到银行卡

2018-01-03 00:00 274 查看
微信官方文档:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_2

1.第一步准备好商户的证书,在商户后台下载





2第二步准备好微信RSA公钥

微信官方地址:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_7



这里简单实例展示,需要的自行拆分封装

$mch_id     =   123456;//自己的商户号
$str        =   md5(rand(1000,9999));//随机字符串
$sign_type  =   "MD5";//加密类型
$key        =   "abcde";//商户的key
$stringA    =   "mch_id={$mch_id}&nonce_str={$str}&sign_type={$sign_type}&key={$key}";
$md5_str    =   MD5($stringA);//md5加密
$sign       =   strtoupper($md5_str);//转大写
$url        =   "https://fraud.mch.weixin.qq.com/risk/getpublickey";//微信生成RSA公钥接口地址
$xml=<<<EOF
<xml>
<mch_id>{$mch_id}</mch_id>
<nonce_str>{$str}</nonce_str>
<sign_type>MD5</sign_type>
<sign>$sign</sign>
</xml>
EOF;
$apiclient_key   =   './Xcxpay/Certificate/Jw/apiclient_cert.pem';//证书路径 在商户平台下载
$apiclient_cert  =   './Xcxpay/Certificate/Jw/apiclient_key.pem';//证书路径 在商户平台下载
$ch = curl_init();
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//使用证书:cert 与 key 分别属于两个.pem文件
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
//		curl_setopt($ch,CURLOPT_SSLCERT, 'apiclient_key证书的路径');//上面第一步在商户后台下载的证书
curl_setopt($ch,CURLOPT_SSLCERT, $apiclient_key);//上面第一步在商户后台下载的证书
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
//		curl_setopt($ch,CURLOPT_SSLKEY, 'apiclient_cert证书的路径');//上面第一步在商户后台下载的证书
curl_setopt($ch,CURLOPT_SSLKEY, $apiclient_cert);//上面第一步在商户后台下载的证书
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
$data = curl_exec($ch);
//返回结果
if($data){
curl_close($ch);
} else {
$error = curl_errno($ch);
curl_close($ch);
}
libxml_disable_entity_loader(true);
$result     =   json_decode(json_encode(simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
print_r($result);

成功后返回的数据



把pub_key的内容保存成为一个文件, 已 .pem后缀的文件 例如 wx_public.pem 等等需要用到这个文件

如:





再将wx_public.pem 格式转换

openssl rsa -RSAPublicKey_in -in 刚刚保存的文件 -pubout > 新的文件



得到新的pem文件,等等要用到。这个文件主要是要来RAS加密 银行卡号和姓名

新建一个类

class Wxyxk
{
public $value=array(
'mch_id'=>'',
'partner_trade_no'=>'',
'nonce_str'=>'',
'enc_bank_no'=>'',
'enc_true_name'=>'',
'bank_code'=>'',
'amount'=>'',
'desc'=>'',
);
public $app_id;
public $mch_id;
public $key;
public $url = "https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank";
public $apiclient_cert;
public $apiclient_key;
public $public_pem;

public function __construct($mch_id, $key)
{
$this->mch_id       =   $this->value['mch_id']      =   $mch_id;
$this->key          =   $key;
}

public function sendRed()
{

foreach($this->value as $k=>$v){
if(empty($v)){
return $k.' 不能为空';
}
}

if(empty($this->apiclient_cert) || empty($this->apiclient_key) || empty($this->key)){
return '证书路径和key不能为空';
}
$this->MakeSign();
$xml = $this->ToXml();
$result_xml = $this->postXmlCurl($xml,$this->url);
$result = $this->FromXml($result_xml);
//		$this->wirteLog($this->setMsg($result));

return $result;
}

public function getOrderStatus($order_on)
{
$url            =   "https://api.mch.weixin.qq.com/mmpaysptrans/query_bank";
$rand_str       =   md5(rand(100000,99999));
$data           =   array("mch_id"=>$this->mch_id,"nonce_str"=>$rand_str,'partner_trade_no'=>$order_on);
$str            =   "mch_id={$this->mch_id}&nonce_str={$rand_str}&partner_trade_no={$order_on}&key={$this->key}";
$sign           =   strtoupper(md5($str));
$data['sign']   =   $sign;

$xml = "<xml>";
foreach ($data as $key=>$val) {
if (is_numeric($val)){
$xml    .=  "<".$key.">".$val."</".$key.">";
}else{
$xml    .=  "<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml            .=  "</xml>";

$result_xml     =   $this->postXmlCurl($xml, $url);
$result         = $this->FromXml($result_xml);
return $result;

}

/**
* 输出xml字符
* @throws WxPayException
**/
public function ToXml()
{
if(!is_array($this->value)
|| count($this->value) <= 0)
{
throw new WxPayException("数组数据异常!");
}

$xml = "<xml>";
foreach ($this->value as $key=>$val)
{
if (is_numeric($val)){
$xml.="<".$key.">".$val."</".$key.">";
}else{
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</xml>";
return $xml;
}

public function createXml($data)
{
if(!is_array($data)
|| count($data) <= 0)
{
throw new WxPayException("数组数据异常!");
}

$xml = "<xml>";
foreach ($data as $key=>$val)
{
if (is_numeric($val)){
$xml.="<".$key.">".$val."</".$key.">";
}else{
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</xml>";
return $xml;
}

public function createMakeSign($data)
{
$buff = "";
foreach ($data as $k => $v)
{
if($k != "sign" && $v != "" && !is_array($v)){
$buff .= $k . "=" . $v . "&";
}
}

$buff = trim($buff, "&");
$buff = $buff . "&key=".$this->key;
$string = md5($buff);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return  $result;
}

/**
* 生成签名
* @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
*/
public function MakeSign()
{
//签名步骤一:按字典序排序参数
ksort($this->value);
$string = $this->ToUrlParams();
//签名步骤二:在string后加入KEY
$string = $string . "&key=".$this->key;
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
$this->value['sign'] = $result;
return $result;
}

/**
* 格式化参数格式化成url参数
*/
public function ToUrlParams()
{
$buff = "";
foreach ($this->value as $k => $v)
{
if($k != "sign" && $v != "" && !is_array($v)){
$buff .= $k . "=" . $v . "&";
}
}

$buff = trim($buff, "&");
return $buff;
}

public function FromXml($xml)
{
if(!$xml){
throw new \Exception("xml数据异常!");
}
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $this->values;
}

/**
* 以post方式提交xml到对应的接口url
*
* @param string $xml  需要post的xml数据
* @param string $url  url
* @param bool $useCert 是否需要证书,默认不需要
* @param int $second   url执行超时时间,默认30s
* @throws WxPayException
*/
private function postXmlCurl($xml, $url, $useCert = false, $second = 30)
{
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//        if($useCert == true){
//设置证书
//使用证书:cert 与 key 分别属于两个.pem文件
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT, $this->apiclient_key);
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY, $this->apiclient_cert);
//        }
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行curl
$data = curl_exec($ch);
//返回结果
if($data){
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
//            throw new \Exception("curl出错,错误码:$error");
}
}

public function RAS($str)
{
$public_pem     =   file_get_contents($this->public_pem);
openssl_public_encrypt($str,$decrypted,$public_pem,OPENSSL_PKCS1_OAEP_PADDING);
return base64_encode($decrypted);
}

public function partnerTradeNo($value)
{
$this->value['partner_trade_no']    =   $value;
}
public function nonceStr($value)
{
$this->value['nonce_str']           =   $value;
}
public function encBankNo($value)
{
$this->value['enc_bank_no']         =    $this->RAS($value);
}
public function encTrueName($value)
{
$this->value['enc_true_name']       =    $this->RAS($value);
}
public function bankCode($value)
{
$this->value['bank_code']           =    $value;
}
public function amount($value)
{
$this->value['amount']              =    $value;
}
public function desc($value)
{
$this->value['desc']                =    $value;
}

}

<?php
require './Xcxpay/Wxyxk.php';//引入刚刚的类
$mch_id                 =   '123456';
$key                    =   "1111111111";
$model                  =   new Wxyxk($mch_id,$key);
$model->apiclient_key   =   './Xcxpay/Certificate/Jw/apiclient_cert.pem';//证书路径 在商户平台下载 第一步获取的证书
$model->apiclient_cert  =   './Xcxpay/Certificate/Jw/apiclient_key.pem';//证书路径 在商户平台下载 第一步获取的证书
$model->public_pem      =   "./Xcxpay/Certificate/Jw/wx_public8.pem";//第二步获取的 微信RAS公匙
$model->partnerTradeNo($order_on);//订单号
$model->nonceStr(md5(rand(1000,9999)));
$model->encBankNo($employee_bank_info['bank_no']);//银行卡号
$model->encTrueName($employee_bank_info['name']);//银行卡持卡人姓名
$model->bankCode($employee_bank_info['bank_code']);//微信银行卡id 见下图
$model->amount($amount);//金额
$model->desc($declare);//订单说明
$result                 =   $model->sendRed();


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: