8 Replies
      Latest reply on Oct 8, 2019 11:20 AM by PBK
      kdang.kim Level 1 Level 1 (0 points)

        I am completing a transaction by calling finishTransaction after purchasing the item.

        However, if the network is disconnected when calling finishTransaction,

        Consume state of purchased item fails with “paymentQueue: removedTransactions” Observer callback response.

        Is there a parameter that identifies consume state? If not, is there a guide on how to handle it?

        • Re: What should I do if finishTransaction fails with network disconnect?
          KMT Level 9 Level 9 (15,305 points)

          Quoting the IAP FAQ...

           

          "Consider the case where tapping the "Buy" button results in the serial call sequence in an app: The app first sends a product request to the App Store to validate an in-app purchase product identifier, then calls addPayment: to make a purchase. If for some reasons (such as a network failure), the product request fails and the app does not verify that the response.product array contains the SKProduct object associated with the product identifier, then the app should not call addPayment:. If however, the app makes the addPayment: call with an SKPayment object thats uses an invalid product identifier as seen in Listing 4, at best, nothing happens. At worst, the app crashes for using a nil identifier. To App Review, the issue was triggered by tapping the "Buy" button and nothing happened (or the app crashed)."

            • Re: What should I do if finishTransaction fails with network disconnect?
              kdang.kim Level 1 Level 1 (0 points)

              Um .. I don't request 'appPayment' if the purchase request failed due to network failure.

               

              If the network connection is lost, 'finishTransaction:' will fail, but the transaction will be delivered and removed from the queue, so you won't know if it failed. It is difficult to distinguish between transaction status and success time.

               

              The part I contact is when the purchase request 'addPayment:' succeeds, pays for the item, and the 'finishTransaction:' fails.

              step 1. Success addPayment:

              step 2. Success item delivery

              step 3. Fail finishTransaction:

               

              If I call finishTransaction with a network disconnection, it will be removed from the queue, but the following message will occur for future purchases.:

               

              This In-App Purchase has already been bought. It will be restored for free.

              The "This In-App Purchase has already been bought. It will be restored for free." message indicates that you did not call SKPaymentQueue's finishTransaction: in your application. Calling finishTransaction: allows you to remove a transaction from the payment queue. It notifies the App Store that the application acknowledges the transaction so that the App Store can mark it as completed.

               

               

              1. Does finishTransaction: always succeed?

               

              2. Is the purchased SKPaymentTransaction always 'SKPaymentTransactionStatePurchased' when consume processing succeeds or fails after finishTransaciton: is called?

               

              3. Is there no need to distinguish between cases where finishTransaction fails due to network disconnection?

               

              4. 'Calling 'finishTransaction:' results in a response of 'paymentQueue: removedTransactions:'. At this time, can I not check whether the transaction status is consumed?

                • Re: What should I do if finishTransaction fails with network disconnect?
                  KMT Level 9 Level 9 (15,305 points)

                  1. According to Apple:

                  Your app needs to finish every transaction, regardless of whether the transaction succeeded or failed.

                  Regardless of the transaction result, you always finish the transaction to remove it from the payment queue and then handle the state (successful or failed) in your code in order to provide the user with the appropriate info.

                   

                  2. A payment transaction is created whenever a payment is added to the payment queue. Transactions are delivered to your app when the App Store has finished processing the payment. Completed transactions provide a receipt and transaction identifier that your app can use to save a permanent record of the processed payment.

                   

                  3. See #1

                   

                  4. Consumed and purchased are two different things. There is no transaction status 'consumed'.

              • Re: What should I do if finishTransaction fails with network disconnect?
                PBK Level 7 Level 7 (3,365 points)

                I don't believe this can happen.  finishTransaction is a local thing.

                 

                > “paymentQueue: removedTransactions” Observer callback response.

                 

                This indicates finishTransaction worked.

                 

                >'finishTransaction:' will fail, but the transaction will be delivered and removed from the queue

                 

                This indicates that finishTransaction worked.

                 

                >"This In-App Purchase has already been bought. It will be restored for free."

                 

                This indicates that finishTransaction worked.  The transaction is finished, the purchase completed.  If you try to buy a non-consumable IAP a second time you get this message.

                 

                1. Does finishTransaction: always succeed?

                 

                Pretty much, yes.

                 

                2. Is the purchased SKPaymentTransaction always 'SKPaymentTransactionStatePurchased' when consume processing succeeds or fails after finishTransaciton: is called?

                 

                SKPaymentTransaction is set in a call to updatedTransactions.  finishTransaction is called after that call to updatedTransactions - the value of the SKPayementTransaction won't change when you call finishTransaction.  But the value won't be preserved after you exit updatedTransactions.

                 

                3. Is there no need to distinguish between cases where finishTransaction fails due to network disconnection?

                 

                Only in the case of a consumable IAP to avoid giving the purchaser a double credit.  You can use paymentQueue:removedTransactions to check that finishTransaction worked.  But how often do you expect the network to break given that it was working in the call to updatedTransactions?  This is one reason why I think 'better than best practice' is to call finsihTransactions from within updatedTransactions and take over the responsibility to 'complete' the transaction with any remote server.

                 

                4. 'Calling 'finishTransaction:' results in a response of 'paymentQueue: removedTransactions:'. At this time, can I not check whether the transaction status is consumed?

                 

                I am not sure what you mean by 'status is consumed' but a call to this method indicates you have finished the transaction.

                  • Re: What should I do if finishTransaction fails with network disconnect?
                    kdang.kim Level 1 Level 1 (0 points)

                    Thank you.

                     

                    I don't think there's a lot of network breaks.

                    However, due to the nature of mobile, network disconnection may occur at certain times.

                     

                    If you call "finishTransaction:" after a network disconnect, it will be removed from the queue. However, when you reboot the app, the purchase transaction is confirmed.

                    So, it doesn't seem to be a local api, and I see it as an api where failure is possible.

                     

                    Until you reboot, there is no way to see the corresponding purchase list in the queue where finishTransaction has not completed. Is there a way to update the queue at runtime?

                      • Re: What should I do if finishTransaction fails with network disconnect?
                        PBK Level 7 Level 7 (3,365 points)

                        It is difficult to understand your question when you use terms that are not defined.

                         

                        > If you call "finishTransaction:" after a network disconnect, it will be removed from the queue. However, when you reboot the app, the purchase transaction is confirmed.

                         

                        Please explain what you mean by "the purchase transaction is confirmed".

                         

                        > Until you reboot, there is no way to see the corresponding purchase list in the queue where finishTransaction has not completed.

                         

                        Please explain what you mean by "see the corresponding purchase list in the queue".  What queue?  What list?

                          • Re: What should I do if finishTransaction fails with network disconnect?
                            kdang.kim Level 1 Level 1 (0 points)

                            Please explain what you mean by "the purchase transaction is confirmed".

                            >>

                            Follow the steps below:

                             

                            step1. Launch app

                            step2. Responce paymentQueue:updatedTransactions: (paymentQueue.transacitons is empty)

                            step3. Request addPayment:

                            step4. Responce paymentQueue:updatedTransactions: (paymentQueue.transacitons have a purchase transaction.)

                            step5. Delivery item

                            step6. Disconnect network

                            step7. Request finishTransaction

                            step8. Responce paymentQueue:removedTransactions: (paymentQueue.transacitons is empty)

                            step9. Relaunch after closing the app

                            step10. Responce paymentQueue:updatedTransactions: (paymentQueue.transacitons have a purchase transaction.

                            It's a Transacion of step4)

                             

                            Please explain what you mean by "see the corresponding purchase list in the queue".  What queue?  What list?

                            >>

                            How to check transaction (Transaction of step4) of paymentQueue between step8 and step9?

                            Disconnecting the network and requesting a finishTransaction for the purchase transaction removes from the paymentQueue.

                            Since relaunching the app adds it back, I think finishTransaction may fail depending on network conditions.

                            I want to check the list that transaction list of paymentQueue (Transaction of unfinished step4) before relaunching.

                              • Re: What should I do if finishTransaction fails with network disconnect?
                                PBK Level 7 Level 7 (3,365 points)

                                step2. Responce paymentQueue:updatedTransactions: (paymentQueue.transacitons is empty)

                                 

                                //   you finish THIS transaction in step 7

                                 

                                step3. Request addPayment:

                                step4. Responce paymentQueue:updatedTransactions: (paymentQueue.transacitons have a purchase transaction.)

                                 

                                // you never finish this transaction

                                 

                                step7. Request finishTransaction 

                                 

                                //   this finishes the first transaction delivered in step2 not the second transaction initiated in step3 and delivered in step4

                                 

                                step10. Responce paymentQueue:updatedTransactions: (paymentQueue.transacitons have a purchase transaction.

                                It's a Transacion of step4) 

                                 

                                // as expected - you never finished THIS transaction