<?php
namespace Payment\Notify; use Illuminate\Support\Facades\Log; use Payment\Common\AliConfig; use Payment\Common\PayException; use Payment\Config; use Payment\Utils\ArrayUtil; use Payment\Utils\Rsa2Encrypt; use Payment\Utils\RsaEncrypt; class AliNotify extends NotifyStrategy { public function __construct(array $config) { try { $this->config = new AliConfig($config); } catch (PayException $e) { throw $e; } } public function getNotifyData() { $data = empty($_POST) ? $_GET : $_POST; if (empty($data) || ! is_array($data)) { return false; } return $data; } public function checkNotifyData(array $data) { $status = $this->getTradeStatus($data['trade_status']); if ($status !== Config::TRADE_STATUS_SUCC) { return false; } $flag = $this->verifySign($data); return $flag; } protected function getRetData(array $data) { if ($this->config->returnRaw) { $data['channel'] = Config::ALI_CHARGE; return $data; } $retData = [ 'notify_time' => ArrayUtil::get($data, 'notify_time'), 'notify_type' => ArrayUtil::get($data, 'notify_type'), 'notify_id' => ArrayUtil::get($data, 'notify_id'), 'app_id' => ArrayUtil::get($data, 'app_id'), 'transaction_id' => ArrayUtil::get($data, 'trade_no'), 'order_no' => ArrayUtil::get($data, 'out_trade_no'), 'out_biz_no' => ArrayUtil::get($data, 'out_biz_no'), 'buyer_id' => ArrayUtil::get($data, 'buyer_id'), 'buyer_account' => ArrayUtil::get($data, 'buyer_logon_id'), 'seller_id' => ArrayUtil::get($data, 'seller_id'), 'seller_email' => ArrayUtil::get($data, 'seller_email'), 'trade_state' => $this->getTradeStatus($data['trade_status']), 'amount' => ArrayUtil::get($data, 'total_amount'), 'receipt_amount' => ArrayUtil::get($data, 'receipt_amount'), 'invoice_amount' => ArrayUtil::get($data, 'invoice_amount'), 'pay_amount' => ArrayUtil::get($data, 'buyer_pay_amount'), 'point_amount' => ArrayUtil::get($data, 'point_amount'), 'refund_fee' => ArrayUtil::get($data, 'refund_fee'), 'subject' => ArrayUtil::get($data, 'subject'), 'body' => ArrayUtil::get($data, 'body'), 'trade_create_time' => ArrayUtil::get($data, 'gmt_create'), 'pay_time' => ArrayUtil::get($data, 'gmt_payment'), 'trade_refund_time' => ArrayUtil::get($data, 'gmt_refund'), 'trade_close_time' => ArrayUtil::get($data, 'gmt_close'), 'channel' => Config::ALI_CHARGE, ]; if (isset($data['passback_params']) && ! empty($data['passback_params'])) { $retData['return_param'] = $data['passback_params']; } if (isset($data['fund_bill_list']) && ! empty($data['fund_bill_list'])) { $retData['fund_bill_list'] = \GuzzleHttp\json_decode($data['fund_bill_list'], true); } if (isset($data['voucher_detail_list']) && ! empty($data['voucher_detail_list'])) { $retData['voucher_detail_list'] = \GuzzleHttp\json_decode($data['voucher_detail_list'], true); } return $retData; } protected function replyNotify($flag, $msg = '') { if ($flag) { return 'success'; } else { Log::error('支付宝回调通知：' . $msg); return 'fail'; } } protected function getTradeStatus($status) { if (in_array($status, ['TRADE_SUCCESS', 'TRADE_FINISHED'])) { return Config::TRADE_STATUS_SUCC; } else { return Config::TRADE_STATUS_FAILD; } } protected function verifySign(array $data) { $signType = strtoupper($data['sign_type']); $sign = $data['sign']; $values = ArrayUtil::removeKeys($data, ['sign', 'sign_type']); $values = ArrayUtil::paraFilter($values); $values = ArrayUtil::arraySort($values); $preStr = ArrayUtil::createLinkstring($values); if ($signType === 'RSA') { $rsa = new RsaEncrypt($this->config->rsaAliPubKey); return $rsa->rsaVerify($preStr, $sign); } elseif ($signType === 'RSA2') { $rsa = new Rsa2Encrypt($this->config->rsaAliPubKey); return $rsa->rsaVerify($preStr, $sign); } else { return false; } } } 