VIP

VIP 小程序迁移指南(VIP MINI 1)

VIP 小程序运行在 VIP.World App 里,采用兼容微信风格的源码格式(app.json、WXML、WXSS、JS),现有项目一般可以打包成 ZIP 导入,再做少量修改即可运行。VIP 小程序是独立的平台,不是微信小程序,不能使用微信账号、微信支付和微信云开发。微信是腾讯公司的商标,VIP.World 与腾讯公司无关联。

打开制作平台:vip.world/mini-program-studio · English: Migration guide

1. 快速开始:导入 ZIP

  1. 用 VIP 账号登录小程序制作平台,填写「1. 开发者资料」(商户名称和联系方式)。
  2. 在「2. 我的小程序」里创建小程序(名称、简介、类目)。
  3. 准备源码:找到包含 app.json 的目录,删除 node_modules、miniprogram_npm、cloudfunctions 和 project.private.config.json,并把分包页面合并到主包的 pages 列表。
  4. 把这个目录打包成 ZIP(app.json 在根目录,或在唯一的一层顶级目录里)。限制:ZIP 不超过 8 MiB,最多 300 个文件,单个文件不超过 1 MiB,解压后不超过 6 MiB,1 到 50 个页面。只保留 .js .json .wxml .wxss 和 .png .jpg .jpeg .gif .webp 文件。
  5. 在「3. 制作与预览」里点「导入源码 ZIP」,再点「检查兼容性」,按第 3、4 节逐条修复列出的问题。
  6. 在「业务 HTTPS 域名」里填写你的后台域名(第 5 节)。
  7. 点「预览」,然后「保存新版本」(例如 1.0.0)。预览已保存的版本,勾选两项确认,点「提交审核」。
  8. VIP 工作人员审核通过后,点「发布此版本」。发布后,在 VIP App 的「消息」页下拉(或点右上角的九宫格图标)以及网站目录 /mini-programs 都能看到它;每个小程序还有可分享的网页 /m/<id>。

2. 运行方式

3. 已支持的能力

生命周期与全局对象

wx 接口

类别接口
网络wx.request(仅限已声明的 HTTPS 域名)
登录wx.login、wx.checkSession、wx.getUserProfile、wx.getAccountInfoSync(第 6 节)
界面wx.showToast、wx.hideToast、wx.showLoading、wx.hideLoading、wx.showModal、wx.showActionSheet、wx.setNavigationBarTitle、wx.pageScrollTo
路由wx.navigateTo、wx.redirectTo、wx.navigateBack、wx.reLaunch、wx.switchTab
存储wx.getStorageSync、wx.setStorageSync、wx.removeStorageSync、wx.clearStorageSync、wx.getStorage、wx.setStorage、wx.removeStorage、wx.clearStorage
系统wx.getSystemInfoSync、wx.getSystemInfo、wx.getWindowInfo、wx.getDeviceInfo、wx.getAppBaseInfo、wx.canIUse、wx.nextTick

请直接写 wx.方法名(...)。const api = wx、wx['login'] 这类写法无法静态检查,会被拒绝。

WXML

4. 暂不支持的能力及替代方案

微信风格的能力VIP 替代方案
微信登录(api.weixin.qq.com 的 code2Session)、unionid、session_key、encryptedDataVIP 登录适配器:wx.login + VIP 的 code2session(第 6 节)。只提供本小程序专属的 openid,没有 unionid 和加密数据
<button open-type="getUserInfo">、open-type="getPhoneNumber"用 bindtap + wx.getUserProfile({ desc }) 获取昵称和头像。不提供手机号,需要时请在你自己的表单里让用户填写
wx.requestPayment、微信支付VIP MINI 1 暂不提供。可以展示价格并通过你自己的后台下单;VIP 支付适配器在规划中
wx.cloud.*、云函数、云数据库使用你自己的 HTTPS 后台 + wx.request
wx.uploadFile、wx.downloadFile、wx.connectSocket暂不支持,请用 wx.request(JSON)和轮询
wx.chooseImage、wx.chooseMedia、wx.scanCode、wx.getLocation、wx.chooseLocation、地图、相机暂不支持,请改用文字输入或链接
onShareAppMessage、wx.navigateToMiniProgram、订阅消息/模板消息不支持
自定义组件(Component()、usingComponents)、Behavior、插件、npm 包把组件结构直接写进页面,把工具代码复制到自己的文件里(require('./utils/x'))
WXS、<template>、<import>、<include>逻辑移到页面 JS,结构直接写在页面里
web-view、HTML 的 on…= 属性不允许
分包把所有页面写进主包的 pages 数组

5. 域名白名单

6. VIP 登录适配器

VIP App 会保护用户账号:小程序永远拿不到 VIP 登录令牌、手机号、邮箱或 VIP 号。流程如下:

  1. 小程序调用 wx.login(),VIP App 弹出授权确认(「允许 你的小程序 使用 VIP 账号登录」)。用户同意后,小程序拿到一个 code;用户拒绝时,wx.login 失败,返回 login:fail user denied。基础登录授权会按「用户 + 小程序」记在这台手机上。
  2. 这个 code 是随机生成的,只能用一次,5 分钟内有效,并且只对你的 AppID 有效。
  3. 你的服务器用 code 和 AppSecret 向 VIP 换取 openid:同一个用户在你的小程序里的固定标识(不同小程序拿到的值不同)。
  4. wx.getUserProfile({ desc: '用于在订单上显示你的名字' }) 每次都会再次询问用户。同意后返回 userInfo(nickName、avatarUrl)和一个 code,用这个 code 换取时也会返回 nickname 和 avatarUrl。

登录在 VIP App 和网站运行页(vip.world/m/<id>)里可用,并且只对已发布且已生成 AppSecret 的小程序有效。在网页版制作平台的预览里(仅供商户自测),wx.login 仍会失败并提示 VIP login is only available in the VIP app,因为预览没有授权宿主。

获取 AppSecret

制作平台 → 你的小程序 → 「5. VIP 登录(AppSecret)」→「生成 AppSecret」。密钥只显示一次,请保存在服务器的环境变量里(不要写进小程序代码或代码仓库)。「重置 AppSecret」会立即替换旧密钥,并作废未使用的 code。AppID 就是小程序 ID(vipmp_…)。

小程序端代码

// app.js
App({
  onLaunch() {
    if (wx.getStorageSync('token')) return;
    wx.login({
      success: ({ code }) => {
        wx.request({
          url: 'https://api.example.com/vip/login',
          method: 'POST',
          data: { code },
          success: (res) => wx.setStorageSync('token', res.data.token),
        });
      },
      fail: (err) => console.log('登录失败', err.errMsg),
    });
  },
});

服务器端换取 openid

POST https://api.vip.world/api/mini-programs/oauth/code2session,请求体为 JSON。也兼容微信的字段名 appid 和 js_code。AppSecret 只能放在请求体里,放在网址里的请求会被拒绝。

POST /api/mini-programs/oauth/code2session HTTP/1.1
Host: api.vip.world
Content-Type: application/json

{"appId":"vipmp_0123456789abcdef01234567","secret":"vms_…","code":"vmc_…"}

成功时返回:

{"code":0,"message":"ok","data":{"openid":"vo_3kq…","scope":"base"}}

如果是 profile 授权,data 里还会有 "nickname" 和 "avatarUrl"。

Node.js(Express,Node 18 及以上):

const express = require('express');
const app = express();
app.use(express.json());
app.use((req, res, next) => { res.set('Access-Control-Allow-Origin', '*'); res.set('Access-Control-Allow-Headers', 'Content-Type, Authorization'); next(); });
app.options('*', (req, res) => res.sendStatus(204));

app.post('/vip/login', async (req, res) => {
  const r = await fetch('https://api.vip.world/api/mini-programs/oauth/code2session', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ appId: process.env.VIP_APP_ID, secret: process.env.VIP_APP_SECRET, code: String(req.body.code || '') }),
  });
  const body = await r.json();
  if (body.code !== 0) return res.status(401).json({ error: body.message });
  const user = await findOrCreateUserByVipOpenid(body.data.openid); // 你自己的数据库
  res.json({ token: await createYourSessionToken(user) });          // 你自己的登录态
});
app.listen(8080);

Python(仅用标准库):

import json, os, urllib.request

def vip_code2session(code: str) -> dict:
    payload = json.dumps({"appId": os.environ["VIP_APP_ID"], "secret": os.environ["VIP_APP_SECRET"], "code": code}).encode()
    req = urllib.request.Request("https://api.vip.world/api/mini-programs/oauth/code2session",
                                 data=payload, headers={"Content-Type": "application/json"}, method="POST")
    try:
        with urllib.request.urlopen(req, timeout=10) as r:
            body = json.load(r)
    except urllib.error.HTTPError as e:
        body = json.load(e)
    if body.get("code") != 0:
        raise PermissionError(body.get("message"))
    return body["data"]  # {"openid": "...", "scope": "base"}

错误码

HTTPcode含义
40040001appId、secret 或 code 缺失或格式不对
40140125AppID 或 AppSecret 错误
40040029code 不存在、已过期或属于其他小程序
40040163code 已经用过(每个 code 只能用一次)
40340013该 VIP 用户已不可用
40310002小程序未发布或已被暂停
40942201还没有生成 AppSecret(VIP 登录未开启)
42940002 / 45011请求过于频繁

安全检查清单

7. 审核与发布

8. 名称规范

请把你的产品称为 VIP 小程序,可以说明「兼容微信风格的源码格式」。不要把它称为微信小程序,也不要使用微信的标志。