MemberAlipayService.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. <?php
  2. namespace app\frontend\modules\member\services;
  3. use app\common\services\Session;
  4. use app\frontend\modules\member\services\MemberService;
  5. use app\common\services\alipay\request\AlipaySystemOauthTokenRequest;
  6. use app\common\services\alipay\request\AlipayUserInfoShareRequest;
  7. use app\common\services\alipay\AopClient;
  8. use app\common\helpers\Url;
  9. use app\frontend\modules\member\models\MemberModel;
  10. use Yunshop\AlipayOnekeyLogin\models\MemberAlipay;
  11. class MemberAlipayService extends MemberService
  12. {
  13. const LOGIN_TYPE = 8;
  14. private $url = "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm";
  15. //支付宝网关
  16. private $alipay_api = "https://openapi.alipay.com/gateway.do";
  17. private $aop;
  18. public function __construct()
  19. {
  20. // parent::__construct();
  21. $this->aop = $this->aopClient();
  22. }
  23. public function login()
  24. {
  25. //商城默认头像
  26. $member_avatar = \Setting::get('shop.member')['headimg'];
  27. $uniacid = \YunShop::app()->uniacid;
  28. // $appId = \YunShop::app()->app_id;
  29. $code = \YunShop::request()->auth_code;
  30. //回调域名
  31. $host = ($_SERVER['REQUEST_SCHEME'] ? $_SERVER['REQUEST_SCHEME'] : 'http') . '://' . $_SERVER['HTTP_HOST'];
  32. $callback = urlencode($host.$_SERVER['PHP_SELF']);
  33. //回调地址
  34. if($_SERVER['QUERY_STRING']) $callback = $callback.'?'.$_SERVER['QUERY_STRING'];
  35. if (empty($code)) {
  36. $this->_setClientRequestUrl();
  37. $alipay_redirect = $this->__CreateOauthUrlForCode($this->aop->appId, $callback);
  38. redirect($alipay_redirect)->send();
  39. exit();
  40. }
  41. $request = new AlipaySystemOauthTokenRequest();
  42. $request->setGrantType("authorization_code");
  43. $request->setCode($code);//这里传入 code
  44. $result = $this->aop->execute($request);
  45. $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
  46. $result = json_decode($result, true);
  47. $user = $result[$responseNode];
  48. if ($user = $result[$responseNode]) {
  49. //第一步获取到支付宝用户user_id,判断商城是否已存在这个用户
  50. //第二步用户已存在则直接登录,不存在则 通过 access_token 获取用户信息添加到支付宝用户表
  51. $userInfo = $this->getUserInfo($user['access_token']);
  52. $alipay_user['openid'] = $userInfo['user_id'];
  53. $alipay_user['nickname'] = $userInfo['nick_name'];
  54. $alipay_user['headimgurl'] = !empty($userInfo['avatar'])?$userInfo['avatar']:$member_avatar;
  55. $alipay_user['sex'] = $userInfo['gender'] == 'F' ? 0 : 1;
  56. $alipay_user['province'] = $userInfo['province'];
  57. $alipay_user['city'] = $userInfo['city'];
  58. $alipay_user['country'] = '';
  59. $member_id = $this->memberLogin($alipay_user);
  60. Session::set('member_id', $member_id);
  61. //添加 yz_member_alipay 表
  62. $bool = MemberAlipay::insertData($userInfo, ['member_id' =>$member_id, 'uniacid' => $uniacid]);
  63. if (!$bool) {
  64. \Log::debug('支付宝用户信息保存失败 user_id:'.$userInfo['user_id'].'会员uid:'.$member_id);
  65. }
  66. /*alipay_system_oauth_token_response" => array:6 [
  67. "access_token" => "authusrB6e094cbc0cd54ed18e69b35e2000aX41"
  68. "alipay_user_id" => "20880051464321899646564260914141"
  69. "expires_in" => 1296000
  70. "re_expires_in" => 2592000
  71. "refresh_token" => "authusrB070ef1be4ccb4c98abd97ca781faaX41"
  72. "user_id" => "2088212325598416
  73. ]*/
  74. } else {
  75. /*error_response" => array:4 [
  76. "code" => "40002"
  77. "msg" => "Invalid Arguments"
  78. "sub_code" => "isv.code-invalid"
  79. "sub_msg" => "授权码code无效"
  80. ]*/
  81. \Log::debug('支付宝授权失败code:'.$result['error_response']['code']);
  82. return show_json(-3, '支付宝授权失败');
  83. }
  84. $redirect_url = $this->_getClientRequestUrl();
  85. redirect($redirect_url)->send();
  86. exit;
  87. //return show_json(1, Session::get('member_id'));
  88. }
  89. private function aopClient()
  90. {
  91. $alipay_set = \Setting::get('plugin.alipay_onekey_login');
  92. $aop = new AopClient;
  93. $aop->gatewayUrl = $this->alipay_api;
  94. $aop->appId = $alipay_set['app']['alipay_appid'];
  95. $aop->rsaPrivateKey = base64_decode($alipay_set['app']['private_key']);
  96. $aop->alipayrsaPublicKey = base64_decode($alipay_set['app']['alipay_public_key']);
  97. $aop->signType= $alipay_set['rsa'] == 1 ? 'RSA' : 'RSA2';
  98. $aop->apiVersion = '1.0';
  99. $aop->format = "json";
  100. $aop->postCharset = "UTF-8";
  101. return $aop;
  102. }
  103. /**
  104. * 根据access_token 获取用户信息
  105. * @param ))
  106. * @return 返回用户信息
  107. */
  108. protected function getUserInfo($access_token)
  109. {
  110. $request = new AlipayUserInfoShareRequest();
  111. $info = $this->aop->execute ($request,$access_token); //这里传入获取的access_token
  112. $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
  113. $json_info = json_decode($info, true);
  114. if (!empty($json_info['error_response'])) {
  115. \Log::debug('支付宝获取用户信息失败code:'.$json_info['error_response']['code']);
  116. return show_json(-3, '支付宝授权失败');
  117. }
  118. return $json_info[$responseNode];
  119. }
  120. public function getFansModel($user_id)
  121. {
  122. $model = MemberAlipay::getUid($user_id);
  123. if (!is_null($model)) {
  124. $model->uid = $model->member_id;
  125. }
  126. return $model;
  127. }
  128. /**
  129. * 设置客户端请求地址
  130. *
  131. * @return string
  132. */
  133. private function _setClientRequestUrl()
  134. {
  135. if (\YunShop::request()->yz_redirect) {
  136. $yz_redirect = base64_decode(\YunShop::request()->yz_redirect);
  137. $redirect_url = $yz_redirect . '&t=' . time();
  138. /* if (preg_match('menu', $yz_redirect)) {
  139. $redirect_url = preg_replace('/menu/', 'redir_menu', $yz_redirect);
  140. } else {
  141. $redirect_url = preg_replace('/from=singlemessage/', 'redir_menu', $yz_redirect);
  142. }
  143. */
  144. Session::set('client_url', $redirect_url);
  145. } else {
  146. Session::set('client_url', '');
  147. }
  148. }
  149. /**
  150. * 获取客户端地址
  151. *
  152. * @return mixed
  153. */
  154. private function _getClientRequestUrl()
  155. {
  156. return Session::get('client_url');
  157. }
  158. /**
  159. * 构造获取token的url连接
  160. * @param string $callback 支付宝服务器回跳的url,需要url编码
  161. * @return 返回构造好的url
  162. */
  163. private function __CreateOauthUrlForCode($appId, $callback, $state = 'info')
  164. {
  165. //return $this->url."?app_id=".$appId."&scope=auth_userinfo&redirect_uri=".$callback."&state=".$state;
  166. return $this->url."?app_id=".$appId."&scope=auth_user&redirect_uri=".$callback."&state=".$state;
  167. }
  168. /**
  169. * 验证登录状态
  170. *
  171. * @return bool
  172. */
  173. public function checkLogged($login = null)
  174. {
  175. return MemberService::isLogged();
  176. }
  177. }