Anticheat methods

  1. Get response about a completed transaction from the payment system.

  2. Either send data about the received transaction for verification by calling devtodev anti-cheat methods or use your own tools for transaction verification.

  3. If the transaction has successfully passed verification, perform the Payment event.

  4. If the transaction hasn’t passed verification, do not perform the Payment event and mark the user as a cheater.

Payment Validation

The devtodev service allows you to validate transactions to prevent fraud from influencing your statistics. For this, you need to integrate DTDAntiCheat module.

We strongly discourage you from using verification results for deciding on allowing or denying users to receive their purchases! Employ this method exclusively for preventing fraud transaction data from being sent to devtodev!

To validate the transaction you can use the verifyPayment(completionHandler: @escaping (DTDVerifyResponse) -> Void) method immediately during the transaction processing, e.g.:

extension Purchases: SKPaymentTransactionObserver {
    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            switch transaction.transactionState {
                case .purchased:
                    DTDAntiCheat.verifyPayment { response in
                            switch response.receiptStatus {
                                case .receiptInternalError: 
                                  // your code
                                  break
                                case .receiptValid:
                                  // your code
                                  break
                                case .receiptSandbox:
                                  // your code
                                  break
                                case .receiptServerError:
                                  // your code
                                  break
                                case .receiptNotValid: 
                                  // your code
                                  break
                                @unknown default: break
                            }
                            SKPaymentQueue.default().finishTransaction(transaction)
                        }

                case .restored:
                    SKPaymentQueue.default().finishTransaction(transaction)

                case .failed:
                    SKPaymentQueue.default().finishTransaction(transaction)

                default:
                    break
            }
        }
    }
}

DTDVerifyResponse

The DTDVerifyResponse object returned while validating the transaction has two properties:

Property

Description

receiptStatus

Enum type DTDReceiptStatus that represents the result of the transaction validation.

verificationResult

Additional information from the validation server.

DTDReceiptStatus

The enum type returned as a result of validation can receive the following values:

Value

Description

receiptValid

The payment is valid, the transaction is genuine.

receiptNotValid

The payment is invalid, the transaction may be a duplicate or fraud.

receiptServerError

Server error when validating the payment.

receiptSandbox

Test payment.

receiptInternalError

Internal SDK error.

We recommend calling the Real Currency Payment method in all cases except when you receive receiptNotValid or receiptSandbox as a result of the validation.

Last updated

#989: best practices - improved readability

Change request updated