插件功能页

插件功能页从微信小程序基础库版本 2.1.0 开始支持。

某些接口不能在插件中直接调用(如 wx.login),但插件开发者可以使用插件功能页的方式来实现功能。目前,插件功能页包括:

  • 获取用户信息,包括 openid 和昵称等(相当于 wx.login 和 wx.getUserInfo 的功能),详见 用户信息功能页;

从基础库版本 2.22.1 起,以下功能页已经废弃,可以直接调用对应接口实现功能:

  • 支付(直接使用 wx.requestPluginPayment)

从基础库版本 2.16.1 起,以下三个功能页已经废弃,可以直接调用对应接口实现功能;原有和新使用的 <functional-page-navigator> 在点击后将不会跳到功能页,而是直接生效:

  • 收货地址功能页(直接使用 wx.chooseAddress)
  • 发票抬头功能页(直接使用 wx.chooseInvoiceTitle)
  • 发票功能页(直接使用 wx.chooseInvoice)

要使用插件功能页,需要先激活功能页特性,配置对应的功能页函数,再使用 functional-page-navigator 组件跳转到插件功能页,从而实现对应的功能。详情请参考下文。

使用插件功能页前,需要确定插件已经 开通,否则可能出现 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 将没有任何反应。

真机开发测试的常规步骤

目前,功能页的跳转目前不支持在开发者工具中调试,请在真机上测试。初次进行真机开发测试时,通常步骤如下:

  1. 在开发者工具上打开插件所有者微信小程序项目,并点击“预览”;
  2. 用测试用的真机扫一下预览二维码,此时会进入插件所有者微信小程序,进入后就可以直接退出这个微信小程序;
  3. 在开发者工具上打开插件项目,将插件中 functional-page-navigator 中的 version 属性设置为 develop
  4. 点击预览可以生成插件预览二维码,用测试用的真机扫码即可预览功能页;如果更改了插件代码,重新生成并扫描插件的预览二维码即可;
  5. 如果过了一段时间之后,跳转功能页时出现“开发版已过期”这样的提示,从第 1 步开始重试一次。

注意functional-page-navigatorversion=develop 仅用于调试,因此在插件提审前,需要:

  1. 确保已发布设置了 "functionalPages": true 的插件所有者微信小程序;
  2. 确保所有的 functional-page-navigator 组件属性设置为 version="release"

功能页常见问题 FAQ

如何正确编辑插件所有者微信小程序?

  • 应该在开发者工具的“微信小程序”类型项目中编辑,而不是在“插件”类型的项目中编辑。比如,“微信小程序示例插件”的所有者微信小程序是“微信小程序示例”,它们的 AppID 都是 wxidxxxxxxxxxxxxxx ,如果是初次开发“微信小程序示例”微信小程序,可以在开发者工具中创建一个微信小程序项目,其 AppID 为 wxidxxxxxxxxxxxxxx ;如果之前开发过“微信小程序示例”微信小程序,直接打开之前的微信小程序项目即可。

点击 functional-page-navigator 之后没有任何反应。

  • 请检查引用插件的微信小程序和插件本身是不是同一个 AppID ,如果是,跳转到自己的功能页需要基础库 2.4.0 支持,否则使用 functional-page-navigator 不会有任何反应。

点击 functional-page-navigator 之后,展示了一个页面提示“页面不存在”。

  • 这种情况是因为插件所有者微信小程序没有正确设置 "functionalPages": true 。如果 functional-page-navigatorversion="develop" ,这部手机需要扫码并进入插件所有者微信小程序一次;如果 version="release" ,请确保包含 "functionalPages": true 的插件所有者微信小程序已被发布。

点击 <functional-page-navigator version="develop"> 之后,弹窗提示“微信小程序开发版已过期”。

  • 遇到这种情况,重新扫码并进入插件所有者微信小程序一次即可。

点击 <functional-page-navigator name="requestPayment"> 之后,展示了一个页面提示“该功能无法使用”。

  • 在使用插件功能页时,微信小程序不能是个人微信小程序,同时,插件也需要额外的步骤申请开通插件支付权限(位于 管理后台 -> 微信小程序插件 -> 基本设置 -> 支付能力 )。

点击 <functional-page-navigator name="requestPayment"> 之后,点击页面中的“支付”按钮,立刻退出了支付功能页。

  • 这通常是因为没有找到功能页函数 beforeRequestPayment ,请检查插件所有者微信小程序的 functional-pages/request-payment.js 文件和其中的 beforeRequestPayment 函数是否存在。

点击 functional-page-navigator 之后,展示了一个仅有返回按钮的页面。

  • 请检查 functional-page-navigator 的 name 属性是否被正确设置。

开发版可以正常跳转,但审核反馈不能跳转。

  • 请发布设置了 "functionalPages": true 的插件所有者微信小程序,且所有的 functional-page-navigator 组件属性设置为 version="release"

Bugs & Tip

  • 功能页是插件所有者微信小程序中的一个特殊页面,开发者不能自定义这个页面的外观。
  • 插件所有者微信小程序本身也可以引用这个插件,此时,functional-page-navigator 组件的 version 属性将不会生效,而是取决于当前运行的插件所有者微信小程序的版本。
  • functional-page-navigator 可以在开发者工具中使用,但功能页的跳转目前不支持在开发者工具中调试,请在真机上测试。
  • Bug:在微信版本 6.6.7 中,功能页被拉起时会触发 App 的部分生命周期并使得功能页启动时间变得比较长。在后续的微信版本中这一行为会发生变更,使 App 生命周期不再被触发。

用户信息功能页

用户信息功能页用于帮助插件获取用户信息,包括 openid 和昵称等,相当于 wx.login 和 wx.getUserInfo 的功能。

在基础库版本 2.3.1 前,用户信息功能页是插件中唯一的获取 code 和用户信息的方式;

自基础库版本 2.3.1 起,用户在该功能页中进行过授权后,插件可以直接调用 wx.login 和 wx.getUserInfo:

  • 授权是以【用户 + 微信小程序 + 插件】为维度进行授权的,即同一个用户在不同微信小程序中使用同一个插件,或同一个微信小程序中使用不同插件,都需要单独进行授权
  • 自基础库版本 2.6.3 起,可以使用 wx.getSetting 来查询用户是否授权过

另外,在满足以下任一条件时,插件可以直接调用 wx.login:

  1. 使用插件的微信小程序与插件拥有相同的 AppId
  2. 使用插件的微信小程序与插件绑定了同一个 微信开放平台 账号,且使用插件的微信小程序与插件均与开放平台账号为同主体或关联主体

不满足以上条件时,wx.login 和 wx.getUserInfo 将返回失败。

调用参数

用户信息功能页使用 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 后,将跳转到如下的用户信息功能页:

用户信息功能页

在微信开发者工具中查看示例

  1. 由于插件需要 appid 才能工作,请填入一个 appid;
  2. 由于当前代码片段的限制,打开该示例后请 手动将 appid 填写到 miniprogram/app.json 中(如下图)使示例正常运行。

手动填写 appid

微信小程序支付功能页

自2025年6月26日起,不再支持新申请插件支付功能,如果要在微信小程序中实现给向第三方支付,请使用「打开半屏微信小程序」功能

支付功能页用于帮助插件完成支付,相当于 wx.requestPayment 的功能。

自基础库版本 2.22.1 起,可以直接在插件中调用 wx.requestPluginPayment 实现跳转支付;通过 functional-page-navigator 跳转将会被废弃。

在满足以下条件时,调用 wx.requestPluginPayment 或点击 navigator 都将直接拉起支付收银台,跳过支付功能页:

  • 微信小程序与插件绑定在同一个 open 平台账号上

  • 微信小程序与插件均为 open 账号的同主体 / 关联主体时。

需要注意的是:插件使用支付功能,需要进行额外的权限申请,申请位置位于 管理后台 的“微信小程序插件 -> 基本设置 -> 支付能力”设置项中。另外,无论是否通过申请,主体为个人微信小程序在使用插件时,都无法正常使用插件里的支付功能。

调用参数

参数说明:

参数名 类型 必填 说明
fee Number 需要显示在页面中的金额,单位为分
paymentArgs Object 任意数据,传递给功能页中的响应函数
currencyType String 需要显示在页面中的货币符号的代码,默认为 CNY

currencyType 的合法值:

说明 最低版本
CNY 货币符号 ¥
USD 货币符号 US$
JPY 货币符号 J¥
EUR 货币符号 €
HKD 货币符号 HK$
GBP 货币符号 £
AUD 货币符号 A$
MOP 货币符号 MOP$
KRW 货币符号 ₩

示例代码

wx.requestPluginPayment 方式

自基础库版本 2.22.1 起,推荐使用该方式。

<!-- plugin/components/pay.wxml -->
<button bindtap="handlePay">支付 0.01 元</button>
// plugin/components/pay.js
Component({
  data: {
    fee: 1,             // 支付金额,单位为分
    paymentArgs: 'A', // 将传递到功能页函数的自定义参数
    currencyType: 'USD' // 货币符号,页面显示货币简写 US$ 
    version: 'develop', // 上线时,version 应改为 "release",并确保插件所有者微信小程序已经发布
  },
  methods: {
    handlePay() {
        const { fee, paymentArgs, currencyType, version } = this.data
        wx.requestPluginPayment({
            fee,
            paymentArgs,
            currencyType,
            version,
            success(r) {
                console.log(r)
            },
            fail(e) {
                console.error(e)
            }
        })
    }
  }
})

functionl-page-navigator 方式(将废弃)

该方式将会被废弃,仅供参考

<!-- plugin/components/pay.wxml -->
<!-- 上线时,version 应改为 "release",并确保插件所有者微信小程序已经发布 -->
<!-- name 参数固定为 "requestPayment" -->
<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);
    }
  }
})

用户调用 wx.requestPluginPayment 或点击 navigator 后,将会进行权限判断,然后直接拉起支付收银台或跳转到如下的支付功能页:

支付功能页

配置功能页函数

支付功能页需要插件开发者在插件所有者微信小程序中提供一个函数来响应插件中的支付调用。即,在插件中跳转到支付功能页或调用 wx.requestPluginPayment 时,这个函数就会在合适的时机被调用,来帮助完成支付。如果不提供功能页函数,功能页调用将通过 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,参数如下

requestPaymentArgs 的参数:

用于发起支付,和 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/doc/v2/merchant/4011938514
          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.16.1 起,该功能页已经废弃,可以直接使用 wx.chooseAddress 实现对应的功能;点击 functional-page-navigator 也将不再进入功能页,直接进入收货地址选择页。

文档

收货地址功能页用于展示用户的收货地址列表,用户可以选择其中的收货地址。自基础库版本 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);
    }
  }
});

发票功能页

从基础库版本 2.16.1 起,该功能页已经废弃,可以直接使用 wx.chooseInvoice 实现对应的功能;点击 functional-page-navigator 也将不再进入功能页,直接进入发票选择页。

文档

发票功能页用于展示用户的发票列表,用户可以选择其中的发票。自基础库版本 2.14.1 开始支持。

调用参数

发票功能页使用 functional-page-navigator 进行跳转时,对应的参数 name 应为固定值 chooseInvoice ,返回参数与 wx.chooseInvoice 相同。

bindsuccess 返回参数说明:

属性 类型 说明
invoiceInfo String 用户选中的发票信息,格式为一个 JSON 字符串,包含三个字段: card_id:所选发票卡券的 cardId,encrypt_code:所选发票卡券的加密 code,报销方可以通过 cardId 和 encryptCode 获得报销发票的信息,app_id: 发票方的 appId。

示例代码

<!--plugin/components/hello-component.wxml-->
  <functional-page-navigator
    name="chooseInvoice"
    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);
    }
  }
});

发票抬头功能页

从基础库版本 2.16.1 起,该功能页已经废弃,可以直接使用 wx.chooseInvoiceTitle 实现对应的功能;点击 functional-page-navigator 也将不再进入功能页,直接进入发票抬头选择页。

文档

发票抬头功能页用于展示用户的发票抬头列表,用户可以选择其中的发票抬头。自基础库版本 2.14.1 开始支持。

调用参数

发票抬头功能页使用 functional-page-navigator 进行跳转时,对应的参数 name 应为固定值 chooseInvoiceTitle ,返回参数与 wx.chooseInvoiceTitle 相同。

bindsuccess 返回参数说明:

属性 类型 说明
type string 抬头类型
title string 抬头名称
taxNumber string 抬头税号
companyAddress string 单位地址
telephone string 手机号码
bankName string 银行名称
bankAccount string 银行账号
errMsg string 错误信息

res.type 的合法值

说明 最低版本
0 单位
1 个人

示例代码

<!--plugin/components/hello-component.wxml-->
  <functional-page-navigator
    name="chooseInvoiceTitle"
    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);
    }
  }
});