Skip to content

Commit 8cef0b6

Browse files
committed
文档: 补充 SDK 使用案例
1 parent cfc7fa4 commit 8cef0b6

1 file changed

Lines changed: 191 additions & 1 deletion

File tree

README.md

Lines changed: 191 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,75 @@ $menu = $official->post('cgi-bin/menu/create', [
8181
]);
8282
```
8383

84+
85+
## 调用约定
86+
87+
SDK 不把官方接口包装成大量固定方法,核心约定是“官方文档 path + 参数数组”:
88+
89+
```php
90+
// GET:第二个参数会作为 query string。
91+
$result = $official->get('cgi-bin/user/get', ['next_openid' => '']);
92+
93+
// POST:第二个参数默认作为 JSON body。
94+
$result = $official->post('cgi-bin/message/custom/send', [
95+
'touser' => 'openid',
96+
'msgtype' => 'text',
97+
'text' => ['content' => 'hello'],
98+
]);
99+
100+
// call:显式指定 HTTP 方法,并可透传 Guzzle options。
101+
$result = $official->call('cgi-bin/menu/get', [], 'GET');
102+
```
103+
104+
调用时需要注意:
105+
106+
| 场景 | 写法 |
107+
|------|------|
108+
| 微信普通接口需要 `access_token` | 默认自动附加。 |
109+
| 微信授权、登录等不需要 `access_token` 的接口 |`['with_token' => false]`|
110+
| POST JSON | 默认行为,直接传 `$params`|
111+
| GET query |`get($path, $query)`|
112+
| 自定义 query + JSON body | `post($path, $body, ['query' => [...], 'json' => $body])`|
113+
| 表单提交或原始 body | 透传 Guzzle 的 `form_params``body`|
114+
115+
示例:小程序登录接口不需要 access token,应该关闭自动 token:
116+
117+
```php
118+
$session = $wxapp->get('sns/jscode2session', [
119+
'appid' => 'wx_appid',
120+
'secret' => 'app_secret',
121+
'js_code' => 'login_code',
122+
'grant_type' => 'authorization_code',
123+
], ['with_token' => false]);
124+
```
125+
126+
## 配置来源示例
127+
128+
生产项目通常从数据库或配置中心读取账号配置,再使用 `fromArray()` 构造配置对象:
129+
130+
```php
131+
use We\Client;
132+
use We\Config\WechatPlatformConfig;
133+
use We\Support\FileCacheStore;
134+
135+
$row = [
136+
'appid' => 'wx_appid',
137+
'appsecret' => 'app_secret',
138+
'token' => 'message_token',
139+
'encoding_aes_key' => 'encoding_aes_key',
140+
'storage_scope' => 'tenant:10001:account:20002',
141+
];
142+
143+
$client = new Client(
144+
cache: new FileCacheStore(__DIR__ . '/runtime/wechat-cache'),
145+
cacheKeyPrefix: 'my_project_prod',
146+
);
147+
148+
$official = $client->wechatPlatform(WechatPlatformConfig::fromArray($row));
149+
```
150+
151+
`cacheKeyPrefix` 建议按项目和环境区分,例如 `mall_prod``mall_test``storage_scope` 建议按租户、账号或业务线区分,避免同一 appid 在不同业务上下文中复用缓存。
152+
84153
## 入口 Client
85154

86155
```php
@@ -289,6 +358,8 @@ $plain = $official->post('decrypt_message', [
289358

290359
## 微信小程序
291360

361+
登录换取 `openid``session_key`
362+
292363
```php
293364
use We\Config\WechatWxappConfig;
294365

@@ -297,12 +368,24 @@ $wxapp = $client->wechatWxapp(new WechatWxappConfig(
297368
appSecret: 'app_secret',
298369
));
299370

300-
$result = $wxapp->get('sns/jscode2session', [
371+
$session = $wxapp->get('sns/jscode2session', [
372+
'appid' => 'wx_appid',
373+
'secret' => 'app_secret',
301374
'js_code' => 'login_code',
302375
'grant_type' => 'authorization_code',
376+
], ['with_token' => false]);
377+
```
378+
379+
获取手机号:
380+
381+
```php
382+
$phone = $wxapp->post('wxa/business/getuserphonenumber', [
383+
'code' => 'phone_code_from_client',
303384
]);
304385
```
305386

387+
如果官方接口返回图片、文件等二进制内容,默认 `post()` 会按 JSON 响应解析,不适合直接处理;建议注入自定义 Guzzle 客户端或在业务侧扩展专用下载方法。
388+
306389
## 微信开放平台
307390

308391
```php
@@ -405,6 +488,113 @@ $page = $pay->post('page', [
405488
]);
406489
```
407490

491+
492+
## 常见业务案例
493+
494+
### 公众号:创建菜单并发送客服消息
495+
496+
```php
497+
$official->post('cgi-bin/menu/create', [
498+
'button' => [
499+
[
500+
'name' => '服务',
501+
'sub_button' => [
502+
['type' => 'view', 'name' => '官网', 'url' => 'https://example.com'],
503+
['type' => 'click', 'name' => '帮助', 'key' => 'HELP'],
504+
],
505+
],
506+
],
507+
]);
508+
509+
$official->post('cgi-bin/message/custom/send', [
510+
'touser' => 'openid',
511+
'msgtype' => 'text',
512+
'text' => ['content' => '您好,客服消息已发送。'],
513+
]);
514+
```
515+
516+
### 公众号:网页授权 URL 与用户资料
517+
518+
```php
519+
$redirectUri = 'https://example.com/oauth/callback';
520+
$url = 'https://open.weixin.qq.com/connect/oauth2/authorize?' . http_build_query([
521+
'appid' => 'wx_appid',
522+
'redirect_uri' => $redirectUri,
523+
'response_type' => 'code',
524+
'scope' => 'snsapi_userinfo',
525+
'state' => 'state-value',
526+
]) . '#wechat_redirect';
527+
528+
$oauth = $official->get('sns/oauth2/access_token', [
529+
'appid' => 'wx_appid',
530+
'secret' => 'app_secret',
531+
'code' => $code,
532+
'grant_type' => 'authorization_code',
533+
], ['with_token' => false]);
534+
535+
$user = $official->get('sns/userinfo', [
536+
'access_token' => $oauth['access_token'],
537+
'openid' => $oauth['openid'],
538+
'lang' => 'zh_CN',
539+
], ['with_token' => false]);
540+
```
541+
542+
### 开放平台:授权回调后保存授权方 Token
543+
544+
```php
545+
$componentToken = $service->componentAccessToken($componentVerifyTicket);
546+
$auth = $service->queryAuth($componentToken, $authorizationCode);
547+
548+
$authorization = $auth['authorization_info'] ?? [];
549+
$authorizerAppid = (string)($authorization['authorizer_appid'] ?? '');
550+
551+
// 业务系统应把 authorizer_refresh_token 保存到数据库,后续 StoreTokenInterface 会读取它。
552+
$repository->saveAuthorizerToken($authorizerAppid, $authorization);
553+
```
554+
555+
### 微信支付:创建 JSAPI 订单
556+
557+
```php
558+
$order = $payment->post('v3/pay/transactions/jsapi', [
559+
'appid' => 'wx_appid',
560+
'mchid' => 'mch_id',
561+
'description' => '测试订单',
562+
'out_trade_no' => 'T202605020001',
563+
'notify_url' => 'https://example.com/wechat-pay/notify',
564+
'amount' => ['total' => 1, 'currency' => 'CNY'],
565+
'payer' => ['openid' => 'openid'],
566+
]);
567+
```
568+
569+
前端调起支付需要的 `paySign` 可由业务系统使用返回的 `prepay_id` 再按微信支付文档签名生成。SDK 只负责 APIv3 请求签名、回调验签与资源解密。
570+
571+
### 支付宝:电脑网站支付与退款
572+
573+
```php
574+
$page = $pay->post('page', [
575+
'out_trade_no' => 'P202605020001',
576+
'total_amount' => '0.01',
577+
'subject' => '测试订单',
578+
'product_code' => 'FAST_INSTANT_TRADE_PAY',
579+
], [
580+
'return_url' => 'https://example.com/alipay/return',
581+
'notify_url' => 'https://example.com/alipay/notify',
582+
]);
583+
584+
$refund = $pay->post('refund', [
585+
'out_trade_no' => 'P202605020001',
586+
'refund_amount' => '0.01',
587+
'refund_reason' => '用户退款',
588+
]);
589+
```
590+
591+
## 框架集成建议
592+
593+
- 在 Laravel、Hyperf、Symfony 等框架中,建议把 `Client` 注册为容器服务,缓存实现接入框架 Redis 或 Cache 组件。
594+
- 多租户系统应把租户 ID、账号 ID 放入 `storage_scope``cacheKeyPrefix`,保证 token 缓存隔离。
595+
- 密钥、证书、APIv3 Key、支付宝私钥应由业务系统加密保存,运行时解密后传入配置对象。
596+
- 日志中不要记录 app secret、access token、refresh token、私钥、证书、回调密文和支付签名。
597+
408598
## 异常处理
409599

410600
SDK 抛出的异常基类为:

0 commit comments

Comments
 (0)