Skip to content

购买非消耗类型的物品后,调用初始化后.就会进入交易成功. #2

Open

Description

@corle-bell

购买非消耗类型的物品后,重新启动应用。
调用初始化后.就会进入交易成功的状态是为什么?

QQ截图20240618103718

Activity

  1. itenfay commented on Jun 22, 2024

    @itenfay
    Owner

    付款完成,交易票据验证通过拿到server响应后,客户端要调用以下方法关闭此次交易,不然每次启动苹果server会通知客户端还有交易未完成,另外非消耗产品需要提供额外的恢复购买的按钮提供用户使用。

    // Completes a pending transaction.
    [DllImport("__Internal")]
    private static extern void DYFFinishTransaction(string transactionId, string originalTransactionId);
    
    // Completes a pending transaction.
    [DllImport("__Internal")]
    private static extern void DYFFinishTransaction_(string transactionId);
    
  2. corle-bell commented on Jun 24, 2024

    @corle-bell
    Author

    我在验证成功之后调用的关闭交易,调用了关闭交易还是存在这个问题。 无法正确的关闭时因为transactionId不正确么,我在恢复购买后,进行验证。然后再下行信息里拿到的transactionId和 初始化后弹出的交易里的transactionId并不一样。但是他们的originalTransactionId是一样的。当然他们都是同一个商品。

  3. itenfay commented on Jun 25, 2024

    @itenfay
    Owner

    你看一下 UnityIAPConnector.mm 文件这段代码。因为非消耗型产品,在恢复购买后,transactionId与之前不一样,但originalTransactionId是一样的,导致传新的transactionId找不到Restored transaction。

    /// Completes a pending transaction.
    void DYFFinishTransaction(const char* transactionId, const char* originalTransactionId)
    {
        NSString *transactionIdentifier = __OBJC_STRING(transactionId);
        NSString *orgTransactionIdentifier = __OBJC_STRING(originalTransactionId);
        
        DYFStore *store = DYFStore.defaultStore;
        SKPaymentTransaction *pt = [store extractPurchasedTransaction:transactionIdentifier];
        if (pt) {
            [DYFStore.defaultStore finishTransaction:pt];
        } else {
            SKPaymentTransaction *rt = [store extractRestoredTransaction:transactionIdentifier];
            [DYFStore.defaultStore finishTransaction:rt];
        }
        DYFStoreUserDefaultsPersistence *persister = [[DYFStoreUserDefaultsPersistence alloc] init];
        [persister removeTransaction:transactionIdentifier];
        
        if (orgTransactionIdentifier) {
            [persister removeTransaction:orgTransactionIdentifier];
        }
    }
    
  4. itenfay commented on Jun 25, 2024

    @itenfay
    Owner
    - (SKPaymentTransaction *)extractRestoredTransaction:(NSString *)transactionIdentifier
    {
        __block SKPaymentTransaction *transaction = nil;
        if (!transactionIdentifier || transactionIdentifier.length == 0) {
            return transaction;
        }
        
        [self.restoredTranscations enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            SKPaymentTransaction *tempTransaction = obj;
            NSString *id = tempTransaction.transactionIdentifier;
            NSString *originalId = tempTransaction.originalTransaction.transactionIdentifier;
            DYFStoreLog(@"index: %zi, transactionId: %@, originalTransactionId: %@", idx, id, originalId);
            
            if ([id isEqualToString:transactionIdentifier]) {
                transaction = tempTransaction;
            }
        }];
        
        return transaction;
    }
    

    你过滤一下日志,看一下这段代码的日志打印的是什么,在这里回复我一下,我看到后分析定位问题所在,然后进行修复。

  5. corle-bell commented on Jun 26, 2024

    @corle-bell
    Author
    - (SKPaymentTransaction *)extractRestoredTransaction:(NSString *)transactionIdentifier
    {
        __block SKPaymentTransaction *transaction = nil;
        if (!transactionIdentifier || transactionIdentifier.length == 0) {
            return transaction;
        }
        
        [self.restoredTranscations enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            SKPaymentTransaction *tempTransaction = obj;
            NSString *id = tempTransaction.transactionIdentifier;
            NSString *originalId = tempTransaction.originalTransaction.transactionIdentifier;
            DYFStoreLog(@"index: %zi, transactionId: %@, originalTransactionId: %@", idx, id, originalId);
            
            if ([id isEqualToString:transactionIdentifier]) {
                transaction = tempTransaction;
            }
        }];
        
        return transaction;
    }
    

    你过滤一下日志,看一下这段代码的日志打印的是什么,在这里回复我一下,我看到后分析定位问题所在,然后进行修复。

    这里是log,初始化后processPurchaseNotification这里收到的是DYFStorePurchaseStateSucceeded,而不是Restore
    image

    e1faff28cdeba57b8957b1ba92d1e684

  6. itenfay commented on Jun 30, 2024

    @itenfay
    Owner
    - (SKPaymentTransaction *)extractRestoredTransaction:(NSString *)transactionIdentifier
    {
        __block SKPaymentTransaction *transaction = nil;
        if (!transactionIdentifier || transactionIdentifier.length == 0) {
            return transaction;
        }
        
        [self.restoredTranscations enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            SKPaymentTransaction *tempTransaction = obj;
            NSString *id = tempTransaction.transactionIdentifier;
            NSString *originalId = tempTransaction.originalTransaction.transactionIdentifier;
            DYFStoreLog(@"index: %zi, transactionId: %@, originalTransactionId: %@", idx, id, originalId);
            
            if ([id isEqualToString:transactionIdentifier]) {
                transaction = tempTransaction;
            }
        }];
        
        return transaction;
    }
    

    你过滤一下日志,看一下这段代码的日志打印的是什么,在这里回复我一下,我看到后分析定位问题所在,然后进行修复。

    这里是log,初始化后processPurchaseNotification这里收到的是DYFStorePurchaseStateSucceeded,而不是Restore image

    e1faff28cdeba57b8957b1ba92d1e684

    1. 红框标记和下面遍历Purchased Transcations都对得上。
    2. 看完log,发现调用完成交易的方法传入的交易id是null或是空的,你看下C#那边传的参数什么?
    3. 调用完成交易会进入下面的方法,检查一下交易id和原始交易id。
    /// Completes a pending transaction.
    void DYFFinishTransaction(const char* transactionId, const char* originalTransactionId)
    {
        NSString *transactionIdentifier = __OBJC_STRING(transactionId);
        NSString *orgTransactionIdentifier = __OBJC_STRING(originalTransactionId);
        
        DYFStore *store = DYFStore.defaultStore;
        SKPaymentTransaction *pt = [store extractPurchasedTransaction:transactionIdentifier];
        if (pt) {
            [DYFStore.defaultStore finishTransaction:pt];
        } else {
            SKPaymentTransaction *rt = [store extractRestoredTransaction:transactionIdentifier];
            [DYFStore.defaultStore finishTransaction:rt];
        }
        DYFStoreUserDefaultsPersistence *persister = [[DYFStoreUserDefaultsPersistence alloc] init];
        [persister removeTransaction:transactionIdentifier];
        
        if (orgTransactionIdentifier) {
            [persister removeTransaction:orgTransactionIdentifier];
        }
    }
    
  7. corle-bell commented on Jul 1, 2024

    @corle-bell
    Author
    - (SKPaymentTransaction *)extractRestoredTransaction:(NSString *)transactionIdentifier
    {
        __block SKPaymentTransaction *transaction = nil;
        if (!transactionIdentifier || transactionIdentifier.length == 0) {
            return transaction;
        }
        
        [self.restoredTranscations enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            SKPaymentTransaction *tempTransaction = obj;
            NSString *id = tempTransaction.transactionIdentifier;
            NSString *originalId = tempTransaction.originalTransaction.transactionIdentifier;
            DYFStoreLog(@"index: %zi, transactionId: %@, originalTransactionId: %@", idx, id, originalId);
            
            if ([id isEqualToString:transactionIdentifier]) {
                transaction = tempTransaction;
            }
        }];
        
        return transaction;
    }
    

    你过滤一下日志,看一下这段代码的日志打印的是什么,在这里回复我一下,我看到后分析定位问题所在,然后进行修复。

    这里是log,初始化后processPurchaseNotification这里收到的是DYFStorePurchaseStateSucceeded,而不是Restore image
    e1faff28cdeba57b8957b1ba92d1e684

    1. 红框标记和下面遍历Purchased Transcations都对得上。
    2. 看完log,发现调用完成交易的方法传入的交易id是null或是空的,你看下C#那边传的参数什么?
    3. 调用完成交易会进入下面的方法,检查一下交易id和原始交易id。
    /// Completes a pending transaction.
    void DYFFinishTransaction(const char* transactionId, const char* originalTransactionId)
    {
        NSString *transactionIdentifier = __OBJC_STRING(transactionId);
        NSString *orgTransactionIdentifier = __OBJC_STRING(originalTransactionId);
        
        DYFStore *store = DYFStore.defaultStore;
        SKPaymentTransaction *pt = [store extractPurchasedTransaction:transactionIdentifier];
        if (pt) {
            [DYFStore.defaultStore finishTransaction:pt];
        } else {
            SKPaymentTransaction *rt = [store extractRestoredTransaction:transactionIdentifier];
            [DYFStore.defaultStore finishTransaction:rt];
        }
        DYFStoreUserDefaultsPersistence *persister = [[DYFStoreUserDefaultsPersistence alloc] init];
        [persister removeTransaction:transactionIdentifier];
        
        if (orgTransactionIdentifier) {
            [persister removeTransaction:orgTransactionIdentifier];
        }
    }
    

    调用传入的transactionIdentifier是正确的,最后的log是在这里输出的。
    image
    这里使用的值是 传入的SKPaymentTransaction中的字段 ,如果在上一步没有找到正确的SKPaymentTransaction这里就会出现空的字符串。和C# 传入的值没关系。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions