NotifyController.php 7.2 KB
<?php
/**
 * Created by PhpStorm.
 * User: 29925
 * Date: 2018/6/13
 * Time: 17:53
 */

namespace api\portal\controller;

use api\portal\controller\NotifyCommonController;
use think\Config;
use think\Db;

class NotifyController extends NotifyCommonController
{

    // 微信支付回调
    public function notify() {
        require_once VENDOR_PATH."WxpayAPI/lib/WxPay.Api.php";
        require_once VENDOR_PATH."WxpayAPI/lib/WxPay.Notify.php";
        require_once VENDOR_PATH.'WxpayAPI/example/log.php';

        $post = $this->request->param();
        if($post==null){
            $post = file_get_contents("php://input");
            if($post == null){
                $post = $GLOBALS['HTTP_RAW_POST_DATA'];
            }
        }
        if(!empty($post)) {
            $xml = $post;  //微信的回调数据
            $base = new \WxPayResults();            //实例化数据对象结果类
            $data = $base->FromXml($xml);
            if($base->CheckSign() == true){
                if ($data["return_code"] == "SUCCESS") {
                    $where['order_sn'] = $data['attach'];
                    if (empty($where['order_sn'])) {
                        $where['order_sn'] = $data['out_trade_no'];
                    }
//                    $where['money'] = $data['total_fee']/100;
                    $pay_type = 1;
                    $title = 'pc微信扫码支付';
                    if($data["trade_type"] == 'MWEB') {
                        $pay_type = 2;
                        $title = '网页H5支付';
                    }
                    $result = $this->changeOrderStatus($where,$data['transaction_id'],$pay_type,$title);
                    if($result) {
                        $this->return_success();
                    }
                }
            }
        }
    }

    /**
     * 微信支付退款结果回调
     */
    public function refund_notify() {
        $post = $this->request->param();
        if($post==null){
            $post = file_get_contents("php://input");
            if($post == null){
                $post = $GLOBALS['HTTP_RAW_POST_DATA'];
            }
        }
        if(!empty($post)) {
            $xml = $post;  //微信的回调数据
            $data = $this->xmlToArray($xml);
            if($data['return_code'] == 'SUCCESS' && !empty($data['req_info'])) {
                $key = md5(Config::get('wx_key'));
                $array = $this->xmlToArray($this->refund_decrypt($data['req_info'],$key));
                $refund_where = [
                    'order_sn' => $array['out_refund_no'],
                    'refund_id' => $array['refund_id'],
                ];
                $order_where = [
                    'transaction_id' => $array['transaction_id'],
                ];
                $handle_sql = true;
                Db::startTrans();
                if($array['refund_status'] == 'SUCCESS') {
                    $refundInfo = Db::name('Refund')->where($refund_where)->find();
                    $refund_update = [
                        'status' => 2,
                        'refund_time' => strtotime($array['success_time']),
                        'remark' => $array['refund_account'],
                        'more' => json_encode($array),
                    ];
                    $refund_result = Db::name('Refund')->where($refund_where)->update($refund_update);
                    $order_update = [
                        'status' => 4,
                        'refund_time' => strtotime($array['success_time'])
                    ];
                    $order_result = Db::name('Order')->where($order_where)->update($order_update);
                    $order_type = '';
                    if($refundInfo['user_type'] == 1) {
                        $order_type = 4;
                    }if($refundInfo['user_type'] == 2) {
                        $order_type = 5;
                    }
                    $insert = [
                        'order_id' => $refundInfo['order_id'],
                        'user_id' => $refundInfo['user_id'],
                        'user_type' => $refundInfo['user_type'],
                        'title' => '退款',
                        'order_type' => $order_type,
                        'type' => 1,
                        'reason' => $refundInfo['reason'],
                        'create_time' => time(),
                        'update_time' => time()
                    ];
                    $money_detail_insert = Db::name('MoneyDetail')->insertGetId($insert);
                    if(!$refund_result || !$order_result || !$money_detail_insert) {
                        $handle_sql = false;
                    }
                } elseif($array['refund_status'] == 'CHANGE') {
                    $refund_update = [
                        'status' => 4,
//                        'refund_time' => strtotime($array['success_time']),
//                        'remark' => $array['refund_account'],
                        'more' => json_encode($array),
                    ];
                    $refund_result = Db::name('Refund')->where($refund_where)->update($refund_update);
                    if(!$refund_result) {
                        $handle_sql = false;
                    }
                } elseif($array['refund_status'] == 'REFUNDCLOSE') {
                    $refund_update = [
                        'status' => 3,
//                        'refund_time' => strtotime($array['success_time']),
//                        'remark' => $array['refund_account'],
                        'more' => json_encode($array),
                    ];
                    $refund_result = Db::name('Refund')->where($refund_where)->update($refund_update);
                    if(!$refund_result) {
                        $handle_sql = false;
                    }
                }
                if(!$handle_sql) {
                    Db::rollback();
                } else {
                    Db::commit();
                    $this->return_success();
                }
            }
        }
    }

    /**
     * 微信退款回调数据
     * (1)对加密串A做base64解码,得到加密串B
     * (2)对商户key做md5,得到32位小写key* ( key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 )
     * (3)用key*对加密串B做AES-256-ECB解密(PKCS7Padding)
     */

    private function refund_decrypt($str, $key) {
        $str = base64_decode($str);
        $decrypted = openssl_decrypt($str, 'AES-256-ECB', $key, OPENSSL_RAW_DATA);
        return $decrypted;
    }

    //xml转换成数组
    private function xmlToArray($xml) {


        //禁止引用外部xml实体


        libxml_disable_entity_loader(true);


        $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);


        $val = json_decode(json_encode($xmlstring), true);


        return $val;
    }

    /*
     * 给微信发送确认订单金额和签名正确,SUCCESS信息
     */
    private function return_success(){
        $return['return_code'] = 'SUCCESS';
        $return['return_msg'] = 'OK';
        $xml_post = '<xml>
                    <return_code>'.$return['return_code'].'</return_code>
                    <return_msg>'.$return['return_msg'].'</return_msg>
                    </xml>';
        echo $xml_post;exit;
    }
}