Most online articles about in-app purchase payment are the same, describing how to create an in-app purchase project, and then write the relevant code to initiate the in-app purchase. However, in the actual development, about the internal purchase pit but many people crazy, such as the common single, repeated recharge and so on. Some user feedback I had clearly deducted money, why did not recharge? In some cases, the user pays once, but gives two + credits. In either case, it is a disaster for the developer, on the one hand, the user experience, on the other hand, the company losses. Before I also wrote an article about the purchase in the purchase and payment of tread pit and their solutions, the friend asked, recently back to look after find expression in some places is too chaos, so decided to organize an article during the purchase and payment process and some parts need to be aware of, of course, this is just my problems in the development, if there are other issues and strategies, Welcome to add.
Next, I will first talk about two common processes and ideas, list the problems that will arise, and finally talk about the processes and coping strategies developed by myself
1. Put the authentication on the client
When I first took over the project, I was not so concerned about the internal purchase because it was outsourced before, and I just wanted to complete the function. After checking the orders and users’ feedback, I found that many orders were lost. Here is my general description of the process of this strategy:
1.1 process
1. Determine whether in-app purchases are allowed
2. Request specific product information based on the product ID
3. The commodity information request is successful, the payment transaction is created, the payment is initiated, and then the observer provided by the system goes
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions
4. If the payment is unsuccessful, close the transaction
5. The payment is successful, the transaction is closed, the voucher is obtained, and the local verification is carried out (the specific verification method is not posted here, but there are a lot of codes on the Internet).
6. Wait for the verification result. If the verification is successful, call the recharge interface; otherwise, no recharge
1.2 Possible problems
After looking at the above process, we can find that the previous process is ok, but the verification process is completely out of control. For example, the verification fails, or the recharge interface is not called in time after the verification is returned, or the recharge interface is not back, so the user exits the interface or app. Since the transaction is ended when the payment is successful, if the verification result is not returned or the recharge is not carried out smoothly after the verification result is returned, the order will be lost, which is a loss for the user. In addition, there is a problem on the client side, vouchers can be forged, if someone intercepts the request, forged vouchers, it can be unscrupulous recharge, for the company, this is a loss, so there is no need to think about this scheme is full of mistakes.
2. The payment is performed on the client and the checksum recharge is performed on the server
Based on the first option, the second option is better, and the third option I mention below is also an improvement on the second option.
2.1 process
1. Determine whether in-app purchases are allowed
2. Request specific product information based on the product ID
3. The commodity information request is successful, the payment transaction is created, the payment is initiated, and then the observer provided by the system goes
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions
4. The payment fails and the transaction ends
5. After the payment is successful, take out the voucher and upload it to the server. The server verifies and recharges the voucher.
There is nothing wrong with doing this, and it is correct if the process is followed. But there are surprises, and there are surprises:
- The credentials received by the server may also be forged
- Server-side validation is working with apple server, could not so fast, if this time the user out of the app, then the deal is not the end, the next start will still perform upload credentials subsequent operations, since each access credentials and timestamp, so the service side in judging proof it was not safe on repeatability, which could cause repeated top-up
3. The scheme to be introduced in this paper is based on the improvement of the second scheme
Because of the transaction revalue, if you rely on the data returned by Apple, you can expect to be killed. ApplicationUserName, which you think is ok, can also give you nil, and there is no way to check the account, so the best way to determine the logic is to use our own data. Here’s my process, all of which starts with clicking the buy button:
3.1 process
- Request the server to create an order interface. This order is generated by the server to determine the uniqueness of each request and is also used as an identifier for reconciliation.
- Enter the in-purchase payment process
- Request item information based on the item ID
- The commodity information request is successful, and the transaction is initiated
- The payment is unsuccessful and the transaction is closed
- Pay success, judge the transaction first
transactionIdentifier
If yes, the transaction is invalid and the transaction is directly terminated. If no, the authentication logic is used
- Validation logic: take the credentials out of the sandbox and upload them to the server with the order ID generated earlier. The server fails to receive them and does nothing. Receive successful, will trade
transactionIdentifier
Save it locally and close the transaction at the same time, and the rest of the verification is on the server.
- Server verification process: The server will maintain a list of order ids, the initial status of this order ID is not verified, when receiving the certificate sent by the client, the status of this order ID is set to verification. If the verification is successful, the order ID status is set to invalid, and the recharge result is returned to the client.
One might ask, what if the client quits at this point? This doesn’t matter, because once you upload credentials from the client to the server, the client doesn’t have to do anything, and all the verification and verification, recharge logic is controlled by the server.
Better yet, in order to let the user know that the recharge is successful, the server can send a push notification to the user after the recharge is completed. At the same time, after the client successfully uploads the credentials, it will prompt the user to delay the recharge.
The following is a simulation of some unexpected situations. Since the payment tool class is a singleton, it only simulates the exit of app, not the exit of payment page:
-
The transaction still exists in the cache of Apple server. Next time the user launches the interface, he will check whether there is any unfinished transaction from the cache. If there is, he will continue to execute the logic after successful payment, and there is no need to worry about the case of order loss
-
Uploading credentials succeeds, but what if server authentication fails? This is not within the control of the client, and the client has done the operation of closing the transaction and removing the transaction ID, so is it possible to lose the order? Let me elaborate: Said before, in front of the server has a order id identifies each pay deal, immediately after receiving the documents will be according to save the order id, if validation fails, the server might do with timer polling validation operation, as long as is a valid order id, will go to verify, already know, only the check is successful, the order id is invalid, So this ensures that the documents will be to verify, and ultimately will be verified through, thus greatly reduce the probability of losing a single, and because the server the rigorous logic judgment, so repeated top-up situation does not exist in the normal logic (exclude users malicious refund, this is not repeated prepaid phone, but also a kind of situation, Due to Apple’s disgusting secrecy mechanism, we can’t get details of the refund, so we can’t deal with this malicious behavior.)
Conclusion: In general, these, because the code involves specific business and interface, I only use language here to state, there is not in place to describe the situation, but also pointed out in the message area, have better ideas, please also communicate in the message area. The in-app purchase area has been a big hole and I hope to fill it up one day for everyone’s benefit.