cxgj/controllers/notify/PaymentController.php
2023-11-27 09:45:13 +08:00

391 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* @author Any
* @description KISS
* @date 2021年10月3日
* @version 1.0.0
*
* _____LOG_____
*
*/
namespace app\controllers\notify;
use app\models\Order;
use app\models\wechat\WechatApp;
use Wechat\Wechat;
use Wechat\DataConversion;
use app\controllers\Controller;
use app\models\PaymentOrder;
use app\models\PaymentOrderUnion;
use app\models\common\PluginService;
use app\components\SysConst;
use app\models\common\notify\payment\PaymentNotify;
use app\models\log\PayNotifyLog;
use app\models\Model;
class PaymentController extends Controller
{
public $enableCsrfValidation = false;
public $wechat;
//服务项目订单微信支付异步通知
public function actionWxpay()
{
$xml = file_get_contents("php://input");
$res = DataConversion::xmlToArray($xml);
if ($res && !empty($res['out_trade_no'])) { //微信支付回调
$this->handleWxpayNotify($res);
}
}
private function handleWxpayNotify($res)
{
//记录日志
if(isset($res['out_trade_no'])){
PayNotifyLog::logger($res['out_trade_no'], $res);
}
if ($res['result_code'] != 'SUCCESS' && $res['return_code'] != 'SUCCESS') {
return;
}
$paymentOrderUnion = PaymentOrderUnion::findOne(['order_no' => $res['out_trade_no']]);
if($paymentOrderUnion == null){
return;
}
$plugin = new PluginService();
$wechat = $plugin->getWxmpService($paymentOrderUnion->cx_mch_id);
$sign = $wechat->pay->makeSign($res);
if ($sign != $res['sign']) {
echo "Sign 错误";
$this->handleError($paymentOrderUnion->order_no, 'Sign错误');
return;
}
if ($paymentOrderUnion->is_pay == 1) {
echo "订单已支付";
$this->handleError($paymentOrderUnion->order_no, '订单已支付');
return;
}
$paymentOrderUnion->is_pay = 1;
$paymentOrderUnion->pay_type = SysConst::$cxPayTypeWxpay;
$paymentOrderUnion->updated_at = time();
$paymentOrderUnion->transaction_id = $res['transaction_id'];
if ($paymentOrderUnion->save()) {
//支付完成之后,相关的操作
$form = new PaymentNotify();
$resp = $form->notify($paymentOrderUnion);
if($resp['code'] != 0){
//记录错误
$this->handleError($paymentOrderUnion->order_no, $resp['msg']);
}
echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
return;
} else {
echo "支付失败";
return;
}
}
//银联支付回调异步通知
public function actionUnionpay()
{
$req = file_get_contents("php://input");
if(!empty($req)){
$this->handleUnionpayNotify($req);
}
}
private function handleUnionpayNotify($req)
{
$reqArr = json_decode($req,true);
//记录日志
if(isset($reqArr["response"]["msgBody"]["remark"])){
PayNotifyLog::logger($reqArr["response"]["msgBody"]["remark"], $req);
}
$plugin = new PluginService();
$updcService = $plugin->getUpdcService();
//签名原文不能使用json字符串和数组之间的转换获取该处理过程将键值冒号前的空着除去导致与原文不一致
$sindex=strpos($req,'"sign":');
$reqJson=substr($req,0,$sindex-1)."}";
$reqSign = $reqArr['sign'];
$r = $updcService->signature->verify($reqJson,$reqSign);
if(!$r){
echo "响应报文验签失败\n";
return;
}
//验签通过
$res = $reqArr;
if(!isset($res['code']) || $res['code'] != '00000'){
$msg = isset($res['msg']) ? "[{$res['code']}]{$res['msg']}" : "[{$res['code']}]error";
throw new \Exception($msg);
}
if(!isset($res['response'])){
echo '缺少response参数' .PHP_EOL;
return;
}
$response = $res['response'];
if(!isset($response['subCode']) || $response['subCode'] != '00000'){
$msg = isset($response['subMsg']) ? "[{$response['subCode']}]{$response['subMsg']}" : "[{$response['subCode']}]error";
echo $msg .PHP_EOL;
return;
}
if(!isset($response['msgBody'])){
echo '缺少msgBody参数' .PHP_EOL;
return;
}
$msgBody = $response['msgBody'];
if(!isset($msgBody['retCode']) || $msgBody['retCode'] != '00000'){
$msg = isset($msgBody['retMsg']) ? "[{$msgBody['retCode']}]{$msgBody['retMsg']}" : "[{$msgBody['retCode']}]error";
echo $msg .PHP_EOL;
return;
}
$out_trade_no = $msgBody['oriMerOrdrNo'];
$paymentOrderUnion = PaymentOrderUnion::findOne(['out_trade_no' => $out_trade_no]);
if($paymentOrderUnion == null){
echo '支付订单不存在' .PHP_EOL;
return;
}
if ($paymentOrderUnion->is_pay == 1) {
echo "订单已支付" .PHP_EOL;
$this->handleError($paymentOrderUnion->order_no, '订单已支付');
return;
}
$paymentOrderUnion->is_pay = 1;
$paymentOrderUnion->pay_type = SysConst::$cxPayTypeUnionpay;
$paymentOrderUnion->updated_at = time();
$chnlMerOrdrNo = isset($msgBody['chnlMerOrdrNo']) ? $msgBody['chnlMerOrdrNo'] : 0;
$paymentOrderUnion->transaction_id = $chnlMerOrdrNo;
if ($paymentOrderUnion->save()) {
//支付完成之后,相关的操作
$form = new PaymentNotify();
$resp = $form->notify($paymentOrderUnion);
if($resp['code'] != 0){
//记录错误
$this->handleError($paymentOrderUnion->order_no, $resp['msg']);
}
echo '支付成功' .PHP_EOL;
return;
} else {
echo "支付失败" .PHP_EOL;
return;
}
}
private function handleError($order_no, $err_msg)
{
$message = "ORDER_NO:{$order_no} ERR_MSG:{$err_msg}";
\Yii::error($message,'NotifyPayment');
}
//支付回调测试
public function actionTest()
{
$open = false;
if(!$open){
$data = $this->invaildRequest();
return $this->responseHandler($data);
}
$params = \Yii::$app->request->post();
$paymentOrderUnion = PaymentOrderUnion::findOne(['order_no' => $params['out_trade_no']]);
if($paymentOrderUnion == null){
$data = $this->requestNotFound();
return $this->responseHandler($data);
}
$paymentOrderUnion->is_pay = 1;
$paymentOrderUnion->pay_type = SysConst::$cxPayTypeWxpay;
$paymentOrderUnion->updated_at = time();
if ($paymentOrderUnion->save()) {
//支付完成之后,相关的操作
$form = new PaymentNotify();
$resp = $form->notify($paymentOrderUnion);
if($resp['code'] != 0){
//记录错误
$this->handleError($paymentOrderUnion->order_no, $resp['msg']);
}
return $this->responseHandler($resp);
} else {
$data = (new Model())->getModelError($paymentOrderUnion);
return $this->responseHandler($data);
}
}
//微信退款回调-押金
public function actionWxpayDepositRefunds()
{
$xml = file_get_contents("php://input");
$res = DataConversion::xmlToArray($xml);
// $associatedData = $res['resource']['associated_data'];
// $nonceStr = $res['resource']['nonce'];
// $ciphertext = $res['resource']['ciphertext'];
//
// $plugin = new \app\models\common\PluginService();
// $wxmpService = $plugin->getWxmpService(0);
//
// $ctext = substr($ciphertext, 0, 16);
// $authTag = substr($ciphertext, 16);
// $res_json = openssl_decrypt($ctext, 'aes-256-gcm', $wxmpService->apiKey_three, 1, $nonceStr,$authTag, $associatedData);
// $res = json_decode($res_json,true);
if ($res && !empty($res['out_trade_no'])) { //微信支付回调
$this->handleWxpayDepositRefundsNotify($res);
}
}
//微信退款回调-押金
private function handleWxpayDepositRefundsNotify($res)
{
try {
//记录日志
if(isset($res['out_trade_no'])){
PayNotifyLog::logger($res['out_trade_no'], $res);
}
$plugin = new PluginService();
$wechat = $plugin->getWxmpService(0);
$sign = $wechat->pay->makeSign($res);
if ($sign != $res['sign']) {
echo "Sign 错误";
$this->handleError($res['out_trade_no'], 'Sign错误');
return;
}
//SUCCESS退款成功,CLOSED退款关闭,ABNORMAL退款异常
if($res['refund_status'] == 'SUCCESS'){
$status = 1; //退款成功
}elseif ($res['refund_status'] == 'CLOSED'){
$status = 2; //退款关闭状态
}elseif ($res['refund_status'] == 'ABNORMAL'){
$status = 3; //退款异常
}else{
echo "退款失败";
return;
}
$paymentOrderUnion = PaymentOrderUnion::findOne(['order_no' => $res['out_trade_no']]);
if($paymentOrderUnion == null){
echo "退款失败";
return;
}
$paymentOrder = PaymentOrder::findOne(['payment_order_union_id' => $paymentOrderUnion->id]);
if($paymentOrder == null){
echo "退款失败";
return;
}
$order = Order::findOne(['order_no' => $paymentOrder->order_no]);
if($order == null){
echo "退款失败";
return;
}
$order->is_confirm = $status;
$order->updated_at = time();
if(!$order){
echo "退款失败";
return;
}
echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
return;
}catch (\Exception $e){
echo "ERROR";
return;
}
}
//微信支付退款回调-订单
public function actionWxpayOrderRefunds()
{
$xml = file_get_contents("php://input");
$res = DataConversion::xmlToArray($xml);
// $associatedData = $res['resource']['associated_data'];
// $nonceStr = $res['resource']['nonce'];
// $ciphertext = $res['resource']['ciphertext'];
//
// $plugin = new \app\models\common\PluginService();
// $wxmpService = $plugin->getWxmpService(0);
//
// $ctext = substr($ciphertext, 0, 16);
// $authTag = substr($ciphertext, 16);
// $res_json = openssl_decrypt($ctext, 'aes-256-gcm', $wxmpService->apiKey_three, 1, $nonceStr,$authTag, $associatedData);
// $res = json_decode($res_json,true);
if ($res && !empty($res['out_trade_no'])) { //微信支付回调
$this->handleWxpayOrderRefundsNotify($res);
}
}
//微信支付退款回调-订单
private function handleWxpayOrderRefundsNotify($res)
{
try {
//记录日志
if(isset($res['out_trade_no'])){
PayNotifyLog::logger($res['out_trade_no'], $res);
}
if ($res['result_code'] != 'SUCCESS' && $res['return_code'] != 'SUCCESS') {
return;
}
$plugin = new PluginService();
$wechat = $plugin->getWxmpService(0);
$sign = $wechat->pay->makeSign($res);
if ($sign != $res['sign']) {
echo "Sign 错误";
$this->handleError($res['out_trade_no'], 'Sign错误');
return;
}
//SUCCESS退款成功,CLOSED退款关闭,ABNORMAL退款异常
if($res['refund_status'] == 'SUCCESS'){
$status = 0; //已完成状态
}elseif ($res['refund_status'] == 'CLOSED'){
$status = 2; //退款关闭状态
}elseif ($res['refund_status'] == 'ABNORMAL'){
$status = 3; //退款异常
}else{
echo "退款失败";
return;
}
$paymentOrderUnion = PaymentOrderUnion::findOne(['order_no' => $res['out_trade_no']]);
if($paymentOrderUnion == null){
echo "退款失败";
return;
}
$paymentOrder = PaymentOrder::findOne(['payment_order_union_id' => $paymentOrderUnion->id]);
if($paymentOrder == null){
echo "退款失败";
return;
}
$order = Order::findOne(['order_no' => $paymentOrder->order_no]);
if($order == null){
echo "退款失败";
return;
}
$order->status = $status;
$order->updated_at = time();
if(!$order){
echo "退款失败";
return;
}
echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
return;
}catch (\Exception $e){
echo "退款失败";
return;
}
}
}