<?php
/**
 * Created by PhpStorm.
 * User: travis
 * Date: 2019/12/12
 * Time: 6:20
 */

namespace api\logic;

use backend\modules\payment\logic\WxPaymentManager;
use yii\helpers\Json;
use yii\httpclient\Client;
use yii\web\BadRequestHttpException;
use backend\modules\shop\models\ars\PaymentLog;
use yii\db\Exception;
use Yii;

class WxPaymentLogic extends WxPaymentManager
{
    /**
     * @return array|bool
     * @throws BadRequestHttpException
     * @throws \yii\base\InvalidConfigException
     * @throws \yii\httpclient\Exception
     * 微信支付回调
     */
    public function notify()
    {
        $notifyData = Json::decode(Json::encode(simplexml_load_string(Yii::$app->request->getRawBody(), 'SimpleXMLElement', LIBXML_NOCDATA)));
        Yii::info($notifyData, "notify");
        if (!$this->checkSign($notifyData)) {
            throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
        }
        $tra = Yii::$app->db->beginTransaction('SERIALIZABLE');
        try {
            if ($notifyData->result_code != 'SUCCESS' || $notifyData->return_code != 'SUCCESS') {
                throw new BadRequestHttpException('result_code or return_code is false');
            }

            $paymentLog = PaymentLog::findOne(['order_id' => $notifyData->out_trade_no]);
            $this->notifyUrl = Yii::$app->request->hostInfo . $paymentLog->notify_url;
            $paymentLog->mch_id = $notifyData->mch_id;
            $paymentLog->wx_payment_id = $notifyData->transaction_id; //交易号
            $paymentLog->status = self::STATUS_PAYMENT_SUCCESS;
            $paymentLog->payment_at = time();
            if (!$paymentLog->save()) {
                throw new Exception(Helper::errorMessageStr($paymentLog->errors));
            }

            if (!$tra->commit()) {
                throw new Exception('保存数据失败');
            }
            /*转发回调信息*/
            $this->forwardNotify($notifyData, true);

            return ['return_code' => 'SUCCESS', 'return_msg' => 'OK'];//回传成功信息到微信服务器
        } catch (Exception $e) {
            $tra->rollBack();
            $this->forwardNotify($notifyData, false);
            Yii::info($e->getMessage(), 'notify');
            return false;
        } catch (BadRequestHttpException $e) {
            $tra->rollBack();
            $this->forwardNotify($notifyData, false);
            Yii::info($e->getMessage(), 'notify');
            return false;
        }
    }

    /**
     * @param $notifyData
     * @param $status
     * @return bool
     * @throws \yii\base\InvalidConfigException
     * @throws \yii\httpclient\Exception
     * 转发异步回调信息
     */
    protected function forwardNotify($notifyData, $status)
    {
        $notify = [
            'notify' => [
                'status' => $status,
                'notify' => $notifyData
            ]
        ];
        $client = new Client();
        $response = $client->createRequest()
            ->setMethod('POST')
            ->setUrl($this->notifyUrl)
            ->addHeaders(['content-type' => 'application/json'])
            ->setContent(Json::encode($notify))
            ->send();
        if ($response->isOk) {
            return true;
        } else {
            return false;
        }
    }

}