Unity Soomla Android In App Purchase(IAP) by

31
Aug
0

วันนี้เราจะมาสอนวิธีการใส่ In App Purchase ใน App ของเรากันนะครับ โดยใช้ Library ที่ชื่อว่า Soomla นะครับ ซึ่งตัว Soomla นี้เป็น Library ที่สามารถทำ In App Purchase ได้ทั้งฝั่ง Android และ iOS เลยนะครับ แต่วันนี้เป็นของฝั่ง Android นะครับ ของ iOS จะยกไปไว้คราวหน้านะครัช

วิธี Import Library และ Settings ค่าก่อนเริ่มต้น

  • ขั้นแรก ให้ Download Soomla จากที่นี่ ก่อนนะครับ
  • Import Soomla จาก Unity package ที่ Download มาใน Project ของเรานะครับ
  • Build Project ให้เป็น .apk และ Upload ขึ้นไปบน Google Console
    ** ต้องใส่ Keystore, Keystore password, เลือก Alias และใส่ Alias password ให้ครบก่อน (ใส่ได้ที่ Build Settings => Player Settings => Publishing Settings)
    *** หากยังไม่มี Keystore แนะนำให้ไปสร้างจากเครื่องที่เป็น iOS เพราะจากประสบการณ์ที่ผ่านมาเคยสร้างจากเครื่อง Windows แล้ว Keystore ใช้ไม่ได้ Sign ไม่ผ่าน – -”
  • เพิ่ม In App Products ใน Google Console อย่าลืมตั้งเป็น Active
    ** ตรงนี้กว่าที่ In App Products จะสามารถใช้ได้จริงอาจจะกินเวลาหลายชั่วโมงหรือ เป็นวันก็เป็นได้
  • เพิ่ม Testing Google Account ใน Google Developer Console (อันอื่นที่ไม่ใช้ Developer Account)
  • ใน Unity หลังจาก Import Soomla Package เสร็จแล้ว ใน Tap Window จะมี ตัวเลือก Soomla เพิ่มขึ้นมา ให้เลือก และ เลือก Edit Settings (Window => Soomla => Edit Settings) ใส่ Soomla Secret (ใส่แล้วห้ามเปลี่ยนอีก) และ ในตัวเลือก Google Play ใส่ API Key ที่ได้จากใน Google Developer Console

ต่อไปเป็นตัวอย่างการนำ Library Soomla มาใช้นะครับ

  • สร้าง C# Script ใหม่ให้ชื่อว่า StoreAssets ซึ่งสืบทอดมาจาก IStoreAssets อีกทีนะครับ Script นี้จะมีหน้าที่ในการกำหนดค่าต่างๆเกี่ยวกับ Products ของเรานะครับ จะเพิ่มหรือแก้ไข Products ก็มาแก้ใน Script นี้เลยนะครับ

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using Soomla.Store;

    public class StoreAssets : IStoreAssets {

    public int GetVersion() {
    return 0;
    }

    public VirtualCurrency[] GetCurrencies() {
    return new VirtualCurrency[]{};
    }

    public VirtualGood[] GetGoods() {
    return new VirtualGood[] {ITEM1, ITEM2, ITEM3, PURCHASED};
    }

    public VirtualCurrencyPack[] GetCurrencyPacks() {
    return new VirtualCurrencyPack[] {};
    }

    public VirtualCategory[] GetCategories() {
    return new VirtualCategory[]{};
    }

    public NonConsumableItem[] GetNonConsumableItems() {
    return new NonConsumableItem[]{NO_ADDS_NONCONS, CANCELED, REFUNDED, ITEM_UNAVAILABLE};//add Names
    }

    /** Static Final members **/

    public const string NO_ADDS_NONCONS_PRODUCT_ID = "no_ads";

    public const string MY_TEST1_PRODUCT_ID = "item1";
    public const string MY_TEST2_PRODUCT_ID = "item2";
    public const string MY_TEST3_PRODUCT_ID = "item3";

    public const string ANDROID_TEST_PURCHASED_ID = "android.test.purchased";
    public const string ANDROID_TEST_CANCELED_ID = "android.test.canceled";
    public const string ANDROID_TEST_REFUNDED_ID = "android.test.refunded";
    public const string ANDROID_TEST_ITEM_UNAVAILABLE_ID = "android.test.item_unavailable";

    /** Market MANAGED Items **/

    public static NonConsumableItem NO_ADDS_NONCONS = new NonConsumableItem(
    "No Ads",//Name
    "Test purchase of MANAGED item.",//Description
    "no_ads",//id
    new PurchaseWithMarket(new MarketItem(NO_ADDS_NONCONS_PRODUCT_ID, MarketItem.Consumable.NONCONSUMABLE , 0.99))
    );
    public static VirtualGood ITEM1 = new SingleUseVG(
    "Item 1", // name
    "Test purchase of Item 1.", // description
    "item1", // id
    new PurchaseWithMarket(new MarketItem(MY_TEST1_PRODUCT_ID, MarketItem.Consumable.CONSUMABLE , 0.99f))
    );
    public static VirtualGood ITEM2 = new SingleUseVG(
    "Item 2", // name
    "Test purchase of Item 2.", // description
    "item2", // id
    new PurchaseWithMarket(new MarketItem(MY_TEST2_PRODUCT_ID, MarketItem.Consumable.NONCONSUMABLE , 0.99f))
    );
    public static VirtualGood ITEM3 = new SingleUseVG(
    "Item 3", // name
    "Test purchase of Item 3.", // description
    "item3", // id
    new PurchaseWithMarket(new MarketItem(MY_TEST3_PRODUCT_ID, MarketItem.Consumable.NONCONSUMABLE , 0.99f))
    );
    public static VirtualGood PURCHASED = new SingleUseVG(
    "ANDROID TEST PURCHASED", // name
    "Description for: android.test.purchased.", // description
    ANDROID_TEST_PURCHASED_ID, // id
    new PurchaseWithMarket(new MarketItem(ANDROID_TEST_PURCHASED_ID, MarketItem.Consumable.NONCONSUMABLE , 0.99f))
    );
    public static NonConsumableItem CANCELED = new NonConsumableItem(
    "ANDROID TEST CANCELED", // name
    "Description for: android.test.canceled.", // description
    ANDROID_TEST_CANCELED_ID, // id
    new PurchaseWithMarket(new MarketItem(ANDROID_TEST_CANCELED_ID, MarketItem.Consumable.NONCONSUMABLE , 0.99f))
    );
    public static NonConsumableItem REFUNDED = new NonConsumableItem(
    "ANDROID TEST REFUNDED", // name
    "Description for: android.test.refunded.", // description
    ANDROID_TEST_REFUNDED_ID, // id
    new PurchaseWithMarket(new MarketItem(ANDROID_TEST_REFUNDED_ID, MarketItem.Consumable.NONCONSUMABLE , 0.99f))
    );
    public static NonConsumableItem ITEM_UNAVAILABLE = new NonConsumableItem(
    "ANDROID TEST ITEM_UNAVAILABLE", // name
    "Description for: android.test.item_unavailable.", // description
    ANDROID_TEST_ITEM_UNAVAILABLE_ID, // id
    new PurchaseWithMarket(new MarketItem(ANDROID_TEST_ITEM_UNAVAILABLE_ID, MarketItem.Consumable.NONCONSUMABLE , 0.99f))
    );
    }

  • สร้าง C# Script ให้ชื่อว่า Foo     Script นี้มีหน้าที่ดัก Event ต่างๆ
    using UnityEngine;
    using System.Collections;
    using Soomla;
    using Soomla.Store;

    public class Foo : MonoBehaviour {

    public UILabel Label;

    // Use this for initialization
    void Start () {
    StoreEvents.OnMarketPurchaseStarted += OnMarketPurchaseStarted;
    StoreEvents.OnMarketPurchase += OnMarketPurchase;
    StoreEvents.OnItemPurchaseStarted += OnItemPurchaseStarted;
    StoreEvents.OnItemPurchased += OnItemPurchased;
    StoreEvents.OnSoomlaStoreInitialized += OnSoomlaStoreInitialized;
    StoreEvents.OnUnexpectedErrorInStore += OnUnexpectedErrorInStore;

    SoomlaStore.Initialize(new StoreAssets());
    }

    string s = "";

    public void OnMarketPurchaseStarted( PurchasableVirtualItem pvi ) {
    Debug.Log( "OnMarketPurchaseStarted: " + pvi.ItemId );
    s += "OnMarketPurchaseStarted: " + pvi.ItemId+"\n";

    Label.text = s;
    }
    public void OnMarketPurchase( PurchasableVirtualItem pvi, string purchaseToken, string payload ) {
    Debug.Log( "OnMarketPurchase: " + pvi.ItemId + ", " + purchaseToken + ", " + payload);
    s += "OnMarketPurchase: " + pvi.ItemId + ", " + purchaseToken+ ", " + payload+"\n";

    Label.text = s;
    }
    public void OnItemPurchaseStarted( PurchasableVirtualItem pvi ) {
    Debug.Log( "OnItemPurchaseStarted: " + pvi.ItemId );
    s += "OnItemPurchaseStarted: " + pvi.ItemId+"\n";

    Label.text = s;
    }
    public void OnItemPurchased( PurchasableVirtualItem pvi, string payload ) {
    Debug.Log( "OnItemPurchased: " + pvi.ItemId + ", " + payload);
    s += "OnItemPurchased: " + pvi.ItemId + ", " + payload+"\n";

    Label.text = s;
    }
    public void OnSoomlaStoreInitialized(){
    Debug.Log( "OnSoomlaStoreInitialized" );
    s += "OnSoomlaStoreInitialized"+"\n";

    Label.text = s;
    }
    public void OnUnexpectedErrorInStore( string err ) {
    Debug.Log( "OnUnexpectedErrorInStore" + err );
    s += "OnUnexpectedErrorInStore" + err+"\n";

    Label.text = s;
    }
    public void buyItem1(){
    Debug.Log ("buy item1 click");
    s += "buy item1 click"+"\n";

    Label.text = s;

    //SoomlaStore.BuyMarketItem(StoreAssets.ITEM1.ItemId, "");
    StoreInventory.BuyItem( StoreAssets.ITEM1.ItemId );
    }
    public void buyItem2(){
    Debug.Log ("buy item2 click");
    s += "buy item2 click"+"\n";

    Label.text = s;

    //SoomlaStore.BuyMarketItem(StoreAssets.ITEM2.ItemId, "");
    StoreInventory.BuyItem( StoreAssets.ITEM2.ItemId );
    }
    public void buyItem3(){
    Debug.Log ("buy item3 click");
    s += "buy item3 click"+"\n";

    Label.text = s;

    //SoomlaStore.BuyMarketItem(StoreAssets.ITEM3.ItemId, "");
    StoreInventory.BuyItem( StoreAssets.ITEM3.ItemId );
    }

    public void buyPurchased(){
    Debug.Log ("buy purchased click");
    s += "buy purchased click"+"\n";

    Label.text = s;

    //SoomlaStore.BuyMarketItem(StoreAssets.PURCHASED.ItemId, "");
    StoreInventory.BuyItem( StoreAssets.PURCHASED.ItemId );
    }
    public void buyCanceled(){
    Debug.Log ("buy canceled click");
    StoreInventory.BuyItem( StoreAssets.CANCELED.ItemId );
    //SoomlaStore.BuyMarketItem(StoreAssets.ITEM2.ItemId, "");
    }
    public void buyRefunded(){
    Debug.Log ("buy refunded click");
    StoreInventory.BuyItem( StoreAssets.REFUNDED.ItemId );
    //SoomlaStore.BuyMarketItem(StoreAssets.ITEM2.ItemId, "");
    }
    public void buyItem_unavailable(){
    Debug.Log ("buy item_unavailable click");
    StoreInventory.BuyItem( StoreAssets.ITEM_UNAVAILABLE.ItemId );
    //SoomlaStore.BuyMarketItem(StoreAssets.ITEM2.ItemId, "");
    }
    }

  • สร้าง GameObject เปล่าขึ้นมา แล้วลาก Script Foo ใส่ไปใน GameObject นี้
  • ลาก Prefab ชื่อ StoreEvents และ CoreEvents ใส่ใน Scene ของเรา
    ** Prefab อยู่ใน Soomla => Prefabs
  • สร้างปุ่มที่เรียก Event BuyItem1 หรือ Item ไหนที่เราต้องการ
  • Build Project และ Upload ขึ้นไปที่ Google Developer Console และนำ .apk ตัวเดียวกันนี้ไป Install ลงในมือถือ Android และลองเล่น In App Purchase ดู ถึงตอนนี้ก็น่าจะใช้ได้แล้วนะคร้าฟฟ
    ** หากยังใช้ไม่ได้ ให้รอเวลาอาจจะติดที่ In App Products ยังไม่ Active ก็ได้ครับ ใช้เวลานานอยู่เหมือนกัน

Enjoy this article?

Consider subscribing to our RSS feed!

ไม่มีความเห็น

ยังไม่มีความเห็น

ใส่ความเห็น

RSS feed for comments on this post