Unity接入苹果内购(IAP)

Unity接入苹果内购(IAP)

  Unity接入苹果内购(IAP)

        苹果支付流程

        配置App

        配置商品 

        协议、税务和银行业务 

        沙盒测试账号

        Unity(IAP) 

        测试 


苹果支付流程

在接苹果支付前我们需要先来大体了解下苹果支付的流程是怎样的:

苹果支付流程图

大体可以理解为我们要想在自己的app里面购买自己定义的商品,首先我们先把自己的商品注册在apple服务器上然后去购买apple服务器上我们注册的商品并完成支付,为了安全性考虑(防止越狱机等),我们一般都会在支付后有一步支付凭证的验证过程来确保商品确实是经过正规途径购买的,具体流程慢慢往下看好了!

配置App

首先我们需要App Store Connect 这里配置一下你的app应用,
当然要想进入这之前你需要登录开发者账号,如果进入的不是这个界面可能你的账号是未付费的或者权限不够,我是用公司的开发者账号登录的。然后点击 我的app 会进入到这个界面:

在这里插入图片描述

当然要想进入这之前你需要登录开发者账号,如果进入的不是这个界面可能你的账号是未付费的或者权限不够,我是用公司的开发者账号登录的。然后点击 我的app 会进入到这个界面:

在这里插入图片描述

如果你以前没有创建过那么这地方会是空的,这里会显示你以前创建过的所有app应用,点击应用就可以看见以前的设置信息,我们先创建一个应用,点击左上方的+号创建 选择 新建App 会进入到如下界面:

在这里插入图片描述

其实这些设置都有官方的说明文档,可以去看看,填写完就可以创建我们的app应用了。创建完我们会进入到下面那个界面

在这里插入图片描述

因为我们只是测试一下沙盒环境下的支付,所以这些信息不用填写!

配置商品 

接下来我们就要配置一下我们app内的商品信息了,找到下面这个界面:

在这里插入图片描述

然后点击+号来添加我们的商品,商品类型分为以下几类:

在这里插入图片描述

示例里面已经把这几类商品介绍的很清楚了,这就不一一赘述了,选择自己需要创建的商品类型,这里为了测试方便选择了第一种

在这里插入图片描述

在这里插入图片描述

上面的信息除了推广外其余最好都填写,因为不填写会报此商品元数据缺失,我也不知道后续会有啥问题,屏幕快照随便找一个640*920的图片上传就可以,其他分辨率可能上传不成功!然后我们商品基本信息设置完成,点击右上角存储然后会发现这个商品已经添加到我们的商品列表中,并且商品状态变成准备提交状态。还有最后容易忽略的一步,非常重要,我就是因为这步没有设置导致找不到商品信息浪费了不少时间,进入App Store下的准备提交界面找到APP内购买项目 添加我们的配置的商品信息,如下:

在这里插入图片描述

这里选择刚刚我们创建的商品添加进去就可以了

协议、税务和银行业务 

一开始忘记配置这的信息了,导致打出的ios包在真机上总是报商品初始化不成功错误,折腾了好久才发现公司账户没有配置银行信息,-_-||,还有一点这些设置最好在苹果上面配置(包括下面的沙盒账号申请),一开始我是在windows上面配置的,到了这一步发现会出现各种奇葩的界面,估计是浏览器或者系统的问题(当然也有可能是我的问题。。。),如果公司以前没有配置过的话进入后只有一个免费App一项,然后我们可以申请付费app协议,由于我已经配置过没有发现创建项,我就不在此一一赘述了,可以去这儿看看详细步骤,因为是以前的帖子一些界面有所改动,不过仔细看看问题不大!还有这个里面的银行账户设置后是可以修改的你可以配置公司的账户,当然也可以为了测试添加自己的账户也是可以的!配置完成后等待苹果审核通过,我当时等了大概不到一小时就显示审核通过了,通过后我们的商品配置基本完成!

沙盒测试账号

苹果支付分为真实环境和沙盒环境,真实环境就是你用自己的苹果账号购买商品(会真实扣费的),沙盒环境就是苹果专门为支付测试而生的一种测试账号(支付成功也不会扣费),说白了就是你的app只要没有通过苹果审核没有正式上线,所有的支付都是沙盒环境的,如果你登录自己的苹果账号去测试会出错的,沙盒环境下就需要我们去使用沙盒账号去测试支付,沙盒账号我们可以去下面这去申请:

在这里插入图片描述

额,这我是在mac上面申请的,因为window上面显示不出来这个界面,然后自己创建一个测试账号就可以了,没啥大问题就不截图了,按照提示来就可以!
以上就是测试苹果支付的商品注册步骤,基本没啥大问题,接下来梳理一下unity里面IAP的使用

Unity(IAP) 

AP,是in-App Purchase的缩写,可以理解为在App内购买,这也是为何IAP又被称为内购的原因。
苹果规定,凡是在App内提供的服务需要付费时,必须使用IAP,比如说游戏的金币,道具等;而在App外提供的服务需要付费时,可以使用其他的支付方式,比如支付宝SDK、微信SDK等。说的更通俗一点,如果付费购买的商品是虚拟商品,比如游戏中的道具,并不是现实中存在的,那么必须使用IAP;
首先我们先在我们的项目中下载IAP,有两种方式你可以选择去assetstore去下载,也可以找到这个界面:

在这里插入图片描述

把标识的打开会进入到这个界面:

在这里插入图片描述

如果你已经下载过这里会变成Update如果没有点击导入就好了,等待完成,然后你项目里会多出一些东西,其实下面这些你可以看unity官方的IAP文档就可以,比较详细。客户端添加商品有两种方法,一种是window窗口可以创建IAP Button,这种方法可以自己百度,我觉得太麻烦就用的第二种,第二种方法就是自己建立一个管理类自己管理自己的商品,代码如下:


using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Text;
using LitJson;
using UnityEngine;
using UnityEngine.Purchasing;
using UnityEngine.Networking;
[Serializable]
public class Products
{
    public string id;
    public int productType;
}
/// 
/// 购买管理理
/// 
public class PurchaseManager : MonoBehaviour, IStoreListener
{
    public List products = new List();
    public string publicKey;
    ConfigurationBuilder builder;
    private IStoreController m_Controller;
    private IAppleExtensions m_AppleExtensions;
    private int productIndex;
    private static bool isInited = false;
    private bool isInitFailed = false;
    void Awake()
    {
        if (!isInited)
        {
            InitPurchase();
        }
    }
    /// 
    /// 初始化
    /// 
    void InitPurchase()
    {
        Debug.Log("初始化");
        var module = StandardPurchasingModule.Instance();
        builder = ConfigurationBuilder.Instance(module);
        for (int i = 0; i < products.Count; i++)
        {
            builder.AddProduct(products[i].id,
            (ProductType)products[i].productType);
        }
        UnityPurchasing.Initialize(this, builder);
    }
    /// 
    /// 初始化成功
    /// 
    /// Controller.
    /// Extensions.
    public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
    {
        //Debug.Log("初始化成功");
        m_Controller = controller;
        m_AppleExtensions =extensions.GetExtension();
        m_AppleExtensions.RegisterPurchaseDeferredListener(OnDeferred);
        isInited = true;
    }
    /// 
    /// iOS ⽹网络延迟错误
    /// 
    /// Item.
    private void OnDeferred(Product item)
    {
        //Debug.Log("⽹网络连接不不稳");
    }
    /// 
    /// 初始化失败
    /// 
    /// Error.
    public void OnInitializeFailed(InitializationFailureReason error)
    {
        isInitFailed = true;
        //Debug.Log("初始化失败");
        Debug.Log("IAPInitializeFailed!!!" + "Reason:" + error);
    }
    /// 
    /// 恢复购买
    /// 
    public void RestorePurchases()
    {
        if (Application.platform == RuntimePlatform.IPhonePlayer ||
        Application.platform == RuntimePlatform.OSXPlayer)
        {
            if (!isInited)
            {
                //loading.SetActive(false);
                InitPurchase();
            }
            StartCoroutine("InitAndRestore");
        }
    }
    IEnumerator InitAndRestore()
    {
        if (isInitFailed || !isInited)
        {
            //初始化失败
            StopCoroutine("InitAndRestore");
        }
        yield return new WaitUntil(() =>
        {
            return m_Controller != null &&m_AppleExtensions != null;
        });
        m_AppleExtensions.RestoreTransactions((result) =>
        {
            // The first phase of restoration. If no more responses are received on ProcessPurchase then
            // no purchases are available to be restored.
            Debug.Log("RestorePurchases continuing: " + result +". If no further messages, no purchases available to restore.");
            if (result)
            {
                //产品已经restore,不不过官⽅方的解释是恢复过程成功了了,并不不代表所购买的物品都恢复了了
            }
            else
            {
                // 恢复失败
            }
            StopCoroutine("InitAndRestore");
        });
    }
    /// 
    /// 按钮点击  也可以重写为传入产品ID  此处是序列号
    /// 
    /// Index.
    public void OnPurchaseClicked(int index)
    {
        if (Application.platform == RuntimePlatform.IPhonePlayer ||
        Application.platform == RuntimePlatform.OSXPlayer ||
        Application.platform == RuntimePlatform.OSXEditor)
        {
            if (!isInited)
                InitPurchase();
            StartCoroutine("InitAndPurchase", index);
        }
    }
    IEnumerator InitAndPurchase(int index)
    {
        if (isInitFailed || !isInited)
        {
            //初始化失败
            StopCoroutine("InitAndPurchase");
        }
        yield return new WaitUntil(() =>
        {
            return m_Controller != null && m_AppleExtensions != null;
        });
        m_Controller.InitiatePurchase(products[index].id);
        StopCoroutine("InitAndPurchase");
    }
    /// 
    /// 购买成功回调
    /// 
    /// The purchase.
    /// E.
    public PurchaseProcessingResult
    ProcessPurchase(PurchaseEventArgs e)
    {
        //Debug.Log("购买成功回调");
        //使⽤用id判断是否是当前购买的产品,我这⾥里里只有⼀一个产品,所以就是products[0]
        if (e.purchasedProduct.definition.id == products[0].id)
        {
            //此处可以对订单进行验证,因为我们项目吧验证放到服务器了,所以我们可以把购买成功后的凭证发给服务器去验证
            //这个购买验证码特别特别长,验证分为沙盒验证和真实验证 就不赘述了
        }
        return PurchaseProcessingResult.Complete;
    }
    public void OnPurchaseFailed(Product i, PurchaseFailureReason p)
    {
        //购买失败的逻辑
        //Debug.Log("购买失败的逻辑");
    }

}

一些注释已经解释的很清楚了,这里解释一下Products 和PublicKey 这两个字段:

在这里插入图片描述

Products里面的id就是上面的产品ID,productType就是我们注册这个商品时的消耗类型,然后publicKey可以在上面的App专用共享秘钥查看,这个每一个app是固定不变的!然后我们只需要给我们的商品btn添加事件就可以了!

测试 

我们可以做一个简单的测试工程,工程里不需要多只需要一个商品按钮就可以了,然后我们在打个ios包导入到我们苹果设备上(具体IOS打包请自行百度,其实和打android包差不多,只不过需要xcode编译一下,然后配置一下证书和访问权限就可以了),然后在手机上运行测试工程,这里有一个问题需要注意一下,由于我们是沙盒测试支付(是需要用沙盒账号去测试的),所以在进入工程前我们需要去我们的手机appstore上把我们的苹果账号登出,不然进入工程会默认登录的,然后进入我们的测试工程项目点击购买,项目有点简陋(▽)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

测试成功!!!以上就是沙盒环境下的苹果支付测试,有很多不足之处欢迎大佬指正! 

你可能感兴趣的:(Unity,IOS,unity)