การตรวจสอบใบเสร็จ
ใบเสร็จสินค้าที่ไม่ได้รับ¶
การส่งสินค้าอาจล้มเหลวหรือถูกยกเลิกหลังจากการซื้อ เพื่อป้องกันสถานการณ์นี้ ให้ขอข้อมูลใบเสร็จของสินค้าที่ไม่ได้รับโดยการเรียกใช้วิธีการ restore()
ของคลาส IAPV4
- หากมีการส่งคืน
SUCCESS
และ ReceiptList ถูกส่งหลังจากเรียกใช้restore()
หมายความว่ามีรายการที่ต้องการการกู้คืนอยู่ ส่งรายการที่ยังไม่ได้ให้และทำให้กระบวนการกู้คืนเสร็จสมบูรณ์ - หากไม่มีการส่งคืน
SUCCESS
หลังจากเรียกใช้restore()
จะไม่มีการดำเนินการเพิ่มเติมที่จำเป็นสำหรับสตูดิโอเกม - หากเกิดข้อผิดพลาดขณะเรียกใช้วิธี
restore()
ให้แจ้ง เฉพาะข้อผิดพลาดบางประการที่จำเป็นต้องรับรู้ และข้ามข้อผิดพลาดอื่น ๆ เพื่อให้ผู้ใช้สามารถเล่นเกมของคุณต่อไปได้ - เมื่อใช้ตลาด
GOOGLE_PLAYSTORE
ในแอป Windows สำหรับ Google Play (Hive SDK v4 Unity Windows 23.0.0 หรือสูงกว่า) หากข้อมูลการรับรองสำหรับบัญชี Google ที่ใช้ในการชำระเงินหมดอายุในขณะเรียกใช้วิธีrestore()
Hive SDK จะเริ่มกระบวนการรับรองความถูกต้องใหม่โดยอัตโนมัติ
ต่อไปนี้คือตัวอย่างโค้ดเพื่อขอข้อมูลใบเสร็จของรายการที่ไม่ได้ให้
API Reference: hive .IAPV4.restore
using hive;
IAPV4.restore((ResultAPI result, List receiptList) => {
if (result.isSuccess()) {
if (result.errorCode = ResultAPI.ErrorCode.SUCCESS) {
// TODO: Request receipt verification using the received receiptList
} else if (result.errorCode = ResultAPI.ErrorCode.NOT_OWNED) {
// No unpaid items
}
}
}
#include "HiveIAPV4.h"
FHiveIAPV4::Restore(FHiveIAPV4OnRestoreDelegate::CreateLambda([this](const FHiveResultAPI& Result, const TArray<FHiveIAPV4Receipt>& IAPV4ReceiptList) {
if (Result.IsSuccess()) {
if (Result.ErrorCode == FHiveResultAPI::EErrorCode::SUCCESS) {
// TODO: ขอการตรวจสอบใบเสร็จโดยใช้รายการใบเสร็จที่ได้รับ
} else if (Result.ErrorCode == FHiveResultAPI::EErrorCode::RESTORE_NOT_OWNED) {
// ไม่มีรายการที่ยังไม่ได้ชำระเงิน
}
}
}));
API Reference: IAPV4 ::restore
#include <HIVE_SDK_Plugin/HIVE_CPP.h>
using namespace std;
using namespace hive;
IAPV4::restore([=](ResultAPI const & result, vector<reference_wrapper<IAPV4Receipt>> receiptList) {
if (result.isSuccess()) {
if (result.errorCode == ResultAPI::ErrorCode::SUCCESS) {
// TODO: Request receipt verification using the received receiptList
} else if (result.errorCode == ResultAPI::ErrorCode::RESTORE_NOT_OWNED) {
// No unpaid items
}
}
});
API Reference: IAPV4.restore
import com.hive.IAPV4
import com.hive.ResultAPI
IAPV4.restore(object : IAPV4.IAPV4RestoreListener {
override fun onIAPV4Restore(result: ResultAPI, iapv4ReceiptList: ArrayList<IAPV4.IAPV4Receipt>?) {
if (result.isSuccess) {
if (result.errorCode == ResultAPI.SUCCESS) {
// TODO: Request receipt verification using the received iapv4ReceiptList
} else if (result.errorCode == ResultAPI.RESTORE_NOT_OWNED) {
// No unpaid items
}
}
}
})
API Reference: com.hive.IAPV4.restore
import com.hive.IAPV4;
import com.hive.ResultAPI;
IAPV4.INSTANCE.restore((result, iapv4ReceiptList) -> {
if (result.isSuccess()) {
if (result.getErrorCode() == ResultAPI.Companion.getSUCCESS()) {
// TODO: Request receipt verification using the received iapv4ReceiptList
} else if (result.getErrorCode() == ResultAPI.Companion.getRESTORE_NOT_OWNED()) {
// No unpaid items
}
}
});
API Reference: IAPV4Interface .restore
API Reference: HIVEIAPV4::restore
#import <HIVEService/HIVEService-Swift.h>
[HIVEIAPV4 restore: ^(HIVEResultAPI *result, NSArray<HIVEIAPV4Receipt *> *receiptList) {
if ([result isSuccess]) {
if ([result getErrorCode] == HIVEResultAPITypeSuccess) {
// TODO: Request receipt verification using the received receiptList
} else if ([result getErrorCode] == HIVEResultAPITypeNotOwned){
// No unpaid items
}
}
}];
Note
may differ by operating system/market. For more details, see the status of supported features.
รายการรหัสข้อผิดพลาดในการกู้คืนการซื้อ¶
รหัสข้อผิดพลาด | คำอธิบาย |
---|---|
NEED_INITIALIZE | ไม่สามารถเริ่มต้นได้ |
NETWORK | ข้อผิดพลาดเครือข่าย |
NOT_SUPPORTED | ไม่สามารถกู้คืนได้ (การซื้อในแอปถูกปฏิเสธบนอุปกรณ์ ฯลฯ) ผู้ใช้ตั้งร้านค้าที่ไม่สามารถใช้งานได้ |
INVALID_SESSION | เซสชันไม่ถูกต้องสำหรับการกู้คืน |
IN_PROGRESS | API การกู้คืนกำลังดำเนินการ |
RESTORE_NOT_OWNED | ไม่มีรายการให้กู้คืน |
NOT_OWNED | ไม่มีรายการให้กู้คืน |
RESPONSE_FAIL | ข้อผิดพลาดของเซิร์ฟเวอร์ IAP |
การตรวจสอบใบเสร็จการซื้อ¶
ก่อนที่จะส่งรายการจากเซิร์ฟเวอร์เกม API การตรวจสอบจาก IAP ควรยืนยันว่าบิลนั้นถูกต้อง
hiveiap_transaction_id
ใน API การตรวจสอบเป็น ID ที่ไม่ซ้ำกันที่ออกโดยบิล ดังนั้นให้บันทึก ID ไว้ในเซิร์ฟเวอร์เกมเพื่อตรวจสอบบิลที่ซ้ำกัน
หากคุณใช้ API การตรวจสอบและจากนั้นส่งข้อมูลทั้งหมดจากพารามิเตอร์ Request เซิร์ฟเวอร์ IAP จะส่งต่อข้อมูลเกมเพื่อวิเคราะห์สถานะการขาย ใช้ API เพื่อค้นหาการชำระเงินที่ Hive One > ค้นหาทั้งหมด ด้วย
สำหรับรายละเอียดเพิ่มเติม โปรดดูที่ IAP Receipt Verification API.
การเติมเพื่อให้รายการที่ซื้อหรือยังไม่ได้ให้¶
หากเซิร์ฟเวอร์เกมส่งไอเท็มหลังจากการซื้อ ให้แน่ใจว่าได้เรียกใช้วิธี transactionFinish()
ของคลาส IAPV4 เพื่อทำให้การซื้อเสร็จสมบูรณ์
Warning
หากคุณไม่เรียกใช้เมธอด transactionFinish()
รายการจะยังคงอยู่ในสถานะที่ยังไม่ได้ให้
สาเหตุนี้ทำให้ใบเสร็จคืนภายใต้การเรียกใช้วิธีการ restore()
ดังนั้นโปรดตรวจสอบให้แน่ใจว่าได้เรียกใช้ API เสร็จสิ้นหลังจากกระบวนการทั้งหมดเสร็จสิ้น
Note
ด้วย Hive SDK v4.12.0 และเวอร์ชันที่ใหม่กว่านั้นใน Android Google Play Store การชำระเงินจะถูกคืนเงินโดยอัตโนมัติหากผลลัพธ์ของการเรียกใช้วิธี TransactionFinish()
ในคลาส IAPV4 ไม่สำเร็จภายในสามวันหรือห้าหลังจากการชำระเงินในสถานะทดสอบ
ต่อไปนี้คือตัวอย่างโค้ดที่ทำการส่งคำขอสำหรับการส่งสินค้า
เอกสาร API: hive .IAPV4.transactionFinish
API Reference: IAPV4 ::transactionFinish
API Reference: IAPV4.transactionFinish
import com.hive.IAPV4
import com.hive.ResultAPI
val marketPid = "{YOUR_PRODUCT_MARKET_PID}"
IAPV4.transactionFinish(marketPid, object : IAPV4.IAPV4TransactionFinishListener {
override fun onIAPV4TransactionFinish(result: ResultAPI, marketPid: String) {
if (result.isSuccess) {
// call successful
}
}
})
API Reference: com.hive.IAPV4.transactionFinish
API Reference: IAPV4Interface.transactionFinish
API Reference: HIVEIAPV4::transactionFinish:handler:
ต่อไปนี้เป็นตัวอย่างโค้ดในการขอส่งหลายรายการ
API Reference: hive .IAPV4.transactionMultiFinish
using hive;
List marketPidList = new List();
marketPidList.Add("{YOUR_PRODUCT_MARKET_PID_01}");
marketPidList.Add("{YOUR_PRODUCT_MARKET_PID_02}");
marketPidList.Add("{YOUR_PRODUCT_MARKET_PID_03}");
IAPV4.transactionMultiFinish((List<ResultAPI> resultList, List<String> marketPidList) => {
for (ResultAPI result in resultList) {
if (result.isSuccess()) {
// call successful
}
}
});
#include "HiveIAPV4.h"
TArray<FString> MarketPidList;
MarketPidList.Add(TEXT("YOUR_PRODUCT_MARKET_PID_01"));
MarketPidList.Add(TEXT("YOUR_PRODUCT_MARKET_PID_02"));
MarketPidList.Add(TEXT("YOUR_PRODUCT_MARKET_PID_03"));
FHiveIAPV4::TransactionMultiFinish(MarketPidList, FHiveIAPV4OnTransactionMultiFinishDelegate::CreateLambda([this](const TArray<FHiveResultAPI>& ResultList, const TArray<FString>& MarketPidList) {
for (const auto& Result : ResultList) {
if (Result.IsSuccess()) {
// API call successful
}
}
}));
API Reference: IAPV4 ::transactionMultiFinish
#include <HIVE_SDK_Plugin/HIVE_CPP.h>
using namespace std;
using namespace hive;
vector<string> marketPidList;
marketPidList.push_back("{YOUR_PRODUCT_MARKET_PID_01}");
marketPidList.push_back("{YOUR_PRODUCT_MARKET_PID_02}");
marketPidList.push_back("{YOUR_PRODUCT_MARKET_PID_03}");
IAPV4::transactionMultiFinish(marketPidList, [=](vector<ResultAPI> const & resultList, vector<string> const & marketPidList) {
for (ResultAPI result : resultList) {
if (result.isSuccess()) {
// call successful
}
}
});
API Reference: IAPV4.transactionMultiFinish
import com.hive.IAPV4
import com.hive.ResultAPI
val marketPidList = arrayListOf(
"{YOUR_PRODUCT_MARKET_PID_01}",
"{YOUR_PRODUCT_MARKET_PID_02}",
"{YOUR_PRODUCT_MARKET_PID_03}"
)
IAPV4.transactionMultiFinish(marketPidList, object : IAPV4.IAPV4TransactionMultiFinishListener {
override fun onIAPV4TransactionMultiFinish(resultList: ArrayList<ResultAPI>, marketPidList: ArrayList<String>) {
for (i in 0 until resultList.size) {
if (resultList[i].isSuccess) {
// call successful
}
}
}
})
API Reference: com.hive.IAPV4.transactionMultiFinish
import com.hive.IAPV4;
import com.hive.ResultAPI;
ArrayList<String> marketPidList = new ArrayList<>(Arrays.asList(
"{YOUR_PRODUCT_MARKET_PID_01}",
"{YOUR_PRODUCT_MARKET_PID_02}",
"{YOUR_PRODUCT_MARKET_PID_03}"
));
IAPV4.INSTANCE.transactionMultiFinish(marketPidList, (resultList, marketPidList1) -> {
for (ResultAPI result : resultList) {
if (result.isSuccess()) {
// call successful
}
}
});
API Reference: IAPV4Interface.transactionMultiFinish
import HIVEService
var marketPidList = [String]()
marketPidList.append("{YOUR_PRODUCT_MARKET_PID_01}")
marketPidList.append("{YOUR_PRODUCT_MARKET_PID_02}")
marketPidList.append("{YOUR_PRODUCT_MARKET_PID_03}")
IAPV4Interface.transactionMultiFinish(marketPidList) { resultList, marketPidList in
for result in resultList {
if result.isSuccess() {
// call successful
}
}
}
API Reference: HIVEIAPV4::transactionMultiFinish
#import <HIVEService/HIVEService-Swift.h>
NSMutableArray<NSString *> *maketPidList = [NSMutableArray array];
[maketPidList addObject:@"{YOUR_PRODUCT_MARKET_PID_01}"];
[maketPidList addObject:@"{YOUR_PRODUCT_MARKET_PID_02}"];
[maketPidList addObject:@"{YOUR_PRODUCT_MARKET_PID_03}"];
[HIVEIAPV4 transactionMultiFinish: maketPidList handler: ^(NSArray<HIVEResultAPI *> *resultList, NSArray<NSString *> *marketPidList) {
for (HIVEResultAPI *result in resultList) {
if ([result isSuccess]) {
// call successful
}
}
}];
รับข้อมูลกิจกรรมการซื้อของผู้ใช้: ใช้ AccountUuid
¶
อาจมีผู้ใช้ที่ใช้ระบบการชำระเงินในทางที่ผิด เช่น บัญชีเกมเดียวที่ใช้บัญชีร้านค้าแอปหลายบัญชีในการชำระเงิน ในด้านของสตูดิโอเกม คุณสามารถรับและวิเคราะห์พฤติกรรมของผู้ใช้เฉพาะโดยการเปรียบเทียบข้อมูลผู้ใช้ที่ชำระเงิน (AccountUuid)
วิธีการด้านล่างจะส่งคืน AccountUuid
ซึ่งเป็นค่าแฮชของ PlayerId ในรูปแบบ UUID v3 ที่ Hive SDK ส่งไปยังร้านแอป
API Reference: IAPV4.getAccountUuid
API Reference: IAPV4 ::getAccountUuid
API Reference: IAPV4.getAccountUuid
API Reference: IAPV4.INSTANCE .getAccountUuid
API Reference: IAPV4Interface.getAccountUuid
API Reference: [HIVEIAPV4 getAccountUuid ]
สตูดิโอเกมสามารถใช้ค่าแฮชนี้ร่วมกับข้อมูลใบเสร็จการซื้อเพื่อวิเคราะห์การซื้อของผู้ใช้
ตัวอย่างด้านล่างแสดงการวิเคราะห์กิจกรรมการซื้อของบัญชีเกมที่มี PlayerId เฉพาะผ่าน AccountUuid
เมื่อมีตัวละครในเกมหลายตัวในบัญชีเกมนี้ ตัวอย่างนี้ใช้เพื่อการพัฒนาเท่านั้นและไม่รับประกันการทำงานจริง.
เก็บข้อมูลเมตาของการซื้อในเซิร์ฟเวอร์เกมล่วงหน้า¶
ก่อนที่จะมีการร้องขอการซื้อ เก็บข้อมูลเมตาของการซื้อ (AccountUuid
และข้อมูลตัวละคร) ไว้ที่เซิร์ฟเวอร์เกม
/* The game client pass the info to the game server before the purchase occurs.
*
* @param purchaseTime: purchase time. The receipts are usually based on UTC. since the epoch (Jan 1, 1970).
* @param productId: purchase product ID.
* @param accountUuId: hashed PlayerId. It is included in the receipt and can be obtained with IAPV4.getAccountUuid().
* @param characterId: the character identifier within PlayerId.
*/
game.sendPurchaseGameData(purchaseTime, productId, accountUuid, characterId)
ส่ง bypassInfo
¶
เมื่อมีการร้องขอการซื้อ ให้ส่งข้อมูล bypassInfo
ไปยังเซิร์ฟเวอร์เกม โค้ดด้านล่างเป็นโค้ดจำลองสำหรับการอ้างอิงในการพัฒนา
การขอการตรวจสอบใบเสร็จ¶
เซิร์ฟเวอร์เกมส่งข้อมูล bypassInfo
ไปยังเซิร์ฟเวอร์ IAP v4 และขอให้ตรวจสอบความถูกต้องของใบเสร็จ สำหรับรายละเอียดเกี่ยวกับการขอการตรวจสอบใบเสร็จ โปรดดูที่ ที่นี่. AccountUuid
ที่รวมอยู่ใน hiveiap_receipt
ซึ่งเป็นใบเสร็จต้นฉบับจากตลาด/ร้านแอปที่ได้รับภายในค่าการตอบกลับ.
# Apple
# Purchase time: purchase_date_ms
# Purchased products: product_id
# AccountUuid: app_account_token
# Google
# Purchase time: purchaseTime
# Purchased products: productId
# AccountUuid: obfuscatedAccountId
วิเคราะห์โดยการจับคู่ AccountUuid
ของข้อมูลเมตาของการซื้อกับ AccountUuid
ของ hiveiap_receipt
¶
ค้นหาข้อมูลผู้ใช้ที่จำเป็นสำหรับการวิเคราะห์ เช่น ข้อมูลตัวละครเกม โดยการจับคู่ AccountUuid
ที่เก็บไว้ก่อนหน้านี้ในข้อมูลเมตาของการซื้อกับ AccountUuid
ที่ได้รับจากผลลัพธ์ของการตรวจสอบใบเสร็จ คุณสามารถวิเคราะห์กิจกรรมการซื้อของบัญชีเกมที่เกี่ยวข้องโดยการจับคู่ข้อมูลเมตาของการซื้อกับข้อมูลใบเสร็จ
หากผู้ใช้ได้ทำการซื้อสินค้าหลายรายการ การซื้อแต่ละครั้งสามารถระบุได้โดยการจับคู่ข้อมูลเมตาของการซื้อกับ purchaseTime
ของ hiveiap_receipt
สำหรับรายละเอียดเกี่ยวกับ hiveiap_receipt
โปรดดูที่ ตรวจสอบใบเสร็จ และตรวจสอบการตอบสนองของ API ตามตลาด
รับข้อมูลกิจกรรมการซื้อของผู้ใช้: ใช้ iadPayload
¶
เมื่อขอซื้อด้วย Purchase หากคุณรวมข้อมูลการวิเคราะห์กิจกรรมการซื้อที่กำหนดไว้ล่วงหน้าโดยบริษัทเกมใน iapPayload
เซิร์ฟเวอร์ Hive จะจับคู่ใบเสร็จการซื้อที่ตรงกับ iapPayload
และส่งไปยังเซิร์ฟเวอร์เกม สตูดิโอเกมสามารถวิเคราะห์กิจกรรมการซื้อของผู้ใช้โดยใช้ข้อมูลในใบเสร็จพร้อมกับข้อมูลใน iadPayload
。
Note
ด้วยวิธีนี้ เนื่องจาก Hive Server จะจับคู่ข้อมูลเมตาของการซื้อแต่ละรายการกับใบเสร็จแต่ละใบและส่งไปยังเซิร์ฟเวอร์เกมของคุณ คุณจึงไม่จำเป็นต้องจับคู่ข้อมูลเมตาของการซื้อและใบเสร็จด้วย AccountUuid
ด้วยตัวเองตามที่แสดงข้างต้น
กำหนด iapPayload
และดำเนินการ Purchase()
¶
เมื่อดำเนินการแต่ละ คำขอซื้อผลิตภัณฑ์ ให้กำหนดฟิลด์และค่าที่ต้องการใน iapPayload
และใช้เป็นอาร์กิวเมนต์ กระบวนการนี้คล้ายกับการกำหนด ข้อมูลเมตาของการซื้อ.
ขอการตรวจสอบใบเสร็จ และรับ iapPayload
และใบเสร็จที่เกี่ยวข้อง¶
เมื่อการชำระเงินเสร็จสมบูรณ์และมีการขอ การตรวจสอบใบเสร็จ เซิร์ฟเวอร์ Hive จะจับคู่ iapPayload
กับใบเสร็จที่เกี่ยวข้องตามการซื้อและส่งมอบให้กับเซิร์ฟเวอร์เกม สตูดิโอเกมสามารถใช้ข้อมูลใน iapPayload
และใบเสร็จเพื่อตรวจสอบกิจกรรมการซื้อของผู้ใช้ได้
ด้านล่างนี้คือตัวอย่างของสถานการณ์ที่ใช้ iapPayload.
- บัญชีตลาด: A, Hive PlayerId: a, ตัวละครแอป: 1 เข้าสู่ระบบ
- ซื้อ(marketPid, "playerId a - character 1")
- เปลี่ยนบัญชีเป็น Hive PlayerId: b, ตัวละครแอป 2
- กู้คืน()
- ได้รับใบเสร็จที่มี iapPayload "playerId a - character 1"