You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
49 lines
1.4 KiB
49 lines
1.4 KiB
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Illuminate\Support\Facades\Http;
|
|
use RuntimeException;
|
|
|
|
class WeChatMiniProgramService
|
|
{
|
|
/**
|
|
* @return array{openid: string, unionid?: string, session_key: string}
|
|
*/
|
|
public function codeToSession(string $code): array
|
|
{
|
|
$appId = config('services.wechat.mini_program.app_id');
|
|
$secret = config('services.wechat.mini_program.secret');
|
|
|
|
if (! $appId || ! $secret) {
|
|
throw new RuntimeException('微信小程序 AppID/Secret 未配置');
|
|
}
|
|
|
|
$response = Http::timeout(10)->get('https://api.weixin.qq.com/sns/jscode2session', [
|
|
'appid' => $appId,
|
|
'secret' => $secret,
|
|
'js_code' => $code,
|
|
'grant_type' => 'authorization_code',
|
|
]);
|
|
|
|
$payload = $response->json();
|
|
if (! is_array($payload)) {
|
|
throw new RuntimeException('微信登录响应异常');
|
|
}
|
|
|
|
if (! empty($payload['errcode'])) {
|
|
throw new RuntimeException((string) ($payload['errmsg'] ?? '微信登录失败'));
|
|
}
|
|
|
|
if (empty($payload['openid'])) {
|
|
throw new RuntimeException('微信登录未返回 openid');
|
|
}
|
|
|
|
return [
|
|
'openid' => (string) $payload['openid'],
|
|
'unionid' => isset($payload['unionid']) ? (string) $payload['unionid'] : null,
|
|
'session_key' => (string) ($payload['session_key'] ?? ''),
|
|
];
|
|
}
|
|
}
|