插件功能页从小程序基础库版本 2.1.0 开始支持。
某些接口不能在插件中直接调用(如 wx.login),但插件开发者可以使用插件功能页的方式来实现功能。目前,插件功能页包括:
要使用插件功能页,需要先激活功能页特性,配置对应的功能页函数,再使用 functional-page-navigator 组件跳转到插件功能页,从而实现对应的功能。详情请参考下文。
开始开发之前,我们需要知道,插件功能页是指 插件所有者小程序 中的一个特殊页面。
插件所有者小程序,指的是与插件 AppID 相同的小程序。例如,“小程序示例”小程序开发了一个“小程序示例插件”,那么无论这个插件被哪个小程序使用,这个插件的 插件所有者小程序 都是“小程序示例”。下文中会继续使用 插件所有者小程序 这个说法。
通常,在开始使用插件功能页的时候,需要开启两个开发者工具窗口,其中一个打开插件项目,另一个打开插件所有者小程序的小程序项目。例如,一个打开“小程序示例插件”项目,另一个打开“小程序示例”项目。
这两个窗口,前者用于编辑插件,后者用于编辑插件所有者小程序。下文中所有需要编辑插件所有者小程序的内容,都是在后者中进行。
要在插件中调用插件功能页,需要先激活插件所有者小程序的功能页特性。具体来说,在插件所有者小程序的 app.json 文件中添加 functionalPages 定义段,并令其值为 true ,例如:
代码示例:
{
"functionalPages": {
"independent": true
}
}
目前,兼容旧式写法:
{
"functionalPages": true
}
旧式写法将在未来将被移除支持,未来将不能编译上传。
这两种写法的区别在于,新式的写法 "independent": true 会使得插件功能页的代码独立于其他代码,这意味着插件功能页可以被独立下载、加载,具有更好的性能表现。 但也同时使得插件功能页目录 functional-pages/ (支付功能页会使用其中的文件)不能 require 这个目录以外的文件(反之亦然:这个目录以外的文件也不能调用这个目录内的)。
注意,新增或改变这个字段时,需要这个小程序发布新版本,才能在正式环境中使用插件功能页。
功能页不能使用 wx.navigateTo 来进行跳转,而是需要一个名为 functional-page-navigator 的组件。以获取用户信息为例,可以在插件中放置如下的 functional-page-navigator:
代码示例:
<functional-page-navigator name="loginAndGetUserInfo" args="" version="develop" bind:success="loginSuccess">
<button>登录到插件</button>
</functional-page-navigator>
用户在点击这个 navigator 时,会自动跳转到插件所有者小程序的对应功能页。功能页会提示用户进行登录或其他相应的操作。操作结果会以组件事件的方式返回。
functional-page-navigator 的参数和详细使用方法可以参考组件说明 。
从小程序基础库版本 2.4.0 开始,支持插件所有者小程序跳转到自己的功能页。在基础库版本低于 2.4.0 时,点击跳转到自己的功能页的 functional-page-navigator 将没有任何反应。
目前,功能页的跳转目前不支持在开发者工具中调试,请在真机上测试。初次进行真机开发测试时,通常步骤如下:
注意:functional-page-navigator 的 version=develop 仅用于调试,因此在插件提审前,需要:
用户信息功能页用于帮助插件获取用户信息,包括 openid 和昵称等,相当于 wx.login 和 wx.getUserInfo 的功能。
此外,自基础库版本 2.3.1 起,用户在这个功能页中授权之后,插件就可以直接调用 wx.login 和 wx.getUserInfo 。无需再次进入功能页获取用户信息。自基础库版本 2.6.3 起,可以使用 wx.getSetting 来查询用户是否授权过。
用户信息功能页使用 functional-page-navigator 进行跳转时,对应的参数 name 应为固定值 loginAndGetUserInfo,其余参数与 wx.getUserInfo 相同,具体来说:
args参数说明:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
withCredentials | Boolean | 否 | 是否带上登录态信息 |
lang | String | 否 | 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。默认为en。 |
timeout | Number | 否 | 超时时间,单位 ms |
注:当 withCredentials 为 true 时,返回的数据会包含 encryptedData, iv 等敏感信息。
bindsuccess返回参数说明:
参数 | 类型 | 说明 |
---|---|---|
code | String | 同 wx.login 获得的用户登录凭证(有效期五分钟)。开发者需要在开发者服务器后台调用 api,使用 code 换取 openid 和 session_key 等信息 |
errMsg | String | 调用结果 |
userInfo | OBJECT | 用户信息对象,不包含 openid 等敏感信息 |
rawData | String | 不包括敏感信息的原始数据字符串,用于计算签名。 |
signature | String | 使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息,参考文档 signature。 |
encryptedData | String | 包括敏感数据在内的完整用户信息的加密数据,详细见加密数据解密算法 |
iv | String | 加密算法的初始向量,详细见加密数据解密算法 |
userInfo参数说明:
参数 | 类型 | 说明 |
---|---|---|
nickName | String | 用户昵称 |
avatarUrl | String | 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表132*132正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。 |
gender | String | 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知 |
city | String | 用户所在城市 |
province | String | 用户所在省份 |
country | String | 用户所在国家 |
language | String | 用户的语言,简体中文为zh_CN |
代码示例:
<!--plugin/components/hello-component.wxml-->
<functional-page-navigator
name="loginAndGetUserInfo"
args="{{ args }}"
version="develop"
bind:success="loginSuccess"
bind:fail="loginFail"
>
<button class="login">登录到插件</button>
</functional-page-navigator>
// plugin/components/hello-component.js
Component({
properties: {},
data: {
args: {
withCredentials: true,
lang: 'zh_CN'
}
},
methods: {
loginSuccess: function (res) {
console.log(res.detail);
},
loginFail: function (res) {
console.log(res);
}
}
});
用户点击该 navigator 后,将跳转到如下的用户信息功能页:
在微信开发者工具中查看示例:
支付功能页用于帮助插件完成支付,相当于 wx.requestPayment 的功能。
需要注意的是:插件使用支付功能,需要进行额外的权限申请,申请位置位于管理后台的“小程序插件 -> 基本设置 -> 支付能力”设置项中。另外,无论是否通过申请,主体为个人小程序在使用插件时,都无法正常使用插件里的支付功能。
支付功能页使用 functional-page-navigator 进行跳转时,对应的参数 name 应为固定值 requestPayment,其他参数如下:
args参数说明:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
fee | Number | 是 | 需要显示在页面中的金额,单位为分 |
paymentArgs | Object | 否 | 任意数据,传递给功能页中的响应函数 |
currencyType | String | 否 | 需要显示在页面中的货币符号的代码,默认为 CNY |
currencyType 的合法值:
值 | 说明 | 最低版本 |
---|---|---|
CNY | 货币符号 yen | |
USD | 货币符号 US$ | |
JPY | 货币符号 Jyen | |
EUR | 货币符号 EUR | |
HKD | 货币符号 HK$ | |
GBP | 货币符号 £ | |
AUD | 货币符号 A$ | |
MOP | 货币符号 MOP$ | |
KRW | 货币符号 |
代码示例:
<!-- plugin/components/pay.wxml -->
<!-- 上线时,version 应改为 "release",并确保插件所有者小程序已经发布 -->
<functional-page-navigator
version="develop"
name="requestPayment"
args="{{ args }}"
bind:success="paymentSuccess"
bind:fail="paymentFailed"
>
<button class="payment-button">支付 0.01 元</button>
</functional-page-navigator>
// plugin/components/pay.js
Component({
data: {
args: {
fee: 1, // 支付金额,单位为分
paymentArgs: 'A', // 将传递到功能页函数的自定义参数
currencyType: 'USD' // 货币符号,页面显示货币简写 US$
}
},
methods: {
// 支付成功的回调接口
paymentSuccess: function (e) {
console.log(e);
e.detail.extraData.timeStamp // 用 extraData 传递数据,详见下面功能页函数代码
},
// 支付失败的回调接口
paymentFailed: function (e) {
console.log(e);
}
}
})
用户点击该 navigator 后,将跳转到如下的支付功能页:
支付功能页需要插件开发者在插件所有者小程序中提供一个函数来响应插件中的支付调用。即,在插件中跳转到支付功能页时,这个函数就会在合适的时机被调用,来帮助完成支付。如果不提供功能页函数,功能页调用将通过 fail 事件返回失败。
支付功能页函数应以导出函数的形式提供在插件所有者小程序的根目录下的 functional-pages/request-payment.js 文件中,名为 beforeRequestPayment。该函数应接收两个参数:
参数名 | 类型 | 说明 |
---|---|---|
paymentArgs | Object | 即通过 functional-page-navigator 的 arg 参数中的 paymentArgs 字段传递到功能页的自定义数据 |
callback | Function | 回调函数,调用该函数后,小程序将发起支付(类似于 wx.requestPayment) |
callback函数的参数:
参数名 | 类型 | 说明 |
---|---|---|
error | Object | 失败信息,若无失败,应返回 null
|
requestPaymentArgs | Object | 支付参数,用于调用 wx.requestPayment,参数如下 |
reqeustPaymentArgs 的参数:
用于发起支付,和 wx.requestPayment 的参数相同,但没有回调函数(success, fail, complete):
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
timeStamp | String | 是 | 时间戳从1970年1月1日00:00:00至今的秒数,即当前的时间 |
nonceStr | String | 是 | 随机字符串,长度为32个字符以下。 |
package | String | 是 | 统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*** |
signType | String | 是 | 签名算法,暂支持 MD5 |
paySign | String | 是 | 签名,具体签名方案参见小程序支付接口文档; |
extraData | any | 否 | 由开发者决定的自定义数据段,该字段将被无修改地透传到支付成功的回调参数中,具体见代码示例中的使用方法。基础库 2.9.1 开始支持 |
了解更多信息,请查看微信支付接口文档
功能页函数代码示例:
// functional-pages/request-payment.js
exports.beforeRequestPayment = function (paymentArgs, callback) {
// 注意:
// 功能页函数(这个函数)不应 require 其他非 functional-pages 目录中的文件,
// 其他非 functional-pages 目录中的文件也不应 require 这个目录中的文件,
// 这样的 require 调用在未来将不被支持。
//
// 同在 functional-pages 中的文件可以 require
var getOpenIdURL = require('./URL').getOpenIdURL;
var paymentURL = require('./URL').paymentURL;
// 自定义的参数,此处应为从插件传递过来的 'A'
var customArgument = paymentArgs.customArgument;
// 第一步:调用 wx.login 方法获取 code,然后在服务端调用微信接口使用 code 换取下单用户的 openId
// 具体文档参考 https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html?t=20161230#wxloginobject
wx.login({
success: function (data) {
wx.request({
url: getOpenIdURL,
data: { code: data.code },
success: function (res) {
// 拉取用户 openid 成功
// 第二步:在服务端调用支付统一下单,返回支付参数。这里的开发和普通的 wx.requestPayment 相同
// 文档可以参考 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_4&index=3
wx.request({
url: paymentURL,
data: { openid: res.data.openid },
method: 'POST',
success: function (res) {
console.log('unified order success, response is:', res);
var payargs = res.data.payargs;
// 第三步:调用回调函数 callback 进行支付
// 在 callback 中需要返回两个参数: err 和 requestPaymentArgs:
// err 应为 null (或者一些失败信息);
// requestPaymentArgs 将被用于调用 wx.requestPayment,除了 success/fail/complete 不被支持外,
// 应与 wx.requestPayment 参数相同。
var error = null;
var requestPaymentArgs = {
timeStamp: payargs.timeStamp,
nonceStr: payargs.nonceStr,
package: payargs.package,
signType: payargs.signType,
paySign: payargs.paySign,
extraData: { // 用 extraData 传递自定义数据
timeStamp: payargs.timeStamp
},
};
callback(error, requestPaymentArgs);
}
});
},
fail: function (res) {
console.log('拉取用户openid失败,将无法正常使用开放接口等服务', res);
// callback 第一个参数为错误信息,返回错误信息
callback(res);
}
});
},
fail: function (err) {
console.log('wx.login 接口调用失败,将无法正常使用开放接口等服务', err)
// callback 第一个参数为错误信息,返回错误信息
callback(err);
}
});
}
注意:功能页函数不应 require 其他非 functional-pages 目录中的文件,其他非 functional-pages 目录中的文件也不应 require 这个目录中的文件。这样的 require 调用在未来将不被支持。
这个目录和文件应当被放置在插件所有者小程序代码中(而非插件代码中),它是插件所有者小程序的一部分(而非插件的一部分)。 如果需要新增或更改这段代码,需要发布插件所有者小程序,才能在正式版中生效;需要重新预览插件所有者小程序,才能在开发版中生效。
收货地址功能页用于展示用户的收货地址列表,用户可以选择其中的收货地址。自基础库版本 2.4.0 开始支持。
用户信息功能页使用 functional-page-navigator 进行跳转时,对应的参数 name 应为固定值 chooseAddress ,返回参数与 wx.chooseAddress 相同。
bindsuccess返回参数说明:
属性 | 类型 | 说明 | 最低版本 |
---|---|---|---|
userName | string | 收货人姓名 | |
postalCode | string | 邮编 | |
provinceName | string | 国标收货地址第一级地址 | |
cityName | string | 国标收货地址第一级地址 | |
countyName | string | 国标收货地址第一级地址 | |
detailInfo | string | 详细收货地址信息 | |
nationalCode | string | 收货地址国家码 | |
telNumber | string | 收货人手机号码 | |
errMsg | string | 错误信息 |
代码示例:
<!--plugin/components/hello-component.wxml-->
<functional-page-navigator
name="chooseAddress"
version="develop"
bind:success="onSuccess"
bind:fail="onFail"
>
<button>选择收货地址</button>
</functional-page-navigator>
// plugin/components/hello-component.js
Component({
methods: {
onSuccess: function (res) {
console.log(res.detail);
},
onFail: function (res) {
console.log(res);
}
}
});
(c) 2024 chaojicainiao.com MIT license