ข้ามไปที่เนื้อหา

การตรวจสอบใบเสร็จ

ใบเสร็จสินค้าที่ไม่ได้ให้

การส่งรายการอาจล้มเหลวหรือถูกยกเลิกหลังจากการซื้อ เพื่อป้องกันสถานการณ์นี้ ให้ขอข้อมูลใบเสร็จของรายการที่ไม่ได้รับโดยการเรียกใช้วิธีการ 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

import HIVEService    
    IAPV4Interface.restore() { result, receiptList in    
        if result.isSuccess() {    
            if result.getErrorCode() == .success {    
            // TODO: Request receipt verification using the received receiptList    
            } else if result.getErrorCode() == .notOwned {    
            // No unpaid items    
            }    
        }    
}

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

using hive;    
    String marketPid = "{YOUR_PRODUCT_MARKET_PID}";    
    IAPV4.transactionFinish(marketPid, (ResultAPI result, String marketPid) => {    
         if (result.isSuccess()) {    
             // call successful    
         }    
});
#include "HiveIAPV4.h"

FString MarketPid = TEXT("YOUR_PRODUCT_MARKET_PID");
FHiveIAPV4::TransactionFinish(MarketPid, FHiveIAPV4OnTransactionFinishDelegate::CreateLambda([this, idx](const FHiveResultAPI& Result, const FString& MarketPid) {
        if (Result.IsSuccess()) {
                // call successful 
        }
}));

API Reference: IAPV4 ::transactionFinish

#include <HIVE_SDK_Plugin/HIVE_CPP.h>    
using namespace std;    
using namespace hive;    
string marketPid = "{YOUR_PRODUCT_MARKET_PID}";    

IAPV4::transactionFinish(marketPid, [=](ResultAPI const & result, string marketPid) {    
if (result.isSuccess()) {    
// call successful    
}    
});

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

import com.hive.IAPV4;    
    import com.hive.ResultAPI;    
    String pid = "{YOUR_PRODUCT_MARKET_PID}";    
    IAPV4.INSTANCE.transactionFinish(pid, (result, marketPid) -> {    
         if (result.isSuccess()) {    
             // call successful    
         }    
});

API Reference: IAPV4Interface.transactionFinish

import HIVEService    
    let marketPid = "{YOUR_PRODUCT_MARKET_PID}"    
    IAPV4Interface.transactionFinish() { result, marketPid in    
    if result.isSuccess() {    
        // call successful    
        }    
}

API Reference: HIVEIAPV4::transactionFinish:handler:

#import <HIVEService/HIVEService-Swift.h>    
    NSString *marketPid = @"{YOUR_PRODUCT_MARKET_PID}";    
    [HIVEIAPV4 transactionFinish: marketPid handler: ^(HIVEResultAPI *result, NSString *marketPid) {    
         if ([result isSuccess]) {    
             // call successful    
         }    
}];

ต่อไปนี้เป็นตัวอย่างโค้ดในการขอส่งหลายรายการ

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: IAPV4.getAccountUuid

using hive;    
String accountUuid = IAPV4.getAccountUuid();
#include "HiveIAPV4.h"

FString AccountUuid = FHiveIAPV4::GetAccountUuid();

API Reference: IAPV4 ::getAccountUuid

#include <HIVE_SDK_Plugin/HIVE_CPP.h>    
    using namespace std;    
    using namespace hive;    
string accountUuid = IAPV4::getAccountUuid();

API Reference: IAPV4.getAccountUuid

import com.hive.IAPV4    
val accountUuid = IAPV4.getAccountUuid()

API Reference: IAPV4.INSTANCE .getAccountUuid

import com.hive.IAPV4;    
String accountUuid = IAPV4.INSTANCE.getAccountUuid();

API Reference: IAPV4Interface.getAccountUuid

import HIVEService    
let accountUuid = IAPV4Interface.getAccountUuid()

API Reference: [HIVEIAPV4 getAccountUuid ]

#import <HIVEService/HIVEService-Swift.h>    
NSString *accountUuid = [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 ไปยังเซิร์ฟเวอร์เกม โค้ดด้านล่างเป็นโค้ดตัวอย่างสำหรับการอ้างอิงในการพัฒนา

IAPV4.purchaseproductId) {
    iapv4Receipt -> game.sendReceipt(iapv4Receipt.purchase_bypass_info)
}

การขอการตรวจสอบใบเสร็จ

เซิร์ฟเวอร์เกมส่งข้อมูล 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 และใบเสร็จเพื่อวิเคราะห์กิจกรรมการซื้อของผู้ใช้。