1341 行
60 KiB
PHP
可执行文件
1341 行
60 KiB
PHP
可执行文件
<?php
|
||
|
||
namespace Pay\Controller;
|
||
|
||
use Common\Business\PayCoupon;
|
||
use Common\Model\PayInfoModel;
|
||
use Common\Model\RetailPayOrderModel;
|
||
use Common\Model\RetailPaySetModel;
|
||
use Common\Model\SystemConfigModel;
|
||
use Think\Controller;
|
||
|
||
//[1.8.68]
|
||
|
||
/**
|
||
* 微信支付
|
||
* Class NewWxPayController
|
||
* @package Pay\Controller
|
||
*/
|
||
class NewWxPayController extends BaseController
|
||
{
|
||
public function toWxPay($pay_order, $bill_id, $config)
|
||
{
|
||
if ($pay_order["m_pay_type"] == 1) {
|
||
$post['appid'] = $config['wx_appid'];
|
||
$post['mch_id'] = $config['wx_mch_id'];
|
||
$post['body'] = $config['name'] . '-' . $config['storetag'];
|
||
$post['out_trade_no'] = $pay_order['out_trade_no'];
|
||
$post['total_fee'] = $pay_order['trade_amount'];
|
||
$post['auth_code'] = $pay_order['code'];
|
||
$post['key'] = $config['wx_secret_key'];
|
||
} else {
|
||
//查询合作伙伴配置
|
||
$id = $config["merchantid"];
|
||
$partnerid = M("retail_merchant")->where(array("id" => $id))->getField("partnerid");
|
||
$cache = M("systemconfig")->where(array("partnerid" => $partnerid))->find();
|
||
$post['appid'] = $cache['wx_appid'];
|
||
$post['mch_id'] = $cache['mch_id'];
|
||
$post['body'] = $config['name'] . '-' . $config['storetag'];
|
||
$post['out_trade_no'] = $pay_order['out_trade_no'];
|
||
$post['total_fee'] = $pay_order['trade_amount'];
|
||
$post['auth_code'] = $pay_order['code'];
|
||
$post['key'] = $cache['wx_key'];
|
||
$post['sub_mch_id'] = $config["wx_sub_mchid"];
|
||
if (!empty($config['wx_sub_appid'])) {
|
||
$post['sub_appid'] = $config['wx_sub_appid'];
|
||
}
|
||
}
|
||
//调起支付
|
||
$WxPaysdk = new \Util\Wx\WxMicroPay($post);
|
||
// print_r($WxPaysdk);
|
||
$result = $WxPaysdk->postWxMicro();
|
||
|
||
file_put_contents('./okok.txt', '1: ' . json_encode($post) . "\r\n", FILE_APPEND);
|
||
file_put_contents('./okok.txt', '2: ' . json_encode($result) . "\r\n", FILE_APPEND);
|
||
|
||
$data['post'] = $post;
|
||
if (!empty($result) && $result['result_code'] == 'SUCCESS' && $result['return_code'] == 'SUCCESS') {
|
||
//修改订单状态
|
||
$save ['trade_no'] = $result ['transaction_id'];
|
||
$save ['order_state'] = 'SUCCESS';
|
||
$time = substr($result['time_end'], 0, strlen($result['time_end']) - 10) . '-' . substr($result['time_end'], -10, 2) . '-' . substr($result['time_end'], -8, 2) . ' ' . substr($result['time_end'], -6, 2) . ':' . substr($result['time_end'], -4, 2) . ':' . substr($result['time_end'], -2, 2);
|
||
$save ['trade_date'] = strtotime($time);
|
||
$save ['extend_content'] = json_encode($result);
|
||
|
||
$PayOrderModel = D('PayOrder');
|
||
$update = $PayOrderModel->updateOrder(array('id' => $pay_order['id']), $save);//更新订单信息
|
||
if ($update) {
|
||
if ($pay_order["m_pay_type"] == 2) {
|
||
A('Api/Vip')->toMark($result['sub_openid'], $pay_order['id'], $pay_order['trade_amount']);
|
||
} else {
|
||
A('Api/Vip')->toMark($result['openid'], $pay_order['id'], $pay_order['trade_amount']);
|
||
}
|
||
file_put_contents('./orderid.txt', $pay_order['id']);
|
||
$data['status'] = 1;
|
||
$data['msg'] = '支付成功';
|
||
$data['order_id'] = $pay_order['out_trade_no'];
|
||
A('Sellapi/NewPay')->changeOrder($bill_id, 3);
|
||
$this->ajaxReturn($data);
|
||
} else {
|
||
$data['status'] = 0;
|
||
$data['msg'] = '付款成功,更新订单失败,请联系管理员1';
|
||
$this->ajaxReturn($data);
|
||
}
|
||
} else if (!empty($result) && $result['err_code'] == 'USERPAYING' && $result["return_code"] == "SUCCESS" && $result["return_msg"] == "OK") {//用户支付中
|
||
$this->getMicroPayState($pay_order, $bill_id);
|
||
} else if (!empty($result)) {
|
||
$data['status'] = 0;
|
||
$data['msg'] = '收款失败';
|
||
$data['data'] = $result;
|
||
$this->ajaxReturn($data);
|
||
} else {
|
||
$data['status'] = 0;
|
||
$data['data'] = $result;
|
||
$data['msg'] = "收款失败,请重试";
|
||
$this->ajaxReturn($data);
|
||
}
|
||
}
|
||
|
||
//反复请求用户长时间才输入密码的支付状态 PS:下方orderid 为retail_pay_order支付表id 并非后台用户商品订单需要的id
|
||
protected function getMicroPayState($Order, $bill_id)
|
||
{
|
||
$PayOrderModel = D('PayOrder');
|
||
$map['id'] = $Order['id'];
|
||
$res = $this->searchWxOrder($Order['storeid'], $Order['out_trade_no']);
|
||
$data['data'] = $res;
|
||
if ($res['trade_state'] == "USERPAYING" || $res['trade_code'] == "USERPAYING") {
|
||
//用户支付中
|
||
$time = get_runtime();
|
||
if ($time < 20) {
|
||
$this->getMicroPayState($Order, $bill_id);
|
||
} else {
|
||
//撤销订单
|
||
$this->canselOrder($Order['storeid'], $Order);
|
||
}
|
||
} else if ($res['trade_state'] == "SUCCESS" || $res['trade_code'] == "SUCCESS") {//支付成功修改订单
|
||
$save ['trade_no'] = $res ['transaction_id'];
|
||
$save ['order_state'] = 'SUCCESS';
|
||
$time = substr($res['time_end'], 0, strlen($res['time_end']) - 10) . '-' . substr($res['time_end'], -10, 2) . '-' . substr($res['time_end'], -8, 2) . ' ' . substr($res['time_end'], -6, 2) . ':' . substr($res['time_end'], -4, 2) . ':' . substr($res['time_end'], -2, 2);
|
||
$save ['trade_date'] = strtotime($time);
|
||
$save ['mdate'] = time();
|
||
$save ['extend_content'] = json_encode($res);
|
||
|
||
$update = $PayOrderModel->updateOrder($map, $save);//更新订单信息
|
||
if ($update) {
|
||
if (isset($res['sub_appid'])) {
|
||
A('Api/Vip')->toMark($res['sub_openid'], $Order['id'], $Order['trade_amount']);
|
||
} else {
|
||
A('Api/Vip')->toMark($res['openid'], $Order['id'], $Order['trade_amount']);
|
||
}
|
||
// file_put_contents('./orderid2.txt', $Order['id']);
|
||
//支付成功
|
||
$data['status'] = 1;
|
||
$data['msg'] = '支付成功';
|
||
$data['order_id'] = $Order['out_trade_no'];
|
||
A('Sellapi/NewPay')->changeOrder($bill_id, 3);
|
||
$this->ajaxReturn($data);
|
||
} else {
|
||
$data['status'] = 0;
|
||
$data['msg'] = '付款成功,更新订单失败,请联系管理员2';
|
||
$this->ajaxReturn($data);
|
||
}
|
||
} else {
|
||
$save ['order_state'] = 'REVOKED';
|
||
$save ['mdate'] = time();
|
||
$update = $PayOrderModel->updateOrder($map, $save);//更新订单信息
|
||
$data['status'] = 0;
|
||
$data['msg'] = '用户取消支付';
|
||
$data['res'] = $res;
|
||
$this->ajaxReturn($data);
|
||
}
|
||
}
|
||
|
||
// 查询订单信息
|
||
protected function searchWxOrder($storeid, $out_trade_no)
|
||
{
|
||
// file_put_contents('wx_searchWxOrder.txt','out_trade_no: '.$out_trade_no."\r\n",FILE_APPEND);
|
||
$config = D('Payset')->getFindConfig($storeid);//获取商户微信配置信息
|
||
$order = M('retail_pay_order')->where(array('out_trade_no' => $out_trade_no, 'storeid' => $storeid))->find();
|
||
if ($order["m_pay_type"] == 1) {
|
||
$key = $config['wx_secret_key'];
|
||
$obj['appid'] = $config['wx_appid'];
|
||
$obj['mch_id'] = $config['wx_mch_id'];
|
||
} else {
|
||
$partnerid = M("retail_merchant")->where(array("id" => $config["merchantid"]))->getField("partnerid");
|
||
$cache = M("systemconfig")->where(array("partnerid" => $partnerid))->find();
|
||
$key = $cache['wx_key'];
|
||
$obj['appid'] = $cache['wx_appid'];
|
||
$obj['mch_id'] = $cache['mch_id'];
|
||
if (!empty($config['wx_sub_appid'])) {
|
||
$obj['sub_appid'] = $config['wx_sub_appid'];
|
||
}
|
||
$obj['sub_mch_id'] = $config['wx_sub_mchid'];
|
||
}
|
||
$WxMicroPay = new \Util\Wx\WxMicroPay(array('key' => $key));
|
||
$obj['out_trade_no'] = $out_trade_no;
|
||
$obj['nonce_str'] = $WxMicroPay->createNoncestr(32);
|
||
$obj['sign'] = $WxMicroPay->getSign($obj);
|
||
|
||
// file_put_contents('./okok.txt', '2: ' . json_encode($obj) . "\r\n", FILE_APPEND);
|
||
|
||
$url = 'https://api.mch.weixin.qq.com/pay/orderquery';
|
||
$xml = $WxMicroPay->arrayToXml($obj);//转换为xml
|
||
$response = $WxMicroPay->postXmlCurl($xml, $url, 30);
|
||
|
||
$response = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
||
// file_put_contents("./2.txt", '3: '.json_encode($response) . "\r\n", FILE_APPEND);
|
||
// file_put_contents("./2.txt", json_encode($obj) . "\r\n", FILE_APPEND);
|
||
$response['obj'] = $obj;
|
||
return $response;
|
||
}
|
||
|
||
// 撤销订单
|
||
protected function canselOrder($storeid, $Order)
|
||
{
|
||
$config = D('Payset')->getFindConfig($storeid);
|
||
if ($Order["m_pay_type"] == 1) {
|
||
$post['appid'] = $config['wx_appid'];
|
||
$post['mch_id'] = $config['wx_mch_id'];
|
||
$arr['apiclient_cert'] = $config['apiclient_cert'];
|
||
$arr['apiclient_key'] = $config['apiclient_key'];
|
||
$arr['key'] = $config['wx_secret_key'];
|
||
} else {
|
||
//查询合作伙伴配置
|
||
$id = $config["merchantid"];
|
||
$partnerid = M("retail_merchant")->where(array("id" => $id))->getField("partnerid");
|
||
$cache = M("systemconfig")->where(array("partnerid" => $partnerid))->find();
|
||
$post['appid'] = $cache['wx_appid'];
|
||
$post['mch_id'] = $cache['mch_id'];
|
||
if (!empty($config['wx_sub_appid'])) {
|
||
$post['sub_appid'] = $config['wx_sub_appid'];
|
||
}
|
||
$post['sub_mch_id'] = $config['wx_sub_mchid'];
|
||
|
||
$arr['apiclient_cert'] = $cache['wx_apiclient_cert'];
|
||
$arr['apiclient_key'] = $cache['wx_apiclient_key'];
|
||
$arr['key'] = $cache['wx_key'];
|
||
}
|
||
$WxMicroPay = new \Util\Wx\WxMicroPay($arr);
|
||
$post['out_trade_no'] = $Order['out_trade_no'];
|
||
$post['nonce_str'] = $WxMicroPay->createNoncestr(32);
|
||
$post['sign'] = $WxMicroPay->getSign($post);
|
||
|
||
$url = 'https://api.mch.weixin.qq.com/secapi/pay/reverse';
|
||
$xml = $WxMicroPay->arrayToXml($post);
|
||
$response = $WxMicroPay->postXmlCurlCancel($xml, $url, 30);
|
||
|
||
$response = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
||
|
||
if ($response['result_code'] == 'SUCCESS' && $response['return_code'] == 'SUCCESS') {
|
||
$res = $this->searchWxOrder($storeid, $Order['out_trade_no']);
|
||
if ($res['trade_state'] == "REVOKED" || $res['trade_code'] == "CLOSED") {
|
||
$save ['order_state'] = 'REVOKED';
|
||
$PayOrderModel = D('PayOrder');
|
||
$res = $PayOrderModel->updateOrder(array('out_trade_no' => $Order['out_trade_no']), $save);//更新订单信息
|
||
$data['status'] = 1;
|
||
$data['msg'] = '订单超时,并已撤销';
|
||
} else {
|
||
$time = get_runtime();
|
||
if ($time < 10) {
|
||
$this->canselOrder($storeid, $Order);
|
||
} else {
|
||
$data['responseS'] = $res;
|
||
$data['status'] = 0;
|
||
$data['msg'] = '订单超时,但撤销失败,请用户别支付';
|
||
}
|
||
}
|
||
} else {
|
||
$data['status'] = 0;
|
||
$data['msg'] = '订单超时,但撤销失败';
|
||
}
|
||
$this->ajaxReturn($data);
|
||
}
|
||
|
||
|
||
/*-----------------------------2019-5-17 组合支付开始--------------------------------------*/
|
||
/**
|
||
* 开始执行微信支付
|
||
* @param $payOrder
|
||
* @param $config
|
||
* @return mixed
|
||
*/
|
||
public function toWxPay_v1($payOrder, $config)
|
||
{
|
||
$post['body'] = $config['body'] ? $config['body'] : '买单';
|
||
$post['out_trade_no'] = $payOrder['out_trade_no'];
|
||
$post['auth_code'] = $payOrder['code'];
|
||
if ($payOrder["m_pay_type"] == 1) {
|
||
$post['appid'] = $config['wx_appid'];
|
||
$post['mch_id'] = $config['wx_mch_id'];
|
||
$post['total_fee'] = $payOrder['trade_amount'];
|
||
$post['key'] = $config['wx_secret_key'];
|
||
} else {
|
||
//查询合作伙伴配置
|
||
$systemConfig = $config['systemConfig'];
|
||
$post['appid'] = $systemConfig['wx_appid'];
|
||
$post['mch_id'] = $systemConfig['mch_id'];
|
||
$post['total_fee'] = $payOrder['trade_amount'];
|
||
$post['key'] = $systemConfig['wx_key'];
|
||
$post['sub_mch_id'] = $config["wx_sub_mchid"];
|
||
if (!empty($config['wx_sub_appid'])) {
|
||
$post['sub_appid'] = $config['wx_sub_appid'];
|
||
}
|
||
}
|
||
//调起支付
|
||
// print_r($config['systemConfig']);
|
||
$WxPaysdk = new \Util\Wx\WxMicroPay($post);
|
||
$result = $WxPaysdk->postWxMicro();
|
||
// print_r($result);
|
||
|
||
file_put_contents('./okok.txt', '1: ' . json_encode($post) . "\r\n", FILE_APPEND);
|
||
file_put_contents('./okok.txt', '2: ' . json_encode($result) . "\r\n", FILE_APPEND);
|
||
|
||
// $res['post'] = $post;
|
||
if (!empty($result) && $result['result_code'] == 'SUCCESS' && $result['return_code'] == 'SUCCESS') {
|
||
//修改订单状态
|
||
$save ['trade_no'] = $result ['transaction_id'];
|
||
$save ['order_state'] = 'SUCCESS';
|
||
$time = substr($result['time_end'], 0, strlen($result['time_end']) - 10) . '-' . substr($result['time_end'], -10, 2) . '-' . substr($result['time_end'], -8, 2) . ' ' . substr($result['time_end'], -6, 2) . ':' . substr($result['time_end'], -4, 2) . ':' . substr($result['time_end'], -2, 2);
|
||
$save ['trade_date'] = strtotime($time);
|
||
$save ['extend_content'] = json_encode($result);
|
||
|
||
$PayOrderModel = D('PayOrder');
|
||
$update = $PayOrderModel->updateOrder(array('id' => $payOrder['id']), $save);//更新订单信息
|
||
if ($update) {
|
||
if ($payOrder["m_pay_type"] == 2) {
|
||
A('Api/Vip')->toMark($result['sub_openid'], $payOrder['id'], $payOrder['trade_amount']);
|
||
} else {
|
||
A('Api/Vip')->toMark($result['openid'], $payOrder['id'], $payOrder['trade_amount']);
|
||
}
|
||
file_put_contents('./orderid.txt', $payOrder['id']);
|
||
$res['status'] = 1;
|
||
$res['msg'] = '支付成功';
|
||
} else {
|
||
$res['status'] = 0;
|
||
$res['msg'] = '付款成功,更新订单失败,请联系管理员1';
|
||
}
|
||
} else if (!empty($result) && $result['err_code'] == 'USERPAYING' && $result["return_code"] == "SUCCESS" && $result["return_msg"] == "OK") {//用户支付中
|
||
$res = $this->getMicroPayState_v1($payOrder, $config);
|
||
} else if (!empty($result)) {
|
||
$res['status'] = 0;
|
||
$res['msg'] = '收款失败';
|
||
$res['data'] = $result;
|
||
} else {
|
||
$res['status'] = 0;
|
||
$res['data'] = $result;
|
||
$res['msg'] = "收款失败,请重试";
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* 查询订单支付状态
|
||
* @param $payOrder
|
||
* @param $config
|
||
* @return mixed
|
||
*/
|
||
protected function getMicroPayState_v1($payOrder, $config)
|
||
{
|
||
$PayOrderModel = D('PayOrder');
|
||
$map['id'] = $payOrder['id'];
|
||
$canReturn = false;
|
||
while (!$canReturn) {
|
||
$res = $this->searchWxOrder_v1($payOrder, $config);
|
||
$result['data'] = $res;
|
||
if ($res['trade_state'] == "USERPAYING" || $res['trade_code'] == "USERPAYING") {
|
||
//用户支付中
|
||
$time = get_runtime();
|
||
if ($time > 40) {
|
||
//撤销订单
|
||
$res = $this->cancelOrder_v1($payOrder, $config);
|
||
$result = $res;
|
||
$canReturn = true;
|
||
}
|
||
} else if ($res['trade_state'] == "SUCCESS" || $res['trade_code'] == "SUCCESS") {//支付成功修改订单
|
||
$save ['trade_no'] = $res ['transaction_id'];
|
||
$save ['order_state'] = 'SUCCESS';
|
||
$time = substr($res['time_end'], 0, strlen($res['time_end']) - 10) . '-' . substr($res['time_end'], -10, 2) . '-' . substr($res['time_end'], -8, 2) . ' ' . substr($res['time_end'], -6, 2) . ':' . substr($res['time_end'], -4, 2) . ':' . substr($res['time_end'], -2, 2);
|
||
$save ['trade_date'] = strtotime($time);
|
||
$save ['mdate'] = time();
|
||
$save ['extend_content'] = json_encode($res);
|
||
$update = $PayOrderModel->updateOrder($map, $save);//更新订单信息
|
||
if ($update) {
|
||
//支付成功
|
||
$result['status'] = 1;
|
||
$result['msg'] = '支付成功';
|
||
$canReturn = true;
|
||
} else {
|
||
$result['status'] = 0;
|
||
$result['msg'] = '付款成功,更新订单失败,请联系管理员2';
|
||
$canReturn = true;
|
||
}
|
||
} else {
|
||
$save ['order_state'] = 'REVOKED';
|
||
$save ['mdate'] = time();
|
||
$update = $PayOrderModel->updateOrder($map, $save);//更新订单信息
|
||
$result['status'] = 0;
|
||
$result['msg'] = '用户取消支付';
|
||
$canReturn = true;
|
||
}
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 查询订单支付状态
|
||
* @param $payOrder
|
||
* @param $config
|
||
* @return mixed
|
||
*/
|
||
protected function searchWxOrder_v1($payOrder, $config)
|
||
{
|
||
// file_put_contents('wx_searchWxOrder.txt','out_trade_no: '.$out_trade_no."\r\n",FILE_APPEND);
|
||
if ($payOrder["m_pay_type"] == 1) {
|
||
$key = $config['wx_secret_key'];
|
||
$obj['appid'] = $config['wx_appid'];
|
||
$obj['mch_id'] = $config['wx_mch_id'];
|
||
} else {
|
||
$systemConfig = $config['systemConfig'];
|
||
$key = $systemConfig['wx_key'];
|
||
$obj['appid'] = $systemConfig['wx_appid'];
|
||
$obj['mch_id'] = $systemConfig['mch_id'];
|
||
if (!empty($config['wx_sub_appid'])) {
|
||
$obj['sub_appid'] = $config['wx_sub_appid'];
|
||
}
|
||
$obj['sub_mch_id'] = $config['wx_sub_mchid'];
|
||
}
|
||
$WxMicroPay = new \Util\Wx\WxMicroPay(array('key' => $key));
|
||
$obj['out_trade_no'] = $payOrder['out_trade_no'];
|
||
$obj['nonce_str'] = $WxMicroPay->createNoncestr(32);
|
||
$obj['sign'] = $WxMicroPay->getSign($obj);
|
||
|
||
// file_put_contents('./okok.txt', '2: ' . json_encode($obj) . "\r\n", FILE_APPEND);
|
||
|
||
$url = 'https://api.mch.weixin.qq.com/pay/orderquery';
|
||
$xml = $WxMicroPay->arrayToXml($obj);//转换为xml
|
||
$response = $WxMicroPay->postXmlCurl($xml, $url, 30);
|
||
|
||
$response = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
||
// file_put_contents("./2.txt", '3: '.json_encode($response) . "\r\n", FILE_APPEND);
|
||
// file_put_contents("./2.txt", json_encode($obj) . "\r\n", FILE_APPEND);
|
||
$response['obj'] = $obj;
|
||
return $response;
|
||
}
|
||
|
||
/**
|
||
* 撤销订单
|
||
* @param $payOrder
|
||
* @param $config
|
||
* @return mixed
|
||
*/
|
||
protected function cancelOrder_v1($payOrder, $config)
|
||
{
|
||
if ($payOrder["m_pay_type"] == 1) {
|
||
$post['appid'] = $config['wx_appid'];
|
||
$post['mch_id'] = $config['wx_mch_id'];
|
||
$arr['apiclient_cert'] = $config['apiclient_cert'];
|
||
$arr['apiclient_key'] = $config['apiclient_key'];
|
||
$arr['key'] = $config['wx_secret_key'];
|
||
} else {
|
||
//查询合作伙伴配置
|
||
$systemConfig = $config['systemConfig'];
|
||
$post['appid'] = $systemConfig['wx_appid'];
|
||
$post['mch_id'] = $systemConfig['mch_id'];
|
||
if (!empty($config['wx_sub_appid'])) {
|
||
$post['sub_appid'] = $config['wx_sub_appid'];
|
||
}
|
||
$post['sub_mch_id'] = $config['wx_sub_mchid'];
|
||
|
||
$arr['apiclient_cert'] = $systemConfig['wx_apiclient_cert'];
|
||
$arr['apiclient_key'] = $systemConfig['wx_apiclient_key'];
|
||
$arr['key'] = $systemConfig['wx_key'];
|
||
}
|
||
$WxMicroPay = new \Util\Wx\WxMicroPay($arr);
|
||
$post['out_trade_no'] = $payOrder['out_trade_no'];
|
||
$post['nonce_str'] = $WxMicroPay->createNoncestr(32);
|
||
$post['sign'] = $WxMicroPay->getSign($post);
|
||
|
||
$url = 'https://api.mch.weixin.qq.com/secapi/pay/reverse';
|
||
$xml = $WxMicroPay->arrayToXml($post);
|
||
$response = $WxMicroPay->postXmlCurlCancel($xml, $url, 30);
|
||
|
||
$response = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
||
|
||
if ($response['result_code'] == 'SUCCESS' && $response['return_code'] == 'SUCCESS') {
|
||
$res = $this->searchWxOrder_v1($payOrder, $config);
|
||
if ($res['trade_state'] == "REVOKED" || $res['trade_code'] == "CLOSED") {
|
||
$save ['order_state'] = 'REVOKED';
|
||
$PayOrderModel = D('PayOrder');
|
||
$res = $PayOrderModel->updateOrder(array('out_trade_no' => $payOrder['out_trade_no']), $save);//更新订单信息
|
||
$result['status'] = 0;
|
||
$result['msg'] = '订单超时,并已撤销';
|
||
} else {
|
||
$result['responseS'] = $res;
|
||
$result['status'] = 0;
|
||
$result['msg'] = '订单超时,但撤销失败,请用户别支付';
|
||
}
|
||
} else {
|
||
$result['status'] = 0;
|
||
$result['msg'] = '订单超时,但撤销失败';
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 退款接口
|
||
* @param $payOrder pay_order退款数据
|
||
* @param $config 支付设置
|
||
* @return mixed
|
||
*/
|
||
public function toWxRefund_v1($payOrder, $config)
|
||
{
|
||
if ($payOrder['m_pay_type'] == 1) {
|
||
$obj['apiclient_cert'] = $config['apiclient_cert'];
|
||
$obj['apiclient_key'] = $config['apiclient_key'];
|
||
$obj['key'] = $config['wx_secret_key'];
|
||
$WxMicroPay = new \Util\Wx\WxMicroPay($obj);
|
||
$post['appid'] = $config['wx_appid'];
|
||
$post['mch_id'] = $config['wx_mch_id'];
|
||
} else {
|
||
$obj['apiclient_cert'] = $config['systemConfig']['wx_apiclient_cert'];
|
||
$obj['apiclient_key'] = $config['systemConfig']['wx_apiclient_key'];
|
||
$obj['key'] = $config['systemConfig']['wx_key'];
|
||
$WxMicroPay = new \Util\Wx\WxMicroPay($obj);
|
||
$post['appid'] = $config['systemConfig']['wx_appid'];
|
||
$post['mch_id'] = $config['systemConfig']['mch_id'];
|
||
if (!empty($config['wx_sub_appid'])) {
|
||
$post['sub_appid'] = $config['wx_sub_appid'];
|
||
}
|
||
$post['sub_mch_id'] = $config['wx_sub_mchid'];
|
||
}
|
||
// print_r($post);
|
||
//以下为往微信发送的数据
|
||
$post['nonce_str'] = $WxMicroPay->createNoncestr(32);
|
||
$post['transaction_id'] = $payOrder['trade_no'];
|
||
$post['out_trade_no'] = $payOrder['out_trade_no'];
|
||
$post['out_refund_no'] = $payOrder['out_refund_no'];
|
||
$post['total_fee'] = $payOrder['before_amount'] * 100;
|
||
$post['refund_fee'] = $payOrder['trade_amount'] * 100;
|
||
$post['sign'] = $WxMicroPay->getSign($post);
|
||
|
||
$url = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
|
||
$xml = $WxMicroPay->arrayToXml($post);
|
||
file_put_contents('./wxrefunddata.txt', 1);
|
||
$response = $WxMicroPay->postXmlCurlCancel($xml, $url, 30);
|
||
// print_r($response);
|
||
|
||
$response = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
||
file_put_contents('./wxrefundreturn.txt', json_encode($response) . "\r\n", FILE_APPEND);
|
||
if ($response['result_code'] == 'SUCCESS' && $response['return_code'] == 'SUCCESS') {
|
||
$res = $this->searchRefund_v1($response['refund_id'], $payOrder, $config);
|
||
} else {
|
||
$res['status'] = 0;
|
||
$res['msg'] = $response['err_code_des'] ? $response['err_code_des'] : $response['return_msg'] ? $response['return_msg'] : '退款失败';
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* 查询退款
|
||
* @param $refund_id 微信退款id
|
||
* @param $payOrder pay_order退款数据
|
||
* @param $config 支付设置
|
||
* @return mixed
|
||
*/
|
||
protected function searchRefund_v1($refund_id, $payOrder, $config)
|
||
{
|
||
if ($payOrder['m_pay_type'] == 1) {
|
||
$obj['apiclient_cert'] = $config['apiclient_cert'];
|
||
$obj['apiclient_key'] = $config['apiclient_key'];
|
||
$obj['key'] = $config['wx_secret_key'];
|
||
$WxMicroPay = new \Util\Wx\WxMicroPay($obj);
|
||
$post['appid'] = $config['wx_appid'];
|
||
$post['mch_id'] = $config['wx_mch_id'];
|
||
} else {
|
||
$obj['apiclient_cert'] = $config['systemConfig']['wx_apiclient_cert'];
|
||
$obj['apiclient_key'] = $config['systemConfig']['wx_apiclient_key'];
|
||
$obj['key'] = $config['systemConfig']['wx_key'];
|
||
$WxMicroPay = new \Util\Wx\WxMicroPay($obj);
|
||
$post['appid'] = $config['systemConfig']['wx_appid'];
|
||
$post['mch_id'] = $config['systemConfig']['mch_id'];
|
||
if (!empty($config['wx_sub_appid'])) {
|
||
$post['sub_appid'] = $config['wx_sub_appid'];
|
||
}
|
||
$post['sub_mch_id'] = $config['wx_sub_mchid'];
|
||
}
|
||
|
||
$post['nonce_str'] = $WxMicroPay->createNoncestr(32);
|
||
$post['transaction_id'] = $payOrder['trade_no'];
|
||
$post['out_trade_no'] = $payOrder['out_trade_no'];
|
||
$post['out_refund_no'] = $payOrder['out_refund_no'];
|
||
$post['refund_id'] = $refund_id;
|
||
$post['sign'] = $WxMicroPay->getSign($post);
|
||
|
||
$url = 'https://api.mch.weixin.qq.com/pay/refundquery';
|
||
$xml = $WxMicroPay->arrayToXml($post);
|
||
$response = $WxMicroPay->postXmlCurlCancel($xml, $url, 30);
|
||
|
||
$response = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
||
file_put_contents('./wxrefund.txt', json_encode($response));
|
||
if ($response['result_code'] == 'SUCCESS' && $response['return_code'] == 'SUCCESS') {
|
||
switch ($response['refund_status_0']) {
|
||
case 'PROCESSING':
|
||
case 'SUCCESS':
|
||
$res['status'] = 1;
|
||
$res['data'] = $response;
|
||
$res['msg'] = '退款成功';
|
||
break;
|
||
case 'REFUNDCLOSE':
|
||
//退款关闭
|
||
$res['status'] = 0;
|
||
$res['msg'] = '退款关闭';
|
||
break;
|
||
case 'CHANGE':
|
||
//退款异常-退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,可前往商户平台(pay.weixin.qq.com)-交易中心,手动处理此笔退款。
|
||
$res['status'] = 0;
|
||
$res['msg'] = '退款异常,商户银行卡异常';
|
||
}
|
||
} else {
|
||
$res['status'] = 0;
|
||
$res['data'] = $response;
|
||
$res['msg'] = '退款失败';
|
||
}
|
||
return $res;
|
||
}
|
||
/*-----------------------------2019-5-17 组合支付结束--------------------------------------*/
|
||
|
||
|
||
/*-----------------------------2019-6-22 新版支付开始--------------------------------------*/
|
||
/**
|
||
* 开始执行微信刷卡支付
|
||
* @param $payOrder
|
||
* @param $config
|
||
* @return mixed
|
||
*/
|
||
public function toWxPay_v2($payOrder, $config)
|
||
{
|
||
$result = $this->toCodeWxPay_v2($payOrder, $config);
|
||
if ($result['status'] == 1) {
|
||
$PayOrderModel = D('RetailPayOrder');
|
||
$PaySetModel = D('RetailPaySet');
|
||
if ($payOrder[$PayOrderModel::M_PAY_TYPE] == 1) {
|
||
$mch_id = $config[$PaySetModel::WX_MCH_ID];
|
||
} else {
|
||
//子商户号
|
||
$mch_id = $config[$PaySetModel::WX_SUB_MCH_ID];
|
||
}
|
||
$save = array(
|
||
$PayOrderModel::TRADE_NO => $result ['transaction_id'],
|
||
$PayOrderModel::ORDER_STATE => 'SUCCESS',
|
||
$PayOrderModel::TRADE_DATE => time(),
|
||
$PayOrderModel::EXTEND_CONTENT => json_encode($result),
|
||
$PayOrderModel::MER_ID => $mch_id,
|
||
);
|
||
if ($result['coupon_count'] > 0 || $result['coupon_fee'] > 0) {
|
||
//代金券
|
||
$PayCouponClass = new PayCoupon();
|
||
$couponResult = $PayCouponClass->couponVerification_v1(json_encode([
|
||
'pay_info' => $result,
|
||
'use_type' => $payOrder['order_type'],
|
||
'order_id' => $payOrder['bill_id'] ? $payOrder['bill_id'] : $payOrder['id'],
|
||
'store_id' => $payOrder['store_id'],
|
||
'use_scene' => 2,
|
||
'merchant_id' => $payOrder['merchant_id'],
|
||
'coupon_way'=>1
|
||
]));//修改代金券使用状态
|
||
if ($couponResult['status'] == 1) {
|
||
$save['pay_coupon_id_str'] = $couponResult['data']['pay_coupon_id_str'];
|
||
$save['pay_coupon_fee'] = $couponResult['data']['pay_coupon_fee'];
|
||
$save['trade_amount'] = $couponResult['data']['cash_fee'];
|
||
$res['pay_coupon_id_str'] = $couponResult['data']['pay_coupon_id_str'];
|
||
$res['pay_coupon_fee'] = $couponResult['data']['pay_coupon_fee'];
|
||
}
|
||
}
|
||
$update = $PayOrderModel->updateOrder(array($PayOrderModel::ID => $payOrder[$PayOrderModel::ID]), $save);//更新订单信息
|
||
if ($payOrder[$PayOrderModel::M_PAY_TYPE] == 2) {
|
||
$this->doAddRate($result ['transaction_id'], $payOrder, 2);//分润
|
||
}
|
||
if ($update) {
|
||
$res['status'] = 1;
|
||
$res['msg'] = '支付成功';
|
||
} else {
|
||
$res['status'] = 0;
|
||
$res['msg'] = '数据库发生错误,付款成功,更新订单失败,请联系管理员1';
|
||
}
|
||
} else {
|
||
$res = $result;
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
protected function toCodeWxPay_v2($payOrder, $config)
|
||
{
|
||
$PayOrderModel = D('RetailPayOrder');
|
||
$PaySetModel = D('RetailPaySet');
|
||
$post['body'] = $config['body'] ? $config['body'] : '买单';
|
||
$post['out_trade_no'] = $payOrder[$PayOrderModel::OUT_TRADE_NO];
|
||
if (!empty($payOrder[$PayOrderModel::FACE_TOKEN])) {
|
||
$post['face_code'] = $payOrder[$PayOrderModel::FACE_TOKEN];
|
||
$post['openid'] = $payOrder['openid'];
|
||
} else {
|
||
$post['auth_code'] = $payOrder[$PayOrderModel::CODE];
|
||
}
|
||
if ($payOrder[$PayOrderModel::M_PAY_TYPE] == 1) {
|
||
$post['appid'] = $config[$PaySetModel::WX_APPID];
|
||
$post['mch_id'] = $config[$PaySetModel::WX_MCH_ID];
|
||
$post['key'] = $config[$PaySetModel::WX_SECRET_KEY];
|
||
} else {
|
||
//查询合作伙伴配置
|
||
$SystemConfigModel = D('SystemConfig');
|
||
$systemConfig = $config['systemConfig'];
|
||
$post['appid'] = $systemConfig[$SystemConfigModel::WX_APPID];
|
||
$post['mch_id'] = $systemConfig[$SystemConfigModel::MCH_ID];
|
||
$post['key'] = $systemConfig[$SystemConfigModel::WX_KEY];
|
||
$post['sub_mch_id'] = $config[$PaySetModel::WX_SUB_MCH_ID];
|
||
if (!empty($config[$PaySetModel::WX_SUB_APPID])) {
|
||
$post['sub_appid'] = $config[$PaySetModel::WX_SUB_APPID];
|
||
}
|
||
}
|
||
if (!empty($payOrder['plug']['wxpaycoupon']) && !empty($payOrder['shop_coupon']['goods_tag']) && !empty($payOrder['shop_coupon']['goods_detail'])) {
|
||
//满足代金券使用条件
|
||
$post['version'] = '1.0';
|
||
$post['goods_tag'] = strval($payOrder['shop_coupon']['goods_tag']);
|
||
$post['detail'] = $payOrder['shop_coupon']['goods_detail'];
|
||
}
|
||
$post['total_fee'] = $payOrder[$PayOrderModel::TRADE_AMOUNT];
|
||
//调起支付
|
||
$WxPaysdk = new \Util\Wx\WxMicroPay($post);
|
||
$result = $WxPaysdk->postWxMicro();
|
||
//调起支付
|
||
if (!empty($result) && $result['result_code'] == 'SUCCESS' && $result['return_code'] == 'SUCCESS') {
|
||
//修改订单状态
|
||
$res = $this->getMicroPayState_v2($payOrder, $config);
|
||
} else if (!empty($payOrder[$PayOrderModel::FACE_TOKEN])) { //微信刷脸
|
||
$res = $this->faceOrderQuery($payOrder, $config);//订单支付失败或者未支付,查询订单状态n
|
||
} else if (!empty($result) && $result['err_code'] == 'USERPAYING' && $result["return_code"] == "SUCCESS" && $result["return_msg"] == "OK") {//用户支付中
|
||
$res = $this->getMicroPayState_v2($payOrder, $config);
|
||
} else if (!empty($result)) {
|
||
$res['status'] = 0;
|
||
$res['msg'] = $result["err_code_des"] ? $result["err_code_des"] : ($result['return_msg'] ? $result['return_msg'] : '收款失败');
|
||
$res['data'] = $result;
|
||
$res['post'] = $post;
|
||
} else {
|
||
$res['status'] = 0;
|
||
$res['data'] = $result;
|
||
$res['msg'] = "收款失败,请重试";
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
/*
|
||
* 微信刷脸失败请求的方法
|
||
*/
|
||
public function faceOrderQuery($payOrder, $config)
|
||
{
|
||
$canReturn = false;
|
||
while (!$canReturn) {
|
||
$result = $this->searchWxFaceOrder($payOrder, $config);
|
||
if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == "SUCCESS") {
|
||
$return['status'] = 0;
|
||
switch ($result['trade_state']) {
|
||
case "SUCCESS":
|
||
//交易成功
|
||
$return['status'] = 1;
|
||
$return['msg'] = "订单支付成功";
|
||
$canReturn = true;
|
||
break;
|
||
case "REVOKED":
|
||
//订单撤销
|
||
$return['msg'] = "订单已撤销";
|
||
$canReturn = true;
|
||
break;
|
||
case "REFUND":
|
||
//转入退款
|
||
$return['msg'] = "订单转入退款";
|
||
$canReturn = true;
|
||
break;
|
||
case "PAYERROR":
|
||
//支付失败
|
||
$return['msg'] = "订单支付失败";
|
||
$canReturn = true;
|
||
break;
|
||
case "TRADE_PAYING":
|
||
//正在支付中
|
||
$time = get_runtime();
|
||
if ($time > 16) {//撤销订单
|
||
$return['msg'] = "订单已取消";
|
||
$canReturn = true;
|
||
}
|
||
break;
|
||
default:
|
||
$time = get_runtime();
|
||
if ($time > 16) {
|
||
$return = $this->cancelFaceOrder($payOrder, $config);
|
||
$canReturn = true;
|
||
}
|
||
break;
|
||
}
|
||
} else {
|
||
$return['status'] = 0;
|
||
$return['msg'] = $result['err_code_des'];
|
||
$canReturn = true;
|
||
}
|
||
}
|
||
return $return;
|
||
}
|
||
|
||
/*
|
||
* 查询微信刷脸订单
|
||
*/
|
||
public function searchWxFaceOrder($payOrder, $config)
|
||
{
|
||
$PayOrderModel = D('RetailPayOrder');
|
||
$PaySetModel = D('RetailPaySet');
|
||
$url = "https://api.mch.weixin.qq.com/pay/facepayquery";
|
||
$post['out_trade_no'] = $payOrder[$PayOrderModel::OUT_TRADE_NO];//商户系统内部的订单号,当没提供 transaction_id 时需要传这个
|
||
$post['sign_type'] = "MD5";//签名类型 支持HMAC-SHA256和MD5
|
||
$post['nonce_str'] = createKey();//随机字符串 不长于32位
|
||
if ($payOrder[$PayOrderModel::M_PAY_TYPE] == 1) { //普通商户
|
||
$post['appid'] = $config[$PaySetModel::WX_APPID];
|
||
$post['mch_id'] = $config[$PaySetModel::WX_MCH_ID];
|
||
} else {//服务商
|
||
$systemConfig = $config['systemConfig'];
|
||
$SystemConfigModel = D('SystemConfig');
|
||
$post['appid'] = $systemConfig[$SystemConfigModel::WX_APPID];
|
||
$post['mch_id'] = $systemConfig[$SystemConfigModel::MCH_ID];
|
||
$post['sub_mch_id'] = $config[$PaySetModel::WX_SUB_MCH_ID];
|
||
if (!empty($config[$PaySetModel::WX_SUB_APPID])) {
|
||
$post['sub_appid'] = $config[$PaySetModel::WX_SUB_APPID];
|
||
}
|
||
}
|
||
if ($payOrder[$PayOrderModel::M_PAY_TYPE] == 1) {
|
||
$sign = createSign($post, $config[$PaySetModel::WX_SECRET_KEY]);
|
||
} else {
|
||
$sign = createSign($post, $systemConfig[$SystemConfigModel::WX_KEY]);
|
||
}
|
||
$post['sign'] = $sign;//签名
|
||
$params = arrToXml($post);//考虑到与后台人脸支付API的一致性, 统一采用xml格式
|
||
$result = http_request($url, $params);
|
||
$result = xmlToArray($result);
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 查询订单支付状态
|
||
* @param $payOrder
|
||
* @param $config
|
||
* @return mixed
|
||
*/
|
||
protected function searchWxOrder_v2($payOrder, $config)
|
||
{
|
||
$PayOrderModel = D('RetailPayOrder');
|
||
$PaySetModel = D('RetailPaySet');
|
||
if ($payOrder[$PayOrderModel::M_PAY_TYPE] == 1) {
|
||
$post['appid'] = $config[$PaySetModel::WX_APPID];
|
||
$post['mch_id'] = $config[$PaySetModel::WX_MCH_ID];
|
||
$key = $config[$PaySetModel::WX_SECRET_KEY];
|
||
} else {
|
||
$systemConfig = $config['systemConfig'];
|
||
$SystemConfigModel = D('SystemConfig');
|
||
$post['appid'] = $systemConfig[$SystemConfigModel::WX_APPID];
|
||
$post['mch_id'] = $systemConfig[$SystemConfigModel::MCH_ID];
|
||
$post['sub_mch_id'] = $config[$PaySetModel::WX_SUB_MCH_ID];
|
||
if (!empty($config[$PaySetModel::WX_SUB_APPID])) {
|
||
$post['sub_appid'] = $config[$PaySetModel::WX_SUB_APPID];
|
||
}
|
||
$key = $systemConfig[$SystemConfigModel::WX_KEY];
|
||
}
|
||
$WxMicroPay = new \Util\Wx\WxMicroPay(array('key' => $key));
|
||
$post['out_trade_no'] = $payOrder[$PayOrderModel::OUT_TRADE_NO];
|
||
$post['nonce_str'] = $WxMicroPay->createNoncestr(32);
|
||
$post['sign'] = $WxMicroPay->getSign($post);
|
||
|
||
$url = 'https://api.mch.weixin.qq.com/pay/orderquery';
|
||
$xml = $WxMicroPay->arrayToXml($post);//转换为xml
|
||
$response = $WxMicroPay->postXmlCurl($xml, $url, 30);
|
||
|
||
$response = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
||
// $response['post'] = $post;
|
||
return $response;
|
||
}
|
||
|
||
/**
|
||
* 微信刷脸撤销订单
|
||
*/
|
||
public function cancelFaceOrder($payOrder, $config)
|
||
{
|
||
$PayOrderModel = D('RetailPayOrder');
|
||
$PaySetModel = D('RetailPaySet');
|
||
$url = "https://api.mch.weixin.qq.com/secapi/pay/facepayreverse";
|
||
$key = $this->getRefundData($payOrder, $config);
|
||
if ($payOrder[$PayOrderModel::M_PAY_TYPE] == 1) { //普通商户
|
||
$post['appid'] = $config[$PaySetModel::WX_APPID]; //商户公众号appid
|
||
$post['mch_id'] = $config[$PaySetModel::WX_MCH_ID]; //商户号
|
||
} else {//服务商
|
||
$systemConfig = $config['systemConfig'];
|
||
$SystemConfigModel = D('SystemConfig');
|
||
$post['appid'] = $systemConfig[$SystemConfigModel::WX_APPID]; //服务商公众号appid
|
||
$post['mch_id'] = $systemConfig[$SystemConfigModel::MCH_ID]; //服务商商户号
|
||
$post['sub_appid'] = $config[$PaySetModel::WX_SUB_APPID]; //子商户公众号appid
|
||
$post['sub_mch_id'] = $config[$PaySetModel::WX_SUB_MCH_ID]; //子商户号
|
||
}
|
||
$WxMicroPay = new \Util\Wx\WxMicroPay($key);
|
||
$post['nonce_str'] = $WxMicroPay->createNoncestr(32);
|
||
$post['out_trade_no'] = $payOrder[$PayOrderModel::OUT_TRADE_NO];
|
||
$post['sign'] = $WxMicroPay->getSign($post);
|
||
$xml = $WxMicroPay->arrayToXml($post);
|
||
$response = $WxMicroPay->postXmlCurlCancel($xml, $url, 30);
|
||
$result = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
||
if ($result['return_code'] == "SUCCESS" && $result['result_code'] == "SUCCESS") {
|
||
$return['status'] = 0;
|
||
$return['msg'] = "订单已撤销";
|
||
} else {
|
||
$return['status'] = 0;
|
||
$return['msg'] = "订单撤销失败" . $result['return_msg'];
|
||
}
|
||
return $return;
|
||
}
|
||
|
||
/**
|
||
* 获取退款证书信息
|
||
* @return mixed
|
||
*/
|
||
public function getRefundData($payOrder, $config)
|
||
{
|
||
$PayOrderModel = D('RetailPayOrder');
|
||
$PaySetModel = D('RetailPaySet');
|
||
switch ($payOrder[$PayOrderModel::M_PAY_TYPE]) {
|
||
case 1:
|
||
//普通商户
|
||
$key['apiclient_cert'] = $config[$PaySetModel::WX_AC_CERT];
|
||
$key['apiclient_key'] = $config[$PaySetModel::WX_AC_KEY];
|
||
$key['key'] = $config[$PaySetModel::WX_SECRET_KEY];
|
||
break;
|
||
case 2:
|
||
$systemConfig = $config['systemConfig'];
|
||
$SystemConfigModel = D('SystemConfig');
|
||
//服务商
|
||
$key['apiclient_cert'] = $systemConfig[$SystemConfigModel::WX_AC_CERT];
|
||
$key['apiclient_key'] = $systemConfig[$SystemConfigModel::WX_AC_KEY];
|
||
$key['key'] = $systemConfig[$SystemConfigModel::WX_KEY];
|
||
break;
|
||
}
|
||
return $key;
|
||
}
|
||
|
||
/**
|
||
* 查询订单支付状态
|
||
* @param $payOrder
|
||
* @param $config
|
||
* @return mixed
|
||
*/
|
||
protected function getMicroPayState_v2($payOrder, $config)
|
||
{
|
||
$PayOrderModel = D('RetailPayOrder');
|
||
$canReturn = false;
|
||
while (!$canReturn) {
|
||
$res = $this->searchWxOrder_v2($payOrder, $config);
|
||
$result['data'] = $res;
|
||
if ($res['trade_state'] == "USERPAYING" || $res['trade_code'] == "USERPAYING") {
|
||
//用户支付中
|
||
$time = get_runtime();
|
||
if ($time > 60) {
|
||
//撤销订单
|
||
$res = $this->cancelOrder_v2($payOrder, $config);
|
||
$result = $res;
|
||
$canReturn = true;
|
||
}
|
||
} else if ($res['trade_state'] == "SUCCESS" || $res['trade_code'] == "SUCCESS") {//支付成功修改订单
|
||
$result = $res;
|
||
$result['status'] = 1;
|
||
$canReturn = true;
|
||
} else {
|
||
$map = array(
|
||
$PayOrderModel::ID => $payOrder[$PayOrderModel::ID]
|
||
);
|
||
$save = array(
|
||
$PayOrderModel::ORDER_STATE => 'REVOKED',
|
||
);
|
||
$update = $PayOrderModel->updateOrder($map, $save);//更新订单信息
|
||
$result['status'] = 0;
|
||
$result['msg'] = $res["err_code_des"] ? $res["err_code_des"] : '用户取消支付';
|
||
$canReturn = true;
|
||
}
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 撤销订单
|
||
* @param $payOrder
|
||
* @param $config
|
||
* @return mixed
|
||
*/
|
||
protected function cancelOrder_v2($payOrder, $config)
|
||
{
|
||
$PayOrderModel = D('RetailPayOrder');
|
||
$PaySetModel = D('RetailPaySet');
|
||
$obj = $this->getRefundData($payOrder, $config);
|
||
if ($payOrder[$PayOrderModel::M_PAY_TYPE] == 1) {
|
||
$post['appid'] = $config[$PaySetModel::WX_APPID];
|
||
$post['mch_id'] = $config[$PaySetModel::WX_MCH_ID];
|
||
} else {
|
||
$systemConfig = $config['systemConfig'];
|
||
$SystemConfigModel = D('SystemConfig');
|
||
$post['appid'] = $systemConfig[$SystemConfigModel::WX_APPID];
|
||
$post['mch_id'] = $systemConfig[$SystemConfigModel::MCH_ID];
|
||
$post['sub_mch_id'] = $config[$PaySetModel::WX_SUB_MCH_ID];
|
||
if (!empty($config[$PaySetModel::WX_SUB_APPID])) {
|
||
$post['sub_appid'] = $config[$PaySetModel::WX_SUB_APPID];
|
||
}
|
||
}
|
||
$WxMicroPay = new \Util\Wx\WxMicroPay($obj);
|
||
$post['out_trade_no'] = $payOrder[$PayOrderModel::OUT_TRADE_NO];
|
||
$post['nonce_str'] = $WxMicroPay->createNoncestr(32);
|
||
$post['sign'] = $WxMicroPay->getSign($post);
|
||
|
||
$url = 'https://api.mch.weixin.qq.com/secapi/pay/reverse';
|
||
$xml = $WxMicroPay->arrayToXml($post);
|
||
$response = $WxMicroPay->postXmlCurlCancel($xml, $url, 30);
|
||
$response = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
||
file_put_contents('./cancelWxOrder.txt', date('Y-m-d H:i:s') . json_encode($response) . "\r\n", FILE_APPEND);
|
||
if ($response['result_code'] == 'SUCCESS' && $response['return_code'] == 'SUCCESS') {
|
||
$res = $this->searchWxOrder_v2($payOrder, $config);
|
||
if ($res['trade_state'] == "REVOKED" || $res['trade_code'] == "CLOSED") {
|
||
$save [$PayOrderModel::ORDER_STATE] = 'REVOKED';
|
||
$res = $PayOrderModel->updateOrder(array($PayOrderModel::ID => $payOrder[$PayOrderModel::ID]), $save);//更新订单信息
|
||
$result['status'] = 0;
|
||
$result['msg'] = '订单超时,并已撤销';
|
||
} else {
|
||
$result['responseS'] = $res;
|
||
$result['status'] = 0;
|
||
$result['msg'] = '订单超时,但撤销失败,请用户别支付';
|
||
}
|
||
} else {
|
||
$result['status'] = 0;
|
||
$result['msg'] = '订单超时,但撤销失败,请用户不要支付';
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 退款接口
|
||
* @param $payOrder pay_order退款数据
|
||
* @param $config 支付设置
|
||
* @return mixed
|
||
*/
|
||
public function toWxRefund_v2($payOrder, $config)
|
||
{
|
||
$PayOrderModel = D('RetailPayOrder');
|
||
$PaySetModel = D('RetailPaySet');
|
||
$obj = $this->getRefundData($payOrder, $config);
|
||
if ($payOrder[$PayOrderModel::M_PAY_TYPE] == 1) {
|
||
$post['appid'] = $config[$PaySetModel::WX_APPID];
|
||
$post['mch_id'] = $config[$PaySetModel::WX_MCH_ID];
|
||
} else {
|
||
$systemConfig = $config['systemConfig'];
|
||
$SystemConfigModel = D('SystemConfig');
|
||
$post['appid'] = $systemConfig[$SystemConfigModel::WX_APPID];
|
||
$post['mch_id'] = $systemConfig[$SystemConfigModel::MCH_ID];
|
||
$post['sub_mch_id'] = $config[$PaySetModel::WX_SUB_MCH_ID];
|
||
if (!empty($config[$PaySetModel::WX_SUB_APPID])) {
|
||
$post['sub_appid'] = $config[$PaySetModel::WX_SUB_APPID];
|
||
}
|
||
}
|
||
|
||
$WxMicroPay = new \Util\Wx\WxMicroPay($obj);
|
||
//以下为往微信发送的数据
|
||
$post['nonce_str'] = $WxMicroPay->createNoncestr(32);
|
||
$post['transaction_id'] = $payOrder[$PayOrderModel::TRADE_NO];
|
||
$post['out_refund_no'] = $payOrder[$PayOrderModel::OUT_TRADE_NO];
|
||
$post['total_fee'] = $payOrder['before_amount'] * 100;
|
||
$post['refund_fee'] = $payOrder[$PayOrderModel::TRADE_AMOUNT] * 100;
|
||
$post['sign'] = $WxMicroPay->getSign($post);
|
||
|
||
$url = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
|
||
$xml = $WxMicroPay->arrayToXml($post);
|
||
$response = $WxMicroPay->postXmlCurlCancel($xml, $url, 30);
|
||
|
||
$response = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
||
if ($response['result_code'] == 'SUCCESS' && $response['return_code'] == 'SUCCESS') {
|
||
$res = $this->searchRefund_v2($response['refund_id'], $payOrder, $config);
|
||
} else {
|
||
$res['status'] = 0;
|
||
$res['msg'] = $response['err_code_des'] ? $response['err_code_des'] : ($response['return_msg'] ? $response['return_msg'] : '退款失败');
|
||
}
|
||
$res['post'] = $post;
|
||
$res['obj'] = $obj;
|
||
$res['response'] = $response;
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* 查询退款
|
||
* @param $refund_id 微信退款id
|
||
* @param $payOrder pay_order退款数据
|
||
* @param $config 支付设置
|
||
* @return mixed
|
||
*/
|
||
protected function searchRefund_v2($refund_id, $payOrder, $config)
|
||
{
|
||
$PayOrderModel = D('RetailPayOrder');
|
||
$PaySetModel = D('RetailPaySet');
|
||
$obj = $this->getRefundData($payOrder, $config);
|
||
if ($payOrder[$PayOrderModel::M_PAY_TYPE] == 1) {
|
||
$post['appid'] = $config[$PaySetModel::WX_APPID];
|
||
$post['mch_id'] = $config[$PaySetModel::WX_MCH_ID];
|
||
} else {
|
||
$systemConfig = $config['systemConfig'];
|
||
$SystemConfigModel = D('SystemConfig');
|
||
$post['appid'] = $systemConfig[$SystemConfigModel::WX_APPID];
|
||
$post['mch_id'] = $systemConfig[$SystemConfigModel::MCH_ID];
|
||
$post['sub_mch_id'] = $config[$PaySetModel::WX_SUB_MCH_ID];
|
||
if (!empty($config[$PaySetModel::WX_SUB_APPID])) {
|
||
$post['sub_appid'] = $config[$PaySetModel::WX_SUB_APPID];
|
||
}
|
||
}
|
||
$WxMicroPay = new \Util\Wx\WxMicroPay($obj);
|
||
|
||
$post['nonce_str'] = $WxMicroPay->createNoncestr(32);
|
||
$post['transaction_id'] = $payOrder[$PayOrderModel::TRADE_NO];
|
||
$post['out_refund_no'] = $payOrder[$PayOrderModel::OUT_TRADE_NO];
|
||
$post['refund_id'] = $refund_id;
|
||
$post['sign'] = $WxMicroPay->getSign($post);
|
||
|
||
$url = 'https://api.mch.weixin.qq.com/pay/refundquery';
|
||
$xml = $WxMicroPay->arrayToXml($post);
|
||
$response = $WxMicroPay->postXmlCurlCancel($xml, $url, 30);
|
||
|
||
$response = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
||
if ($response['result_code'] == 'SUCCESS' && $response['return_code'] == 'SUCCESS') {
|
||
switch ($response['refund_status_0']) {
|
||
case 'PROCESSING':
|
||
case 'SUCCESS':
|
||
//分润退款
|
||
$this->doRefundRate($payOrder[$PayOrderModel::TRADE_NO], $payOrder[$PayOrderModel::TRADE_AMOUNT], 1);//分润
|
||
$res['status'] = 1;
|
||
$res['data'] = $response;
|
||
$res['msg'] = '退款成功';
|
||
break;
|
||
case 'REFUNDCLOSE':
|
||
//退款关闭
|
||
$res['status'] = 0;
|
||
$res['msg'] = '退款关闭';
|
||
break;
|
||
case 'CHANGE':
|
||
//退款异常-退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,可前往商户平台(pay.weixin.qq.com)-交易中心,手动处理此笔退款。
|
||
$res['status'] = 0;
|
||
$res['msg'] = '退款异常,商户银行卡异常';
|
||
}
|
||
} else {
|
||
$res['status'] = 0;
|
||
$res['data'] = $response['err_code_des'] ? $response['err_code_des'] : $response['return_msg'] ? $response['return_msg'] : '退款失败';
|
||
$res['msg'] = '退款失败';
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
/*-----------------------------2019-6-22 新版支付结束--------------------------------------*/
|
||
|
||
|
||
/**
|
||
* 查询订单状态并更新订单信息
|
||
* @param $order 订单信息
|
||
* @return mixed
|
||
*/
|
||
public function queryOrderAndUpdate($order)
|
||
{
|
||
$PaySetModel = new RetailPaySetModel();
|
||
$paySet = $PaySetModel->getFindMerchantConfig($order['merchant_id'], 1);
|
||
$config = $paySet['config'];
|
||
$response = $this->getMicroPayState_v2($order, $config);
|
||
if ($response['status'] == 1) {
|
||
$time = substr($response['time_end'], 0, strlen($response['time_end']) - 10) . '-' . substr($response['time_end'], -10, 2) . '-' . substr($response['time_end'], -8, 2) . ' ' . substr($response['time_end'], -6, 2) . ':' . substr($response['time_end'], -4, 2) . ':' . substr($response['time_end'], -2, 2);
|
||
if ($order['m_pay_type'] == 1) {
|
||
$mch_id = $config['wx_mch_id'];
|
||
} else {
|
||
//查询合作伙伴配置
|
||
$mch_id = $config['wx_sub_mchid'];
|
||
}
|
||
$save = array(
|
||
'trade_no' => $response ['transaction_id'],
|
||
'order_state' => 'SUCCESS',
|
||
'trade_date' => strtotime($time),
|
||
'extend_content' => json_encode($response),
|
||
'mer_id' => $mch_id,
|
||
);
|
||
$PayOrderModel = new RetailPayOrderModel();
|
||
$PayOrderModel->updateOrder(array('id' => $order['id']), $save);//更新订单信息
|
||
$where = [
|
||
'merchant_id' => $order['merchant_id'],
|
||
'openid' => $response['openid']
|
||
];
|
||
$PayInfo = new PayInfoModel();
|
||
$pay_info = $PayInfo->getFind($where);
|
||
if (empty($pay_info)) {
|
||
$pay_info = [
|
||
'merchant_id' => $order['merchant_id'],
|
||
'pay_order_id' => $order['id'],
|
||
'vip_id' => $order['vid'] ? $order['vid'] : 0,
|
||
'xcx_id' => $order['uid'] ? $order['uid'] : 0,
|
||
'm_pay_type' => $order['m_pay_type'],
|
||
'openid' => $response['openid'],
|
||
'sub_openid' => $response['sub_openid'] ? $response['sub_openid'] : '',
|
||
'type' => 2,
|
||
'add_time' => time(),
|
||
];
|
||
$PayInfo->addOrder($pay_info);
|
||
}
|
||
if ($order['m_pay_type'] == 2) {
|
||
$this->doAddRate($response['transaction_id'], $order, 2);//分润
|
||
}
|
||
}
|
||
return $response;
|
||
}
|
||
|
||
|
||
/**
|
||
* 提交支付 2020-10-16
|
||
* @param $payOrder
|
||
* @param $config
|
||
* @return mixed
|
||
*/
|
||
public function toCodeWxPay_v3($payOrder, $config)
|
||
{
|
||
$post['body'] = $config['body'] ? $config['body'] : '买单';
|
||
$post['out_trade_no'] = $payOrder['out_trade_no'];
|
||
if (!empty($payOrder['face_token'])) {
|
||
$post['face_code'] = $payOrder['face_token'];
|
||
$post['openid'] = $payOrder['openid'];
|
||
} else {
|
||
$post['auth_code'] = $payOrder['code'];
|
||
}
|
||
if ($payOrder['m_pay_type'] == 1) {
|
||
$post['appid'] = $config['wx_appid'];
|
||
$post['mch_id'] = $config['wx_mch_id'];
|
||
$post['key'] = $config['wx_secret_key'];
|
||
} else {
|
||
//查询合作伙伴配置
|
||
$systemConfig = $config['systemConfig'];
|
||
$post['appid'] = $systemConfig['wx_appid'];
|
||
$post['mch_id'] = $systemConfig['mch_id'];
|
||
$post['key'] = $systemConfig['wx_key'];
|
||
$post['sub_mch_id'] = $config['wx_sub_mchid'];
|
||
if (!empty($config['wx_sub_appid'])) {
|
||
$post['sub_appid'] = $config['wx_sub_appid'];
|
||
}
|
||
}
|
||
if (!empty($payOrder['plug']['wxpaycoupon']) && !empty($payOrder['shop_coupon']['goods_detail'])) {
|
||
//满足代金券使用条件
|
||
if (!empty($payOrder['shop_coupon']['goods_tag'])) {
|
||
$post['goods_tag'] = strval($payOrder['shop_coupon']['goods_tag']);
|
||
}
|
||
$post['version'] = '1.0';
|
||
$post['detail'] = $payOrder['shop_coupon']['goods_detail'];
|
||
}
|
||
$post['total_fee'] = $payOrder['trade_amount'];
|
||
//调起支付
|
||
$WxPaysdk = new \Util\Wx\WxMicroPay($post);
|
||
$result = $WxPaysdk->postWxMicro();
|
||
if (!empty($result) && $result['result_code'] == 'SUCCESS' && $result['return_code'] == 'SUCCESS') {
|
||
$res = $result;
|
||
$res['status'] = 1;
|
||
$res['message'] = '发起支付成功';
|
||
} else if (!empty($result) && $result['err_code'] == 'USERPAYING' && $result["return_code"] == "SUCCESS" && $result["return_msg"] == "OK") {//用户支付中
|
||
$res['status'] = 1;
|
||
$res['message'] = '发起支付成功';
|
||
} else if (!empty($result)) {
|
||
$res['status'] = 0;
|
||
$res['message'] = $result["err_code_des"] ? $result["err_code_des"] : ($result['return_msg'] ? $result['return_msg'] : '收款失败');
|
||
$res['data'] = $result;
|
||
$res['post'] = $post;
|
||
} else {
|
||
$res['status'] = 0;
|
||
$res['data'] = $result;
|
||
$res['message'] = "收款失败,请重试";
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
|
||
/**
|
||
*查询微信支付订单 2020-10-16
|
||
* @param $payOrder
|
||
* @param $config
|
||
* @return bool|mixed|string
|
||
*/
|
||
public function searchWxOrder_v3($payOrder, $config)
|
||
{
|
||
if ($payOrder['m_pay_type'] == 1) {
|
||
$post['appid'] = $config['wx_appid'];
|
||
$post['mch_id'] = $config['wx_mch_id'];
|
||
$key = $config['wx_secret_key'];
|
||
} else {
|
||
$systemConfig = $config['systemConfig'];
|
||
$post['appid'] = $systemConfig['wx_appid'];
|
||
$post['mch_id'] = $systemConfig['mch_id'];
|
||
$post['sub_mch_id'] = $config['wx_sub_mchid'];
|
||
if (!empty($config['wx_sub_appid'])) {
|
||
$post['sub_appid'] = $config['wx_sub_appid'];
|
||
}
|
||
$key = $systemConfig['wx_key'];
|
||
}
|
||
$WxMicroPay = new \Util\Wx\WxMicroPay(array('key' => $key));
|
||
$post['out_trade_no'] = $payOrder['out_trade_no'];
|
||
$post['nonce_str'] = $WxMicroPay->createNoncestr(32);
|
||
$post['sign'] = $WxMicroPay->getSign($post);
|
||
if (!empty($payOrder['face_token'])) {
|
||
//刷脸
|
||
$url = "https://api.mch.weixin.qq.com/pay/facepayquery";
|
||
$post['sign_type'] = "MD5";//签名类型 支持HMAC-SHA256和MD5
|
||
} else {
|
||
//二维码
|
||
$url = 'https://api.mch.weixin.qq.com/pay/orderquery';
|
||
}
|
||
$xml = $WxMicroPay->arrayToXml($post);//转换为xml
|
||
$response = $WxMicroPay->postXmlCurl($xml, $url, 30);
|
||
libxml_disable_entity_loader(true); //禁止外部xml
|
||
$response = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
||
return $response;
|
||
}
|
||
|
||
|
||
/**
|
||
* 撤销微信订单 2020-10-16
|
||
* @param $payOrder 流水信息
|
||
* @param $config 支付配置
|
||
* @return mixed
|
||
*/
|
||
public function cancelWxOrder($payOrder, $config)
|
||
{
|
||
$obj = $this->getRefundData($payOrder, $config);
|
||
if ($payOrder['m_pay_type'] == 1) {
|
||
$post['appid'] = $config['wx_appid'];
|
||
$post['mch_id'] = $config['wx_mch_id'];
|
||
} else {
|
||
$systemConfig = $config['systemConfig'];
|
||
$post['appid'] = $systemConfig['wx_appid'];
|
||
$post['mch_id'] = $systemConfig['mch_id'];
|
||
$post['sub_mch_id'] = $config['wx_sub_mchid'];
|
||
if (!empty($config['wx_sub_appid'])) {
|
||
$post['sub_appid'] = $config['wx_sub_appid'];
|
||
}
|
||
}
|
||
$WxMicroPay = new \Util\Wx\WxMicroPay($obj);
|
||
$post['out_trade_no'] = $payOrder['out_trade_no'];
|
||
$post['nonce_str'] = $WxMicroPay->createNoncestr(32);
|
||
$post['sign'] = $WxMicroPay->getSign($post);
|
||
if (!empty($payOrder['face_token'])) {
|
||
//刷脸
|
||
$url = "https://api.mch.weixin.qq.com/secapi/pay/facepayreverse";
|
||
} else {
|
||
$url = 'https://api.mch.weixin.qq.com/secapi/pay/reverse';
|
||
}
|
||
$xml = $WxMicroPay->arrayToXml($post);
|
||
$response = $WxMicroPay->postXmlCurlCancel($xml, $url, 30);
|
||
libxml_disable_entity_loader(true); //禁止外部xml
|
||
$response = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
||
file_put_contents('./cancelWxOrder.txt', date('Y-m-d H:i:s') . json_encode($response) . "\r\n", FILE_APPEND);
|
||
return $response;
|
||
}
|
||
} |