|
|
@ -10,14 +10,12 @@ namespace api\logic; |
|
|
|
|
|
|
|
use backend\modules\shop\models\ars\PaymentLog; |
|
|
|
use backend\modules\shop\models\ars\WxPayConfig; |
|
|
|
use common\models\User; |
|
|
|
use Yii; |
|
|
|
use backend\modules\shop\models\ars\Config; |
|
|
|
use EasyWeChat\Factory; |
|
|
|
use backend\modules\shop\models\ars\Order; |
|
|
|
use yii\db\Exception; |
|
|
|
use yii\helpers\Json; |
|
|
|
use yii\httpclient\Client; |
|
|
|
use yii\web\BadRequestHttpException; |
|
|
|
use yii\web\NotFoundHttpException; |
|
|
|
use yii\base\BaseObject; |
|
|
|
|
|
|
|
class WxPaymentLogic extends BaseObject |
|
|
@ -33,7 +31,7 @@ class WxPaymentLogic extends BaseObject |
|
|
|
public $key; |
|
|
|
public $certPath; |
|
|
|
public $keyPath; |
|
|
|
public $notifyUrl = 'http://baidu.com'; |
|
|
|
public $notifyUrl; |
|
|
|
public $tradeType; |
|
|
|
public $payType; |
|
|
|
public $app; |
|
|
@ -98,6 +96,7 @@ class WxPaymentLogic extends BaseObject |
|
|
|
$paymentLog->payment_amount = $paymentAmount; |
|
|
|
$paymentLog->notify_url = $notifyUrl; |
|
|
|
$paymentLog->type = $this->payType; |
|
|
|
$paymentLog->status = PaymentLog::PAYMENT_STATUS_WAITING; |
|
|
|
if (!$paymentLog->save()) { |
|
|
|
throw new Exception(Helper::errorMessageStr($paymentLog->errors)); |
|
|
|
} |
|
|
@ -127,31 +126,26 @@ class WxPaymentLogic extends BaseObject |
|
|
|
private function initObject() |
|
|
|
{ |
|
|
|
$path = Yii::getAlias('@backend'); |
|
|
|
|
|
|
|
$wxPayConfig = WxPayConfig::find()->one(); |
|
|
|
// $wxConfig = WxConfig::find()->one();
|
|
|
|
// switch ($this->payType) {
|
|
|
|
// case self::PAY_TYPE_WEB:
|
|
|
|
// $this->appId = trim($config->wx_appId);
|
|
|
|
// $this->mchId = trim($config->wx_mchId);
|
|
|
|
// $this->key = trim($config->wx_key);
|
|
|
|
// $this->keyPath = trim($path . $config->wx_keyPath);
|
|
|
|
// $this->appId = trim($wxConfig->wx_appId);
|
|
|
|
// break;
|
|
|
|
// case self::PAY_TYPE_MINI_PROGRAM:
|
|
|
|
// $this->appId = trim($config->mini_program_appId);
|
|
|
|
// $this->mchId = trim($config->mini_program_mchId);
|
|
|
|
// $this->key = trim($config->mini_program_key);
|
|
|
|
// $this->appId = trim($wxConfig->mini_program_appId);
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
|
|
|
|
$wxPayConfig = WxPayConfig::find()->one(); |
|
|
|
$this->mchId = $wxPayConfig->mch_id; |
|
|
|
$this->certPath = trim($path . $wxPayConfig->cert_path); |
|
|
|
$this->keyPath = trim($path . $wxPayConfig->key_path); |
|
|
|
$this->notifyUrl = Yii::$app->request->hostInfo . '/wx-payment/notify'; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param $unifyParams |
|
|
|
* @return mixed |
|
|
|
* @throws Exception |
|
|
|
* 统一下单 |
|
|
|
*/ |
|
|
|
private function unify($unifyParams) |
|
|
@ -164,60 +158,34 @@ class WxPaymentLogic extends BaseObject |
|
|
|
/** |
|
|
|
* @return array|bool |
|
|
|
* @throws BadRequestHttpException |
|
|
|
* 支付回调 |
|
|
|
* @throws \yii\base\InvalidConfigException |
|
|
|
* @throws \yii\httpclient\Exception |
|
|
|
* 微信支付回调 |
|
|
|
*/ |
|
|
|
public function notify() |
|
|
|
{ |
|
|
|
$result = [ |
|
|
|
'appid' => 'wxdccdddaa336353e1', |
|
|
|
'bank_type' => 'OTHERS', |
|
|
|
'cash_fee' => '926', |
|
|
|
'fee_type' => 'CNY', |
|
|
|
'is_subscribe' => 'N', |
|
|
|
'mch_id' => '1395812402', |
|
|
|
'nonce_str' => '5df366a248edb', |
|
|
|
'openid' => 'ovT0C0UB8xQbfYHVVS2VGWMjDMhI', |
|
|
|
'out_trade_no' => '201912131823156640Q', |
|
|
|
'result_code' => 'SUCCESS', |
|
|
|
'return_code' => 'SUCCESS', |
|
|
|
'sign' => 'EA6FFD717A206D203856EAFB554F666F', |
|
|
|
'time_end' => '20191213182333', |
|
|
|
'total_fee' => '926', |
|
|
|
'trade_type' => 'JSAPI', |
|
|
|
'transaction_id' => '4200000423201912134049863433', |
|
|
|
]; |
|
|
|
$xmlString = $this->arrayToXml($result); |
|
|
|
$notifyData = json_decode(json_encode(simplexml_load_string($xmlString, 'SimpleXMLElement', LIBXML_NOCDATA))); |
|
|
|
|
|
|
|
// $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);
|
|
|
|
// }
|
|
|
|
$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 Exception('result_code or return_code is false'); |
|
|
|
} |
|
|
|
|
|
|
|
$user = User::findOne(['wx_openid' => $notifyData->openid, 'status' => User::STATUS_ACTIVE]) |
|
|
|
?? User::findOne(['mini_openid' => $notifyData->openid, 'status' => User::STATUS_ACTIVE]);/*根据openid获取用户*/ |
|
|
|
if (empty($user)) { |
|
|
|
throw new Exception('用户不存在或已被禁用'); |
|
|
|
throw new BadRequestHttpException('result_code or return_code is false'); |
|
|
|
} |
|
|
|
|
|
|
|
$paymentLog = PaymentLog::findOne(['order_id' => $notifyData->out_trade_no]); |
|
|
|
$paymentLog->mch_id = $this->mch_id; |
|
|
|
$this->notifyUrl = Yii::$app->request->hostInfo . $paymentLog->notify_url; |
|
|
|
$paymentLog->mch_id = $notifyData->mch_id; |
|
|
|
$paymentLog->wx_refund_id = $notifyData->transaction_id; //交易号
|
|
|
|
$paymentLog->status = 1; |
|
|
|
$paymentLog->status = PaymentLog::PAYMENT_STATUS_SUCCESS; |
|
|
|
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'];//回传成功信息到微信服务器
|
|
|
@ -226,15 +194,42 @@ class WxPaymentLogic extends BaseObject |
|
|
|
$this->forwardNotify($notifyData, false); |
|
|
|
Yii::info($e->getMessage(), 'notify'); |
|
|
|
return false; |
|
|
|
} catch (BadRequestHttpException $e) { |
|
|
|
Yii::info($e->getMessage(), 'notify'); |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @param $notifyData |
|
|
|
* @param $status |
|
|
|
* @return bool |
|
|
|
* @throws \yii\base\InvalidConfigException |
|
|
|
* @throws \yii\httpclient\Exception |
|
|
|
* 转发异步回调信息 |
|
|
|
*/ |
|
|
|
private 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; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @param $data |
|
|
@ -269,41 +264,5 @@ class WxPaymentLogic extends BaseObject |
|
|
|
return strtoupper(md5($queryString)); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param $arr |
|
|
|
* @param null $dom |
|
|
|
* @param null $node |
|
|
|
* @param string $root |
|
|
|
* @param bool $cdata |
|
|
|
* @return string |
|
|
|
* 数组转xml字符串 |
|
|
|
*/ |
|
|
|
function arrayToXml($arr, $dom = null, $node = null, $root = 'xml', $cdata = false) |
|
|
|
{ |
|
|
|
if (!$dom) { |
|
|
|
$dom = new \DOMDocument('1.0','utf-8'); |
|
|
|
} |
|
|
|
if (!$node) { |
|
|
|
$node = $dom->createElement($root); |
|
|
|
$dom->appendChild($node); |
|
|
|
} |
|
|
|
foreach ($arr as $key=>$value) { |
|
|
|
$child_node = $dom->createElement(is_string($key) ? $key : 'node'); |
|
|
|
$node->appendChild($child_node); |
|
|
|
if (!is_array($value)) { |
|
|
|
if (!$cdata) { |
|
|
|
$data = $dom->createTextNode($value); |
|
|
|
} else { |
|
|
|
$data = $dom->createCDATASection($value); |
|
|
|
} |
|
|
|
$child_node->appendChild($data); |
|
|
|
} else { |
|
|
|
$this->arrayToXml($value,$dom,$child_node,$root,$cdata); |
|
|
|
} |
|
|
|
} |
|
|
|
return $dom->saveXML(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |