Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
corle-bell opened this issue Jun 18, 2024 · 6 comments

Comments

@corle-bell
Copy link

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

QQ截图20240618103718

@itenfay
Copy link
Owner

itenfay commented Jun 22, 2024

付款完成,交易票据验证通过拿到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);

@corle-bell
Copy link
Author

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

@itenfay
Copy link
Owner

itenfay commented Jun 25, 2024

你看一下 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];
    }
}

@itenfay
Copy link
Owner

itenfay commented Jun 25, 2024

- (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;
}

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

@corle-bell
Copy link
Author

corle-bell commented Jun 26, 2024

- (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

@itenfay
Copy link
Owner

itenfay commented Jun 30, 2024

- (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];
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants