뒤끝 영수증 검증 질문입니다.

고객님의 문의에 답변하는 직원은 고객 여러분의 가족 중 한 사람일 수 있습니다.
고객의 언어폭력(비하, 조롱, 욕설, 협박, 성희롱 등)으로부터 직원을 보호하기 위해
관련 법에 따라 수사기관에 필요한 조치를 요구할 수 있으며, 형법에 의해 처벌 대상이 될 수 있습니다.

커뮤니티 이용 정책에 위배되는 게시물을 작성할 경우, 별도 안내 없이 게시물 삭제 또는 커뮤니티 이용이 제한될 수 있습니다.

문의 응대 : 평일 오전 10시 ~ 오후 6시
문의를 남기실 경우 다음 항목을 작성해 주세요.
정보가 부족하거나 응대시간 외 문의하는 경우 확인 및 답변이 지연될 수 있습니다.

  • 뒤끝 SDK 버전 : 5.11.7
  • 프로젝트명 : 3D Match Farm
  • 스테이터스 코드 :
  • 에러 코드 :
  • 에러 메시지 :

구글 플레이 콘솔과 뒤끝 콘솔에 인앱상품 등록 후 IAP 이용하여 결제 테스트를 하는데 영수증 검증이 되지 않습니다. IsValidateGooglePurchase가 실패하고 에러코드는 status code : 400, error code : Receipt Parse Error로 출력되며 영수증을 로그로 찍어보면 {“Payload”:“ThisIsFakeReceiptData”,“Store”:“fake”,“TransactionID”:“8bdc4ca6-7613-4305-8b26-445faa274197”} 라고 출력됩니다.
혹시 코드 상의 문제나 추가로 설정해야 하는 부분이 있는지 문의드립니다.

using System;
using System.Collections;
using System.Collections.Generic;
using BackEnd;
using UnityEngine;
using UnityEngine.Purchasing;

public class IAPManager : Singleton<IAPManager>, IStoreListener
{
    [SerializeField] private string productID = "dia_100";
    
    private static IStoreController m_StoreController;
    private static IExtensionProvider m_StoreExtensionProvider; 

    void Start()
    {
        if (m_StoreController == null)
        {
            InitializePurchasing();
        }
    }

    public void InitializePurchasing() 
    {
        if (IsInitialized())
        {
            return;
        }

        var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
        
        builder.AddProduct(productID, ProductType.Consumable, new IDs()
            {
                {productID, GooglePlay.Name }
            }
        );

        UnityPurchasing.Initialize(this, builder);
    }

    private bool IsInitialized()
    {
        return m_StoreController != null && m_StoreExtensionProvider != null;
    }

    public void PurchaseTest()
    {
        PurchaseProductID(productID);
    }

    void PurchaseProductID(string productId)
    {
        if (IsInitialized())
        {
            Product product = m_StoreController.products.WithID(productId);

            if (product != null && product.availableToPurchase)
            {
                m_StoreController.InitiatePurchase(product);
            }
            
            else
            {
                Debug.Log("PurchaseProductID: FAIL. 상품을 찾을 수 없거나 구매할 수 없습니다.");
            }
        }
        
        else
        {
            Debug.Log("PurchaseProductID FAIL. IAP가 초기화되지 않았습니다.");
        }
    }

    public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
    {
        m_StoreController = controller;
        m_StoreExtensionProvider = extensions;
        Debug.Log("OnInitialized");
    }

    public void OnInitializeFailed(InitializationFailureReason error)
    {
        Debug.Log("OnInitializeFailed InitializationFailureReason:" + error);
    }

    public void OnInitializeFailed(InitializationFailureReason error, string str)
    {
        Debug.Log("OnInitializeFailed InitializationFailureReason:" + error);
    }

    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) 
    {
        Debug.Log("Purchase Process");
        Debug.Log(args.purchasedProduct.receipt);
        if (String.Equals(args.purchasedProduct.definition.id, productID, StringComparison.Ordinal))
        {
            BackendReturnObject validation =
                Backend.Receipt.IsValidateGooglePurchase(args.purchasedProduct.receipt, "receiptDescription", false);

            if (validation.IsSuccess())
            {
                Debug.Log("Validation Success");
                BackendReturnObject bro = Backend.TBC.ChargeTBC(args.purchasedProduct.receipt, null);
            }
            
            else
            {
                Debug.Log(string.Format("ProcessPurchase: FAIL. Unrecognized product: '{0}'", args.purchasedProduct.definition.id));
                Debug.Log("status code : " + validation.GetStatusCode()+ "\nerror code : " + validation.GetErrorCode());
            }
        }
        
        return PurchaseProcessingResult.Complete;
    }

    public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
    {
        Debug.Log(string.Format("OnPurchaseFailed: FAIL. Product: '{0}', PurchaseFailureReason: '{1}'", product.definition.storeSpecificId, failureReason));
    }
}

안녕하세요 개발자님,
문의하신 내용 확인하여 안내드리고자 하였으나 프로젝트 정보가 확인되지 않습니다.
뒤끝에 등록된 프로젝트명을 다시 확인하여 공유해 주세요.

아 실수로 잘못 올렸네요.프로젝트명 수정했습니다.

안녕하세요 개발자님,
'this is fake receipt’로 에러정보가 확인되고 있습니다.
뒤끝 영수증 검증의 경우, 실제 모바일 기기에서 인앱 구매를 통한 영수증 검증의 경우에만 정상적으로 동작하는 점 참고하여 이용해 주시면 감사하겠습니다.

내부 테스트로 출시 후 안드로이드에서 결제되는거 까지 확인했는데 뒤끝 콘솔 영수증 검증 내역에는 따로 올라오는게 없네요…

추가 확인 시 3일에 3회의 추가 에러 발생 기록이 확인됩니다.

bad request, 잘못된 request 입니다

해다 에러는 영수증 토큰에 사용되는 데이터가 다른 데이터와 달리 파싱을 못해서 발생하는 에러입니다.
해당 영수증이 Store : { } 와 같은 형태로 시작되는 데이터를 보내주지 않은 것으로 확인됩니다.

감사합니다. 그럼 혹시 어떻게 수정해야 해당 에러를 해결할 수 있을까요?

개발자 문서의 영수증 검증 페이지에 안내된 예시 코드와 같이
호출을 진행하셨는지 확인해 주시면 감사하겠습니다.