2013-04-18 27 views
7

Tôi có nhiều IAP mua hàng trong ứng dụng của mình. Người dùng có thể mua chúng tốt.iOS StoreKit - Khi nào cần gọi - (void) restoreCompletedTransactions?

Vấn đề của tôi là tôi đang tích hợp với Flurry để theo dõi việc mua thực so với chỉ một sự phục hồi mua hàng, nhưng SKPaymentTransaction 's transactionState tôi luôn luôn trở lại như SKPaymentTransactionStatePurchased hơn SKPaymentTransactionStateRestored.

Rõ ràng SKPaymentTransactionStateRestored chỉ được gọi khi - (void)restoreCompletedTransactions, nhưng khi nào tôi gọi phương thức này?

Quy trình suy nghĩ của tôi là mua hàng sẽ như sau: 1) Người dùng chọn sản phẩm, 2) Người dùng được hỏi xem họ có muốn mua sản phẩm cho số tiền X không. 3) Máy chủ kiểm tra xem người dùng đã mua trước chưa và liệu họ có khôi phục bằng cách đặt SKPaymentTransactionStateRestored hay không. Nếu không, xử lý giao dịch và đặt SKPaymentTransactionStatePurchased. Rõ ràng điều này là sai và tôi giả sử gọi - (void)restoreCompletedTransactions ở đâu đó ở giữa ???

Cảm ơn,

Will

+2

Bạn nên xem http://stackoverflow.com/questions/1757467/when-to-use-restorecompletedtransactions-for-in-app-purchases. Trong trường hợp của tôi, tôi đã sử dụng nó bằng nút "Khôi phục các giao dịch trước đó" –

+0

Cảm ơn Micazeve, nhưng từ góc độ phân tích, có vẻ như người dùng chỉ có thể bỏ qua việc nhấn nút "khôi phục" và khôi phục lại bằng cách cố gắng mua lại. nơi tôi phân tích liệu người dùng đã mua hàng hay chưa.Có lẽ khi họ chọn một sản phẩm, thay vì ngay lập tức bắt đầu giao dịch, tôi có thể thực hiện quy trình gọi lại RestoreCompletedTransactions lâu nhất và phức tạp, xem liệu sản phẩm đã chọn có nằm trong danh sách đó hay không, và cho phép người dùng mua sản phẩm đó . Một nỗi đau như vậy ... – Will

+0

Bạn vừa phải, nút này là không cần thiết vì cố gắng mua lại các mặt hàng đã mua cảnh báo người dùng rằng anh ta đã mua mặt hàng này. Vấn đề chính trong tình huống này là người dùng được cảnh báo SAU KHI anh ta chấp nhận trả tiền một lần nữa: "Nút Restore" là hữu ích theo cách tâm lý, bởi vì người dùng không phải thực hiện thủ tục paiement lần thứ hai. - Bạn có thể thử để thực hiện phương pháp của bạn (mà nên hoạt động), nhưng như bạn đã nói, như một nỗi đau;) –

Trả lời

7

EDIT:

Ban đầu tôi đã đăng một phương pháp rất dài, không cần thiết để có được những gì tôi cần làm, nhưng như bạn sẽ thấy bên dưới, Matt đã giúp tôi tìm ra vari có thể tôi đang tìm kiếm.

Ví dụ: giả sử người dùng đã mua ứng dụng của tôi trước đây, mua tất cả IAP không tiêu hao, sau đó xóa ứng dụng. Khi người dùng cài đặt lại ứng dụng, tôi muốn có thể xác định thời điểm họ chuyển sang "mua" các sản phẩm một lần nữa, đây có phải là lần mua hàng ban đầu (lần đầu tiên) hoặc mua lại không?

Tôi đã triển khai nút "Khôi phục tất cả mua hàng", nhưng giả sử người dùng bỏ qua/không nhìn thấy và cố gắng chọn sản phẩm họ đã mua trước đó.

Như với mua hàng bình thường, tôi làm như sau:

if ([SKPaymentQueue canMakePayments]) 
{ 
     self.productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:productID]]; 

     self.productRequest.delegate = self; 
     [self.productRequest start]; 
} 
else 
{ 
    //error message here 
} 

Sau khi người dùng đã đăng nhập vào tài khoản iTunes của họ, App sẽ cho họ biết họ đã mua này và nó bây giờ sẽ được phục hồi.Phương pháp đại biểu sau đây sẽ được gọi là:

-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions 
{ 
    for (SKPaymentTransaction *transaction in transactions) 
    { 
     switch (transaction.transactionState) 
     { 
      case SKPaymentTransactionStatePurchased: 
      { 
       [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
       if(transaction.originalTransaction) 
       { 
        NSLog(@"Just restoring the transaction"); 
       } 
       else 
       { 
        NSLog(@"First time transaction"); 
       } 

       break; 
      } 
      default: 
       break; 
     } 
    } 
} 

Không có vấn đề nếu giao dịch là một sự phục hồi hoặc mua hàng lần đầu tiên, transaction.transactionState sẽ là bằng SKPaymentTransactionStatePurchased.

Bây giờ, từ thời điểm này, làm cách nào để xác định xem giao dịch mua đó là mua hàng ban đầu hay khôi phục?

Đơn giản: Như đã thấy ở trên, chỉ cần xem nếu transaction.originalTransaction được khởi tạo. Mỗi ghi chú của Apple: // Chỉ hợp lệ nếu trạng thái là SKPaymentTransactionStateRestored.

Nếu 's originalTransaction được khởi tạo, điều đó có nghĩa là đã có giao dịch trước đó. Nếu không, giao dịch này là giao dịch gốc!

Một lần nữa, nhờ Matt đã chỉ cho tôi đúng hướng, và để làm cho logic sạch hơn rất nhiều!

+1

"và nếu họ" mua lại "bất cứ điều gì, tôi không thể phân biệt nếu đó là mua hàng ban đầu hoặc mua hàng phục hồi" Bạn không cần phải phân biệt điều đó. Cửa hàng sẽ phân biệt nó cho bạn. Bạn xếp hàng mua hàng và nếu người dùng này đã thực hiện giao dịch mua này, cửa hàng sẽ cung cấp dịch vụ mà không tính phí người dùng lần thứ hai. – matt

+0

Matt, tôi biết rằng nó sẽ không tính phí người dùng hai lần, nhưng để ghi lại mua hàng (trong trường hợp của tôi ghi lại sự kiện qua Flurry, nhưng điều này cũng có thể được sử dụng để lưu trữ dữ liệu trong cơ sở dữ liệu), tôi cần phân biệt giữa mua ban đầu và phục hồi. – Will

+2

Tôi vẫn không đồng ý. Chỉ cần để cho cửa hàng làm những gì các cửa hàng hiện. Cho phép người dùng đi qua hộp thoại của cửa hàng ("Bạn đã mua ứng dụng này, bạn có muốn tải xuống lại không?"). Nếu đó là khôi phục, khi người quan sát giao dịch của bạn được thông báo, giao dịch sẽ có giá trị 'originalTransaction' và có sự khác biệt của bạn (và tất cả dữ liệu gốc). – matt

2

Nếu bạn đang thực hiện mua trong ứng dụng, bạn cần phải đặt một nút khôi phục nơi nào đó trong ứng dụng của bạn nếu không nó là một lý do từ chối. Bạn có thể xem Get list of purchased products, inApp Purchase iPhone cho một tỷ lệ.

CHỈNH SỬA 2: Có thể có các cách khác hơn là đặt nút để tránh bị từ chối. Một cách mờ được đề xuất trong các ý kiến ​​là để khôi phục trong khởi động ứng dụng, mà dường như đủ để tôi phù hợp với hướng dẫn của apple.

Cũng có một cái nhìn tại phần cuối của hướng dẫn này nó đề cập đến cùng một vấn đề, và cho thấy một cách đơn giản để thực hiện nó: http://www.raywenderlich.com/21081/introduction-to-in-app-purchases-in-ios-6-tutorial

EDIT:

//Draft implementation of transaction observer delegate 

-(void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions 
{ 
    for (SKPaymentTransaction * transaction in transactions) { 
     switch (transaction.transactionState) 
     { 
      case SKPaymentTransactionStatePurchased:     
       ... 
      case SKPaymentTransactionStateFailed: 
       ... 
      case SKPaymentTransactionStateRestored: 
       ... 
      default: 
       break; 
     } 
    }; 
} 
+0

Điều đó thực sự đúng? Các tài liệu ngụ ý rằng bạn có thể bỏ qua nút hoàn toàn. Ví dụ: bạn có thể thực hiện khôi phục khi khởi chạy. Và ngay cả khi không có khôi phục, người dùng có thể thực hiện mua hàng lần nữa và sẽ không bị tính phí lần thứ hai, vậy tại sao cửa hàng nên quan tâm nếu không có nút khôi phục? – matt

+0

tôi hoàn toàn đồng ý với bạn. những gì tôi viết là tổng hợp những thứ tôi đọc ở đây và ở đó, tôi chưa gửi một ứng dụng có hỗ trợ trong ứng dụng. Khôi phục khi khởi chạy có vẻ là giải pháp hợp lý nhất, và thẳng thắn mà tôi không nghĩ đến khi viết câu trả lời. Tôi sẽ cập nhật câu trả lời của tôi dựa trên những gì bạn nói, cảm ơn. – guenis

+2

bạn không thể thực hiện khôi phục khi khởi chạy mà không làm phiền người dùng bằng yêu cầu mật khẩu mỗi lần khởi chạy. không có cách nào thực tế xung quanh nút – ngb

6

Kỳ vọng kinh điển có vẻ là bạn cung cấp nút khôi phục gọi restoreCompletedTransactions. Đối với những gì sẽ xảy ra nếu người dùng bỏ qua điều này và chỉ cần tiếp tục cố gắng đi qua giao diện mua hàng của bạn để mang lại các tính năng mà anh ta đã mua, bạn có thể lo lắng cho mình một cách không cần thiết; các docs nói:

Nếu người dùng cố gắng để mua một sản phẩm restorable (thay vì sử dụng giao diện khôi phục bạn thực hiện), ứng dụng nhận được một giao dịch thường xuyên cho mục đó, không phải là một khôi phục giao dịch. Tuy nhiên, người dùng không bị tính phí lại cho sản phẩm đó. Ứng dụng của bạn nên xử lý các giao dịch này giống với giao dịch ban đầu.

Cửa hàng sẽ đặt hộp thoại tương tác với người dùng ("Bạn đã mua ứng dụng này, bạn có muốn tải xuống lại miễn phí không?") Và thông báo về việc mua lại miễn phí sẽ diễn ra trong paymentQueue:updatedTransactions: như thường lệ và bạn có thể sử dụng số originalTransaction.transactionIdentifier để xác định số tiền đó với giao dịch mua ban đầu.

+0

Vâng, tôi đã cập nhật câu trả lời của tôi sau khi bình luận của bạn nhưng nếu nó chỉ là phần mà bạn suy ra "nó sẽ là ok mà không có một nút khôi phục" Tôi không nghĩ rằng nó là đủ. – guenis

+0

@guenis Đó là những gì tôi đang cố gắng tìm hiểu. Apple yêu cầu điều gì? Họ có nhấn mạnh vào một nút thực tế? Một mặt bạn nghĩ rằng điều này sẽ không cần thiết, nhưng mặt khác họ nói "bạn phải bao gồm một giao diện cho phép người dùng khôi phục các giao dịch mua này". Vì vậy, nó âm thanh với tôi như bạn * làm * cần một nút. Vì vậy, quan điểm của tôi ở đây là, được rồi, nhưng nếu người dùng bỏ qua nút khôi phục và chỉ cố gắng thực hiện lại giao dịch mua, bạn không cần phải lo lắng: nó sẽ hoạt động và người dùng sẽ không bị tính phí hai lần. – matt

+0

Đã sửa đổi câu trả lời của tôi để giải thích cách bạn có thể biết khi nào "mua" thực sự là một tải xuống miễn phí (khi người dùng "mua" thứ gì đó mà anh ấy đã sở hữu). – matt

0

Các tài liệu của Apple IOS SDK được thực sự gây hiểu lầm về vấn đề này vì nó nói rằng:

@property(nonatomic, readonly) SKPaymentTransaction *originalTransaction 
The contents of this property are undefined except when transactionState is set to SKPaymentTransactionStateRestored. 

Vấn đề là khi người dùng nhấp nút mua của bạn, đi qua quá trình mua hàng, và cuối cùng nhận được một thông mà anh ta đã trả tiền và anh ấy có thể tải xuống lại miễn phí, người quan sát của bạn không gửi cho bạn SKPaymentTransactionStateRestored. Nó thực sự gửi cho bạn một SKPaymentTransactionStatePurchased.

Tin vui là mặc dù tài liệu, bạn sẽ thực sự nhận được thuộc tính originalTransaction ngay cả khi trạng thái giao dịch của bạn là SKPaymentTransactionStatePurchased. Chỉ cần kiểm tra xem tài sản này có phải là không hoặc không và bạn sẽ biết giao dịch đó là giao dịch mua mới hay mua cũ được khôi phục miễn phí.