Contents

1 Overview

1.1 How to Use JSSDK

1.1.1 Step 1: Link a domain name

1.1.2 Step 2: Introduce JS file

1.1.3 Step 3: Inject the permission verification configuration via the config API

1.1.4 Step 4: Process the successful verification via the ready API

1.1.5 Step 5: Process the failed verification via the error API

1.2 API Request Format

2 Basic API

2.1 Determining Whether the Current App Version Supports the Specified JS API

3 Sharing APIs

3.1 Customizing the Sharing Content of "Send to Chat" and "Share on QQ" Buttons

3.2 Customizing the Sharing Content of "Share on Moments" and "Share on Qzone" Buttons

3.3 Obtaining the Tapping Status of the "Share on Moments" Button and Customizing the Sharing Content (To Be Discarded)

3.4 Obtaining the Tapping Status of the "Send to Chat" Button and Customizing the Sharing Content (To Be Discarded)

3.5 Obtaining the Tapping Status of the "Share on QQ" Button and Customizing the Sharing Content (To Be Discarded)

3.6 Obtaining the Tapping Status of the "Share on Tencent Weibo" Button and Customizing the Sharing Content

3.7 Obtaining the Tapping Status of the "Share on Qzone" Button and Customizing the Sharing Content (To Be Discarded)

4 Image APIs

4.1 Taking a Photo or Selecting an Image from the Mobile Album

4.2 Image Preview

4.3 Image Upload

4.4 Image Download

4.5 Obtaining Local Images

5 Audio APIs

5.1 Starting Recording

5.2 Stopping Recording

5.3 Listening on the Event that Recording Stops Automatically

5.4 Voice Playback

5.5 Pausing Playback

5.6 Stopping Playback

5.7 Listening on the Event that Voice Playback Ends

5.8 Voice Upload

5.9 Voice Download

6 Smart API

6.1 Recognizing Audio and Returning Recognition Results

7 Device Information API

7.1 Obtaining Network Status

8 Geographic Location APIs

8.1 Viewing Location Using the WeChat Built-in Map

8.2 Obtaining Geographic Location

9 Shake Nearby APIs

9.1 Enabling Search for Nearby iBeacon Devices

9.2 Disabling Search for Nearby iBeacon Devices

9.3 Listening on Nearby iBeacon Devices

10 Interface Operation APIs

10.1 Hiding the Menu in the Upper Right Corner

10.2 Displaying the Menu in the Upper Right Corner

10.3 Closing the Current Webpage Window

10.4 Hiding Feature Buttons in Batch

10.5 Displaying Feature Buttons in Batch

10.6 Hiding All Non-Basic Buttons

10.7 Displaying All Feature Buttons

11 WeChat Scan API

11.1 Invoking WeChat Scan

12 WeChat eShop API

12.1 Redirecting to WeChat Product Page

13 WeChat Card/Coupon APIs

13.1 Obtaining api_ticket

13.2 Fetching Applicable Card/Coupon List and Obtaining User Selection Information

13.3 Adding Cards/Coupons in Batch

13.4 Viewing Cards/Coupons in WeChat Cards & Offers

14 WeChat Pay API

14.1 Initiating a Request for Making Payment via WeChat Pay

15 Quick Entry API

15.1 Sharing Recipient Address in WeChat

16 Appendix 1 - JS-SDK Access Permission Signature Algorithm

17 Appendix 2 - List of All JS APIs

18 Appendix 3 - List of All Menu Items

19 Appendix 4 - Card/Coupon Extension Field and Signature Generation Algorithm

20 Appendix 5 - Common Errors and Solutions

21 Appendix 6 - DEMO Page and Sample Code

22 Appendix 7 - Feedback

Overview

Delivered by the WeChat Official Accounts Platform, WeChat JS-SDK is a web development toolkit based on WeChat for web developers.

By using WeChat JS-SDK, web developers can efficiently use various capabilities of mobile phones through WeChat, such as photo taking, image selecting, voice, and location. Meanwhile, they can directly use WeChat-exclusive features including WeChat Sharing, Scan, Cards & Offers, and WeChat Pay to provide a better web experience for WeChat users.

This document explains how to use WeChat JS-SDK for web developers and describes relevant considerations.

How to Use JSSDK

Log in to the WeChat Official Accounts Platform and navigate to Official Account Settings > Feature Settings. Then, enter the JS API Secure Domain Name.

Note: After login, you can view corresponding API permissions in the Developer Center.

Step 2: Introduce JS file

Introduce the following JS file on the page for calling JS APIs: http://res.wx.qq.com/open/js/jweixin-1.4.0.js (HTTPS is supported).

To further improve the stability of the service, access the following file if the preceding resource is inaccessible: http://res2.wx.qq.com/open/js/jweixin-1.4.0.js (HTTPS is supported).

Note: Loading the JS file with the AMD/CMD standard module loading method is supported.

Step 3: Inject the permission verification configuration via the config API

For any page that needs to use JS-SDK, you must inject configuration information to the page before it can be called. Note that the same URL only needs to be called once. For the SPA web app that changes the URL, you can call the URL every time it changes. Currently, the WeChat app for Android does not support the new HTML5 feature of pushState, and therefore using pushState to implement the web app's page will cause the signature to fail. This issue will be fixed in Android 6.2.

wx.config({
	debug: true, // Enable the debug mode, and the returned values of all APIs that are called will be output as alerts in the app. You can view the incoming parameters on your PC and print the parameter information in a log on PC only.
	appId: '', // (Required) The unique identifier of the Official Account
	timestamp: , // (Required) The timestamp of signature generation
	nonceStr: '', // (Required) The random string for the signature
	signature: '',// (Required) The signature
	jsApiList: [] // (Required) The list of required JS APIs
});

See Appendix 1 for the signature algorithm and Appendix 2 for the list of JS APIs, both at the end of this document.

Step 4: Process the successful verification via the ready API

wx.ready(function(){
	// After the config information is verified, the ready method is executed. API calls are possible only after the config API obtains the result. Calling config is a client-side asynchronous operation. Therefore, if relevant APIs need to be called when the page is loaded, you must call these APIs in the ready function to ensure their proper execution. For APIs that are called only by a user trigger, you can call them directly without having to do so in the ready function.
});

Step 5: Process the failed verification via the error API

wx.error(function(res){
	// If the config information fails to be verified, the error function will be executed. If the verification fails due to the expired signature, you can view specific error message by enabling the debug mode of config. Alternatively, you can check the returned res parameter for the same purpose. For the SPA, the signature can be updated here.
});

API Request Format

All APIs are called by the wx object (or the jWeixin object). A parameter is an object. In addition to the parameters that each API itself needs to pass, the following common parameters are also required:

  1. success: The callback function that is executed when the API call succeeds.

  2. fail: The callback function that is executed when the API call fails.

  3. complete: The callback function that is executed when the API call is completed, regardless of success or failure.

  4. cancel: The callback function that is executed when the user taps Cancel. It is valid for certain APIs involving user cancellation.

  5. trigger: The method that is triggered when listening on the event that a button in the menu is tapped. This method only supports menu-related APIs.

Note: Do not attempt to use an ajax asynchronous request in the trigger to modify the content of the current share, because sharing in the app is a synchronous operation and the ajax response package has not returned yet in this case.

All of the preceding functions have a parameter whose type is object. In addition to the data returned by each API, another common property named errMsg is returned. The value format of this property is as follows:

For a successful call: xxx:ok, where xxx is the name of the API being called.

For cancellation by user: xxx:cancel, where xxx is the name of the API being called.

For a failed call: The specific error message.

Basic API

Determining Whether the Current APP Version Supports the Specified JS API

wx.checkJsApi({
	jsApiList: ['chooseImage'], // The list of JS APIs to be verified. See Appendix 2 for the list of all JS APIs.
	success: function(res) {
	// The value is returned as a key-value pair, which is true for an available API and false for an unavailable API.
	// For example: {"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
	}
});

Note: The checkJsApi API is a new reserved API introduced in WeChat 6.0.2. Previously released APIs cannot be verified with checkJsApi.

Sharing APIs

Note that no violations are allowed, such as incentivized sharing. For any incentivized sharing behavior, API permissions for the Official Account will be permanently reclaimed. For detailed rules, see: Moments Management FAQ.

Note that the previous wx.onMenuShareTimeline, wx.onMenuShareAppMessage, wx.onMenuShareQQ, and wx.onMenuShareQZone APIs will be discarded soon. Therefore, please replace them with the wx.updateAppMessageShareData and updateTimelineShareData APIs that are supported by WeChat 6.7.2 and JSSDK 1.4.0 or above.

Customizing the Sharing Content of "Send to Chat" and "Share on QQ" Buttons (1.4.0)

wx.ready(function () {   // This must be called before the user potentially taps the **Share** button.
    wx.updateAppMessageShareData({ 
        title: '', // The sharing title
        desc: '', // The sharing description
        link: '', // The sharing link whose domain name or path must be consistent with the JS secure domain name of the Official Account corresponding to the current page.
        imgUrl: '', // The sharing icon
        success: function () {
          // Indicates that the configuration is successful.
        }
    })
}); 

Customizing the Sharing Content of "Share on Moments" and "Share on Qzone" Buttons (1.4.0)

wx.ready(function () {      // This must be called before the user potentially taps the **Share** button.
    wx.updateTimelineShareData({ 
        title: '', // The sharing title
        link: '', // The sharing link whose domain name or path must be consistent with the JS secure domain name of the Official Account corresponding to the current page.
        imgUrl: '', // The sharing icon
        success: function () {
          // Indicates that the configuration is successful.
        }
    })
}); 

Obtaining the Tapping Status of the "Share on Moments" Button and Customizing the Sharing Content (To Be Discarded)

wx.onMenuShareTimeline({
	title: '', // The sharing title
	link: '', // The sharing link whose domain name or path must be consistent with the JS secure domain name of the Official Account corresponding to the current page.
	imgUrl: '', // The sharing icon
	success: function () {
	// The callback function that is executed after the user taps **Share**.
},

Obtaining the Tapping Status of the "Send to Chat" Button and Customizing the Sharing Content (To Be Discarded)

wx.onMenuShareAppMessage({
title: '', // The sharing title
desc: '', // The sharing description
link: '', // The sharing link whose domain name or path must be consistent with the JS secure domain name of the Official Account corresponding to the current page.
imgUrl: '', // The sharing icon
type: '', // The sharing type, which can be music, video, or link. "link" is used by default if this parameter is left empty.
dataUrl: '', // If the type is music or video, provide the data link. This parameter is left empty by default.
success: function () {
// The callback function that is executed after the user taps **Share**.
}
});

Obtaining the Tapping Status of the "Share on QQ" Button and Customizing the Sharing Content (To Be Discarded)

wx.onMenuShareQQ({
title: '', // The sharing title
desc: '', // The sharing description
link: '', // The sharing link
imgUrl: '', // The sharing icon
success: function () {
// The callback function that is executed after the user confirms the share.
},
cancel: function () {
// The callback function that is executed after the user cancels the share.
}
});

Obtaining the Tapping Status of the "Share on Tencent Weibo" Button and Customizing the Sharing Content

wx.onMenuShareWeibo({
title: '', // The sharing title
desc: '', // The sharing description
link: '', // The sharing link
imgUrl: '', // The sharing icon
success: function () {
// The callback function that is executed after the user confirms the share.
},
cancel: function () {
// The callback function that is executed after the user cancels the share.
}
});

Obtaining the Tapping Status of the "Share on Qzone" Button and Customizing the Sharing Content (To Be Discarded)

wx.onMenuShareQZone({
title: '', // The sharing title
desc: '', // The sharing description
link: '', // The sharing link
imgUrl: '', // The sharing icon
success: function () {
// The callback function that is executed after the user confirms the share.
},
cancel: function () {
// The callback function that is executed after the user cancels the share.
}
});

Image APIs

Taking a Photo or Selecting an Image from the Mobile Album

wx.chooseImage({
count: 1, // The default is 9.
sizeType: ['original', 'compressed'], // You can specify whether the image is original or compressed. The default is both.
sourceType: ['album', 'camera'], // You can specify whether the source is the album or the camera. The default is both.
success: function (res) {
var localIds = res.localIds; // The list of local IDs of the selected images are returned. localId can be used to display an image as the src property of the img tag.
}
});

Image Preview

wx.previewImage({
current: '', // The HTTP link of the current image.
urls: [] // The list of HTTP links of the images to preview.
});

Image Upload

wx.uploadImage({
localId: '', // The local ID of the image to be uploaded, which is obtained via the chooseImage API.
isShowProgressTips: 1, // Displays the progress prompt. It defaults to 1.
success: function (res) {
var serverId = res.serverId; // The server-side ID of the image is returned.
}
});

Note: The uploaded image remains valid for 3 days. You can use the WeChat Multimedia API to download images to your own server. The serverId obtained here is media_id.

Image Download

wx.downloadImage({
serverId: '', // The server-side ID of the image to be downloaded, which is obtained via the uploadImage API.
isShowProgressTips: 1, // Displays the progress prompt. It defaults to 1.
success: function (res) {
var localId = res.localId; // The local ID of the downloaded image is returned.
}
});

Obtaining Local Images

wx.getLocalImgData({
localId: '', // The localID of the image.
success: function (res) {
var localData = res.localData; // localData is the Base64-coded data of the image. The image can be displayed by using the img tag.
}
});

Note: This API is only available for iOS WKWebview to fix the problem that iOS WKWebview does not support directly displaying an image by using localId. For details, refer to the Web Development Adaptation Guide for iOS WKWebview.

Audio APIs

Starting Recording

wx.startRecord();

Stopping Recording

wx.stopRecord({
success: function (res) {
var localId = res.localId;
}
});

Listening on the Event that Recording Stops Automatically

wx.onVoiceRecordEnd({
// The complete callback is executed when the time elapsed after the recording ends is greater than one minute.
complete: function (res) {
var localId = res.localId;
}
});

Voice Playback

wx.playVoice({
localId: '' // The local ID of the audio to be played, which is obtained via the stopRecord API.
});

Pausing Playback

wx.pauseVoice({
localId: '' // The local ID of the audio to be paused, which is obtained via the stopRecord API.
});

Stopping Playback

wx.stopVoice({
localId: '' // The local ID of the audio to be stopped, which is obtained via the stopRecord API.
});

Listening on the Event that Voice Playback Ends

wx.onVoicePlayEnd({
success: function (res) {
var localId = res.localId; // The local ID of the audio is returned.
}
});

Voice Upload

wx.uploadVoice({
localId: '', // The local ID of the audio to be uploaded, which is obtained via the stopRecord API.
isShowProgressTips: 1, // Displays the progress prompt. It defaults to 1.
success: function (res) {
var serverId = res.serverId; // The server-side ID of the audio is returned.
}
});

Note: The uploaded audio remains valid for 3 days. You can use the WeChat Multimedia API to download the audio to your own server. The serverId obtained here is media_id. Currently, the call frequency of the multimedia file download API is limited to 10,000 times per day. If you need to increase the frequency, log in to the WeChat Official Accounts Platform and apply for a temporary increase of the frequency in Development > API Permissions.

Voice Download

wx.downloadVoice({
serverId: '', // The server-side ID of the audio to be downloaded, which is obtained via the uploadVoice API.
isShowProgressTips: 1, // Displays the progress prompt. It defaults to 1.
success: function (res) {
var localId = res.localId; // The local ID of the audio is returned.
}
});

Smart API

Recognizing Audio and Returning Recognition Results

wx.translateVoice({
localId: '', // The local ID of the audio to be recognized, which is obtained via the recording-related API.
isShowProgressTips: 1, // Displays the progress prompt. It defaults to 1.
success: function (res) {
alert(res.translateResult); // The audio recognition result.
}
});

Device Information API

Obtaining Network Status

wx.getNetworkType({
success: function (res) {
var networkType = res.networkType; // Returned network type, which can be 2G, 3G, 4G, or Wi-Fi.
}
});

Geographic Location APIs

Viewing Location Using the WeChat Built-in Map

wx.openLocation({
latitude: 0, // The latitude, which is a floating number ranging from 90 to -90.
longitude: 0, // The longitude, which is a floating number ranging from 180 to -180.
name: '', // Location name
address: '', // Address details
scale: 1, // The zoom level of the map, which is an integer ranging from 1 to 28. It defaults to 28.
infoUrl: '' // The hyperlink displayed at the bottom of the location viewing interface, which can be tapped for redirect.
});

Obtaining Geographic Location

wx.getLocation({
type: 'wgs84', // It defaults to the GPS coordinates of wgs84. To return the Mars Coordinates that can be directly used by openLocation, input 'gcj02'.
success: function (res) {
var latitude = res.latitude; // The latitude, which is a floating number ranging from 90 to -90.
var longitude = res.longitude; // The longitude, which is a floating number ranging from 180 to -180.
var speed = res.speed; // The speed (in m/s)
var accuracy = res.accuracy; // The accuracy of the location
}
});

Shake Nearby APIs

Enabling Search for Nearby iBeacon Devices

wx.startSearchBeacons({
ticket:"",  // The business ticket of WeChat Shake Nearby. The system automatically adds it to the page link that is popped up via Shake Nearby.
complete:function(argv){
// The callback function that is executed after the search is enabled.
}
});

Note: To access the Shake Nearby feature, refer to "Apply for Activating Shake Nearby".

Disabling Search for Nearby iBeacon Devices

wx.stopSearchBeacons({
complete:function(res){
// The callback function that is executed after the search is disabled.
}
});

Listening on Nearby iBeacon Devices

wx.onSearchBeacons({
complete:function(argv){
// The callback function that returns the list of the nearby devices registered by the merchant in an array format.
}
});

Note: For the instructions and the description of more returned results of the Share Nearby APIs, refer to "Get Device Information via Shake Nearby".

Interface Operation APIs

Closing the Current Webpage Window

wx.closeWindow();

Hiding Feature Buttons in Batch

wx.hideMenuItems({
menuList: [] // The menu items to be hidden. You can only hide the "Communication" and "Protection" buttons. For all menu items, see Appendix 3.
});

Displaying Feature Buttons in Batch

wx.showMenuItems({
menuList: [] // The menu items to be displayed. For all menu items, see Appendix 3.
});

Hiding All Non-Basic Buttons

wx.hideAllNonBaseMenuItem();
// For detailed "basic" buttons, see Appendix 3.

Displaying All Feature Buttons

wx.showAllNonBaseMenuItem();

WeChat Scan API

Invoking WeChat Scan

wx.scanQRCode({
needResult: 0, // It defaults to 0. The scan result is processed by WeChat. If the value is 1, the scan result is returned directly.
scanType: ["qrCode","barCode"], // You can specify whether to scan the QR code or the barcode. The default is both.
success: function (res) {
var result = res.resultStr; // The code scan result returned when the value of needResult is 1.
}
});

WeChat eShop API

Redirecting to WeChat Product Page

wx.openProductSpecificView({
productId: '', // The product ID
viewType: '' // 0: Details page of a general product (default); 1: Details page of a scanned product; 2: Details page of an eShop product.
});

<span id = "53>

WeChat Card/Coupon APIs

The signature credential api_ticket used in WeChat Card/Coupon APIs is different from the signature credential jsapi_ticket used by config in Step 3. During the process of calling WeChat Card/Coupon JS-SDK, developers need to implement two different signatures in turn and properly cache the credential.

Obtaining api_ticket

The api_ticket is a temporary ticket that is used to call WeChat Card/Coupon JS APIs. It is valid for 7200 seconds and is obtained via access_token.

Notes:

  1. The api_ticket used for the card/coupon API signature is different from the jsapi_ticket used in Step 3 for injecting the permission verification configuration via the config API.

  2. Since the number of calls to the API for getting the api_ticket is very limited, frequently refreshing api_ticket can result in restricted API calling, affecting self-developed businesses. Therefore, you need to store and update api_ticket in your services.

API request format

HTTP request method: GET
https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card

Parameters

Parameter Required Description
access_token Yes API call credentials

Response data

Data example:

{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKdvsdshFKA",
"expires_in":7200
}
Parameter Description
errcode Error code
errmsg Error message
ticket The api_ticket, which is the signature credential used in WeChat Card/Coupon API.
expires_in Validity period

Fetching Applicable Card/Coupon List and Obtaining User Selection Information

wx.chooseCard({
shopId: '', // Store ID
cardType: '', // Card/Coupon type
cardId: '', // Card/Coupon ID
timestamp: 0, // The timestamp of the card/coupon signature
nonceStr: '', // The random string of the card/coupon signature
signType: '', // The signature method, which defaults to 'SHA1'
cardSign: '', // The card/coupon signature
success: function (res) {
var cardList= res.cardList; // The information on the list of cards/coupons selected by the user
}
});
Parameter Required Type Example Description
shopId No string(24) 1234 The store ID. The shopID is used to fetch the list of cards/coupons with the specified location_list (shopID). This parameter is optional.
cardType No string(24) GROUPON The card/coupon type. It is used to fetch the list of cards/coupons of the specified coupon type. This parameter is optional. When cardType is empty, the list of all cards/coupons is fetched by default.
cardId No string(32) p1Pj9jr90_SQRaVqYI239Ka1erk The coupon ID. It is used to fetch the list of cards/coupons with the specified cardId. This parameter is optional. When cardId is empty, the list of all cards/coupons is fetched by default.
timestamp Yes string(32) 14300000000 The timestamp
nonceStr Yes string(32) sduhi123 The random string
signType Yes string(32) SHA1 The signature method. Only SHA1 is supported.
cardSign Yes string(64) abcsdijcous123 The signature

For details on cardSign, see Appendix 4.

Note: An incorrect signature will cause the fetched card/coupon list to be empty. Therefore, always check the validity of the parameters relevant to the signature.

Important

The fetched list is solely related to the user's local cards/coupons. Generally, there are three exceptional cases where the fetched list is empty: the signature is incorrect, the timestamp is invalid, and the filtering mechanism is incorrect. For troubleshooting, you need to check all these potential causes in turn.

Adding Cards/Coupons in Batch

wx.addCard({
cardList: [{
cardId: '',
cardExt: ''
}], // The list of cards/coupons to be added
success: function (res) {
var cardList = res.cardList; // The information on the list of added cards/coupons
}
});

For details on cardExt, see Appendix 4. If you encounter an exception such as an signature error or no remaining coupons, perform troubleshooting by referring to Troubleshooting Card/Coupon Signature Errors.

Viewing Cards/Coupons in WeChat Cards & Offers

wx.openCard({
cardList: [{
cardId: '',
code: ''
}]// The list of cards/coupons to be opened
});

WeChat Pay API

Initiating a Request for Making Payment via WeChat Pay

wx.chooseWXPay({
timestamp: 0, // The timestamp of the payment signature. Note that all the timestamp-based fields used in WeChat JS-SDK are in lower case. However, you must capitalize the S letter in timeStamp used by the backend of the latest version of WeChat Pay.
nonceStr: '', // The random string of the payment signature, which must be not greater than 32 characters.
package: '', // The value of the prepay_id parameter returned by the common payment API. The submission format is: prepay_id=\*\*\*).
signType: '', // The signature method, which defaults to 'SHA1'. You need to pass 'MD5' for the latest version of WeChat Pay.
paySign: '', // The payment signature
success: function (res) {
// The callback function that is executed after successful payment.
}
});

Note: The prepay_id is obtained via the common order placement API of WeChat Pay. The paySign is generated by using the common Sign signature generation method of WeChat Pay. Note that appId is also required in the signature in this case. This appId is the same as the appId passed in config. As a result, the parameters involved in the signature are appId, timeStamp, nonceStr, package, and signType.

WeChat Pay development documentation: https://pay.weixin.qq.com/wiki/doc/api/index.html

Quick Entry API

Sharing Recipient Address

wx.openAddress({
success: function (res) {
var userName = res.userName; // Recipient name
var postalCode = res.postalCode; // Postal code
var provinceName = res.provinceName; // Tier-1 address of national standard recipient address (province)
var cityName = res.cityName; // Tier-2 address of national standard recipient address (city)
var countryName = res.countryName; // Tier-3 address of national standard recipient address (country)
var detailInfo = res.detailInfo; // Detailed recipient address
var nationalCode = res.nationalCode; // Country code of the recipient address
var telNumber = res.telNumber; // Mobile number of the recipient
}
});

Note:

The data fields used for WeChat address sharing include:

  • Recipient Name
  • Region (with the province, city, and district)
  • Address
  • Postal Code
  • Contact Number Among these fields, the region must be formatted as a national standard three-tier regional code, such as "Guangdong Province - Guangzhou City - Tianhe District", and the corresponding postal code is 510630. For details, visit http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201401/t20140116_501070.html.

Appendix 1 - JS-SDK Access Permission Signature Algorithm

jsapi_ticket

The jsapi_ticket is a temporary ticket used by the Official Account to call WeChat JS APIs, which is obtained using access_token and valid for 7200s. Since the number of calls to the API for getting the api_ticket is very limited, frequently refreshing api_ticket can result in restricted API calling, affecting self-developed businesses. Therefore, you must globally cache jsapi_ticket in your services.

  1. Obtain access_token (which is valid for 7200s and must be globally cached in your services) by referring to this document: ../15/54ce45d8d30b6bf6758f68d2e95bc627.html.

  2. Use the http_GET method to get jsapi_ticket (which is valid for 7200s and must be globally cached in your services) with the access_token obtained in the previous step: https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

The following JSON is returned for a successful request:

{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in":7200
}

After obtaining jsapi_ticket, you can generate the signature for JS-SDK permission verification.

Signature Algorithm

The signature generation rule is as follows: The fields involved in the signature include noncestr (the random string), the valid jsapi_ticket, timestamp (the timestamp), and url (the URL of the current webpage, excluding the hash tag (#) and the part following the hash tag). Sort the parameters to be signed according to the ASCII codes of their names in ascending lexicographical order, and join these parameters into string1 in the URL key-value format (i.e., key1=value1 & key2=value2...). Note that all parameter names are lowercase characters. Sign string1 using sha1. Both the field name and field value shall be the original values without URL escape,

i.e. signature = sha1 (string1).

noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=http://mp.weixin.qq.com?params=value

Step 1: Sort the parameters to be signed according to the ASCII codes of their names in ascending lexicographical order, and join these parameters into string1 in the URL key-value format (i.e., key1=value1 & key2=value2...):

jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value

Step 2. Sign string1 using sha1 to get a signature:

0f9de62fce790f9a083d5c99e95740ceb90c27ed

Notes

  1. The noncestr and timestamp parameters used for signing must be consistent with the nonceStr and timestamp parameters in wx.config.

  2. The URL for signing must be the full URL of the JS API calling page.

  3. For the sake of security, developers must implement the signature logic on server side.

If you encounter errors such as invalid signature, see Appendix 5 for common errors and their solutions.

Appendix 2 - List of All JS APIs

APIs for version 1.4.0

updateAppMessageShareData

updateTimelineShareData

onMenuShareTimeline (to be discarded)

onMenuShareAppMessage (to be discarded)

onMenuShareQQ (to be discarded)

onMenuShareWeibo

onMenuShareQZone

startRecord

stopRecord

onVoiceRecordEnd

playVoice

pauseVoice

stopVoice

onVoicePlayEnd

uploadVoice

downloadVoice

chooseImage

previewImage

uploadImage

downloadImage

translateVoice

getNetworkType

openLocation

getLocation

hideOptionMenu

showOptionMenu

hideMenuItems

showMenuItems

hideAllNonBaseMenuItem

showAllNonBaseMenuItem

closeWindow

scanQRCode

chooseWXPay

openProductSpecificView

addCard

chooseCard

openCard

Appendix 3 - List of All Menu Items

Basic

Report: "menuItem:exposeArticle"

Reset Font: "menuItem:setFont"

Day Mode: "menuItem:dayMode"

Night Mode: "menuItem:nightMode"

Refresh: "menuItem:refresh"

View Official Account (added): "menuItem:profile"

View Official Account (not added): "menuItem:addContact"

Communication

Send to Chat: "menuItem:share:appMessage"

Share on Moments: "menuItem:share:timeline"

Share on QQ: "menuItem:share:qq"

Share on Weibo: "menuItem:share:weiboApp"

Add to Favorites: "menuItem:favorite"

Share on Facebook: "menuItem:share:facebook"

Share on Qzone: "menuItem:share:QZone"

Protection

Edit Tag: "menuItem:editTag"

Delete: "menuItem:delete"

Copy Link: "menuItem:copyUrl"

Original Webpage: "menuItem:originPage"

Reading Mode: "menuItem:readMode"

Open in QQ Browser: "menuItem:openWithQQBrowser"

Open in Safari: "menuItem:openWithSafari"

Email: "menuItem:share:email"

Special Official Accounts: "menuItem:share:brand"

Appendix 4 - Card/Coupon Extension Field and Signature Generation Algorithm

This section is for JSSDK users. JSAPI users can skip this section.

The card/coupon signature and the JSSDK signature are completely independent due to their completely different algorithms and meanings. The JSSDK signature is a layer of authentication that is required for all JS APIs, which is used to identify the caller and has nothing to do with the card/coupon itself. Comparatively, the card/coupon signature is designed with a set of independent signature protocols in consideration of protocol scalability and simple anti-tampering. In addition, due to historical reasons, JS APIs for cards/coupons appeared prior to JSSDK. At that time, JSAPI did not have an authentication system, and therefore the appsecret/api_ticket identity information was added to the card/coupon signature.

Card/Coupon api_ticket

Card/Coupon api_ticket is a temporary ticket for calling card/coupon-related APIs, which is obtained using access_token and valid for 7200s. Different from jsapi_ticket, the number of calls to the API for getting the api_ticket is very limited, so that frequently refreshing api_ticket will result in restricted API calling, affecting self-developed businesses. Therefore, you must globally cache jsapi_ticket in your services.

  1. Obtain access_token (which is valid for 7200s and must be globally cached in your services) by referring to this document: ../15/54ce45d8d30b6bf6758f68d2e95bc627.html.

  2. Use the http_GET method to get api_ticket (which is valid for 7200s and must be globally cached in your services) with the access_token obtained in the previous step: https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card

Description of the card/coupon extension field cardExt

cardExt is a JSON string, which is the unique information assigned by the merchant to the card/coupon. It contains the following fields:

Field Required Involved in Signature Description
code No Yes The specified card/coupon code that can be claimed only once. This parameter is required for cards/coupons in custom code mode and optional for cards/coupons in non-custom and pre-set code modes. For details, see "use_custom_code".
openid No Yes The openid of the specified claimer who can claim the card/coupon only. This parameter is required for cards/coupons whose bind_openid field is true and optional for cards/coupons whose bind_openid field is false.
timestamp Yes Yes The timestamp generated by the merchant, which is the number of seconds elapsed from January 1, 1970 at 00:00:00 to the current time and needs to be converted into a string. This parameter is passed after generated by the merchant, and its value must be dynamically generated for each addition request. Duplicate values may cause claim failure.
nonce_str No Yes A random string, which is set and passed by developers to enhance security (the request may be resent if this parameter is left empty). It consists up to 32 characters comprised of uppercase and lowercase letters and numbers. The value of nonce must be dynamically generated for each addition request. Duplicate values may cause claim failure.
fixed_begintimestamp No No The time when the card/couppn is claimed from a third-party system, which is a UTC+8 timestamp in sec. It is specially used when the validity period of the card/coupon is DATE_TYPE_FIX_TERM to identify the actual effective time of the card or offer. Using this API can solve the inconsistency between the start time in a merchant's system and the time when the card/coupon is claimed on WeChat.
outer_str No No The claiming channel parameter, which is used to identify the channel of the current claim.
signature Yes - A signature. The merchant signs parameters in the API list as required using SHA-1. See below for specific signature methods. This parameter is passed by the merchant according to the signature rules.

Signature description

  1. Sort the string values of api_ticket, timestamp, card_id, code, openid, and nonce_str in lexicographical order.

  2. Join the strings of the parameters into a string and encrypt the string with Sha1 to generate signature.

  3. Ensure that the timestamp and nonce fields in signature are consistent with the timestamp and nonce_str fields in card_ext.

  4. If code=1434008071, timestamp=1404896688, card_id=pjZ8Yt1XGILfi-FUsewpnnolGgZk, api_ticket=ojZ8YtyVyr30HheH3CM73y7h4jJE, and nonce_str=123, then signature=sha1(12314048966881434008071ojZ8YtyVyr30HheH3CM73y7h4jJEpjZ8Yt1XGILfi-FUsewpnnolGgZk)=f137ab68b7f8112d20ee528ab6074564e2796250.

You are strongly recommended to use the signature tool SDK in the card/coupon kit to sign, or use the debug tool to verify: http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=cardsign

Description of the card/coupon signature field cardSign

  1. Sort the string values of api_ticket, appid, location_id, timestamp, nonce_str, card_id, and card_type in lexicographical order.

  2. Join the strings of the parameters into a string and encrypt the string with Sha1 to generate cardSign.

Appendix 5 - Common Errors and Solutions

When the config API is called, the debug: true parameter can be passed to enable the debug mode. In this case, you will be alerted for an error message on the page. Common errors and their solutions are as follows:

  1. Invalid url domain. This error indicates that the domain name of the current page is not linked to the used appid. In this case, confirm that the entered domain name is correct. In addition, only port 80 (for HTTP) and port 443 (for HTTPS) are supported, and therefore you do not need to enter the port number. (One appid can be linked with three valid domain names. For details, see Section 1.1.1.)

  2. Invalid signature. We recommend that you troubleshoot this error by completing the following steps:

(1) Check that the signature algorithm is correct by using the tool on this page: http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign.

(2) Check that the nonceStr (capitalize the letter s based on the JS hump standard) and timestamp fields in config are consistent with the noncestr and timestamp fields in signature.

(3) Check that the URL is the full URL of the page (please run alert(location.href.split('#')[0]) on the current page to verify). Also, check that the URL includes 'http(s)😕/' and the GET parameters following '?', but excludes the part after the '#' hash tag.

(4) Check that the appid in config is consistent with the appid used to obtain jsapi_ticket.

(5) Check that access_token and jsapi_ticket are cached.

(6) Check that the URL for signature is dynamically obtained. For dynamic pages, see the implementation of PHP in the sample code. For HTML static pages, pass the URL to the backend for signature with ajax on the frontend, and the frontend needs to use JS to get the link of the current page except the '#' hash part (which can be done by running location.href.split('#')[0] along with encodeURIComponent), because once the page is shared, the WeChat app will append other parameters to the end of the link. If the current link is not dynamically obtained, page signature after the share will fail.

  1. The permission value is offline verifying. This error occurs when config is incorrectly executed or the jsApiList parameter of config is not passed in to the called JSAPI. In this case, we recommend that you troubleshoot this error by completing the following steps:

(1) Check that config can be correctly executed.

(2) If the JSAPI is called when the page is loaded, it must be written to the wx.ready callback.

(3) Check that the jsApiList parameter of config includes this JSAPI.

  1. Permission denied. This error indicates that this Official Account has no permission to use the JSAPI or the jsApiList parameter of config is not passed into the called JSAPI (some APIs can be used only after being verified.)

  2. Function not exist. This error indicates that the current app version does not support this API. Upgrade the app to the latest version.

  3. config:ok for version 6.0.1 but not OK for version 6.0.2 or later. (This is because earlier versions than version 6.0.2 do not perform permission verification so that config is OK, but this does not mean that the signature in your config is OK. For this reason, please check that the correct signature is generated in version 6.0.2 to ensure that your config is also OK in the later versions.)

  4. Sharing is unavailable in both iOS and Android. (Confirm that the Official Account has been verified. Only verified Official Accounts has sharing-related API permissions. If the Official Account is confirmed as verified, check whether the listening API is triggered in the wx.ready callback function.)

  5. After service launch, jsapi_ticket cannot be obtained, but no problem can be found in the test. (This is because access_token and jsapi_ticket must be cached in your own server; otherwise the frequency limit will be triggered after service launch. In this case, be sure to cache the token and ticket to reduce 2 server requests. This not only avoids the trigger frequency limit, but also speeds up your own service. Currently, a maximum of 10,000 tickets can be obtained to facilitate tests. After this threshold is exceeded, the service will no longer be available. Therefore, ensure that access_token and jsapi_ticket are cached globally before the service goes online. The validity periods of the two parameters are both 7200 seconds; otherwise the frequency limit will be triggered upon service launch, and the service will no longer be available.)

  6. How to upload multiple images through uploadImage? (Currently, only one image can be uploaded at a time. To upload multiple images, you must call this API again after the previous image has been uploaded.)

  7. Unable to preview the selected local image. (The chooseImage API already supports preview and no additional support is required.)

  8. Invalid signature occurs when I try to jump to link b through link a (for example, by using WeChat authorization login). (The link generated on the backend is the current link using JSSDK, that is, the jumped-to b link. In this case, do not use the authorization link of WeChat Login to calculate the signature. Ensure that the URL of the backend signature is the full URL of the current page using JSSDK without the '#' part.)

  9. The config:fail error occurs. (This is because the passed config parameters are incomplete. In this case, be sure to pass the required appId, timestamp, nonceStr, signature, and jsApiList parameters.)

  10. How to download multimedia resources uploaded to JSAPIs to my own server? (See the notes for the uploadVoice and uploadImage APIs in the document.)

  11. An Android device uploads a resource to the WeChat server via JSSDK, and a third party downloads the resource from WeChat to their own server, but encounters noise. (The WeChat team has fixed this problem, and the backend has been optimized against this.)

  12. After the parent domain name is linked, whether its child domain names are also available? (Yes, valid child domain names are fully supported after the parent domain name is linked.)

  13. In WeChat 6.1 for iOS, the external link of a shared image is not displayed, but only the images internally linked on Official Account pages or stored on the WeChat server can be displayed. This problem has been fixed in WeChat 6.2.

  14. Whether earlier versions need to be manually made compatible? (JSSDK is compatible with earlier versions, and therefore no extra work is required for third parties. However, some APIs are newly introduced in version 6.0.2, which therefore can only be called in the newer versions.)

  15. The Official Account payment signature is invalid, and the transaction cannot be proceeded. (Ensure that the jweixin.js version being used is the officially released version, which not only reduces user traffic, but also fixes certain bugs. You must now copy this file to third-party servers, and official maintenance is no longer available for any problems that arise in it. For the specific payment signature algorithm, refer to the WeChat Pay section in JSSDK.)

  16. Currently, the WeChat app for Andriod does not support the new HTML5 feature of pushState, and therefore using pushState to implement a page of the web app will cause the signature to fail. This problem has been fixed in WeChat 6.2 for Andriod.

  17. In Android, uploadImage is occasionally not executed in the chooseImage callback. This problem will be solved in WeChat 6.2 for Andriod. To support earlier versions, you can set a 100 ms delay in setTimeout for calling uploadImage.

  18. Require subscribe. This error indicates that you have not subscribed to this test number. This error is solely relevant to test numbers.

  19. The coordinates returned by getLocation have a deviation in openLocation. This is because getLocation returns GPS coordinates, while the Tencent Maps opened by openLocation uses Mars Coordinates. In this case, third parties must manually perform the conversion. From WeChat 6.2, Mars Coordinates can be directly obtained.

  20. View Official Account (not added): "menuItem:addContact" is not displayed. Currently, only the link that is propagated from the Official Account can be displayed, in which case the source must be the Official Account.

  21. ICP filing data synchronization is delayed for one day. Therefore, complete linking on the next day.

Appendix 6 - DEMO Page and Sample Code

DEMO page:

http://demo.open.weixin.qq.com/jssdk

Sample code:

http://demo.open.weixin.qq.com/jssdk/sample.zip

Note: The link provides sample code in PHP, Java, Node.js, and Python for reference by third parties. The third parties must cache the obtained accesstoken and jsapi_ticket to ensure that the frequency limit is not triggered.

Appendix 7 - Feedback

Email: weixin-open@qq.com

Subject: [WeChat JS-SDK Feedback]

Content:

Describe the problem concisely and explain the problem scenario clearly. Attach screenshots as needed. The WeChat team will process your feedback as soon as possible.