分享到朋友圈

从基础库 2.11.3 开始支持

支持平台:AndroidiOS:微信8.0.24及以上版本

可以将微信小程序页面分享到朋友圈。这适合内容型的页面分享,不适合有太多交互的页面分享。

设置分享状态

微信小程序页面默认不能分享到朋友圈,开发者需要主动设置“分享到朋友圈”。要让页面允许分享到朋友圈,需要满足两个条件:

  1. 首先,页面需要设置允许“发送给朋友”。具体可以参考 Page.onShareAppMessage 接口文档
  2. 满足条件 1 后,页面需要设置允许“分享到朋友圈”,同时可以自定义标题、分享图片等。具体可以参考 Page.onShareTimeline 接口文档

满足上面两个条件的页面,就可以被分享到朋友圈了。

单页模式

用户在朋友圈打开分享的微信小程序页面时,并不会真正打开微信小程序,而是进入一个“微信小程序单页模式”的页面。“单页模式”有以下特点:

  1. 在“单页模式”下,页面顶部固定有一个导航栏,标题显示为当前页面 JSON 配置的标题。底部固定有一个操作栏,点击操作栏的“前往微信小程序”可以打开微信小程序的当前页面。顶部导航栏和底部操作栏都不支持自定义样式。
  2. “单页模式”默认运行的是微信小程序页面内容,但由于页面固定有顶部导航栏和底部操作栏,很可能会影响微信小程序页面的布局。因此,请开发者特别注意适配“单页模式”的页面交互,以实现流畅完整的交互体验。
  3. 在“单页模式”下,一些组件或接口会有一定限制,详情见下文单页模式下的限制章节

avatar

页面适配

可以通过判断场景值等于 1154 的方法来进行页面适配。另外,在单页模式下,可以设置顶部导航栏与页面的相交状态,具体参考 navigationBarFit 配置。

还需要注意的是,在单页模式下,wx.getSystemInfo 接口返回的 safeArea 是整个屏幕空间。

单页模式下的限制

微信小程序“单页模式”适用于纯内容展示场景,能实现的交互和接口能力有限,因此存在以下限制:

  1. 页面没有登录态,与登录相关的接口,如 wx.login 都不可用;云开发资源需要开启未登录访问才能在单页模式下使用,详见未登录模式
  2. 不允许跳转到其他页面,包括任何跳转微信小程序页面、跳转其他微信小程序、跳转微信原生页面
  3. 不允许横屏使用
  4. 如果页面包含 tabBar,tabBar 不会渲染,包括自定义 tabBar
  5. 本地存储与微信小程序普通模式不共用

对于一些会产生交互的组件或接口,在点击后调用时,会弹出 toast 提示“请前往微信小程序使用完整服务”。为了获得良好的用户体验,请注意适配单页模式的接口能力,不要大量使用被禁用的接口或组件。

禁用能力列表:

分类 功能点
组件 button open-type 、 camera 、 editor 、 form 、 functional-page-navigator 、 live-pusher 、 navigator 、 navigation-bar 、 official-account 、 open-data 、 web-view
路由 wx.redirectTo 、 wx.reLaunch 、 wx.navigateTo 、 wx.switchTab 、 wx.navigateBack
界面 导航栏 、 Tab Bar
网络 mDNS 、 UDP 通信
数据缓存 周期性更新
媒体 VoIP 、 wx.chooseMedia 、 wx.chooseImage 、 wx.saveImageToPhotosAlbum 、 wx.chooseVideo 、 wx.saveVideoToPhotosAlbum 、 wx.getVideoInfo 、 wx.compressVideo
位置 wx.openLocation 、 wx.chooseLocation 、 wx.startLocationUpdateBackground 、 wx.startLocationUpdate
转发 wx.getShareInfo 、 wx.showShareMenu 、 wx.hideShareMenu 、 wx.updateShareMenu
文件 wx.openDocument
开放接口 登录 、 微信小程序跳转 、 用户信息 、 支付 、 授权 、 设置 、 收货地址 、 卡券 、 发票 、 生物认证 、 微信运动 、 微信红包
设备 蓝牙 、 iBeacon 、 Wi-Fi 、 NFC 、 联系人 、 剪贴板 、 电话 、 扫码
广告 ad 、 wx.createRewardedVideoAd 、 wx.createInterstitialAd

运营须知

分享朋友圈功能是为了满足纯内容场景的分享需求,如果滥用于营销、诱导等行为,将会被打击。

  1. 微信小程序提供的服务中,不得存在滥用分享的违规行为。例如强制用户分享的行为;分享后立即获得利益的诱导行为;以及通过明示或暗示的样式来达到诱导分享目的的行为等。详见《微信小程序平台运营规范》
  2. 在“单页模式”下,不得诱导或强制用户点击“打开微信小程序”,应该在“单页模式”中尽可能呈现完整的内容

注意事项

  1. 在低版本微信客户端打开时,会进入一个升级提示页面
  2. 不支持在微信小程序页面内直接发起分享
  3. 自定义分享内容时不支持自定义页面路径
  4. 存在 web-view 组件的页面不支持发起分享
  5. 支持打开开发版、体验版,没有权限的人员进入时页面会提示无权限

账户卡片

一、功能介绍

为了方便用户查看、操作自己在微信小程序中的资金类账户,一键触达微信小程序,微信在「发现-微信小程序」入口新增「我的账户」板块。

具体功能示意图如下:

二、功能介绍

支持微信版本:8.0.41 for Android 及以上;8.0.46 for ios及以上

支持基础库版本:3.1.1 及以上

1. 开通功能

开发者首先需要明确自己的服务业态,当前账户卡片支持的业态包括:

卡片id 卡片名称 类目要求 使用场景 展示字段
5001 基金账户 金融业-公募基金、私募基金 向用户展示资产、收益情况等信息 总资产、昨日收益
5002 电信账户 IT科技-基础电信运营商、电信业务代理商 向用户展示话费余额、剩余流量等信息 话费余额、流量余额
5003 信用卡账户 金融业-银行、信用卡 向用户账单、可用额度、还款日等信息 账单剩余应还、可用额度、还款日
5004 贷款账户 金融业-银行、消费金融、非金融机构自营小额贷款、贷款信息服务 向用户展示本期账单、总计应还,还款日等信息 本期应还、总计应还、还款日
5005 个人养老金卡片账户 金融业-银行、金融业-信用卡 向用户展示养老金资产、收益情况等信息 总资产、昨日收益
5006 保险卡片 金融业-保险、第三方互联网保险 向用户展示已购买保险名称、保险状态、有限期 保险名、是否生效、保险日期
5007 证券卡片 金融业-证券/期货、证券/期货投资资讯、股票信息平台、股票信息服务平台(港股/美股) 向用户展示已购买总资产、今日盈亏、证券名称 总资产、今日盈亏

登录微信公众平台 ,符合类目要求即可在开发管理-其他接口找到「发现页账户卡片」,点击开通,即可开通该功能开发权限

2. 在代码包中创建卡片分包

账户卡片为微信小程序代码包中的独立组件分包。为保证 UI 统一,微信侧会提供不同类型的账户卡片模板,页面样式( WXML 与 WXSS )是由微信提供的固定的代码,JS 逻辑由开发者控制,包括数据请求、渲染、缓存等。

开发者需使用微信开发者工具开发版 Nightly Build 1.06.2309062及以上版本进行创建。具体步骤如下:

2.1 创建分包目录 accountCardPackage

  1. 在 app.json 中开启微信小程序「按需注入」特性(lazyCodeLoading)、声明一个独立分包 accountCardPackage 并进行配置:
{
  // app.json
  // ...
  "lazyCodeLoading": "requiredComponents",
  "subpackages": [
    {
      "root": "accountCardPackage",
      "pages": [],
      "independent": true
    }
  ],
  "accountCardPackage": {
    "root": "accountCardPackage",
    "cardList": []
  }
}

  1. 在accountCardPackage 分包目录中右键,点击新建卡片,输入组件名后创建(图为示例,所有类型卡片都从该入口新建)
  1. 完成以上步骤后,可在 accountCardPackage 目录下看到创建好的卡片,同时 app.json 中也会出现相关配置

注意事项:

  1. 一个微信小程序若符合对应卡片类目要求,可以接入多个不同类型的卡片,但是同一类型的卡片只能接入一个。
  2. 卡片分包的目录结构取决于卡片被添加时的 app.json 的配置,卡片一旦被普通用户添加过,就不能再改动其目录结构,否则已添加过的用户就无法正常使用卡片。
  3. 卡片是运行在一个独立的环境中,卡片之间相互隔离。用户提供的卡片组件在渲染时,其 wxmlwxssjson 会被替换成固定模板,只有开发者的 js 代码会被注入执行。

2.2 实现卡片JS逻辑

创建卡片分包后,开发者可在js文件中实现卡片组件逻辑,包括获取登录态、请求数据、加解密数据等。一个卡片组件逻辑示例如下:

// 以 5001 为例
Component({
  data: {
    totalAmount: 0,
    yesterdayEarnings: 0,
  },
  lifetimes: {
    attached() {
      // 更新卡片数据
      this.setData({
        totalAmount: 6000000,
        yesterdayEarnings: 10000,
      })
      // 数据已准备完毕,通知嵌入卡片方
      this.updateStatus('loaded')
    },
  },
})

具体实现步骤如下:

  1. 设置卡片展示的变量信息。由于WXML文件不支持开发者自定义,因此每种卡片支持显示的字段由平台定义,开发者实现获取与加密逻辑后通过 setData 变更变量信息。不同卡片类型支持的变量信息通过可参考下表:
卡片id 卡片名称 字段 描述 是否可隐藏
5001 基金账户 totalAmount 总资产,单位为分
yesterdayEarnings 昨日收益,单位为分
5002 电信账户 telephoneBalance 话费余额,单位为分
residualData 剩余流量,单位为 MB
5003 信用卡账户 remainingRepayment 本期账单剩余应还款金额,单位为分
availableCreditLimit 信用卡可用额度,单位为分
dueDateMonth 还款日期中的月
dueDateDay 还款日期中的日
cardNumber 卡片尾号,仅展示后四位,默认不显示
pendingRepayCardCnt (多卡情况)共有多少张卡,默认不展示
allCardsEnterPath (多卡情况)若调用了“pendingRepayCardCnt”,则需设置多卡显示区域设置对应的跳转路径
5004 贷款账户 currentRepayment 本期账单剩余应还款金额,单位为分
totalDebt 贷款总计应还金额,单位为分
dueDateMonth 还款日期中的月
dueDateDay 还款日期中的日
cardNumber 卡片尾号,仅展示后四位,默认不显示
loanAccountCardCnt (多卡情况)共x个贷款账户代还,默认不展示
allCardsEnterPath (多卡情况)若调用了“loanAccountCardCnt”,则需设置多卡显示区域设置对应的跳转路径,必填
5005 个人养老金账户 totalAmount 总资产,单位为分
yesterdayEarnings 昨日收益,单位为分
cardNumber 卡片尾号,仅展示后四位,默认不显示
pensionAccountCnt (多卡情况)共x个养老金账户,默认不展示
allCardsEnterPath (多卡情况)若调用了“pensionAccountCnt”,则需设置多卡显示区域设置对应的跳转路径,必填
5006 保险账户 insurance_name 保险名称
insurance_status 分为三种状态:1 未生效 2 生效中 3 已过期
start_date 时间戳,保险开始日期
end_date 时间戳,保险结束日期
cardNumber 卡片尾号,仅展示后四位,默认不显示
insuranceAccountCnt (多卡情况)共x个保险,默认不展示
allCardsEnterPath (多卡情况)若调用了“insuranceAccountCnt”,则需设置多卡显示区域设置对应的跳转路径,必填
5007 证券账户 totalAmount 总资产,单位为分
todayEarnings 今日盈亏,单位为分
securitiesName 证券名称,默认不显示
securitiesCnt (多证券情况)全部x个证券账户,默认不展示
allSecuritiesEnterPath (多卡情况)若调用了“securitiesCnt”,则需设置多卡显示区域设置对应的跳转路径
  1. 更新卡片状态。为了满足不同情况下的展示需求,卡片本身是有状态的,开发者可以根据需要,通过组件的 updateStatus 接口来更新状态。目前支持的状态和变更状态的方法如下:
// 目前支持四种状态:loading、loaded、nologin,默认为 loading 态
this.updateStatus('loading') // 数据准备中,卡片会显示 loading 动画
this.updateStatus('loaded') // 数据准备完毕,卡片会正常显示
this.updateStatus('nologin') // 需要用户进入微信小程序登录,卡片会展示引导文案
this.updateStatus('error') //卡片状态异常,需要用户进入微信小程序检查卡片状态,卡片会展示引导文案
  1. 更新卡片点击跳转路径。卡片被点击时,默认是跳转到微信小程序首页,如果需要跳转到其他路径,可以通过组件的 updateEnterPath 接口来调整点击跳转路径:
this.updateEnterPath('pages/other/index')
  1. 隐藏/显示部分字段。由于业务原因,部分字段无法展示,开发者可以隐藏或显示该字段,具体方法为:
this.showField('cardNumber')
this.hideField('remainingRepayment')

其中,需要注意的是,像5003/5004卡片有可隐藏日期的能力,需要隐藏整个日期字段

this.hideField('dueDate')
  1. 开发业务逻辑。目前在卡片组件内仅支持以下 wx 接口,开发者可以通过以下接口实现业务逻辑:
  • wx.login
  • wx.checkSession
  • wx.getStorage
  • wx.setStorage
  • wx.batchGetStorage
  • wx.batchSetStorage
  • wx.getStorageInfo
  • wx.removeStorage
  • wx.clearStorage
  • wx.request
  • wx.getUserCryptoManager (基础库 3.3.3 版本开始支持)
  • wx.cloud.init (基础库 3.3.3 版本开始支持)
  • wx.cloud.callFunction (基础库 3.3.3 版本开始支持))

注意事项:

  1. wx 接口调用上下文与卡片所属微信小程序一致,也就是说,在卡片中调用 wx 接口和在微信小程序中调用效果是一样的
  2. 卡片通过 wx.setStorage 或 wx.batchSetStorage 写入的数据,不建议微信小程序侧直接依赖,因为微信小程序侧存在一层读缓存,可能读取不到最新写入的数据

3. 调试逻辑

  1. 开发过程中,开发者可以进入「账户详情页」,长按导航栏中的“账户”二字,打开调试面板:
  1. 只有体验版卡片支持输出内容到调试面板,如果列表中没有体验版卡片,调试面板就无法打开。开发者可以调用卡片组件的 debugLog 接口输出内容到调试面板中:
// 输出内容到调试面板上
// 目前只支持 String、Number、Boolean 等基本类型,Object 等类型则需要开发者自行进行序列化处理
if (this.debugLog) this.debugLog('str1', 'str2', 123, false, ...)
  1. 支持云函数,基础库版本需要3.3.3以上:示例
Component({
  data: {
    totalAmount: 0,
    yesterdayEarnings: 0,
  },

  lifetimes: {
    created() {
      if (wx.cloud) {
        wx.cloud.init({
          env: 'xxxx', // 换成真实的云环境
          traceUser: true,
        })
      }
    },

    attached() {
      this.setData({
        totalAmount: 6000000,
        yesterdayEarnings: 10000,
      })
      this.updateStatus('loaded')

      if (wx.cloud) {
        // promise 形式
        wx.cloud.callFunction({
          name: 'xxx', // 换成真实的云函数
          data: {},
        }).then(res => {
          console.log('[Cloud Function Call Success] Result:', res)
        }).catch(err => {
          console.log('[Cloud Function Call Failure] Error Message:', err)
        })

        // callback 形式
        wx.cloud.callFunction({
          name: 'xxx', // 换成真实的云函数
          data: {},
          success: res => {
            console.log('[Cloud Function Call Success] Result:', res)
          },
          fail: err => {
            console.log('[Cloud Function Call Failure] Error Message:', err)
          },
        })
      }
    },
  },
})

注意事项:

  1. 卡片组件内支持组件基础生命周期(如 created、attached 等)和页面生命周期 show 和 hide,但不支持像 selectorQuery 这样的接口,所以开发者的代码逻辑中只需要关心数据即可。
  2. 卡片组件内不支持使用 setTimeout、setInterval 等定时器。
  3. 在卡片隐藏阶段不允许调用 wx 接口。

4. 向用户添加卡片

  1. 卡片准备完成后,需要通过 addAccountCard 接口让用户主动触发添加卡片:
wx.addAccountCard({
  type: 5001, // 卡片类型
  success(res) {
    console.log(res)
  },
})

以下情况会导致用户添加失败:

  • 用户已经添加过该微信小程序同一类型的卡片
  • 用户添加过,但后续从「发现-微信小程序」中删除了卡片
  • 用户添加过,但后续从「微信小程序右上角“…”-设置」中关闭了展示开关
  • 用户当前微信版本不支持此功能(需为8.0.41 for Android 及以上或8.0.46 for iOS及以上)

1.开发者可以提前通过 checkAccountCardAddState 检测卡片是否可添加、是否已添加:

wx.checkAccountCardAddState({
  type: 5001, // 卡片类型
  success(res) {
    // res.couldAdd - 当前是否可以调用接口添加
    // res.hasAdded - 当前是否已添加对应卡片组件
    console.log(res)
  },
})

返回的结果对应的情况:

状态描述 couldAdd hasAdded
正常添加,并且开启 true true
正常添加,手动在设置里关闭了卡片/在发现页账户里删除了卡片 false false
正常添加,又完全删除了微信小程序(在最近使用删除) true false
未添加过,且符合类目要求,已经开通权限的微信小程序 true false

注意事项:

  1. wx.addAccountCard 必须在触发点击行为后才可以调用。
  2. wx.addAccountCard 当前仅支持在体验版或正式版微信小程序中调用。
  3. 不支持重复添加同一张卡片。如果当前用户已经添加了卡片,必须先删除微信小程序后才可以触发添加。
  4. 目前 wx.addAccountCard 仅支持在体验版或正式版调用。如果在体验版调用,那么发现页就会拉取体验版的卡片组件分包进行展示,如果此时要重新添加正式版卡片,需要先删除体验版微信小程序,反之同理。

5. 用户取消卡片展示

用户有2个方式取消展示:

  • 在微信小程序的设置中关闭对应卡片的开关
  • 在「发现-微信小程序」中的账户卡片中长按可展示「删除卡片」入口,用户点击后可删除卡片的展示

注意事项:

  • 若用户直接从「最近使用」中删除微信小程序,则会同步完全删除账户卡片。若想重新展示账户卡片,用户需要重新添加。

生物认证

微信小程序通过 SOTER 提供以下生物认证方式。

目前支持指纹识别、人脸识别认证。设备支持的生物认证方式可使用 wx.checkIsSupportSoterAuthentication 查询

调用流程

流程步骤说明

  1. 调用 wx.startSoterAuthentication,获取 resultJSONresultJSONSignature

  2. (可选)签名校验。此处 resultJSONSignature 使用 SHA256withRSA/PSS 作为签名算法进行验签。此公式数学定义如下: bool 验签结果=verify(用于签名的原串,签名串,验证签名的公钥)

  3. 微信提供后台接口用于可信的密钥验签服务,微信将保证该接口返回的验签结果的正确性与可靠性,并且对于 Android root 情况下该接口具有上述特征(将返回是否保证root情况安全性)。

接口地址:

POST http://api.weixin.qq.com/cgi-bin/soter/verify_signature?access_token=%access_token

post 数据内容(JSON 编码):

{"openid":"$openid", "json_string" : "$resultJSON", "json_signature" : "$resultJSONSignature" }

请求返回数据内容(JSON 编码):

// 验证成功返回
{"is_ok":true}
// 验证失败返回
{"is_ok":false}
// 接口调用失败
{"errcode":"xxx,"errmsg":"xxxxx"}

头像昵称填写

从基础库 2.21.2 开始支持

微信小程序需要让用户完善个人资料时,可以通过微信提供的头像昵称填写能力快速完善。

根据相关法律法规,为确保信息安全,由用户上传的图片、昵称等信息微信侧将进行安全检测,组件从基础库2.24.4版本起,已接入内容安全服务端接口(mediaCheckAsync、msgSecCheck),以减少内容安全风险对开发者的影响。

使用方法

头像选择

需要将 button 组件 open-type 的值设置为 chooseAvatar,当用户选择需要使用的头像之后,可以通过 bindchooseavatar 事件回调获取到头像信息的临时路径。

从基础库2.24.4版本起,若用户上传的图片未通过安全监测,不触发bindchooseavatar 事件。

avatar

昵称填写

需要将 input 组件 type 的值设置为 nickname,当用户在此input进行输入时,键盘上方会展示微信昵称。

从基础库2.24.4版本起,在onBlur 事件触发时,微信将异步对用户输入的内容进行安全监测,若未通过安全监测,微信将清空用户输入的内容,建议开发者通过 form 中form-typesubmit 的button 组件收集用户输入的内容。

avatar

在开发者工具上,input 组件是用 web 组件模拟的,因此部分情况下并不能很好的还原真机的表现,建议开发者在使用到原生组件时尽量在真机上进行调试。

代码示例

在开发者工具中预览效果

<button class="avatar-wrapper" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar">
  <image class="avatar" src="{{avatarUrl}}"></image>
</button> 
<input type="nickname" class="weui-input" placeholder="请输入昵称"/>
const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'

Page({
  data: {
    avatarUrl: defaultAvatarUrl,
  },
  onChooseAvatar(e) {
    const { avatarUrl } = e.detail 
    this.setData({
      avatarUrl,
    })
  }
})

手机号实时验证组件

该能力旨在帮助开发者向用户发起手机号申请,并且必须经过用户同意后,开发者才可获得由平台验证后的手机号,进而为用户提供相应服务。

该能力与手机号快速验证组件的区别为:

  1. 手机号实时验证组件,在每次请求时,平台均会对用户选择的手机号进行实时验证
  2. 手机号快速验证组件,平台会对号码进行验证,但不保证是实时验证

请注意:

  1. 目前该接口针对非个人主体,且完成了认证的微信小程序开放(境外主体目前仅限部分国家地区开放,详见文档
  2. 该能力使用时,用户可选择绑定号码,或自主添加号码。每次请求时,平台均会基于中国三大运营商提供的短信等底层能力对号码进行实时验证
  3. 请开发者根据业务场景需要自行判断并选择是否使用,必要时可考虑增加其他安全验证手段。
  4. 开发者需合理使用,若用户举报或被发现开发者不合理地要求用户提供手机号等个人信息,中断了正常的使用流程,影响了用户的使用体验,微信有权依据《微信小程序平台运营管理规范》对该微信小程序进行处理。常见违规事例和具体解析

收费说明

自2023年8月28日起,手机号实时验证组件将需要付费使用。标准单价为:每次组件调用成功,收费0.04元。更多套餐价格请见微信公众平台-付费管理

购买操作指引

常见问题解答

请注意:

  1. 体验额度:每个微信小程序账号将有1000次体验额度,用于开发、调试和体验。该1000次的体验额度为正式版、体验版和开发版微信小程序共用,超额后,体验版和开发版微信小程序调用同正式版微信小程序一样,均收费;
  2. 资源包有效期:在2023年8月28日前购买的订单,资源包将于2023年8月28日生效;在2023年8月28日后购买的订单,资源包将于支付成功后即刻生效;各资源包将按购买时所选择的有效期,计算相应的到期失效时间;
  3. 资源使用顺序:默认先从体验额度中划扣,划扣完毕后再从付费资源包中划扣;若有多个付费资源包,将按资源包到期时间顺序,先从最近到期的资源包开始划扣,如此类推;
  4. 退款规则:若购买有误,且未正式开始使用资源包前,可以在支付成功后的7天内申请退款。款项将在3-5个工作日内从原支付路径返回;若资源包已经开始使用(使用1次及以上),则不能申请退款;若支付成功后超过7天,未发起退款申请,亦不能再申请退款。
  5. 异常排查:若对调用量有疑问,可参考《手机号计费误差问题排查指南》进行排查。

免费规则

符合以下情况之一的微信小程序,使用此能力不收费,具体如下:

  1. 账号微信认证主体类型为政府、非营利组织的微信小程序;
  2. 账号微信认证主体类型为事业单位,且类目为政务民生的微信小程序;
  3. 账号类目为公立医疗机构、学历教育(学校)的微信小程序

开发者可通过以下两种方式查询微信小程序的微信认证主体类型:

  1. 进入「微信公众平台->点击微信小程序信息->查看基本信息->微信认证主体类型」
  2. 进入「微信公众平台->点击右上角账号头像->可查看基本信息->微信认证主体类型」

集采模式

旨在提供更高效的落地工具,支持批量采购资源包后,可以灵活地分配给多个微信小程序使用。集采模式接入指引

查询和扣费节点说明

  • 查询节点:用户点击button时,进行资源包额度查询。若查询额度不足,开发者将收到错误码 e.detail.errno===1400001 ,同时用户侧将收到平台默认半屏提示“该功能使用次数已达当前微信小程序上限,暂时无法使用”。若开发者想自行兼容欠费逻辑,可将 button 组件中phone-number-no-quota-toast 的值设置为 false,此时平台将不在用户侧进行提示;
  • 扣费节点:开发者获得 bindgetphonenumber 事件的 success 回调信息时,进行扣费。

使用方法

步骤1:需要将 button 组件 open-type 的值设置为 getRealtimePhoneNumber,当用户点击并同意之后,通过 bindgetrealtimephonenumber 事件获取回调信息;

步骤2:将 bindgetrealtimephonenumber 事件回调中的动态令牌code传到开发者后台,并在开发者后台调用微信后台提供的 phonenumber.getPhoneNumber 接口,消费code来换取用户手机号。每个code有效期为5分钟,且只能消费一次。

注:getRealtimePhoneNumber 返回的 codewx.login 返回的 code 作用是不一样的,不能混用。

注意

该能力的bindgetrealtimephonenumber 事件回调中,仅会返回 code,不会返回 encryptedDataiv,开发者仅可通过调用phonenumber.getPhoneNumber 接口,消费 code的方式换取用户手机号。

代码示例

<button open-type="getRealtimePhoneNumber" bindgetrealtimephonenumber="getrealtimephonenumber"></button>
Page({
  getrealtimephonenumber (e) {
    console.log(e.detail.code)  // 动态令牌
    console.log(e.detail.errMsg) // 回调信息(成功失败都会返回)
    console.log(e.detail.errno)  // 错误码(失败时返回)
  }
})

返回参数说明

参数 类型 说明 最低版本
code String 动态令牌。可通过动态令牌换取用户手机号。使用方法详情 phonenumber.getPhoneNumber 接口

手机号快速验证组件

该能力旨在帮助开发者向用户发起手机号申请,并且必须经过用户同意后,开发者才可获得由平台验证后的手机号,进而为用户提供相应服务。

该能力与手机号实时验证组件的区别为:

  1. 手机号快速验证组件,平台会对号码进行验证,但不保证是实时验证
  2. 手机号实时验证组件,在每次请求时,平台均会对用户选择的手机号进行实时验证

请注意:

  1. 目前该接口针对非个人主体,且完成了认证的微信小程序开放(境外主体目前仅限部分国家地区开放,详见文档
  2. 该能力使用时,用户可选择绑定号码,或自主添加号码。平台会基于中国三大运营商提供的短信等底层能力对号码进行验证,但不保证是实时验证
  3. 请开发者根据业务场景需要自行判断并选择是否使用,必要时可考虑增加其他安全验证手段。
  4. 开发者需合理使用,若被发现或用户举报开发者不合理地要求用户提供手机号等个人信息,中断了正常的使用流程,影响了用户的使用体验,微信有权依据《微信小程序平台运营管理规范》对该微信小程序进行处理。常见违规事例和具体解析

收费说明

自2023年8月28日起,手机号快速验证组件将需要付费使用。标准单价为:每次组件调用成功,收费0.03元。更多套餐价格请见微信公众平台-付费管理

购买操作指引

常见问题解答

请注意:

  1. 体验额度:每个微信小程序账号将有1000次体验额度,用于开发、调试和体验。该1000次的体验额度为正式版、体验版和开发版微信小程序共用,超额后,体验版和开发版微信小程序调用同正式版微信小程序一样,均收费;
  2. 资源包有效期:在2023年8月28日前购买的订单,资源包将于2023年8月28日生效;在2023年8月28日后购买的订单,资源包将于支付成功后即刻生效;各资源包将按购买时所选择的有效期,计算相应的到期失效时间;
  3. 资源使用顺序:默认先从体验额度中划扣,划扣完毕后再从付费资源包中划扣;若有多个付费资源包,将按资源包到期时间顺序,先从最近到期的资源包开始划扣,如此类推;
  4. 退款规则:若购买有误,且未正式开始使用资源包前,可以在支付成功后的7天内申请退款。款项将在3-5个工作日内从原支付路径返回;若资源包已经开始使用(使用1次及以上),则不能申请退款;若支付成功后超过7天,未发起退款申请,亦不能再申请退款。
  5. 异常排查:若对调用量有疑问,可参考《手机号计费误差问题排查指南》进行排查。

免费规则

符合以下情况之一的微信小程序,使用此能力不收费,具体如下:

  1. 账号微信认证主体类型为政府、非营利组织的微信小程序;
  2. 账号微信认证主体类型为事业单位,且类目为政务民生的微信小程序;
  3. 账号类目为公立医疗机构、学历教育(学校)的微信小程序

开发者可通过以下两种方式查询微信小程序的微信认证主体类型:

  1. 进入「微信公众平台->点击微信小程序信息->查看基本信息->微信认证主体类型」
  2. 进入「微信公众平台->点击右上角账号头像->可查看基本信息->微信认证主体类型」

集采模式

旨在提供更高效的落地工具,支持批量采购资源包后,可以灵活地分配给多个微信小程序使用。集采模式接入指引

查询和扣费节点说明

  • 查询节点:用户点击button时,进行资源包额度查询。若查询额度不足,开发者将收到错误码 e.detail.errno===1400001 ,同时用户侧将收到平台默认半屏提示“该功能使用次数已达当前微信小程序上限,暂时无法使用”。若开发者想自行兼容欠费逻辑,可将 button 组件中phone-number-no-quota-toast 的值设置为 false,此时平台将不在用户侧进行提示;
  • 扣费节点:开发者获得 bindgetphonenumber 事件的 success 回调信息时,进行扣费。

使用方法

步骤1:需要将 button 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,通过 bindgetphonenumber 事件获取回调信息;

步骤2:将 bindgetphonenumber 事件回调中的动态令牌code传到开发者后台,并在开发者后台调用微信后台提供的 phonenumber.getPhoneNumber 接口,消费code来换取用户手机号。每个code有效期为5分钟,且只能消费一次。

注:getPhoneNumber 返回的 codewx.login 返回的 code 作用是不一样的,不能混用。

注意

从基础库2.21.2开始,对步骤2中换取手机号信息的方式进行了安全升级,上述为新方式使用指南。(旧方式目前可以继续使用,但建议开发者使用新方式,以增强微信小程序安全性)另外,新方式不再需要提前调用wx.login进行登录。

代码示例

<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>
Page({
  getPhoneNumber (e) {
    console.log(e.detail.code)  // 动态令牌
    console.log(e.detail.errMsg) // 回调信息(成功失败都会返回)
    console.log(e.detail.errno)  // 错误码(失败时返回)
  }
})

返回参数说明

参数 类型 说明 最低版本
code String 动态令牌。可通过动态令牌换取用户手机号。使用方法详情 phonenumber.getPhoneNumber 接口

服务端获取开放数据

微信小程序可以通过各种前端接口获取微信提供的开放数据。考虑到开发者服务端也需要获取这些开放数据,微信提供了两种获取方式:

  • 方式一:开发者后台校验与解密开放数据
  • 方式二:云调用直接获取开放数据(云开发)

方式一:开发者后台校验与解密开放数据

微信会对这些开放数据做签名和加密处理。开发者后台拿到开放数据后可以对数据进行校验签名和解密,来保证数据不被篡改。

签名校验以及数据加解密涉及用户的会话密钥 session_key。 开发者应该事先通过 wx.login 登录流程获取会话密钥 session_key 并保存在服务器。为了数据不被篡改,开发者不应该把 session_key 传到微信小程序客户端等服务器外的环境。

数据签名校验

为了确保开放接口返回用户数据的安全性,微信会对明文数据进行签名。开发者可以根据业务需要对数据包进行签名校验,确保数据的完整性。

  1. 通过调用接口(如 wx.getUserInfo)获取数据时,接口会同时返回 rawData、signature,其中 signature = sha1( rawData + session_key )
  2. 开发者将 signature、rawData 发送到开发者服务器进行校验。服务器利用用户对应的 session_key 使用相同的算法计算出签名 signature2 ,比对 signature 与 signature2 即可校验数据的完整性。

如 wx.getUserInfo的数据校验:

接口返回的rawData:

{
  "nickName": "Band",
  "gender": 1,
  "language": "zh_CN",
  "city": "Guangzhou",
  "province": "Guangdong",
  "country": "CN",
  "avatarUrl": "http://wx.qlogo.cn/mmopen/vi_32/1vZvI39NWFQ9XM4LtQpFrQJ1xlgZxx3w7bQxKARol6503Iuswjjn6nIGBiaycAjAtpujxyzYsrztuuICqIM5ibXQ/0"
}

用户的 session-key:

HyVFkGl5F5OQWJZZaNzBBg==

用于签名的字符串为:

{"nickName":"Band","gender":1,"language":"zh_CN","city":"Guangzhou","province":"Guangdong","country":"CN","avatarUrl":"http://wx.qlogo.cn/mmopen/vi_32/1vZvI39NWFQ9XM4LtQpFrQJ1xlgZxx3w7bQxKARol6503Iuswjjn6nIGBiaycAjAtpujxyzYsrztuuICqIM5ibXQ/0"}HyVFkGl5F5OQWJZZaNzBBg==

使用sha1得到的结果为

75e81ceda165f4ffa64f4068af58c64b8f54b88c

加密数据解密算法

接口如果涉及敏感数据(如wx.getUserInfo当中的 openId 和 unionId),接口的明文内容将不包含这些敏感数据。开发者如需要获取敏感数据,需要对接口返回的加密数据(encryptedData) 进行对称解密。 解密算法如下:

  1. 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充。
  2. 对称解密的目标密文为 Base64_Decode(encryptedData)。
  3. 对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。
  4. 对称解密算法初始向量 为Base64_Decode(iv),其中iv由数据接口返回。

微信官方提供了多种编程语言的示例代码((点击下载)。每种语言类型的接口名字均一致。调用方式可以参照示例。

另外,为了应用能校验数据的有效性,会在敏感数据加上数据水印( watermark )

watermark参数说明:

参数 类型 说明
appid String 敏感数据归属 appId,开发者可校验此参数与自身 appId 是否一致
timestamp Int 敏感数据获取的时间戳, 开发者可以用于数据时效性校验

如接口 wx.getUserInfo 敏感数据当中的 watermark:

{
    "openId": "OPENID",
    "nickName": "NICKNAME",
    "gender": GENDER,
    "city": "CITY",
    "province": "PROVINCE",
    "country": "COUNTRY",
    "avatarUrl": "AVATARURL",
    "unionId": "UNIONID",
    "watermark":
    {
        "appid":"APPID",
        "timestamp":TIMESTAMP
    }
}

注:

  1. 解密后得到的json数据根据需求可能会增加新的字段,旧字段不会改变和删减,开发者需要预留足够的空间

会话密钥 session_key 有效性

开发者如果遇到因为 session_key 不正确而校验签名失败或解密失败,请关注下面几个与 session_key 有关的注意事项。

  1. wx.login 调用时,用户的 session_key 可能会被更新而致使旧 session_key 失效(刷新机制存在最短周期,如果同一个用户短时间内多次调用 wx.login,并非每次调用都导致 session_key 刷新)。开发者应该在明确需要重新登录时才调用 wx.login,及时通过 code2Session 接口更新服务器存储的 session_key。
  2. 微信不会把 session_key 的有效期告知开发者。我们会根据用户使用微信小程序的行为对 session_key 进行续期。用户越频繁使用微信小程序,session_key 有效期越长。
  3. 开发者在 session_key 失效时,可以通过重新执行登录流程获取有效的 session_key。使用接口 wx.checkSession可以校验 session_key 是否有效,从而避免微信小程序反复执行登录流程。
  4. 当开发者在实现自定义登录态时,可以考虑以 session_key 有效期作为自身登录态有效期,也可以实现自定义的时效性策略。

方式二:云调用直接获取开放数据

接口如果涉及敏感数据(如wx.getWeRunData),接口的明文内容将不包含这些敏感数据,而是在返回的接口中包含对应敏感数据的 cloudID 字段,数据可以通过云函数获取。完整流程如下:

1. 获取 cloudID

使用 2.7.0 或以上版本的基础库,如果微信小程序已开通云开发,在开放数据接口的返回值中可以通过 cloudID 字段获取(与 encryptedData 同级),cloudID 有效期五分钟。

2. 调用云函数

调用云函数时,对传入的 data 参数,如果有顶层字段的值为通过 wx.cloud.CloudID 构造的 CloudID,则调用云函数时,这些字段的值会被替换为 cloudID 对应的开放数据,一次调用最多可替换 5 个 CloudID

示例:

微信小程序获取到 cloudID 之后发起调用:

wx.cloud.callFunction({
  name: 'myFunction',
  data: {
    weRunData: wx.cloud.CloudID('xxx'), // 这个 CloudID 值到云函数端会被替换
    obj: {
      shareInfo: wx.cloud.CloudID('yyy'), // 非顶层字段的 CloudID 不会被替换,会原样字符串展示
    }
  }
})

在云函数收到的 event 示例:

// event
{
  // weRunData 的值已被替换为开放数据
  "weRunData": {
    "cloudID": "xxx",
    "data": {
      "stepInfoList": [
        {
          "step": 5000,
          "timestamp": 1554814312,
        }
      ],
      "watermark": {
        "appid": "wx1111111111",
        "timestamp": 1554815786
      }
    }
  },
  "obj": {
    // 非顶层字段维持原样
    "shareInfo": "yyy",
  }
}

如果 cloudID 非法或过期,则在 event 中获取得到的将是一个有包含错误码、错误信息和原始 cloudID 的对象。过期 cloudID 换取结果示例:

// event
{
  "weRunData": {
    "cloudID": "xxx",
    "errCode": -601006,
    "errMsg": "cloudID expired."
  },
  // ...
}

授权

部分接口需要经过用户授权同意才能调用。我们把这些接口按使用范围分成多个 scope ,用户选择对 scope 来进行授权,当授权给一个 scope 之后,其对应的所有接口都可以直接使用。

此类接口调用时:

  • 如果用户未接受或拒绝过此权限,会弹窗询问用户,用户点击同意后方可调用接口;
  • 如果用户已授权,可以直接调用接口;
  • 如果用户已拒绝授权,则不会出现弹窗,而是直接进入接口 fail 回调。请开发者兼容用户拒绝授权的场景。

获取用户授权设置

开发者可以使用 wx.getSetting 获取用户当前的授权状态。

打开设置界面

用户可以在微信小程序设置界面(「右上角」 – 「关于」 – 「右上角」 – 「设置」)中控制对该微信小程序的授权状态。

开发者可以调用 wx.openSetting 打开设置界面,引导用户开启授权。

提前发起授权请求

开发者可以使用 wx.authorize 在调用需授权 API 之前,提前向用户发起授权请求。

scope 列表

scope 对应接口 描述
scope.userLocation wx.getLocation, wx.startLocationUpdate, MapContext.moveToLocation 精确地理位置
scope.userFuzzyLocation wx.getFuzzyLocation 模糊地理位置
scope.userLocationBackground wx.startLocationUpdateBackground 后台定位
scope.record live-pusher组件, wx.startRecord, wx.joinVoIPChat, RecorderManager.start 麦克风
scope.camera camera组件, live-pusher组件, wx.createVKSession 摄像头
scope.bluetooth wx.openBluetoothAdapter, wx.createBLEPeripheralServer 蓝牙
scope.writePhotosAlbum wx.saveImageToPhotosAlbum, wx.saveVideoToPhotosAlbum 添加到相册
scope.addPhoneContact wx.addPhoneContact 添加到联系人
scope.addPhoneCalendar wx.addPhoneRepeatCalendar, wx.addPhoneCalendar 添加到日历
scope.werun wx.getWeRunData 微信运动步数
scope.address wx.chooseAddress 通讯地址(已取消授权,可以直接调用对应接口)
scope.invoiceTitle wx.chooseInvoiceTitle 发票抬头(已取消授权,可以直接调用对应接口)
scope.invoice wx.chooseInvoice 获取发票(已取消授权,可以直接调用对应接口)
scope.userInfo wx.getUserInfo 用户信息(微信小程序已回收,请使用头像昵称填写,小游戏可继续调用)

授权有效期

一旦用户明确同意或拒绝过授权,其授权关系会记录在后台,直到用户主动删除微信小程序。

最佳实践

在真正需要使用授权接口时,才向用户发起授权申请,并在授权申请中说明清楚要使用该功能的理由。

注意事项

  1. 需要授权 scope.userLocationscope.userLocationBackgroundscope.userFuzzyLocation 时必须配置地理位置用途说明。
  2. 授权弹窗会展示微信小程序在微信小程序用户隐私保护指引中填写的说明,请谨慎填写。

后台定位

开发者首先需要在后台运行的能力中声明后台定位。

安卓 8.0.0 , iOS 8.0.0 起,若开发者可支持通过 wx.authorize({scope: 'scope.userLocationBackground'}) 唤起后台使用地理位置授权窗口。

低于以上版本,scope.userLocationBackground 不会弹窗提醒用户。需要用户在设置页中,主动将“位置信息”选项设置为“使用微信小程序期间和离开微信小程序后”。开发者可以通过调用wx.openSetting,打开设置页。

background-location

UnionID 机制说明

如果开发者拥有多个移动应用、网站应用、微信小程序、小游戏、公众号、服务号、微信小店、小店联盟带货机构、小店带货助手等,可通过平台开放的 API 获取 UnionID 来区分用户的唯一性,因为只要是同一个微信开放平台账号下的移动应用、网站应用、微信小程序、小游戏、公众号、服务号、微信小店、小店联盟带货机构、小店带货助手,用户的 UnionID 是唯一的。

UnionID获取途径

绑定了开发者账号的微信小程序,可以通过以下途径获取 UnionID。

  1. 开发者可以直接通过 wx.login + code2Session 获取到该用户 UnionID,无须用户授权。

  2. 微信小程序端调用云函数时,可在云函数中通过 Cloud.getWXContext 获取 UnionID。

  3. 用户在微信小程序(暂不支持小游戏)中支付完成后,开发者可以直接通过getPaidUnionID接口获取该用户的 UnionID,无需用户授权。注意:本接口仅在用户支付完成后的5分钟内有效,请开发者妥善处理。

微信小程序绑定开放平台账号的流程

  • 登录微信开发者平台 ,进入控制台首页,然后前往「我的业务 – 开放平台 – 绑定关系 – 微信小程序」
  • 注意不是前往「我的业务 – 微信小程序 – 绑定关系 – 开放平台」

微信小程序登录

微信小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立微信小程序内的用户体系。

登录流程时序

说明

  1. 调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
  2. 调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 、 用户在微信开放平台账号下的唯一标识UnionID(若当前微信小程序已绑定到微信开放平台账号) 和 会话密钥 session_key

之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。

注意事项

  1. 会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到微信小程序,也不应该对外提供这个密钥
  2. 临时登录凭证 code 只能使用一次