文件
mashangyoujiu/Application/Pay/Controller/NewWxPayController.class.php

1341 行
60 KiB
PHP
可执行文件

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<?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;
}
}