123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 |
- <?php
- // +----------------------------------------------------------------------
- // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
- // +----------------------------------------------------------------------
- // | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
- // +----------------------------------------------------------------------
- // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
- // +----------------------------------------------------------------------
- // | Author: CRMEB Team <admin@crmeb.com>
- // +----------------------------------------------------------------------
- namespace service;
- use app\wap\model\activity\EventSignUp;
- use app\wap\model\store\StoreOrder;
- use think\Log;
- use think\Request;
- use think\Url;
- use behavior\wechat\PaymentBehavior;
- use service\HookService;
- use service\SystemConfigService;
- class AlipayTradeWapService
- {
- /**
- * 异步通知地址
- * @var string
- */
- protected static $notifyUrl;
- /**
- * 同步跳转地址
- * @var mixed
- */
- protected static $returnUrl;
- /**
- * 支付宝公钥
- * @var mixed
- */
- protected static $alipayPublicKey;
- /**
- * 应用appid
- * @var mixed
- */
- protected static $alipayAppId;
- /**
- * 应用私钥
- * @var mixed
- */
- protected static $alipayPrivateKey;
- /**
- * 编码格式
- * @var mixed|string
- */
- protected static $charset = 'UTF-8';
- /**
- * 请求网管
- * @var string
- */
- protected static $gatewayUrl = 'https://openapi.alipay.com/gateway.do';
- /**
- * 加密方式
- * @var mixed|string
- */
- protected static $signType = 'RSA2';
- /**
- * 是否开启调试模式
- * @var bool
- */
- public static $isDeBug = true;
- /**
- * 获取不到配置信息错误次数
- * @var int
- */
- private static $ErrorCount = 0;
- /**
- * 获取不到配置信息错误最大次数
- * @var int
- */
- private static $ErrorSum = 3;
- /**
- * AlipayTradeWapService constructor.
- * @param array $confing
- * @throws \Exception
- */
- public function __construct($confing = [])
- {
- self::$ErrorCount++;
- if (self::$ErrorCount >= self::$ErrorSum) return exception('请配置支付宝公钥私钥APPID');
- if ((!self::$alipayAppId || !self::$alipayPublicKey || !self::$alipayPrivateKey) && !$confing) self::confing(true);
- if (isset($confing['returnUrl'])) self::$returnUrl = $confing['returnUrl'];
- if (isset($confing['notifyUrl'])) self::$returnUrl = $confing['notifyUrl'];
- if (isset($confing['signType'])) self::$signType = $confing['signType'];
- if (isset($confing['charset'])) self::$charset = $confing['charset'];
- if (isset($confing['alipay_app_id'])) self::$alipayAppId = $confing['alipay_app_id'];
- if (isset($confing['alipay_public_key'])) self::$alipayPublicKey = $confing['alipay_public_key'];
- if (isset($confing['alipay_private_key'])) self::$alipayPrivateKey = $confing['alipay_private_key'];
- if (!self::$alipayAppId || !self::$alipayPublicKey || !self::$alipayPrivateKey) exception('请配置支付宝公钥私钥APPID');
- self::$ErrorCount = 0;
- }
- /**
- * 设置加密方式
- * @param $signType
- * @return $this
- */
- public function setSignType($signType)
- {
- self::$signType = $signType;
- return $this;
- }
- /**
- * 设置同步回调地址
- * @param $returnUrl
- * @return $this
- */
- public function setReturnUrl($returnUrl)
- {
- self::$returnUrl = $returnUrl;
- return $this;
- }
- /**
- * 设置异步回调地址
- * @param $notifyUrl
- */
- public function setNotifyUrl($notifyUrl)
- {
- self::$notifyUrl = $notifyUrl;
- return $this;
- }
- /**
- * 设置业务参数
- * @param array $biz_content
- * @return string
- */
- protected static function setBizContent(array $biz_content = [])
- {
- if (isset($biz_content['passback_params'])) $biz_content['passback_params'] = urlencode($biz_content['passback_params']);
- if (isset($biz_content['trade_no']) && empty($biz_content['trade_no'])) unset($biz_content['trade_no']);
- $bizContent = json_encode($biz_content);
- //打印业务参数
- self::$isDeBug && self::WriteLog($bizContent);
- return $bizContent;
- }
- /**
- * 获取同步回调地址
- * @return mixed
- */
- public function getReturnUrl()
- {
- return self::$returnUrl;
- }
- /**
- * 获取异步回调地址
- * @return mixed
- */
- public function getNotifyUrl()
- {
- return self::$notifyUrl;
- }
- /**
- * 读取系统配置赋值给静态变量 并加载支付宝官方支付sdk
- * @param bool $isReturn
- * @return AlipayTradeWapService
- */
- public static function confing($isReturn = false)
- {
- $confing = SystemConfigService::more([
- 'alipay_public_key',
- 'alipay_app_id',
- 'alipay_private_key',
- ]);
- self::$alipayAppId = isset($confing['alipay_app_id']) ? trim($confing['alipay_app_id']) : '';
- self::$alipayPublicKey = isset($confing['alipay_public_key']) ? trim($confing['alipay_public_key']) : '';
- self::$alipayPrivateKey = isset($confing['alipay_private_key']) ? trim($confing['alipay_private_key']) : '';
- self::$returnUrl = SystemConfigService::get('site_url') . Url::build('wap/Alipay/alipay_success_synchro');
- self::$notifyUrl = SystemConfigService::get('site_url') . Url::build('wap/Alipay/alipay_success_notify');
- vendor('alipay.AopSdk');
- if ($isReturn == false) return new self;
- }
- /**
- * 静态调用初始化数据
- * @return AlipayTradeWapService
- */
- public static function init()
- {
- return self::confing();
- }
- /**
- * 支付宝异步回调
- */
- public static function handleNotify()
- {
- self::init()->AliPayNotify(function ($data, $result) {
- if($result && isset($data->out_trade_no) && $data->passback_params) {
- if($data->passback_params=='special') {
- StoreOrder::where('order_id', $data->out_trade_no)->where('type',0)->update(['trade_no' => $data->trade_no]);
- }elseif ($data->passback_params=='signup'){
- EventSignUp::where('order_id', $data->out_trade_no)->update(['trade_no' => $data->trade_no]);
- }elseif ($data->passback_params=='member'){
- StoreOrder::where('order_id', $data->out_trade_no)->where('type',1)->update(['trade_no' => $data->trade_no]);
- }elseif ($data->passback_params=='goods'){
- StoreOrder::where('order_id', $data->out_trade_no)->where('type',2)->update(['trade_no' => $data->trade_no]);
- }
- HookService::listen('wechat_pay_success', $data, null, true, PaymentBehavior::class);
- }
- });
- }
- /**
- * 支付宝异步回调
- * @param callable $notifyFn 闭包函数 参数1,回调返回的参数,回调结果
- * @return bool
- */
- protected function AliPayNotify(callable $notifyFn)
- {
- $post = Request::instance()->post();
- $result = self::AliPaycheck($post);
- if ($result) {
- //商户订单号
- $post['out_trade_no'] = isset($post['out_trade_no']) ? $post['out_trade_no'] : '';
- //支付宝交易号
- $post['trade_no'] = isset($post['trade_no']) ? $post['trade_no'] : '';
- //交易状态
- $post['trade_status'] = isset($post['trade_status']) ? $post['trade_status'] : '';
- //备注
- $post['attach'] = isset($post['passback_params']) ? urldecode($post['passback_params']) : '';
- //异步回调成功执行
- try {
- if (is_callable($notifyFn)) $notifyFn((object)$post, $result);
- } catch (\Exception $e) {
- self::$isDeBug && self::WriteLog('支付宝支付成功,订单号为:' . $post['out_trade_no'] . '.回调报错:' . $e->getMessage());
- }
- echo 'success';
- } else {
- echo 'fail';
- }
- self::$isDeBug && self::WriteLog($result);
- return true;
- }
- /**
- * 支付宝同步回调
- * @return array
- */
- public function AliPayReturn()
- {
- //获取返回参数
- $get = Request::instance()->get();
- //验签成功与否
- $result = self::AliPaycheck($get);
- //记录日志
- self::$isDeBug && self::WriteLog(compact('result', 'get'));
- return compact('result', 'get');
- }
- /**
- * 验签方法
- * @param $arr 验签支付宝返回的信息,使用支付宝公钥。
- * @return boolean
- */
- protected static function AliPaycheck($post)
- {
- $aop = new \AopClient();
- $aop->alipayrsaPublicKey = self::$alipayPublicKey;
- return $aop->rsaCheckV1($post, self::$alipayPrivateKey, self::$signType);
- }
- /**
- * 初始化参数
- * @param $request
- * @param bool $ispage
- * @return mixed|\SimpleXMLElement|string|\提交表单HTML文本
- * @throws \Exception
- */
- protected static function AopclientRequestExecute($request, $ispage = false)
- {
- $aop = new \AopClient ();
- //网管地址
- $aop->gatewayUrl = self::$gatewayUrl;
- //appid
- $aop->appId = self::$alipayAppId;
- //私钥
- $aop->rsaPrivateKey = self::$alipayPrivateKey;
- //公钥
- $aop->alipayrsaPublicKey = self::$alipayPublicKey;
- //版本
- $aop->apiVersion = "1.0";
- //编码格式
- $aop->postCharset = self::$charset;
- //内容格式
- $aop->format = 'json';
- //加密方式
- $aop->signType = self::$signType;
- // 开启页面信息输出
- $aop->debugInfo = true;
- if ($ispage) {
- $result = $aop->pageExecute($request, "post");
- echo $result;
- } else
- $result = $aop->Execute($request);
- //打开后,将报文写入log文件
- self::$isDeBug && self::WriteLog($result);
- return $result;
- }
- /**
- * alipay.trade.wap.pay 下单支付手机网站支付版本
- * @param $out_trade_no 下单号
- * @param $total_amount 订单金额 单位元
- * @param $subject 订单标题
- * @param $passback_params 订单备注 会原样返回通常用于回调监听函数
- * @param $product_code 销售产品码,商家和支付宝签约的产品码
- * @param $ispage 是否直接输出
- * @return $response 支付宝返回的信息
- */
- public function AliPayWap($out_trade_no, $total_amount, $subject, $passback_params, $product_code = 'QUICK_MSECURITY_PAY', $ispage = true)
- {
- $request = new \AlipayTradeWapPayRequest();
- $request->setNotifyUrl(self::$notifyUrl);
- $request->setReturnUrl(self::$returnUrl);
- $request->setBizContent(self::setBizContent(compact('out_trade_no', 'total_amount', 'subject', 'passback_params', 'product_code')));
- return self::AopclientRequestExecute($request, $ispage);
- }
- /**
- * alipay.trade.query (统一收单线下交易查询)
- * @param $out_trade_no 下单号
- * @param $trade_no 支付宝订单号
- * @param $passback_params 订单备注 会原样返回通常用于回调监听函数
- * @return $response 支付宝返回的信息
- */
- public function AliPayQuery($out_trade_no, $trade_no, $passback_params)
- {
- $request = new \AlipayTradeQueryRequest();
- $request->setBizContent(self::setBizContent(compact('out_trade_no', 'passback_params', 'trade_no')));
- return self::AopclientRequestExecute($request);
- }
- /**
- * alipay.trade.refund (统一收单交易退款接口)
- * @param $out_trade_no 下单订单号
- * @param $trade_no 支付宝订单号
- * @param $refund_amount 退款金额
- * @param $refund_reason 退款说明
- * @param $passback_params 备注
- * @return $response 支付宝返回的信息
- */
- public function AliPayRefund($out_trade_no, $trade_no, $refund_amount, $refund_reason, $passback_params)
- {
- $request = new \AlipayTradeRefundRequest();
- $request->setBizContent(self::setBizContent(compact('out_trade_no', 'trade_no', 'refund_amount', 'refund_reason', 'passback_params', 'product_code')));
- $result=self::AopclientRequestExecute($request);
- $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
- $resultCode = $result->$responseNode->code;
- return $resultCode;
- }
- /**
- * alipay.trade.close (统一收单交易关闭接口)
- * @param $out_trade_no 订单号
- * @param $trade_no 支付宝订单号
- * @return $response 支付宝返回的信息
- */
- public function AliPayClose($out_trade_no, $trade_no)
- {
- $request = new \AlipayTradeCloseRequest();
- $request->setBizContent(self::setBizContent(compact('out_trade_no', 'trade_no')));
- return self::AopclientRequestExecute($request);
- }
- /**
- * 写入日志
- * @param $content string | array | object
- * @return boolen
- * */
- public static function WriteLog($content)
- {
- try {
- Log::init([
- 'type' => 'File',
- 'path' => LOG_PATH . 'alipay/'
- ]);
- if (is_array($content)) $content = 'response: ' . var_export($content, true);
- if (is_object($content)) $content = 'response: ' . var_export($content, true);
- Log::write(date('Y-m-d H:i:s', time()) . ' ' . $content);
- } catch (\Exception $e) {
- }
- }
- }
|