Open corle-bell opened 3 weeks ago
付款完成,交易票据验证通过拿到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);
我在验证成功之后调用的关闭交易,调用了关闭交易还是存在这个问题。 无法正确的关闭时因为transactionId不正确么,我在恢复购买后,进行验证。然后再下行信息里拿到的transactionId和 初始化后弹出的交易里的transactionId并不一样。但是他们的originalTransactionId是一样的。当然他们都是同一个商品。
你看一下 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];
}
}
- (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;
}
你过滤一下日志,看一下这段代码的日志打印的是什么,在这里回复我一下,我看到后分析定位问题所在,然后进行修复。
- (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
- (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
调用完成交易会进入下面的方法,检查一下交易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];
}
}
- (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
- 红框标记和下面遍历Purchased Transcations都对得上。
- 看完log,发现调用完成交易的方法传入的交易id是null或是空的,你看下C#那边传的参数什么?
- 调用完成交易会进入下面的方法,检查一下交易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是在这里输出的。 这里使用的值是 传入的SKPaymentTransaction中的字段 ,如果在上一步没有找到正确的SKPaymentTransaction这里就会出现空的字符串。和C# 传入的值没关系。
购买非消耗类型的物品后,重新启动应用。 调用初始化后.就会进入交易成功的状态是为什么?