nizerin/baidu-mini-program-sdk

百度小程序第三方 PHP SDK,助力智能小程序开发。

1.0.0 2019-05-24 11:39 UTC

This package is auto-updated.

Last update: 2020-11-24 06:57:37 UTC


README

68747470733a2f2f736d61727470726f6772616d2e62616964752e636f6d2f646f63732f696d672f6c6f676f2e706e67

🐾 百度小程序第三方 PHP SDK,遵循 PSR-7、支持 PHP 5.4,助力智能小程序开发。

🎉 支付宝开放平台第三方 PHP SDK微信小程序转百度小程序注意事项

License PHP from Packagist Packagist Build Status Coverage Status StyleCI

主要目的

目前,百度智能小程序暂时未推出官方 PHP SDK,而仅有的百度收银台 SDK 也只具备生成、验证签名功能,不足以支撑实际开发。

本项目着眼于「小程序」,集成以下功能。

  1. 登录
  2. 解密
  3. 模版消息(又称「消息模板」)
  4. 支付(百度收银台)
  5. 支付通知
  6. 深入

如何使用

墙裂建议:阅读以下文档时,请同时阅读对应方法、类的 PHPDoc,我们准备了详细的参考链接和说明。

准备

  1. 安装。

    composer require nizerin/baidu-mini-program-sdk

    Composer 中国镜像近期处于维护状态;若无法安装,建议使用原版 Packagist 或使用 Laravel-China 镜像

  2. 创建 BaiduClient

    use BaiduMiniProgram;
    
    $app = new BaiduClient('App Key', 'App Secret');

    App Key / App Secret 可通过 「小程序开发者后台」-「智能小程序首页」-「设置」-「开发设置」查看。

    BaiduClient 通常情况会贯穿整条业务,除非你须要在同一套代码内处理多个小程序,否则只需在初始化阶段创建一次即可。

    如无特殊说明,以下 $app 均为此处的 BaiduClient 实例。

登录

详细流程 官方文档 解释得十分详尽,遵循 OAuth 2.0、过程类似微信,在此不再赘述。

例如:小程序端通过 swan.login 得到 code,随后使用 swan.request 发送请求,将 code 发至我方服务端。

我方服务端示例代码如下。

$credential = $app->session($code);

若成功,$credential 为数组,格式如下。

{
    "openid": "ABCDEFG123",
    "session_key": "xxxxxx"
}

若失败,则会抛出 BaiduResponseException

如无特殊说明,以下 $credential 均为此返回值。

解密

智能小程序可以通过各种前端接口获取百度提供的开放数据,而这些数据返回给小程序时是加密过的。

例如:小程序端通过 swan.getUserInfo 得到 dataiv,随后使用 swan.request 发送请求,将其发至我方服务端解密。

我方服务端示例代码如下。

$decrypted = $app->decrypt($data, $iv, $credential['session_key']);

若成功,$decrypted 为解密后的原始数据。

模版消息

在智能小程序开发者后台创建「消息模板」后,即可发送「模板消息」,过程与微信小程序类似。不过,百度小程序支持调用开放接口增删模板消息,这为部分业务场景提供了更加便捷的解决方案。

根据 官方文档, 相关接口本 SDK 调用例子如下。

use BaiduMiniProgram\Services\BaiduTemplate; // 消息模板
use BaiduMiniProgram\Services\BaiduTemplateMessage; // 模板消息

// 获取 BaiduServiceClient 实例,此实例包含 HTTP Client,主要用于发送请求。
$serviceClient = $app->serviceClient();

// 创建 BaiduTemplate 实例,用于管理消息模板。
$template = new BaiduTemplate($serviceClient);
// 调用 $template 相关方法即可。

// 根据模板 ID,发送模板消息,可链式调用。
$data = (new BaiduTemplateMessage($templateId, $serviceClient))
    ->withKeywords([
        'keyword1' => 'foo',
        'keyword2' => 'bar',
    ])
    ->sendTo('小程序用户 Swan ID', 'Scene ID');
// $data 为发送结果,即接口响应的 `data` 字段。

支付

支付部分比较特殊,百度收银台是独立的聚合支付产品线,所以小程序接入稍显复杂,需要单独注册账号并认证。

首先,按照 官方文档 说明,入驻平台、创建服务等。

这里单独说明 设置中心 内几处需要注意的地方。

  1. 生成密钥可使用本 SDK 附带的一键脚本。

    bin/genrsa [密钥生成目录]
  2. 开发者公钥保存后,需要稍等并刷新才会有平台公钥生成。

  3. 平台公钥导出后并非 PEM 格式,无法被 OpenSSL 正确识别,需进行转换;同样可使用 SDK 附带的脚本。

    bin/wrap-key <单行密钥文本>

截至 2018.10.15,我司提交的百度支付认证审核已持续一周处在「审核中」状态。短时间内支付部分可能无法测试,如有哪位大佬审核通过,欢迎通过 Issue 联系我。

支付通知

在支付成功等场景,百度会主动发起通知请求到我方服务器。我方服务器需对请求签名进行验证,确保此请求来自百度服务器,且数据未被篡改。

同时,百度规定了响应格式,我方接口必须按照指定格式响应请求。

在本 SDK 内,可直接使用如下方式实现以上两点。

$response = $payment->handleNotification(
    function ($parameters) {
        // 在这里编写业务逻辑,发生任何错误只需抛异常即可。
        // $parameters 是成功验证签名,并删除「签名」参数的请求参数数组。
        // 若业务逻辑成功处理,可返回一数组或对象,它将被直接填入响应 `data` 字段。
    },
    function (\Exception $exception) {
        // 在这里记录异常,例如发送到 Bugsnag 或 Sentry、记录至日志等。
        // 切勿输出任何内容,在回调通知请求内,你无法得知输出了啥。
    },
    $_POST // 此参数可忽略,默认即为 $_POST;通常用于非 PHP-FPM 等特殊场景(例如 Swoole)传入请求参数数组。
);

// 根据框架不同,可使用不同的方式输出 $response。
echo $response;

有点类似 JavaScript 的异步回调;在回调函数内,所有异常均会被妥善处理为指定格式响应,你需要关心的只有你的业务逻辑,并在第二个回调函数内记录一切发生的异常即可。

你也可以使用任意 Callable 代替闭包。

深入

本 SDK 遵循「PSR-7 HTTP Message」、HTTP 客户端基于「HTTPlug」,因此你可以任意定制 HTTP 客户端,只要兼容 PSR-7 即可。

有什么好处?

通常情况下,本 SDK 使用内置的 BaiduHttpClient 为默认 HTTP 客户端,此客户端使用 CURL 驱动,代码摘自 php-http/curl-client,经过修改后支持 PHP 5.4。

当然,你可以替换成自己喜欢的客户端,查看受支持的 客户端列表

例如替换为 Guzzle 6.x

composer require guzzlehttp/guzzle:^6.0 # 安装 Guzzle,若已安装可跳过
composer require php-http/discovery # 此扩展包用于自动发现可用的 HTTP 客户端
composer require php-http/guzzle6-adapter # 安装适配器,适配 Guzzle + HTTPlug

或者,你也可以自行编写一个实现 Http\Client\HttpClient 接口的客户端,然后在类构造函数内传入即可。

例如替换为 YourHttpClient

class YourHttpClient implements Http\Client\HttpClient
{
    public function sendRequest(Psr\Http\Message\RequestInterface $request) : Psr\Http\Message\ResponseInterface
    {
        // 发送兼容 PSR-7 RequestInterface 的请求
        // 返回兼容 PSR-7 ResponseInterface 的响应
    }
}

$app = new BaiduClient('App Key', 'App Secret', new YourHttpClient());

// 接下来,当调用 $app 内的方法、需要发送 HTTP 请求时,均会通过 YourHttpClient::sendRequest。

其它资源

感想

在研究小程序支付部分时,居然发现其 签名过程SDK 等几乎与 支付宝开放平台 SDK 一模一样。但从修改日期来看,支付宝是 2014 年,百度是 2016 年,且百度的代码相对规范些。

难不成... 是大佬被挖走了?

协议

MIT

欢迎 Issue / PR。

欢迎关注我们的产品。

68747470733a2f2f692e6c6f6c692e6e65742f323031382f30372f32342f356235366464613736623262612e706e67