微应用后端开发
1. 接口说明
通用服务端接口封装于公共模块的MiniAppCommonService服务类中,通过注入该服务类获取服务类的实例,使用示例:
@Resource
private MiniAppCommonService miniAppCommonService;
@Resource
private MiniAppPayService miniAppPayService;
ApplicationVo application = miniAppCommonService.getApplication();
// ...在使用服务端接口之前需要先正确配置微应用的appKey和appSecret,该配置主要用于微应用后端向 Mos 服务端发起请求时,对请求参数进行签名,具体的签名方式开发者无需关心,公共服务已经封装好了,开发者注入相应服务后,直接调用具体方法名即可。
1.1 接口 BaseURL
1.2 接口签名
如果直接用 HTTP 的方式调用,请求体 Body 中必须增加以下字段:
- appKey:微应用 App Key
- sign:签名
签名生成规则:将包含appKey在内的所有参数按升序排序然后转换为QueryString的格式(例如 key1=value1&key2=value2...),再在末尾拼接上 secret=appSecret,最后对这个字符串进行 MD5 即得到签名,Java 示例代码如下:
import org.springframework.util.DigestUtils;
/**
* 获取签名
*
* @param request 请求,这里用 Object 作为示例,实际应该替换为请求体对应的类型或请求基类
* @return 签名
*/
public String getSign(Object request) {
// 将请求转换为Key有序的 TreeMap 默认升序,"appKey" 也需要包含在内
Map<String, String> requestSortedMap = JSON.parseObject(JSON.toJSONString(request), new TypeReference<TreeMap<String, String>>() {
});
requestSortedMap.put("appKey", "<your_app_key>");
// 请求转换为 QueryString 格式,如 key1=value1&key2=value2...
StringBuilder qsBuilder = new StringBuilder();
for (Map.Entry<String, String> entry : requestSortedMap.entrySet()) {
// "sign" 或空值不参与签名
if ("sign".equals(entry.getKey()) || entry.getValue() == null || entry.getValue().isEmpty()) {
continue;
}
qsBuilder.append(entry.getKey()).append("=").append(entry.getValue().trim()).append("&");
}
// 在末尾拼接上 "secret=your_app_secret"
qsBuilder.append("secret=").append("<your_app_secret>");
// MD5处理
return DigestUtils.md5DigestAsHex(qsBuilder.toString().getBytes(StandardCharsets.UTF_8));
}2. 登录鉴权
2.1 获取应用信息
API:MiniAppCommonService.getApplication()
HTTP:POST /open-apis/application/v1/getApplication
获取微应用应用信息
参数
无(但仍需要签名)
响应
| 属性 | 类型 | 说明 |
|---|---|---|
| appName | String | 应用名称 |
| appKey | String | 应用key |
| appSecret | String | 应用密匙 |
| description | String | 应用描述 |
| status | Boolean | 应用状态 |
| notifyUrl | String | 应用回调地址 |
2.2 通用登录
API:MiniAppCommonService.miniAppLogin(String code)
公共模块提供的通用登录接口,通过在小程端获取的 code 和 JWT 生成身份令牌。微应用模块新建后会自带一个默认的登录拦截器com.testproject.mos.miniapp.xxx.interceptor.LoginInterceptor在这个拦截器中会校验微应用前端传过来的令牌,微应用前端使用 Bearer token 的格式传递,Http Header:
Authorization: Bearer <token>鉴权通过后,用户可以通过「获取当前用户信息」接口获取登录用户对应的 openid 和语言类型,从而获取微应用自身的用户信息(微应用自身的用户信息需要自己建立用户表,且用户表中必须有一列存储 openid)。
如果通用登录无法满足用户需求,用户可以通过重写登录拦截器,并自行编写登录和获取当前用户信息的接口。
注意:不要修改公共模块的代码
参数
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | String | 是 | 通过微应用 mos.login 获取的 code |
响应 TokenVo
| 属性 | 类型 | 说明 |
|---|---|---|
| token | String | 身份令牌 |
2.3 获取当前用户信息
API:MiniAppCommonService.getMiniAppUser()
公共模块提供的通用获取当前登录用户的方法,需要配合通用登录接口和默认的登录拦截器才可生效。
参数
无(但仍需要签名)
响应 MiniAppUserBo
| 属性 | 类型 | 说明 |
|---|---|---|
| appKey | String | 应用key |
| openid | String | 用户唯一标识 |
| languageType | LanguageEnum | 语言类型 |
2.4 通过 code 换取Mos会话信息
API:MiniAppCommonService.code2session(String code)
HTTP:POST /open-apis/mp/v1/auth/code2session
获取微应用应用信息
参数
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | String | 是 | 通过微应用 mos.login 获取的 code |
响应 MosSessionVo
| 属性 | 类型 | 说明 |
|---|---|---|
| openid | String | 用户唯一标识 |
| sessionKey | String | 会话Key,暂时没用 |
3. 扫码登录
3.1 生成二维码
HTTP:POST /open-apis/mp/v1/auth/getLoginQrCodeUrl
生成小程序扫码登录二维码,过期时间为120s,小程序使用该二维码字符串生成相应的二维码图片
参数 Body
无(但仍需要签名)
响应 Body
| 属性 | 类型 | 说明 |
|---|---|---|
| qrCode | String | 二维码字符串,格式为 https://mos.me/miniapp-open/login/{uuid} |
| uuid | String | 二维码UUID字符串 |
3.2 获取二维码状态
HTTP:POST /open-apis/mp/v1/auth/getLoginQrCodeStatus
获取二维码的状态,当扫描成功后会返回相应的用户信息
参数 Body
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| qrCodeUuid | String | 是 | 二维码UUID字符串 |
响应 Body
| 属性 | 类型 | 说明 |
|---|---|---|
| status | String | 'NO_SCAN': 未扫描 | 'SCAN': 已扫描 |
| mosOpenUserVo | MosOpenUserVo | 用户信息,扫描成功后才会有 |
响应 MosOpenUserVo
| 属性 | 类型 | 说明 |
|---|---|---|
| openId | String | 用户唯一标识 |
| firstName | String | 姓 |
| lastName | String | 名 |
| headPortrait | String | 头像地址 |
4. 支付
在开发支付相关功能之前需要先申请成为Mos商户,获取对应的商户ID(mcId),支付流程需要用到。
4.1 创建预支付订单
API:MiniAppPayService.prepay(CreatePrepayOrderAo ao)
HTTP:POST /open-apis/mp/v1/pay/prepay
创建预支付订单
参数 CreatePrepayOrderAo
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mcId | String | 是 | 商户ID |
| nonceStr | String | 否 | 随机字符串,需保证系统内唯一 |
| desc | String | 否 | 订单描述 |
| outTradeNo | String | 是 | 商户微应用系统订单号 |
| currency | String | 是 | 货币单位 USD-美元 | KHR-瑞尔 |
| totalAmount | String | 是 | 订单金额 |
| notifyUrl | String | 是 | 回调地址 |
| openid | String | 是 | 用户唯一标识 |
| expireTime | String | 否 | 订单失效时间,时间戳,精确到毫秒 |
响应 PrepayOrderVo
| 属性 | 类型 | 说明 |
|---|---|---|
| prepayId | String | 预支付订单ID |
4.2 商户给用户付款
API:MiniAppPayService.payToMiniAppUser(PayToMiniAppUserAo ao)
HTTP:POST /open-apis/mp/v1/pay/payToMiniAppUser
调用接口给用户进行付款
参数 PayToMiniAppUserAo
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| nonceStr | String | 否 | 随机字符串,需保证系统内唯一 |
| outTradeNo | String | 是 | 商户微应用系统订单号 |
| currency | String | 是 | 货币单位 USD-美元 | KHR-瑞尔 |
| amount | String | 是 | 订单金额 |
| openid | String | 是 | 用户唯一标识 |
响应 PayToMiniAppUserVo
| 属性 | 类型 | 说明 |
|---|---|---|
| prepayId | String | 预支付订单ID |
| nonceStr | String | 随机字符串,需保证系统内唯一 |
| outTradeNo | String | 商户微应用系统订单号 |
| paymentNo | String | mos订单号 |
4.3 查询订单
API:MiniAppPayService.orderQuery(OrderQueryAo ao)
HTTP:POST /open-apis/mp/v1/pay/orderQuery
查询订单
参数 OrderQueryAo
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| nonceStr | String | 是 | 随机字符串,需保证系统内唯一 |
| outTradeNo | String | 是 | 商户微应用系统订单号 |
响应 OrderQueryVo
| 属性 | 类型 | 说明 |
|---|---|---|
| openid | String | 用户唯一标识 |
| prepayId | String | 预支付订单ID |
| outTradeNo | String | 商户微应用系统订单号 |
| country | String | 国家编码 |
| currency | String | 货币单位 |
| totalAmount | String | 订单金额 |
| desc | String | 商品描述 |
| status | String | 订单状态 |
| expireTime | Long | 订单失效时间 |
| createTime | Long | 创建时间 |
5. 客服号
5.1 创建客服号
HTTP:POST /open-apis/mp/v1/customerServ/create
创建客服号
参数 Body
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| openid | String | 是 | 用户唯一标识 |
| name | String | 是 | 客服号名称 |
| headPortrait | String | 否 | 客服号头像,没有则自动生成头像 |
响应 Body
| 属性 | 类型 | 说明 |
|---|---|---|
| token | String | 客服号唯一标识,后续的请求需要用到 |
| webHook | String | 客服号webHook地址 |
| name | String | 客服号名称 |
| headPortrait | String | 客服号头像 |
| descriptor | String | 客服号描述 |
| idNumber | String | 客服号唯一Id |
| link | String | 客服号链接 |
5.2 客服号发送消息
HTTP:POST /open-apis/mp/v1/customerServ/{token}/sendMessage
通过客服号的机器人给指定客户发消息(通过入参 content 与msgType的不同字段组合实现)
参数 Path
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| token | String | 是 | 客服号唯一标识 |
参数 Body
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| openid | String | 是 | 用户唯一标识,表示接受消息的用户 |
| content | Content | 是 | 消息内容,详见 Content |
参数 Content
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| msgType | String | 是 | 消息类型:文本消息 TEXT | 卡片消息 CARD |
| text | String | 否 | 消息文本,最大长度5000字符(当 msgType=TEXT 时必填) |
| inlineButtons | List<List<InlineButton>> | 否 | 内联按钮(可用于任意消息类型),详见 InlineButton |
| cardMessage | CardMessage | 否 | 卡片消息体(当 msgType=CARD 时必填),详见 CardMessage |
参数 InlineButton
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| text | String | 是 | 按钮文案,最大长度30个字符 |
| type | String | 是 | 按钮类型 callback回调请求 miniApp小程序跳转 url外部链接跳转或内部链接则在mos打开 |
| data | String | 是 | 按钮数据,开发者自定义内容 |
内联按钮数量限制:
- 每行最多有4个按钮,也就是每个集合最多有4个按钮对象
- 最多不超过40个按钮
内联按钮类型说明:
- callback (回调类型) :用户点击后,通过 webhook 发送至客服号微应用服务端,将按钮的 data 值传递给客服号微应用服务端。
- url (跳转链接类型):点击后将打开浏览器显示指定链接;若为内部链接(如用户、群组、频道等链接),则会在 MosApp 内打开。
- miniApp(微应用跳转类型): 用户点击后将直接进入该绑定的微应用。
内联按钮键值说明:
- 当类型为 callback 时,data 为 客服号微应用服务端配置的字符串;用户点击按钮时,MosApp 会将该 data 内容直接透传给客服号微应用服务端 请求回调入参格式为
{
"reqId": "唯一请求标识",
"data": "data"
}- 当类型为 url 时,data 为 客服号微应用服务端配置的外部 URL 链接或 MosApp 内部链接
- 当类型为 miniApp 时,data 可配置页面路径等信息;打开微应用时,该路径会以参数形式携带在 URL 后。
参数 CardMessage
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | String | 是 | 标题,最大长度50个字符 |
| messageTitle | String | 否 | 消息标题,最大长度50个字符 |
| cover | String | 否 | 封面图,最大长度1000个字符 |
| price | String | 否 | 价格,最大长度30个字符 |
| linePrice | String | 否 | 划线价,最大长度30个字符 |
响应 Body
无
5.3 获取客服号信息
HTTP:POST open-apis/mp/v1/customerServ/getInfo
获取客服号信息
参数 Body
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| token | String | 是 | 客服号唯一标识 |
响应 Body
| 属性 | 类型 | 说明 |
|---|---|---|
| token | String | 客服号唯一标识 |
| webHook | String | 客服号webHook地址 |
| name | String | 客服号名称 |
| headPortrait | String | 客服号头像 |
| descriptor | String | 客服号描述 |
| idNumber | String | 客服号唯一Id |
| link | String | 客服号链接 |
5.4 更新客服号信息
HTTP:POST /open-apis/mp/v1/customerServ/updateInfo
更新客服号信息
参数 Body
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| token | String | 是 | 客服号唯一标识 |
| name | String | 否 | 客服号名称,最大长度30 |
| headPortrait | String | 否 | 客服号头像,最大长度1000 |
| descriptor | String | 否 | 客服号描述,最大长度300 |
| idNumber | String | 否 | 客服号唯一Id,最大长度30 |
注意:
- 客服号名称、客服号头像、客服号描述、客服号唯一Id 至少填写一个
- 客服号唯一Id 为客服号的唯一标识,不能重复
响应 Body
| 属性 | 类型 | 说明 |
|---|---|---|
| token | String | 客服号唯一标识 |
| webHook | String | 客服号webHook地址 |
| name | String | 客服号名称 |
| headPortrait | String | 客服号头像 |
| descriptor | String | 客服号描述 |
| idNumber | String | 客服号唯一Id |
| link | String | 客服号链接 |
5.5 重置客服号token
HTTP:POST /open-apis/mp/v1/customerServ/resetToken
重置客服号token
参数 Body
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| token | String | 是 | 客服号唯一标识 |
响应 Body
| 属性 | 类型 | 说明 |
|---|---|---|
| token | String | 客服号唯一标识 |
| webHook | String | 客服号webHook地址 |
| name | String | 客服号名称 |
| headPortrait | String | 客服号头像 |
| descriptor | String | 客服号描述 |
| idNumber | String | 客服号唯一Id |
| link | String | 客服号链接 |
5.6 设置客服号Webhook
HTTP:POST /open-apis/mp/v1/customerServ/setWebHook
设置客服号Webhook,即回调按钮触发服务端请求地址
参数 Body
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| token | String | 是 | 客服号唯一标识 |
| webHook | String | 是 | 客服号webHook地址,如果为空则表示删除,最大长度300 |
响应 Body
| 属性 | 类型 | 说明 |
|---|---|---|
| token | String | 客服号唯一标识 |
| webHook | String | 客服号webHook地址 |
| name | String | 客服号名称 |
| headPortrait | String | 客服号头像 |
| descriptor | String | 客服号描述 |
| idNumber | String | 客服号唯一Id |
| link | String | 客服号链接 |