Anticheat methods

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!
App Store (iOS) Swift
App Store (iOS) Objective-C
Google Play (Kotlin)
Google Play (Java)
Microsoft Store (UWP)
Unity (3 stores )
To validate the transaction you can use the verifyPayment(completionHandler: @escaping (DTDVerifyResponse) -> Void) method immediately during the transaction processing, e.g.:
1
extension Purchases: SKPaymentTransactionObserver {
2
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
3
for transaction in transactions {
4
switch transaction.transactionState {
5
case .purchased:
6
DTDAntiCheat.verifyPayment { response in
7
switch response.receiptStatus {
8
case .receiptInternalError:
9
// your code
10
break
11
case .receiptValid:
12
// your code
13
break
14
case .receiptSandbox:
15
// your code
16
break
17
case .receiptServerError:
18
// your code
19
break
20
case .receiptNotValid:
21
// your code
22
break
23
@unknown default: break
24
}
25
SKPaymentQueue.default().finishTransaction(transaction)
26
}
27
28
case .restored:
29
SKPaymentQueue.default().finishTransaction(transaction)
30
31
case .failed:
32
SKPaymentQueue.default().finishTransaction(transaction)
33
34
default:
35
break
36
}
37
}
38
}
39
}
40
Copied!

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.
To validate the transaction you can use the (void)verifyPaymentCompletion:( void (^ _Nonnull)(DTDVerifyResponse * _Nonnull))completionHandler; method immediately during the transaction processing, e.g.:
1
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
2
for(SKPaymentTransaction *transaction in transactions) {
3
switch(transaction.transactionState){
4
case SKPaymentTransactionStatePurchasing: {
5
// Your code ...
6
break;
7
}
8
9
case SKPaymentTransactionStatePurchased: {
10
// Your code ...
11
[DTDAntiCheat verifyPaymentCompletion:^(DTDVerifyResponse * _Nonnull response) {
12
switch ([response receiptStatus]) {
13
case ReceiptStatusReceiptInternalError: {
14
15
break;
16
}
17
case ReceiptStatusReceiptValid: {
18
19
break;
20
}
21
case ReceiptStatusReceiptSandbox: {
22
23
break;
24
}
25
case ReceiptStatusReceiptServerError: {
26
27
break;
28
}
29
case ReceiptStatusReceiptNotValid: {
30
31
break;
32
}
33
}
34
}];
35
break;
36
}
37
38
case SKPaymentTransactionStateRestored: {
39
// Your code ...
40
break;
41
}
42
43
case SKPaymentTransactionStateFailed: {
44
// Your code ...
45
break;
46
}
47
48
case SKPaymentTransactionStateDeferred: {
49
// Your code ...
50
break;
51
}
52
}
53
}
54
}
Copied!

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.
When GooglePlay sends the transaction back to your onActivityResult, validate it by calling the following method: verifyPayment(receipt: String, signature: String, publicKey: String, completionHandler:(DTDVerifyResponse) -> Unit) immediately during the transaction processing, e.g.:
1
DTDAntiCheat.verifyPayment(
2
receipt = "receipt",
3
signature = "signature",
4
publickKey = "publickKey"
5
) { dtdVerifyResponse ->
6
val verificationResult = dtdVerifyResponse.verificationResult
7
/* your code here */
8
when (dtdVerifyResponse.receiptStatus) {
9
DTDReceiptStatus.ReceiptValid -> { /* your code here */ }
10
DTDReceiptStatus.ReceiptNotValid -> { /* your code here */ }
11
DTDReceiptStatus.ReceiptServerError -> { /* your code here */ }
12
DTDReceiptStatus.ReceiptInternalError -> { /* your code here */ }
13
}
14
}
Copied!

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.
receiptInternalError
Internal SDK error.
We recommend calling the Real Currency Payment method in all cases except when you receive receiptNotValid as a result of the validation.
When GooglePlay sends the transaction back to your onActivityResult, validate it by calling the following method: verifyPayment(receipt: String, signature: String, publicKey: String, completionHandler:(DTDVerifyResponse) -> Unit) immediately during the transaction processing, e.g.:
1
DTDAntiCheat.INSTANCE.verifyPayment("receipt", "signature", "publickKey",
2
dtdVerifyResponse -> {
3
// your code
4
switch (dtdVerifyResponse.getReceiptStatus()) {
5
case ReceiptValid:
6
// your code
7
break;
8
case ReceiptNotValid:
9
// your code
10
break;
11
case ReceiptInternalError:
12
// your code
13
break;
14
case ReceiptServerError:
15
// your code
16
break;
17
}
18
return null;
19
});
Copied!

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.
receiptInternalError
Internal SDK error.
We recommend calling the Real Currency Payment method in all cases except when you receive receiptNotValid as a result of the validation.
devtodev sends a request for transaction verification to the payment platform and then forwards the answer to the app. To validate the transaction you can use theTask<DTDReceiptStatus> VerifyPayment(string: receipt) method. As an argument pass the PurchaseResults.ReceiptXml property. More information about it here.
Example of verification:
1
var result = await DTDAntiCheat.VerifyPayment("receipt");
2
switch (result)
3
{
4
case DTDReceiptStatus.Valid:
5
break;
6
case DTDReceiptStatus.Invalid:
7
break;
8
case DTDReceiptStatus.ServerError:
9
break;
10
case DTDReceiptStatus.InternalError:
11
break;
12
default:
13
throw new ArgumentOutOfRangeException();
14
}
Copied!

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
Valid = 0L
The payment is valid, the transaction went through successfully
Invalid = 1L
The payment is invalid, the transaction may be a duplicate or fraud
ServerError = 2L
Server error when validating the payment
InternalError = 4L
Internal SDK error
We recommend calling the Real Currency Payment method in all cases except when you receive Invalid as a result of the validation.

Google Play

If you use Unity IAP for payment validation, call the following method: void VerifyPayment(string publicKey, string receipt, Action completionHandler)
Example:
1
public PurchaseProcessingResult ProcessPurchase (PurchaseEventArgs e)
2
{
3
DTDAntiCheat.VerifyPayment(yourPublicKey, e.purchasedProduct.receipt, result =>
4
{
5
if (result.ReceiptStatus == DTDReceiptVerificationStatus.ReceiptValid ||
6
result.ReceiptStatus == DTDReceiptVerificationStatus.ReceiptInternalError ||
7
result.ReceiptStatus == DTDReceiptVerificationStatus.ReceiptServerError)
8
{
9
// Code for valid result.
10
}
11
else
12
{
13
// Code for invalid result.
14
}
15
});
16
}
Copied!
To validate data received from Google play, use void VerifyPayment(string publicKey, string receipt, string signature,Action<DTDVerifyResponse> completionHandler) when handling the transaction.
1
public void MyNativeCallback (string publicKey, string receipt, string signature)
2
{
3
DTDAntiCheat.VerifyPayment(publicKey, receipt, signature, result =>
4
{
5
if (result.ReceiptStatus == DTDReceiptVerificationStatus.ReceiptValid ||
6
result.ReceiptStatus == DTDReceiptVerificationStatus.ReceiptInternalError ||
7
result.ReceiptStatus == DTDReceiptVerificationStatus.ReceiptServerError)
8
{
9
// Code for valid result.
10
}
11
else
12
{
13
// Code for invalid result.
14
}
15
});
16
}
Copied!
Here's how to find your app's public key for licensing (for Google Play platform only, for other platforms the publicKey is not used):
  1. 1.
    Go to the Google Play Console and sign in. Make sure that you sign in to the account from which the app you are licensing is published (or will be published).
  2. 2.
    In the app details page, locate the Services & APIs link and click it.
  3. 3.
    In the Services & APIs page, locate the Licensing & In-App Billing section. Your public key for licensing is given in the Your License Key For This Application field.

App Store

If you use Unity IAP for payment validation, call the following method: void VerifyPayment(string receipt, Action completionHandler)
1
public PurchaseProcessingResult ProcessPurchase (PurchaseEventArgs e)
2
{
3
DTDAntiCheat.VerifyPayment(e.purchasedProduct.receipt, result =>
4
{
5
if (result.ReceiptStatus == DTDReceiptVerificationStatus.ReceiptValid ||
6
result.ReceiptStatus == DTDReceiptVerificationStatus.ReceiptInternalError ||
7
result.ReceiptStatus == DTDReceiptVerificationStatus.ReceiptServerError)
8
{
9
// Code for valid result.
10
}
11
else
12
{
13
// Code for invalid result.
14
}
15
});
16
}
Copied!

Windows Store (UWP)

If you use Unity IAP for payment validation, call the following method: void VerifyPayment(string receipt, Action completionHandler)
1
public PurchaseProcessingResult ProcessPurchase (PurchaseEventArgs e)
2
{
3
DTDAntiCheat.VerifyPayment(e.purchasedProduct.receipt, result =>
4
{
5
if (result.ReceiptStatus == DTDReceiptVerificationStatus.ReceiptValid ||
6
result.ReceiptStatus == DTDReceiptVerificationStatus.ReceiptInternalError ||
7
result.ReceiptStatus == DTDReceiptVerificationStatus.ReceiptServerError)
8
{
9
// Code for valid result.
10
}
11
else
12
{
13
// Code for invalid result.
14
}
15
});
16
}
Copied!
N.B. You can pass a native XML recipe to the receipt argument.

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.
Export as PDF
Copy link