敬告:此 DEMO 演示为开放测试页面,仅用于开发者快速测试体验应用功能,请严格遵守开发者协议,了解更多。
♦ JS-SDK 引用方式:
♦ 普通网页 script 方式加载:下载最新版 jsBridge-v20240828.zip,请在页面上调用 jsBridge 接口之前引用 jsbridge-mini.js 库;
♦ js module 方式引用:npm install ym-jsbridge 具体请参考 npm package
可能由于家长控制等原因,当前设备不支持APP内购买,在发起内购前可以先判断是否支持。
jsBridge.iap.canMakePayments(function(yes) { alert(yes ? "支持内购" : "不支持内购"); });
jsBridge.iap.getProducts({ //你在 https://appstoreconnect.apple.com/ 创建的产品ID数组 productIds: [ "com.yidiantongqa.app.vip30", "com.yidiantongqa.app.vip60", "com.yidiantongqa.app.vip360" ] }, function(succ, products) { if (succ) { alert(JSON.stringify(products)); } else { alert("操作失败\n" + JSON.stringify(products)); } }); /** products 返回产品信息 { invalidProductIds:[] //无效的产品ID,如果你提供了无效的产品ID,会在这里返回,数组类型 products: //有效的产品信息,数组类型 [{ productId: //产品id,字符串类型 title: //产品标题,字符串类型 description: //产品描述,字符串类型 price: //产品价格,数字类型 formattedPrice: //产品格式化后的价格,如¥6.00,字符串类型 downloadable: //是否有下载内容,布尔类型 downloadContentLengths: //下载内容长度,数字组成的数组 downloadContentVersion: //下载内容的版本,字符串类型 }] } **/
• 调用 getUnfinishedTransactions/purchase/restoreTransactions/finishTransaction 方法之前应设置本监听器,所有交易状态变更都会通知到此监听器。
• 系统以数组形式将交易信息传递给回调参数 transactions
• 如果多次设置监听器,只有最后一个才会收到通知。
jsBridge.iap.setTransanctionListener(function(succ, transactions) { if (succ) { var json = JSON.stringify(transactions); jsBridge.setClipboardText(json); //transactions.forEach(function(x){jsBridge.iap.finishTransaction({transactionId: x.transactionId});}) alert(json); } else { alert("操作失败\n" + JSON.stringify(transactions)); } }); alert("已设置监听器"); /** transactions 返回交易信息数组 [{ state: //交易状态,详见交易状态常量,数字类型 transactionId: //交易id,字符串类型 originalTransactionId: //原始交易id,只在state为恢复购买时有效,字符串类型 transactionDate: //交易时间,UNIX 时间戳(秒) receipt: //交易凭证,经过base64编码,用于验证交易是否合法和有效,避免因越狱破解内购后造成损失,只在state为购买成功时有效,字符串类型 errorCode: //交易失败时的错误码,数字类型 errorMsg: //交易失败时的说明,字符串类型 payment: //商品购买信息 { productId: //商品ID,字符串类型 quantity: //购买数量,数字类型 applicationUsername: //用户信息,字符串类型 }, downloads: //有下载内容时的下载信息列表 [{ state: //下载状态,详见下载状态常量,数字类型 transactionId: //下载内容所属交易id,字符串类型 contentId: //下载内容id,字符串类型 progress: //下载进度,取值范围0~1,数字类型 contentLength: //文件内容大小,数字类型 timeRemaining: //下载剩余时间,-1时表示未知,数字类型 contentVersion: //下载内容的版本,字符串类型 contentURL: //下载成功后文件路径,字符串类型 errorCode: //下载失败时的错误码,数字类型 errorMsg: //下载失败时的错误描述,字符串类型 }] }] state(transaction) 交易状态常量说明 0: 已加入交易队列(Transaction is being added to the server queue.) 1: 交易完成(Transaction is in queue, user has been charged. Client should complete the transaction.) 2: 交易失败(Transaction was cancelled or failed before being added to the server queue.) 3: 恢复购买(Transaction was restored from user's purchase history. Client should complete the transaction.) 4: 交易等待被确认(The transaction is in the queue, but its final status is pending external action.) state(download) 下载状态常量说明 0: 等待下载(Download is inactive, waiting to be downloaded) 1: 正在下载(Download is actively downloading) 2: 暂停下载(Download was paused by the user) 3: 下载完成(Download is finished, content is available) 4: 下载失败(Download failed) 5: 取消下载(Download was cancelled) **/
请在 setTransanctionListener 中接收交易数据
jsBridge.iap.getUnfinishedTransactions();
请在 setTransanctionListener 中接收交易数据
jsBridge.iap.purchase({ //你在 https://appstoreconnect.apple.com/ 创建的产品ID productId : "com.yidiantongqa.app.vip60", //可选,购买数量,不小于1的整数,默认1 quantity : 1, //可选,用户信息,交易回调里面原样返回,默认空 applicationUsername: "myString" });
请在 setTransanctionListener 中接收交易数据
jsBridge.iap.restoreTransactions();
• 在完成购买并提供给用户相关功能后应该完成此次交易;
• finishTransaction 成功后,此交易将从 UnfinishedTransactions 队列中移除;
• 请在 setTransanctionListener 中接收交易数据;
jsBridge.iap.finishTransaction({ //交易id transactionId: "3A266867-8275-4299-9BEF-FF7A8A207D21" });
• 调用 startDownloads/pauseDownloads/resumeDownloads/cancelDownloads 方法之前应设置本监听器,所有下载状态变更都会通知到此监听器。
• 系统以数组形式将下载信息传递给回调参数 downloads
• 如果多次设置监听器,只有最后一个才会收到通知。
jsBridge.iap.setDownloadListener(function(succ, downloads) { if (succ) { alert(JSON.stringify(downloads)); } else { alert("操作失败\n" + JSON.stringify(downloads)); } }); alert("已设置监听器"); /** downloads 下载信息数组 [{ state: //下载状态,详见setTransanctionListener的下载状态常量说明,数字类型 transactionId: //下载内容所属交易id,字符串类型 contentId: //下载内容id,字符串类型 progress: //下载进度,取值范围0~1,数字类型 contentLength: //文件内容大小,数字类型 timeRemaining: //下载剩余时间,-1时表示未知,数字类型 contentVersion://下载内容的版本,字符串类型 contentURL: //下载成功后文件路径,字符串类型 errorCode: //下载失败时的错误码,数字类型 errorMsg: //下载失败时的错误描述,字符串类型 }] **/
请在 setDownloadListener 中接收下载信息
jsBridge.iap.startDownloads({ //下载内容ID组成的数组 contentIds: [ "contentId1", "contentId2", "..." ] });
请在 setDownloadListener 中接收下载信息
jsBridge.iap.pauseDownloads({ //下载内容ID组成的数组 contentIds: [ "contentId1", "contentId2", "..." ] });
请在 setDownloadListener 中接收下载信息
jsBridge.iap.resumeDownloads({ //下载内容ID组成的数组 contentIds: [ "contentId1", "contentId2", "..." ] });
请在 setDownloadListener 中接收下载信息
jsBridge.iap.cancelDownloads({ //下载内容ID组成的数组 contentIds: [ "contentId1", "contentId2", "..." ] });
♦ 接入流程请参考 这里
♦ 关于自动续期订阅类商品:iOS IAP - 自动续期订阅、订阅、续订、退订、恢复订阅
♦ 苹果官方文档 https://developer.apple.com/documentation/appstorereceipts/verifyreceipt
♦ 沙盒凭证验证接口 https://sandbox.itunes.apple.com/verifyReceipt
♦ 生产环境凭证验证接口 https://buy.itunes.apple.com/verifyReceipt
♦ 注意,APP上架审核时苹果审核员用的是沙盒账户;
♦ 识别沙盒环境下收据的方法有两种:
1.根据凭证验证返回的字段 environment = sandbox。
2.根据凭证验证返回的状态码,如果 status = 21007,则表示当前的收据为沙盒环境下凭证;♦ 构造JSON { "receipt-data" : "(receipt 支付凭证)" } POST 到苹果的验证接口,处理返回结果即可。