外观
看购 JSSDK 开发文档
概述
看购 JSSDK 是看购平台面向网页开发者提供的、基于看购 App 内的网页开发工具包。
通过使用看购 JSSDK,网页开发者可借助看购 App 高效地使用拍照、选图、扫一扫等手机系统的能力,同时可以直接使用看购支付、识别用户身份等看购特有的能力,为用户提供更优质的网页体验。
本文档面向网页开发者介绍看购 JSSDK 如何使用及相关注意事项。
还没有创建应用?
先看起步指南,它会带你完成注册、实名认证、创建应用和域名验证。本文假设你已经拿到了 AppKey。
与微信 JSSDK 的关系
看购 JSSDK 的方法名与参数名一律与微信 JSSDK 保持一致。从公众号 H5 迁移过来的页面,基本不用改调用代码。看购暂时用不到的参数也保留占位——照传不会报错、不会被静默改写,将来补齐能力时调用方无需再改。
两点需要注意:
- 签名不经过页面。 微信要求页面自己带
timestamp/nonceStr/signature;看购在config时由 App 与服务端完成校验,这三个参数传了会被忽略。 jsApiList不做权限控制。 看购不按清单开权限,传了只用于debug模式下的提示。
ready 与 error 的触发时机与微信完全一致:ready 只在初始化成功时触发,失败只触发 error,两者互斥。进了 ready 就代表接口可用。
尚未由 App 实现的能力保留了同名方法,调用时走 fail 回调并给出明确的 errMsg,而不是抛异常或静默无声——页面能一眼看出是"这个端还没做",而不是"我参数写错了"。用 kg.checkJsApi 可以提前问出支持情况。
能力支持一览
| 分类 | 接口 | 状态 |
|---|---|---|
| 基础 | config ready error checkJsApi | ✅ 可用 |
| 用户 | getOpenId getUnionId getJsApiTicket getUserProfile | ✅ 可用 |
| 图像 | chooseImage getLocalImgData | ✅ 可用 |
| 扫一扫 | scanQRCode | ✅ 可用 |
| 界面 | closeWindow | ✅ 可用 |
| 支付 | chooseWXPay | ✅ 可用 |
其余与微信同名的接口(图像上传下载、菜单控制、音频、设备、位置)当前尚未实现,方法已保留,调用一律走 fail。清单见尚未实现的接口。
JSSDK 使用步骤
步骤一:绑定域名
先登录看购开放平台,进入「应用管理 → 应用列表」,在你的应用中填写「网站域名」并完成验证。

验证方式:下载 kg_verify_{WebsiteKey}.txt,放到网站根目录,确保可通过 https://你的域名/kg_verify_{WebsiteKey}.txt 直接访问。
WARNING
未完成域名验证时,kg.config 会直接失败。所有要调用 JSSDK 的页面都必须在这个域名之下。
步骤二:引入 JS 文件
在需要调用 JS 接口的页面引入如下 JS 文件:
html
<script src="https://kg.citv.cc/jssdk/jssdk.min.js"></script>TIP
如果你把 SDK 文件下载到了自己的服务器,也可以引用自己的路径,功能一致。建议随平台版本及时更新。
步骤三:通过 config 接口注入配置
所有需要使用 JSSDK 的页面必须先注入配置信息,否则将无法调用。
js
kg.config({
debug: false, // 开启调试模式,调用的所有 api 的返回值会在客户端 console 打印
appId: "YOUR_APP_KEY", // 必填,应用的 AppKey
timestamp: "", // 占位,看购不使用
nonceStr: "", // 占位,看购不使用
signature: "", // 占位,看购不使用
jsApiList: ["chooseImage", "scanQRCode", "chooseWXPay"], // 占位,仅 debug 时用于提示
});与微信的差别
微信要求你在服务器上用 jsapi_ticket 计算 signature 并传进来。看购不需要——App 在页面加载前已经把当前用户的身份注入到了页面上下文,config 时由 SDK 与服务端直接完成校验。所以 timestamp / nonceStr / signature 传空即可。
步骤四:通过 ready 接口处理成功验证
js
kg.ready(function () {
// config 信息验证后会执行 ready 方法
// 所有接口调用都必须在 ready 函数中进行,以确保正确执行
});TIP
ready 只在初始化成功时触发,失败一律走下一步的 error,两者互斥、各触发一次。所以 ready 里不需要再判断一次是否可用。
如果在 config 完成之后才注册 ready,成功时会同步立即触发,不会漏掉。
步骤五:通过 error 接口处理失败验证
js
kg.error(function (res) {
// config 信息验证失败会执行 error 函数
// res 形如 { errMsg: 'config:fail H5APP 未配置 Website' }
console.error(res.errMsg);
});也可以在任意时刻同步取错误信息:
js
var err = kg.getInitError(); // 成功为 null,失败为具体原因接口调用说明
所有与微信同名的接口都使用微信那套回调约定:
js
kg.某接口({
// …接口自己的参数…
success: function (res) {}, // 接口调用成功时执行
fail: function (res) {}, // 接口调用失败时执行
cancel: function (res) {}, // 用户点击取消时执行
complete: function (res) {}, // 接口调用完成时执行,无论成功失败都会执行
});以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性 errMsg,其值格式如下:
| 情况 | errMsg |
|---|---|
| 调用成功 | '<接口名>:ok' |
| 用户取消 | '<接口名>:cancel' |
| 调用失败 | '<接口名>:fail <失败原因>' |
另一种回调风格
chooseImage / scanQRCode / chooseWXPay / getUserProfile 也支持 function (err, res) 这种 Node 风格的回调。两种写法等价,新代码建议用上面与微信一致的写法。
在普通浏览器中调试
在看购 App 之外打开页面时,SDK 检测不到用户身份,会自动进入 mock 模式:openId 是模拟值,原生能力返回模拟数据。
这样你可以先在电脑上把页面逻辑调通,再上真机验证原生能力。打开 debug: true 后,每次调用的结果都会打到 console。
基础接口
判断当前客户端版本是否支持指定 JS 接口
js
kg.checkJsApi({
jsApiList: ["chooseImage", "getLocation", "chooseWXPay"],
success: function (res) {
// res.checkResult => { chooseImage: true, getLocation: false, chooseWXPay: true }
if (!res.checkResult.getLocation) {
console.warn("当前版本不支持定位,改为手动填写地址");
}
},
});| 参数 | 类型 | 说明 |
|---|---|---|
jsApiList | string[] | 需要检测的 JS 接口列表 |
INFO
与微信不同,看购的 checkJsApi 不发起网络请求。支持情况取决于 App 是否实现了对应原生能力,SDK 同步查表后立刻回调。
用户接口
为什么看购没有「网页授权」
如果你做过微信公众号开发,你会习惯这样拿用户身份:页面 302 跳到 open.weixin.qq.com/connect/oauth2/authorize → 用户(可能)看到一个授权页 → 微信带 code 回跳你的页面 → 你的服务器再拿 code + AppSecret 换 openid。
看购不需要这套流程,kg.ready 之后直接 kg.getOpenId() 即可。
原因是身份的来路不同。微信浏览器只是一个通用 WebView,它不会主动告诉页面"当前是谁",所以必须靠一次重定向到微信的授权服务去问。而看购 App 打开 H5APP 页面时,走的是平台自己的入口:App 在页面开始加载之前,就已经把当前登录用户的身份令牌注入到了页面上下文。kg.config 拿这个令牌 + 你的 appId 向看购服务端换取本次会话的 openId / unionId / jsapiTicket,一次请求完成,不需要任何跳转。
微信授权页承担的两件事,看购在别处已经做掉了:
- 确认调用方是谁——微信靠授权链接里的
appid;看购靠开放平台登记的网站域名 + 根目录验证文件,config时校验页面域名确实属于这个 H5APP。 - 确认用户同意——微信
snsapi_userinfo会弹授权页;看购下发的只有openId、unionId和昵称头像等公开资料,不含手机号、实名信息,也不含用户在平台内的全局标识,用户主动点开你的 H5APP 这个动作本身即视为进入你的应用,因此没有额外弹窗。
对照表:
| 微信网页授权 | 看购 | |
|---|---|---|
| 页面如何拿到身份 | 重定向到授权服务 → 回跳带 code → 服务器换 openid | App 注入身份 → config 一次换取 |
| 页面跳转次数 | 至少 2 次重定向 | 0 |
| 是否必须服务端参与 | 是(code 换 openid 要用 AppSecret) | 否,前端 kg.getOpenId() 直接取 |
| 域名白名单 | 公众号后台「网页授权域名」 | 开放平台「网站域名」+ 根目录验证文件 |
| scope 分级 | snsapi_base / snsapi_userinfo | 无分级,统一下发公开资料 |
| 授权弹窗 | snsapi_userinfo 会弹 | 无 |
三条限制
- 只在看购 App 内有效。 在普通浏览器打开页面时 SDK 进入 mock 模式,
getOpenId()返回mock_openid_xxx。要让用户在 App 之外用看购账号登录你的网站,请走OAuth 2.0 授权登录——那才是看购版的"网页授权"。 - 身份在页面初始化时固定。 一个页面生命周期内不能中途切换用户,换人请重新打开页面。
getOpenId()的返回值不能当作凭据传给你的服务器。 它是前端变量,任何人都能改。服务端要认用户,见下面的getJsApiTicket。
获取用户 openId
js
var openId = kg.getOpenId(); // string | nullopenId 是用户在你这个应用内的唯一标识。同一个用户在不同应用中的 openId 不同。
获取用户 unionId
js
var unionId = kg.getUnionId(); // string | nullunionId 是用户在同一开发者主体名下的唯一标识。你名下有多个应用时,可以用它识别出"这几个应用里是同一个人"。
获取 jsapiTicket
js
var ticket = kg.getJsApiTicket(); // string | nulljsapiTicket 是 config 成功后服务端下发的会话凭据,有效期 2 小时。你的服务端应当用它来确认用户身份,而不是相信前端传来的 openId。
正确做法:页面把 jsapiTicket 发给你自己的后端,你的后端带上 X-Kango-Ticket 请求头调用看购接口,返回的 openId 才是可信的。
http
GET https://kg.citv.cc/api/mini/user/profile
X-Kango-Ticket: <jsapiTicket>json
{
"code": 200,
"data": {
"openId": "3f2a9c8b7e6d5a4b3c2d1e0f9a8b7c6d",
"unionId": "…",
"nickname": "张三",
"avatar": "https://…"
}
}ticket 无效或过期时返回 HTTP 401 ticket 无效或已过期,此时请让页面重新执行 kg.config。
获取用户公开资料
js
kg.getUserProfile(function (err, profile) {
if (err) {
console.error(err);
return;
}
console.log(profile.openId, profile.nickname, profile.avatar);
});返回字段:
| 字段 | 类型 | 说明 |
|---|---|---|
openId | string | 用户在本应用的唯一标识 |
unionId | string | 开发者主体下的唯一标识 |
nickname | string | 用户昵称 |
avatar | string | 头像 URL |
sex | number | 性别:0-未知 1-男 2-女 |
faceUrl | string | 聊天头像 URL |
online | number | 在线状态 |
sign | string | 个性签名 |
关于用户隐私
看购只向开发者提供上述公开资料,不提供手机号、身份证等任何实名信息,也不提供用户在平台内的全局标识。
请用 openId 作为你系统内的用户主键。
图像接口
拍照或从手机相册中选图
js
kg.chooseImage({
count: 1,
sizeType: ["compressed"],
sourceType: ["album", "camera"],
success: function (res) {
// res.localIds 是选定照片的本地 id 列表
kg.getLocalImgData({
localId: res.localIds[0],
success: function (r) {
document.getElementById("preview").src = r.localData;
},
});
},
cancel: function () {
/* 用户取消 */
},
});| 参数 | 类型 | 说明 |
|---|---|---|
count | number | 占位。当前一次只返回一张图,传 9 也只会拿到 1 个 localId |
sizeType | string[] | 占位。压缩比由 App 固定 |
sourceType | string[] | 有效。仅含 'camera' 时直接调起相机;其余情况打开相册。默认 ['album','camera'] 按相册处理 |
success 回调返回 res.localIds,与微信一样是不透明的本地 id,不是可直接访问的文件路径。取图请用 getLocalImgData。
获取本地图片
js
kg.getLocalImgData({
localId: "", // 图片的 localId
success: function (res) {
var localData = res.localData; // localData 是图片的 base64 数据
},
});| 参数 | 类型 | 说明 |
|---|---|---|
localId | string | chooseImage 返回的本地 id |
compressionRatio | number | 占位,压缩已在 App 侧完成 |
与微信的一个差别
微信在安卓上返回的 base64 不带 data:image/jpeg;base64, 前缀,需要自己拼。看购统一带前缀,可以直接赋给 <img src>。
需要上传图片时,用它取到 base64 后自行 POST 到你的业务接口。
扫一扫
调起客户端扫一扫
js
kg.scanQRCode({
needResult: 1,
scanType: ["qrCode", "barCode"],
success: function (res) {
var result = res.resultStr; // 扫描结果
},
});| 参数 | 类型 | 说明 |
|---|---|---|
needResult | number | 占位。微信传 0 时由客户端自行处理结果,看购没有这套跳转策略,一律把结果回给页面 |
scanType | string[] | 占位。App 固定识别二维码、EAN-13、Code128 |
界面操作
关闭当前网页窗口
js
kg.closeWindow();与微信一致,不带回调。
支付
发起支付请求
js
// 1. 先让自己的服务器下单并签名
fetch("/api/my-order/create", { method: "POST", body: JSON.stringify(cart) })
.then(function (r) {
return r.json();
})
.then(function (data) {
// 2. 把签好名的 form 原样交给 SDK
kg.chooseWXPay({
payType: "wechat",
form: data.form,
goods: data.goods,
success: function (res) {
// res.status: 'success' | 'failed' | 'closed' | 'pending'
// res.payNo: 看购侧支付单号
if (res.status === "success") location.href = "/order/done";
},
cancel: function () {
/* 用户取消 */
},
fail: function (res) {
console.error(res.errMsg);
},
});
});微信的五个参数(timestamp / nonceStr / package / signType / paySign)在看购jssdk 里是占位:看购jssdk不在页面里拼支付签名,你应该先 在KGPay看购支付系统(pay.citv.cc),开通支付并申请密钥,然后在 你自己的业务服务器使用密钥 把订单表单签名,签名后交给jssdk 转发。签名信息会原样透传给KGPay支付系统,中间不会被改写。
实际生效的参数:
| 参数 | 类型 | 说明 |
|---|---|---|
payType / type | string | 'wechat'(默认)/ 'alipay' / 'union' |
form | object | 由你的业务服务器签好名的下单表单 |
goods | array | 商品快照 [{ name, price, qty }],用于对账与展示 |
form 的字段含义与签名算法见支付接入文档。
密钥绝不能出现在 H5 页面里
支付签名覆盖表单的全部非空字段,App 与看购APP服务端只做转发,一个字段都不会改。签名必须在你自己的服务器上生成——前端能读到密钥,就等于任何人打开开发者工具都能把金额改成 1 分再重新签名下单。
不要自行认定支付成功
支付过程中页面可能停留较久,此时不要关闭页面。success 回调里的 res.status 只用于改善体验,最终结果一律以你自己服务器收到的支付回调为准。
安全提示
AppSecret 务必保存在服务端(环境变量或配置中心),不要写进前端代码,也不要提交进代码库。
如果怀疑泄露,请立即到开发者中心「应用设置 → 安全中心」重置。
尚未实现的接口
下列接口与微信 JSSDK 同名、参数也一致,SDK 里方法都在,但看购 App 目前还没有实现对应的原生能力。调用不会报错、不会抛异常,会走 fail 回调并返回:
text
<接口名>:fail 当前看购 App 尚未实现该能力等 App 补齐后,页面代码无需任何改动即可生效。建议现在就按微信的写法把调用写好,并用 checkJsApi 提前探测、做好降级。
| 分类 | 接口 |
|---|---|
| 图像 | previewImage uploadImage downloadImage |
| 界面菜单 | hideOptionMenu showOptionMenu hideMenuItems showMenuItems hideAllNonBaseMenuItem showAllNonBaseMenuItem |
| 音频 | startRecord stopRecord onVoiceRecordEnd playVoice pauseVoice stopVoice onVoicePlayEnd uploadVoice downloadVoice translateVoice |
| 设备 | getNetworkType |
| 位置 | getLocation openLocation |
| 分享 | updateAppMessageShareData updateTimelineShareData |
推荐的降级写法:
js
kg.ready(function () {
kg.checkJsApi({
jsApiList: ["getLocation"],
success: function (res) {
if (res.checkResult.getLocation) {
kg.getLocation({ success: fillAddressFromGps });
} else {
showManualAddressInput(); // 降级为手动填写
}
},
});
});为什么 getNetworkType 不用浏览器的 navigator.connection 代替
浏览器那个字段给的是带宽等级估计(effectiveType 永远不会返回 'wifi'),拿它冒充网络类型会让页面按错误的网络状况做降级决策。与其给一个不准的值,不如明确返回失败。
附录:常见错误及解决方法
| 错误提示 | 原因 | 解决方法 |
|---|---|---|
config:fail H5APP 未配置 Website | 应用没有填写网站域名 | 在开发者中心补填网站域名并完成验证 |
config:fail WebsiteKey 验证失败 | 验证文件不可访问或内容不对 | 直接在浏览器打开 https://你的域名/kg_verify_{WebsiteKey}.txt 排查 |
config:fail H5APP 不存在或已禁用 | appId 填错,或应用被停用 | 核对 AppKey;到开发者中心确认应用状态 |
config:fail userToken 无效 | 用户登录态已过期 | 让用户在 App 内重新登录后再打开页面 |
<接口名>:fail 当前看购 App 尚未实现该能力 | 调用了尚未实现的接口 | 用 checkJsApi 提前探测,做好降级 |
getOpenId() 返回 mock_openid_xxx | 在普通浏览器中打开了页面 | 属正常的 mock 模式,用看购 App 打开即为真实值 |
ticket 无效或已过期(HTTP 401) | jsapiTicket 超过 2 小时 | 让页面重新执行 kg.config 取新 ticket |
kg is not defined | JS 文件没有引入成功 | 检查 <script> 路径,确认没有被内容安全策略拦截 |
排查建议
- 打开
debug: true,在真机上用远程调试查看 console 输出 - 确认页面域名与应用登记的网站域名完全一致(含协议与子域)
- 确认验证文件放在当前域名的根目录(改过域名会重新生成 WebsiteKey)
- 仍无法解决时,请把 console 中
config:fail的完整文本提供给平台技术支持