inappData: Các thông tin về gói mua, gồm id, purchase token, tên gói, mốc tiến trình mua gói, adid, loại user IAP
onSuccess: Hàm được thực hiện khi gói mua hợp lệ.
onFail: Hàm được thực hiện khi gói mua không hợp lệ
Code mẫu:
string targetLevel = "3"; // Là level cao nhất mà user chưa vượt qua được
string productId = "com.cscmobi.cana.islands.tier2";
string purchaseToken = "bonlghknnoigpaegpeamnppf.AO-J1OzxViPPvXq9ZnZWF6w0DsHBCkRKkMibnrC2aOZwUC4lKvtURI4CPC_myA0C_Rpz4dRhbaNEMS2Pw2spYKdwNjWQWeiZKwNPuNtNyknKwg0KrQrRJKk";
string productName = "piggy_bank"; // Là Tên gói nạp IAP, Có thể bỏ trống
string group = ""; //Tên nhóm, phục vụ cho A/B test, hoặc các level có state khác nhau.. Ví dụ tệp userA, userB, state0, state1...
string subGroup= ""; // Tên nhóm, như group nhưng ở quy mô nhỏ hơn
string userType = "2"; // Là loại user. Có thể bỏ trống
string adid = ""; // Là Adjust Id (Sample: Adjust.getAdid()). Có thể bỏ trống
GSM.Validator.Inapp.InappData data = new GSM.Validator.Inapp.InappData(targetLevel, productId, purchaseToken, productName, group, userType, adid, subGroup);
GSM.Validator.Inapp.Check(data, () => Debug.Log("Valid purchase"), () =>
{
Debug.LogError("Invalid purchase");
});
Lưu ý:
Phía game không được phụ thuộc vào kết quả trả về để trả phần thưởng cho user. Vì nếu server lỗi, thì toàn bộ user sẽ không nhận được thưởng gây ra phản hồi tiêu cực của user.
Cách lấy các thông tin được sử dụng trong API ValidateIAP
Code mẫu:
using UnityEngine.Purchasing;
using UnityEngine.Purchasing.Extension;
[SerializedField] IAPButton iapButton;
private void Start()
{
iapButton.onPurchaseComplete.AddListener(OnCompletePurchase);
}
public void OnCompletePurchase(Product product)//handle effect
{
var wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(product.receipt);
#if UNITY_IOS
var purchaseToken = (string)wrapper["Payload"];
#elif UNITY_ANDROID
var purchaseToken = (string)wrapper["TransactionID"];
#endif
int targetLevel = <your targetLevel>; // Là level cao nhất mà user chưa vượt qua được
string productId = product.definition.id;
string productName = <productName>; // Là Tên gói nạp IAP do game định nghĩa, Có thể bỏ trống
string group = ""; //Tên nhóm, phục vụ cho A/B test, hoặc các level có state khác nhau.. Ví dụ tệp userA, userB, state0, state1...
string subGroup= ""; // Tên nhóm, như group nhưng ở quy mô nhỏ hơn
string userType = <typeUser>; // Là loại user. Có thể bỏ trống
string adid = Adjust.getAdid(); // Là Adjust Id (Sample: Adjust.getAdid()). Có thể bỏ trống
GSM.Validator.Inapp.InappData data = new GSM.Validator.Inapp.InappData(targetLevel, productId, purchaseToken, productName, group, userType, adid, subGroup);
GSM.Validator.Inapp.Check(data, () => Debug.Log("Valid purchase"), () =>
{
Debug.LogError("Invalid purchase");
});
}
Khi user nhấn vào nút mua 1 gói IAP nào đó, thì game gửi lên server trạng thái start 1 iap
Code mẫu:
GSM.Analytics.GSMAnalytics.LogEvent("iap_progress", new GSM.Models.Parameter[]
{
new GSM.Models.Parameter("orderId", "{orderId}"), //Id giao dịch
new GSM.Models.Parameter("productName", "{tên gói nạp}"),
new GSM.Models.Parameter("status", -1) // -1 là thể hiện trạng thái bắt đầu 1 IAP
});
2.3 Khi IAP thành công
Sau khi người chơi hoàn thành việc mua IAP, thì game gửi lên trạng thái thành công
Code mẫu:
GSM.Analytics.GSMAnalytics.LogEvent("iap_progress", new GSM.Models.Parameter[]
{
new GSM.Models.Parameter("orderId", "{orderId}"),//Id giao dịch
new GSM.Models.Parameter("storeOrderId", "{storeOrderId}"), // Là Id giao dịch của store trả về khi IAP thành công
new GSM.Models.Parameter("productName", "{tên gói nạp}"),
new GSM.Models.Parameter("status", 8) // 8 là thể hiện việc mua IAP thành công
});
2.4 Khi IAP bị fail
Trong quá trình thực hiện 1 IAP bị fail vì 1 lý do gì đó, thì client cần gửi lên tiến trình đang fail ở đâu
Code mẫu:
GSM.Analytics.GSMAnalytics.LogEvent("iap_progress", new GSM.Models.Parameter[]
{
new GSM.Models.Parameter("orderId", "{orderId}"),
new GSM.Models.Parameter("productName", "{tên gói nạp}"),
new GSM.Models.Parameter("status", {0->7}) //Các trạng thái fail
});
Các Status -1->8
-1: Start
0: PurchasingUnavailable
1: ExistingPurchasePending
2: ProductUnavailable
3: SignatureInvalid
4: UserCancelled
5: PaymentDeclined
6: DuplicateTransaction
7: Unknown
8: Success
Code mẫu:
using UnityEngine.Purchasing;
using UnityEngine.Purchasing.Extension;
using UnityEngine.UI;
[SerializedField] IAPButton iapButton;
private void Start()
{
iapButton.GetComponent<Button>().onClick.AddListener(PurchaseProduct);
iapButton.onPurchaseComplete.AddListener(OnCompletePurchase);
iapButton.onPurchaseFailed.AddListener(OnFailPurchase);
}
public void OnCompletePurchase(Product product)//handle effect
{
var wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(product.receipt);
string storeOrderId;
#if UNITY_IOS
var purchaseToken = (string)wrapper["Payload"];
try
{
var orderId = (string)wrapper["TransactionID"];
storeOrderId = orderId;
}
catch (System.Exception e)
{
storeOrderId = "";
}
#elif UNITY_ANDROID
var purchaseToken = (string)wrapper["TransactionID"];
try
{
var gpPayLoad = (string)wrapper["Payload"];
var gpJson = (Dictionary<string, object>)MiniJson.JsonDecode(gpPayLoad);
var json = (string)gpJson["json"];
var jsonDetails = (Dictionary<string, object>)MiniJson.JsonDecode(json);
string orderId = (string)jsonDetails["orderId"];
storeOrderId = orderId;
}
catch (System.Exception e)
{
storeOrderId = "";
Debug.LogException(e);
}
#endif
// Other logic
GSM.Analytics.GSMAnalytics.LogEvent("iap_progress", new GSM.Models.Parameter[]
{
new GSM.Models.Parameter("orderId", orderId),
new GSM.Models.Parameter("storeOrderId ", storeOrderId ),
new GSM.Models.Parameter("productName", product.metadata.localizedTitle),
new GSM.Models.Parameter("status", 8)
});
}
public void OnFailPurchase(Product product, PurchaseFailureDescription reason)
{
// Other logic
GSM.Analytics.GSMAnalytics.LogEvent("iap_progress", new GSM.Models.Parameter[]
{
new GSM.Models.Parameter("orderId", orderId),
new GSM.Models.Parameter("productName", product.metadata.localizedTitle),
new GSM.Models.Parameter("status", (int)reason.reason) //Các trạng thái fail
});
}
public void PurchaseProduct()
{
if (buttonType == CodelessButtonType.Purchase)
{
// Other logic
GSM.Analytics.GSMAnalytics.LogEvent("iap_progress", new GSM.Models.Parameter[]
{
new GSM.Models.Parameter("orderId",orderId),
new GSM.Models.Parameter("productName", product.metadata.localizedTitle),
new GSM.Models.Parameter("status", -1)
});
}
}
3. Verify Subcription
Dùng khi user hoàn thành Subcription.
Phía server sẽ lưu doanh thu và thống kê với những dữ liệu Subcription hợp lệ.
data: Các thông tin về gói subcription, gồm id, purchase token, tên gói, mốc tiến trình mua gói, adid, loại user
onSuccess: Hàm được thực hiện khi gói subcription hợp lệ.
onFail: Hàm được thực hiện khi gói subcription không hợp lệ
Code mẫu:
string targetLevel = "3"; // Là level cao nhất mà user chưa vượt qua được
string productId = "com.cscmobi.cana.islands.tier2";
string purchaseToken = "bonlghknnoigpaegpeamnppf.AO-J1OzxViPPvXq9ZnZWF6w0DsHBCkRKkMibnrC2aOZwUC4lKvtURI4CPC_myA0C_Rpz4dRhbaNEMS2Pw2spYKdwNjWQWeiZKwNPuNtNyknKwg0KrQrRJKk";
string productName = "piggy_bank"; // Là Tên gói nạp Subcription, Có thể bỏ trống
string group = ""; //Tên nhóm, phục vụ cho A/B test, hoặc các level có state khác nhau.. Ví dụ tệp userA, userB, state0, state1...
string subGroup= ""; // Tên nhóm, như group nhưng ở quy mô nhỏ hơn
string userType = "2"; // Là loại user. Có thể bỏ trống
string adid = ""; // Là Adjust Id (Sample: Adjust.getAdid()). Có thể bỏ trống
GSM.Validator.Subcription.SubcriptionData data = new GSM.Validator.Subcription.SubcriptionData(targetLevel, productId, purchaseToken, productName, group, userType, adid);
GSM.Validator.Subcription.Check(data, () => Debug.Log("Valid subcription"), () =>
{
Debug.LogError("Invalid subcription");
});
Lưu ý:
Phía game không được phụ thuộc vào kết quả trả về để trả phần thưởng cho user. Vì nếu server lỗi, thì toàn bộ user sẽ không nhận được thưởng gây ra phản hồi tiêu cực của user.