VIP

VIP mini program migration guide (VIP MINI 1)

VIP mini programs run inside the VIP.World app. They use a WeChat-style source format (app.json, WXML, WXSS, JS), so an existing project can usually be imported as a ZIP and adapted with small changes. VIP mini programs are a separate platform: they are not WeChat mini programs, and WeChat accounts, payments and cloud services are not available. WeChat is a trademark of Tencent; VIP.World is not affiliated with Tencent.

Open the studio: vip.world/mini-program-studio · 中文版:迁移指南

1. Quick start: import a ZIP

  1. Sign in at the studio with your VIP account and fill in 1. Developer profile (business name and contact).
  2. Under 2. Your projects, create a project (name, description, category).
  3. Prepare the source: take the folder that contains app.json. Remove node_modules, miniprogram_npm, cloudfunctions and project.private.config.json. Merge sub-packages into the main pages list.
  4. ZIP the folder (app.json at the root, or inside one top-level folder). Limits: ZIP up to 8 MiB, at most 300 files, each file up to 1 MiB, expanded package up to 6 MiB, 1–50 pages. Only .js .json .wxml .wxss and .png .jpg .jpeg .gif .webp files are kept.
  5. In 3. Source and preview, choose Import source ZIP, then Check compatibility. Fix every listed error (see sections 3 and 4).
  6. Enter your backend origins in Backend HTTPS origins (section 5).
  7. Preview, then Save a new version (e.g. 1.0.0). Preview the saved version, tick both confirmations and Submit for review.
  8. After VIP staff approve the version, press Publish this version. It then appears in the VIP app (pull down on the Messages tab or tap the grid icon) and on the website catalog at /mini-programs. Each mini program also has a shareable page at /m/<id>.

2. How it runs

3. Supported features

Lifecycle and globals

wx APIs

AreaAPIs
Networkwx.request (declared HTTPS origins only)
Loginwx.login, wx.checkSession, wx.getUserProfile, wx.getAccountInfoSync (section 6)
UIwx.showToast, wx.hideToast, wx.showLoading, wx.hideLoading, wx.showModal, wx.showActionSheet, wx.setNavigationBarTitle, wx.pageScrollTo
Navigationwx.navigateTo, wx.redirectTo, wx.navigateBack, wx.reLaunch, wx.switchTab
Storagewx.getStorageSync, wx.setStorageSync, wx.removeStorageSync, wx.clearStorageSync, wx.getStorage, wx.setStorage, wx.removeStorage, wx.clearStorage
Systemwx.getSystemInfoSync, wx.getSystemInfo, wx.getWindowInfo, wx.getDeviceInfo, wx.getAppBaseInfo, wx.canIUse, wx.nextTick

Call APIs explicitly as wx.method(...). Aliases such as const api = wx or wx['login'] are rejected because they cannot be checked.

WXML

4. Not supported, and what to use instead

WeChat-style featureVIP replacement
WeChat login (code2Session on api.weixin.qq.com), unionid, session_key, encryptedDataVIP login adapter: wx.login + VIP code2session (section 6). Only an app-scoped openid; no unionid or encrypted data
<button open-type="getUserInfo">, open-type="getPhoneNumber"bindtap + wx.getUserProfile({ desc }) for nickname and avatar. Phone numbers are not shared; ask the user in your own form
wx.requestPayment, WeChat PayNot available in VIP MINI 1. Show prices and take orders through your own backend; a VIP Pay adapter is planned
wx.cloud.*, cloud functions, cloud databaseYour own HTTPS backend + wx.request
wx.uploadFile, wx.downloadFile, wx.connectSocketNot available yet. Use wx.request (JSON) and polling
wx.chooseImage, wx.chooseMedia, wx.scanCode, wx.getLocation, wx.chooseLocation, maps, cameraNot available yet. Use text input or links instead
onShareAppMessage, wx.navigateToMiniProgram, subscription/template messagesNot available
Custom components (Component(), usingComponents), Behavior, plugins, npm packagesInline the markup into pages and copy helper code into your own files (require('./utils/x'))
WXS, <template>, <import>, <include>Move the logic into page JS and the markup into the page
web-view, HTML on…= attributesNot allowed
Sub-packagesList all pages in the main pages array

5. Domain whitelist

6. VIP login adapter

The VIP app protects the user's account: a mini program never receives the VIP session, phone number, email or VIP ID. Instead:

  1. Your mini program calls wx.login(). The VIP app shows a consent sheet ("Allow Your app to sign you in with VIP"). If the user agrees, the mini program receives a code. If they decline, wx.login fails with login:fail user denied. The basic login consent is remembered per user and mini program on that device.
  2. The code is random, single-use, valid for 5 minutes and works only for your AppID.
  3. Your backend sends the code with your AppSecret to VIP and receives openid: a stable ID for this user in your mini program only (other mini programs get a different value).
  4. wx.getUserProfile({ desc: 'Show your name on orders' }) always asks the user again. After consent it returns userInfo (nickName, avatarUrl) plus a code whose exchange also returns nickname and avatarUrl.

Login works inside the VIP app and on the website runner (vip.world/m/<id>) for published mini programs that have an AppSecret. In the web studio preview (merchant testing only), wx.login still fails with VIP login is only available in the VIP app because preview has no consent host.

Get an AppSecret

Studio → your project → 5. VIP login (AppSecret) → Generate AppSecret. It is shown once: store it in your server's environment (never in mini program code or a repository). Reset AppSecret replaces it immediately and cancels unused codes. The AppID is the project ID (vipmp_…).

Mini program code

// 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('login failed', err.errMsg),
    });
  },
});

Exchange the code on your backend

POST https://api.vip.world/api/mini-programs/oauth/code2session with a JSON body. The WeChat field names appid and js_code are accepted too. Send the AppSecret only in the body; requests with the secret in the URL are rejected.

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

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

Success:

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

With the profile scope, data also contains "nickname" and "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); // your database
  res.json({ token: await createYourSessionToken(user) });          // your own session
});
app.listen(8080);

Python (standard library):

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"}

Errors

HTTPcodeMeaning
40040001Missing or malformed appId, secret or code
40140125Wrong AppID or AppSecret
40040029Unknown, expired or other-app code
40040163Code already used (each code works once)
40340013The VIP user is no longer available
40310002The mini program is not published or is suspended
40942201No AppSecret yet (VIP login is off)
42940002 / 45011Too many requests

Security checklist

7. Review and publishing

8. Naming

Call your product a VIP mini program (VIP 小程序). You may say it is "compatible with the WeChat-style source format". Do not present it as a WeChat mini program or use WeChat logos.