简述:最近项目要接入订阅商品,这里总结一下公司大佬们的经验和我整理后脚本。
一、关于订阅
1,跟消耗性和非消耗性的购买类似,开发者账后后台建订阅型商品。 订阅型商品分两种,自动续订和非自动续订的,一般用的是自动续订的。
2,有免费期,如1个月的订阅期,有3天的免费试用期,用户在购买后,前三天如果退订,是不收费的。 如果过了试用期后,用户可以再苹果的设置里面把后面的续订取消掉,这样,一个订阅周期结束后,苹果就不会再自动扣费了。
3、针对订阅商品我们需要解决的问题

a、用户卸载后重新安装,如何恢复订阅的功能

可以用苹果自带的一套恢复机制,如果一个用户订阅了这个app的一个商品,用户再次购买时,苹果会有自己的一套恢复机制。它会提示你之前已经订阅过改商品,为你恢复。所以恢复的机制我们可以直接采用苹果自带的方案

b、如何验证用户的订阅是否结束!

*用户每次购买的商品,苹果都会生成一个receipt,这个相当于我们购买时的一个凭证,这个凭证是可以用来验证这次的购买是否生效的。购买的凭证是苹果自己保存的,所以我们要验证这个产品是否购买过,只需要验证这个receipt就可以了。
验证的方式有两种:
一种是本地的验证,根据苹果的机制,解析到receipt后,会得到相应的字段。但是这种检测的机制已经被破解了,因为hacker可以修改本地的receipt,造成本地的验证失效。但是对于内购不是占据特别大的比例的产品,这个是可以使用的。像我们的休闲类小游戏,内购比重不大可以采用这种方式。
另外一种方式,是通过把receipt发给苹果,苹果通过服务器自己验证。这种验证是100%准确的,后台可以通过苹果解析后的字段,判断本次购买是否准确的。
对于订阅性的商品,如果要通过服务端验证,需要后台添加一个配置,这个字段在服务端针对订阅性商品做验证的时候需要用,这是跟消耗性和非消耗性不同的地方。


而谷歌判断有没有过期只需要autoRenewing属性就可以了 ,如果为true就处于订阅状态,false就是订阅失效了。

c、我们如何测试订阅

订阅的沙盒环境和其它类型的有些不一样,它的过期时间和后台设置的不一致,具体参照下表。

那么我们客户端要做的操作是什么呢?
一、购买

订阅商品的购买与一般商品购买没有区别,按照正常流程购买就好了。
这点有问题的可以参照我的另外一篇博客Unity IAP 谷歌支付,ios支付
注意一点,初始化商品类型的时候订阅产品要选对类型。
如图位置所指位置,订阅商品要选订阅类型(ProductType.Subscription)。

二、验证

订阅商品的难点主要在于判断订阅商品是否到期

由于Unity自带的IAP插件没有找到解析receipt的接口,我们需要导入以下脚本用来解析receipt

using UnityEngine;class GooglePurchaseData
{// INAPP_PURCHASE_DATApublic string inAppPurchaseData;// INAPP_DATA_SIGNATUREpublic string inAppDataSignature;public GooglePurchaseJson json;[System.Serializable]private struct GooglePurchaseReceipt{public string Payload;}[System.Serializable]private struct GooglePurchasePayload{public string json;public string signature;}[System.Serializable]public struct GooglePurchaseJson{public string autoRenewing;public string orderId;public string packageName;public string productId;public string purchaseTime;public string purchaseState;public string developerPayload;public string purchaseToken;}public GooglePurchaseData(string receipt){try{var purchaseReceipt = JsonUtility.FromJson<GooglePurchaseReceipt>(receipt);var purchasePayload = JsonUtility.FromJson<GooglePurchasePayload>(purchaseReceipt.Payload);var inAppJsonData = JsonUtility.FromJson<GooglePurchaseJson>(purchasePayload.json);inAppPurchaseData = purchasePayload.json;inAppDataSignature = purchasePayload.signature;json = inAppJsonData;}catch{Debug.Log("Could not parse receipt: " + receipt);inAppPurchaseData = "";inAppDataSignature = "";}}
}

脚本2 判断是否处于订阅状态

using UnityEngine.Purchasing;
using UnityEngine.Purchasing.Security;/*以下两个方法都是封装好检测是否订阅过的方法。仅针对有一个订阅商品的检测,多个订阅商品可能需要区分ID。暂时未做测试。注意一点,判断订阅状态必须得在商品初始化之后判断。
*/
//订阅控制脚本
public class SubscriptionCtrl:MonoBehaviour
{public void Start(){
//每次进入游戏调用检查订阅方法
#if UNITY_ANDROIDCheckSubscribeReceiptAndorid();
#elif UNITY_IOS || UNITY_STANDALONE_OSXCheckSubscribeReceipt();
#endif}public void CheckOk(){//如果检查处于订阅状态,可以在这里做客户端逻辑处理}public void CheckWrong(){//如果检查处于非订阅状态,可以在这里做客户端逻辑处理}//检查谷歌订阅状态的方法,该方法需要同时导入另外一个脚本GooglePurchaseData 解析谷歌支付的receiptpublic void CheckSubscribeReceiptAndorid(){foreach (Product p in Purchaser.m_StoreController.products.all){if (p.hasReceipt){Debug.Log("recepit all:" + p.receipt);GooglePurchaseData data = new GooglePurchaseData(p.receipt);Debug.Log("recepit autoRenewing:" + data.json.autoRenewing);/*Debug.Log("recepit orderId:" + data.json.orderId);Debug.Log("recepit packageName:" + data.json.packageName);Debug.Log("recepit productId:" + data.json.productId);Debug.Log("recepit purchaseTime:" + data.json.purchaseTime);Debug.Log("recepit purchaseState:" + data.json.purchaseState);Debug.Log("recepit purchaseToken:" + data.json.purchaseToken);*/if (bool.Parse(data.json.autoRenewing)){CheckOk();Debug.Log("sub is active");}else{CheckWrong();Debug.Log("sub not active");}}}}//检查IOS订阅状态的方法, 这里是通过receipt里面的expiredate和当前时间对比来判断当前的订阅商品是否过期。public void CheckSubscribeReceipt(){try{var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());// Get a reference to IAppleConfiguration during IAP initialization.var appleConfig = builder.Configure<IAppleConfiguration>();if (appleConfig == null || string.IsNullOrEmpty(appleConfig.appReceipt)){return;}//Debug.LogError("appReceipt:" + appleConfig.appReceipt);var receiptData = System.Convert.FromBase64String(appleConfig.appReceipt);if (receiptData == null){return;}AppleReceipt receipt = new AppleReceiptParser().Parse(receiptData);if (receipt == null){return;}foreach (AppleInAppPurchaseReceipt productReceipt in receipt.inAppPurchaseReceipts){if (productReceipt.productType == 3){Debug.Log("sub productid = " + productReceipt.productID);DateTime expirationDate = productReceipt.subscriptionExpirationDate;Debug.Log("sub ExpirationDate = " + expirationDate.ToString());DateTime now = DateTime.Now.ToUniversalTime();//DateTime cancellationDate = apple.cancellationDate;if (DateTime.Compare(now, expirationDate) < 0){Debug.Log("sub is active");CheckOk();}else{CheckWrong();Debug.Log("sub not active");}}}}catch (Exception exp){Debug.Log(exp);}}}

以上 是客户端需要对订阅商品的操作。

另外,订阅页面在UI显示的方面也要遵循一些规则,具体可以参考官方文档。晚些也会更新一篇关于后台配置和遵循规则的博客。

关于IAP支付,谷歌和苹果订阅商品——最白话,手把手教你做系列。相关推荐

  1. Unity内IAP支付二次验证/服务器验证————最白话,手把手教你做系列。

    之前的一篇写了Unity支付的IAP支付接入. 后来就出现了一些问题,数据统计的时候出现大量购买订单.但是实际上账户的钱却没有增加.@¥--&¥--*@¥&@初步判定可能存在部分用户通 ...

  2. 如何关闭华为自动杀进程_如何取消苹果自动续费?手把手教你关闭自动续费全步骤...

    如何取消苹果自动续费?一些手机应用的会员在充值时会默认自动续费,有些时候我们可能没看到默认勾选了这个选项,在收到账单才发现自己被扣了钱.想要关闭自动续费却不知道该怎么操作,今天小编就来教大家如何关闭苹 ...

  3. 如何取消苹果自动续费?手把手教你关闭自动续费全步骤

    如何取消苹果自动续费?一些手机应用的会员在充值时会默认自动续费,有些时候我们可能没看到默认勾选了这个选项,在收到账单才发现自己被扣了钱.想要关闭自动续费却不知道该怎么操作,今天小编就来教大家如何关闭苹 ...

  4. 实例:用C#.NET手把手教你做微信公众号开发(20)--使用微信支付线上收款:jsapi方式

    在做线上.线下销售时,可以使用微信便捷支付,通过微信公众号收款有很多种收款方式,如下图: 今天我们来讲一下jsapi支付,场景就是在微信内打开某个页面,完成在线支付,同样一个网页,使用微信打开就是js ...

  5. 实例:用C#.NET手把手教你做微信公众号开发(21)--使用微信支付线上收款:H5方式

    在做线上.线下销售时,可以使用微信便捷支付,通过微信公众号收款有很多种收款方式,如下图: 今天我们来讲一下H5场景支付,使用手机浏览器打开就是H5方式,最常见的推广是短信内置链接,这种场景需要调用微信 ...

  6. 【IAP支付之三】苹果IAP安全支付与防范 receipt收据验证

    这里网上的朋友已经介绍的很详细了,具体的链接已经无法找到了. 这里主要说几点本人在开发中遇到的问题: 1.漏单必须要处理,玩家花RMB购买的东西却丢失了,是绝对不能容忍的.所谓的漏单就是玩家已经正常付 ...

  7. 怎么取消苹果订阅自动续费?教你一招,2分钟搞定!

    案例:苹果怎么取消自动续费? [想问下苹果订阅服务在哪里看?之前好像不小心订阅了什么自动续费,想要取消它.] 苹果订阅自动续费功能在一定程度上方便了用户的购买体验,但有时候我们会忘记取消订阅,导致不必 ...

  8. 实例:用C#.NET手把手教你做微信公众号开发(19)--使用微信支付转账到微信粉丝零钱账户

    公众号给微信用户支付费用的方式有很多种,最常用的是发红包和转账到零钱账户,上一篇文章详细讲解了使用发红包的过程,从公众号内的配置,到微信支付的配置,再到具体的类实现. 本篇主要讲解转账到零钱,具体的类 ...

  9. bert 中文 代码 谷歌_1美元从零开始训练Bert,手把手教你优雅地薅谷歌云TPU羊毛...

    大数据文摘出品 来源:Google Colab 编译:武帅.曹培信 2018年10月,Google AI团队推出了Bert,可以说Bert一出生就自带光环. 在斯坦福大学机器阅读理解水平测试SQuAD ...

最新文章

  1. 北京大学现代农业研究院张华伟实验室招聘启示
  2. windows10用c++部署libtorch过程中遇到的一些问题
  3. Python基础教程:list相关操作
  4. DevStack安装问题 pip安装镜像源
  5. 【渝粤教育】国家开放大学2018年春季 0093-21T刑法 参考试题
  6. Postman用法简介-Http请求模拟工具
  7. vs 中使用32 位mysql_vs2010连接mysql数据库(含win32和x64两种平台)
  8. ninjala还是显示服务器维护,Ninjala更新2.0版本 调整了武器平衡以及BUG修复
  9. 关于深度学习caffe for Windows编译入门
  10. 程序员又惹祸!B站网站后台工程源码泄露 内含部分用户名密码
  11. 小波变换matlab加密,混沌和小波变换的图像加密压缩算法
  12. 转易语言-网页游戏辅助,网络游戏辅助,手游辅助开发技术教程
  13. php 秒拍视频解析,高仿秒拍视频网EMLOG主题模板
  14. 微软bi报表服务器,安装 Power BI 报表服务器
  15. php网页报告2500字,教你写作文2500字
  16. 联合证券|内外利好共振 今年A股可更乐观一点
  17. Burp Suite爆破模块中的四种模式的区别详解和演示(暴力破解)
  18. 计算机页面排版的笔记,推荐6种简单实用的手绘笔记排版
  19. 腾讯地图android,手机腾讯地图
  20. 求2021年某月某日为星期几

热门文章

  1. 计算机考试记不住题目,驾考科目一口诀,科一题目太多记不住?快来看看这些技巧...
  2. c语言乒乓球比赛相关的拓展程序,乒乓球编排软件.pdf
  3. 逻辑回归实现数字手写识别
  4. 数字手写体识别python实现(全连接神经网络)
  5. C#连接达梦数据库基础功公共类
  6. 【Web前端】html+css+javascript
  7. allure如何设置新logo
  8. NormalEstimation法向量估计理论和代码---PCL源码笔记
  9. 英语作文计算机的出现,临时英文(电脑输入法出现临时英文)
  10. littlefs系列:重要的数据结构