验证中...
Languages: PHP
Categories: 微信开发
Latest update 2019-10-14 14:08
gistfile1.txt
Raw Copy
<?php
/**
*企业付款 用于企业向微信用户个人付款
*目前支持向指定微信用户的openid付款。(获取openid参见微信公众平台开发者文档: 网页授权获取用户基本信息)
*https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
*/
namespace app\common\model;
use think\Model;
class Compay extends Model
{
protected $payurl = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';
protected $appid = 'wx7cc9a68xxxxxxxxx'; //appid
protected $mchid = '137xxxxxxxxx';
protected $signkey ='68nsX1NqtoB50Jxxxxxxxxxxxxxxxxxxxxxxxxxxx';//支付密钥
//这里的路径很重要 一定要写相对路径
protected $cacab = array(
'api_cert'=>'./cert_com/apiclient_cert.pem',
'api_key'=>'./cert_com/apiclient_key.pem',
// 'api_ca'=>'./cert_com/rootca.pem',
);
//$data 要传递的参数, $wxchat微信企业支付等信息
/** $data 格式如下
* $data = array(
'userid' //申请退款者ID
'openid' //退款者openid
'refundid' //退款申请ID
'money' //退款金额
'desc' //退款描述
);
*
*/
public function wxbuild($data, $wxchat){
//判断有没有CA证书及支付信息
if(empty($wxchat['api_cert']) || empty($wxchat['api_key']) || empty($wxchat['appid']) || empty($wxchat['mchid'])){
$wxchat['appid'] = $this->appid;
$wxchat['mchid'] = $this->mchid;
$wxchat['api_cert'] = $this->cacab['api_cert'];
$wxchat['api_key'] = $this->cacab['api_key'];
// $wxchat['api_ca'] = $this->cacab['api_ca'];
}else{
$this->appid = $wxchat['appid'] ;
$this->mchid = $wxchat['mchid'];
$this->signkey = $wxchat['signkey'];
$this->cacab['api_cert'] = $wxchat['api_cert'];
$this->cacab['api_key'] = $wxchat['api_key'];
// $this->cacab['api_ca'] = $wxchat['api_ca'];
}
$webdata = array(
'mch_appid' => $wxchat['appid'],
'mchid' => $wxchat['mchid'],
'nonce_str' => md5(time()),
//'device_info' => '1000',
'partner_trade_no' => $data['partner_trade_no'], //商户订单号,需要唯一
'openid' => $data['openid'],
'check_name'=> 'FORCE_CHECK', //OPTION_CHECK不强制校验真实姓名, FORCE_CHECK:强制 NO_CHECK:
're_user_name' => $data['re_user_name'], //收款人用户姓名
'amount' => $data['money'] * 100, //付款金额单位为分
'desc' => empty($data['desc'])? '退款' : $data['desc'],
'spbill_create_ip' => $this->getip(),
);
foreach ($webdata as $k => $v) {
$tarr[] =$k.'='.$v;
}
sort($tarr);
$sign = implode($tarr, '&');
$sign .= '&key='.$this->signkey;
$webdata['sign']=strtoupper(md5($sign));
$wget = $this->array2xml($webdata);
$res = $this->http_post($this->payurl, $wget, $wxchat);
if(!$res){
return array('status'=>3, 'msg'=>"Can't connect the server" );
}
$content = simplexml_load_string($res, 'SimpleXMLElement', LIBXML_NOCDATA);
if(strval($content->return_code) == 'FAIL'){
return array('status'=>2, 'code'=>strval($content->return_code), 'msg'=>strval($content->return_msg));
}
if(strval($content->result_code) == 'FAIL'){
return array('status'=>1, 'code'=>strval($content->err_code),'msg'=>strval($content->err_code_des));
}
$rdata = array(
'status'=>0,
'mch_appid' => strval($content->mch_appid),
'mchid' => strval($content->mchid),
'device_info' => strval($content->device_info),
'nonce_str' => strval($content->nonce_str),
'result_code' => strval($content->result_code),
'partner_trade_no' => strval($content->partner_trade_no),
'payment_no' => strval($content->payment_no),
'payment_time' => strval($content->payment_time),
);
return $rdata;
}
public function getip() {
static $ip = '';
$ip = $_SERVER['REMOTE_ADDR'];
if(isset($_SERVER['HTTP_CDN_SRC_IP'])) {
$ip = $_SERVER['HTTP_CDN_SRC_IP'];
} elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
foreach ($matches[0] AS $xip) {
if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {
$ip = $xip;
break;
}
}
}
return $ip;
}
/**
* 将一个数组转换为 XML 结构的字符串
* @param array $arr 要转换的数组
* @param int $level 节点层级, 1 为 Root.
* @return string XML 结构的字符串
*/
public function array2xml($arr, $level = 1) {
$s = $level == 1 ? "<xml>" : '';
foreach($arr as $tagname => $value) {
if (is_numeric($tagname)) {
$tagname = $value['TagName'];
unset($value['TagName']);
}
if(!is_array($value)) {
$s .= "<{$tagname}>".(!is_numeric($value) ? '<![CDATA[' : '').$value.(!is_numeric($value) ? ']]>' : '')."</{$tagname}>";
} else {
$s .= "<{$tagname}>" . $this->array2xml($value, $level + 1)."</{$tagname}>";
}
}
$s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s);
return $level == 1 ? $s."</xml>" : $s;
}
public function http_post($url, $param, $wxchat) {
$oCurl = curl_init();
if (stripos($url, "https://") !== FALSE) {
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
}
if (is_string($param)) {
$strPOST = $param;
} else {
$aPOST = array();
foreach ($param as $key => $val) {
$aPOST[] = $key . "=" . urlencode($val);
}
$strPOST = join("&", $aPOST);
}
curl_setopt($oCurl, CURLOPT_URL, $url);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($oCurl, CURLOPT_POST, true);
curl_setopt($oCurl, CURLOPT_POSTFIELDS, $strPOST);
if($wxchat){
curl_setopt($oCurl,CURLOPT_SSLCERT,dirname(THINK_PATH).$wxchat['api_cert']);
curl_setopt($oCurl,CURLOPT_SSLKEY,dirname(THINK_PATH).$wxchat['api_key']);
// curl_setopt($oCurl,CURLOPT_CAINFO,dirname(THINK_PATH).$wxchat['api_ca']);
}
$sContent = curl_exec($oCurl);
$aStatus = curl_getinfo($oCurl);
curl_close($oCurl);
if (intval($aStatus["http_code"]) == 200) {
return $sContent;
} else {
return false;
}
}
public function pay($payroll_recordsInfo,$wxchat,$info = ['desc' => '客服电话:0543-7362168'])
{
if (!empty($payroll_recordsInfo['return_code']) || !empty($payroll_recordsInfo['result_code'])){
return ['code'=>1,'msg'=>"订单已经发起支付"];
}
$userInfo = db('admin_user')->where("id",$payroll_recordsInfo['uid'])->find();
if (empty($userInfo['openid'])){
return ['code'=>1,'msg'=>"收款人没有登录过小程序,无法付款"];
}
$data = [];
$data['openid'] = $userInfo['openid'];//收钱的人微信 OPENID
$data['re_user_name'] = $userInfo['zhifubaoxingming'];//收钱的人真实姓名
$data['money'] = $payroll_recordsInfo['count'];
$data['desc'] = $info['desc'];
$data['partner_trade_no'] = md5(get_random($payroll_recordsInfo['uid'].$payroll_recordsInfo['formid']).time());
$res = $this->wxbuild($data, $wxchat);
if ($res['status'] == 0){
//付款成功
/* 业务处理逻辑 */
return ['code'=>0,'msg'=>"付款成功!"];
}else if ($res['status'] == '1'){
//付款失败
/* 业务处理逻辑 */
return ['code'=>1,'msg'=>"付款失败,请手动查询结果或重新发起支付!"];
}else if ($res['status'] == '2'){
//请求失败
/* 业务处理逻辑 */
return ['code'=>1,'msg'=>"付款失败,请重新发起支付,".$res['return_code'].'|'.$res['return_msg']];
}else{
//未知错误
return ['code'=>1,'msg'=>"未知错误,请重新发起支付,"];
}
}
public function repay($payroll_recordsInfo,$wxchat,$info = ['desc' => '客服电话:0543-7362168'])
{
if (empty($payroll_recordsInfo['partner_trade_no'])){
return ['code'=>1,'msg'=>"订单未支付,请核实后查询"];
}
if ($payroll_recordsInfo['return_code'] ==='SUCCESS' || $payroll_recordsInfo['result_code'] === 'SUCCESS'){
return ['code'=>1,'msg'=>"订单已经付款成功"];
}
$userInfo = db('admin_user')->where("id",$payroll_recordsInfo['uid'])->find();
if (empty($userInfo['openid'])){
return ['code'=>1,'msg'=>"收款人没有登录过小程序,无法付款"];
}
$data = [];
$data['openid'] = $payroll_recordsInfo['openid'];//收钱的人微信 OPENID
$data['re_user_name'] = $userInfo['zhifubaoxingming'];//收钱的人真实姓名
$data['money'] = $payroll_recordsInfo['count'];
$data['desc'] = $info['desc'];
$data['partner_trade_no'] = $payroll_recordsInfo['partner_trade_no'];
$res = $this->wxbuild($data, $wxchat);
if ($res['status'] == 0){
//付款成功
/* 业务处理逻辑 */
return ['code'=>0,'msg'=>"付款成功!"];
}else if ($res['status'] == '1'){
//付款失败
/* 业务处理逻辑 */
return ['code'=>1,'msg'=>"付款失败,请手动查询结果或重新发起支付!"];
}else if ($res['status'] == '2'){
//请求失败
/* 业务处理逻辑 */
return ['code'=>1,'msg'=>"付款失败,请重新发起支付,".$res['return_code'].'|'.$res['return_msg']];
}else{
//未知错误
return ['code'=>1,'msg'=>"未知错误,请重新发起支付,"];
}
}
public function gettransferinfo($partner_trade_no, $wxchat)
{
//判断有没有CA证书及支付信息
if(empty($wxchat['api_cert']) || empty($wxchat['api_key']) || empty($wxchat['appid']) || empty($wxchat['mchid'])){
$wxchat['appid'] = $this->appid;
$wxchat['mchid'] = $this->mchid;
$wxchat['api_cert'] = $this->cacab['api_cert'];
$wxchat['api_key'] = $this->cacab['api_key'];
// $wxchat['api_ca'] = $this->cacab['api_ca'];
}else{
$this->appid = $wxchat['appid'] ;
$this->mchid = $wxchat['mchid'];
$this->signkey = $wxchat['signkey'];
$this->cacab['api_cert'] = $wxchat['api_cert'];
$this->cacab['api_key'] = $wxchat['api_key'];
// $this->cacab['api_ca'] = $wxchat['api_ca'];
}
$webdata = array(
'appid' => $wxchat['appid'],
'mch_id' => $wxchat['mchid'],
'nonce_str' => md5(time()),
'partner_trade_no' => $partner_trade_no, //商户订单号
);
foreach ($webdata as $k => $v) {
$tarr[] =$k.'='.$v;
}
sort($tarr);
$sign = implode($tarr, '&');
$sign .= '&key='.$this->signkey;
$webdata['sign']=strtoupper(md5($sign));
$wget = $this->array2xml($webdata);
$res = $this->http_post('https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo', $wget, $wxchat);
if(!$res){
return array('status'=>3, 'msg'=>"Can't connect the server" );
}
$content = simplexml_load_string($res, 'SimpleXMLElement', LIBXML_NOCDATA);
if(strval($content->return_code) == 'FAIL'){
return array('ret'=>2, 'code'=>strval($content->return_code), 'msg'=>strval($content->return_msg));
}
if(strval($content->result_code) == 'FAIL'){
return array('ret'=>1, 'code'=>strval($content->err_code),'msg'=>strval($content->err_code_des));
}
$rdata = array(
'ret'=>0,
'result_code' => strval($content->result_code),
'partner_trade_no' => strval($content->partner_trade_no),
'appid' => strval($content->appid),
'mch_id' => strval($content->mch_id),
'detail_id' => strval($content->detail_id),
'status' => strval($content->status),
'reason' => strval($content->reason),
'openid' => strval($content->openid),
'transfer_name' => strval($content->transfer_name),
'payment_amount' => strval($content->payment_amount / 100),
'transfer_time' => strval($content->transfer_time),
'payment_time' => strval($content->payment_time),
'desc' => strval($content->desc),
);
return $rdata;
}
public function chaxun($payroll_recordsInfo,$wxchat)
{
if (empty($payroll_recordsInfo['partner_trade_no'])){
return ['code'=>1,'msg'=>"订单未支付,请核实后查询"];
}
if ($payroll_recordsInfo['result_code'] === 'SUCCESS'){
return ['code'=>1,'msg'=>"订单已经付款成功,请勿查询"];
}
$res = $this->gettransferinfo($payroll_recordsInfo['partner_trade_no'], $wxchat);
if ($res['ret'] == 0){
if ($res['status'] === 'SUCCESS'){
/* 业务处理逻辑 */
return ['code'=>0,'msg'=>"付款成功!"];
}elseif ($res['status'] === 'FAILED'){
/* 业务处理逻辑 */
return ['code'=>1,'msg'=>"查询成功,请查看在线打款详情!"];
}elseif ($res['status'] === 'PROCESSING'){
/* 业务处理逻辑 */
return ['code'=>1,'msg'=>"查询成功,请查看在线打款详情!"];
}
}else if ($res['ret'] == '1'){
//请求成功
/* 业务处理逻辑 */
return ['code'=>1,'msg'=>"查询成功,请查看在线打款详情!"];
}else if ($res['ret'] == '2'){
//请求失败
/* 业务处理逻辑 */
return ['code'=>1,'msg'=>"查询成功,请查看在线打款详情,".$res['return_code'].'|'.$res['return_msg']];
}else{
//未知错误
return ['code'=>1,'msg'=>"未知错误,请重新发起支付,"];
}
}
}
/*
付款
$compayModel = new Compay();
$wxchat = [];
$wxchat['appid'] = Global_Config['weAppWEAPP_ID'];
$wxchat['mchid'] = Global_Config['mchid'];
$wxchat['signkey'] = Global_Config['signkey'];
$wxchat['api_cert'] = Global_Config['api_cert'];
$wxchat['api_key'] = Global_Config['api_key'];
$info = [];
$info['desc'] = Global_Config['name'];
$PayRet = $compayModel->pay($payroll_records, $wxchat, $info);
*/
/*
重复付款
$compayModel = new Compay();
$wxchat = [];
$wxchat['appid'] = Global_Config['weAppWEAPP_ID'];
$wxchat['mchid'] = Global_Config['mchid'];
$wxchat['signkey'] = Global_Config['signkey'];
$wxchat['api_cert'] = Global_Config['api_cert'];
$wxchat['api_key'] = Global_Config['api_key'];
$info = [];
$info['desc'] = Global_Config['name'];
$PayRet = $compayModel->repay($payroll_records, $wxchat, $info);
*/
/*
查询
$compayModel = new Compay();
$wxchat = [];
$wxchat['appid'] = Global_Config['weAppWEAPP_ID'];
$wxchat['mchid'] = Global_Config['mchid'];
$wxchat['signkey'] = Global_Config['signkey'];
$wxchat['api_cert'] = Global_Config['api_cert'];
$wxchat['api_key'] = Global_Config['api_key'];
$info = [];
$info['desc'] = Global_Config['name'];
$PayRet = $compayModel->chaxun($payroll_records, $wxchat, $info);
*/

Comment list( 0 )

Sign in for post a comment

Help Search