Remote Check
How to validate with Catappult's API?
To validate the transaction with Catappult's API, you need to send a request from your server to our API. In response, you will receive information about the transaction, confirming the purchase is valid.
Client
Swift Client
After completing a purchase in your client app, you will receive an object VerificationResult
that indicates whether the AppCoins Billing SDK was able to verify the purchase's signature. If this validation is successful, VerificationResult.verified
will have an attribute purchase
, which belongs to the following class:
public class Purchase: Codable {
public let uid: String
public let sku: String
public var state: String
public let orderUid: String
public let payload: String?
public let created: String
public let verification: PurchaseVerification
public class PurchaseVerification: Codable {
public let type: String
public let data: PurchaseVerificationData
public let signature: String
}
public class PurchaseVerificationData: Codable {
public let orderId: String
public let packageName: String
public let productId: String
public let purchaseTime: Int
public let purchaseToken: String
public let purchaseState: Int
public let developerPayload: String
}
}
From this object, you should extract all the necessary parameters to validate the purchase server-side. These parameters are: purchase.verification.data.packageName
, purchase.verification.data.productId
, and purchase.verification.data.purchaseToken
.
After obtaining the relevant parameters on the client, pass this information to your server as shown below:
let result = await products?.first?.purchase()
switch result {
case .success(let verificationResult):
switch verificationResult {
case .verified(let purchase):
if await verify_purchase_on_server(package_name: purchase.verification.data.packageName, product_id: purchase.verification.data.productId, purchase_token: purchase.verification.data.purchaseToken) {
// Purchase is verified!
}
}
}
Implement the verify_purchase_on_server
method according to your server’s logic to complete the server-side validation.
Unity Plugin Client
After completing a purchase in your application that is integrating the AppCoins SDK Unity Plugin, you will receive an object PurchaseResult
that contains an attribute Purchase
, which belongs to the following class:
[Serializable]
public class PurchaseData
{
public string UID;
public string Sku;
public string State;
public string OrderUID;
public string Payload;
public string Created;
public PurchaseVerification Verification;
[Serializable]
public class PurchaseVerification
{
public string Type;
public string Signature;
public PurchaseVerificationData Data;
}
[Serializable]
public class PurchaseVerificationData
{
public string OrderId;
public string PackageName;
public string ProductId;
public int PurchaseTime;
public string PurchaseToken;
public int PurchaseState;
public string DeveloperPayload;
}
}
From this object, you should extract all the necessary parameters to validate the purchase server-side. These parameters are: Purchase.Verification.Data.PackageName
, Purchase.Verification.Data.ProductId
, and Purchase.Verification.Data.PurchaseToken
.
After obtaining the relevant parameters on the client, pass this information to your server as shown below:
var purchaseResponse = await AppCoinsSDK.Instance.Purchase("antifreeze");
if (purchaseResponse.State == AppCoinsSDK.PURCHASE_STATE_SUCCESS)
{
string packageName = purchaseResponse.Purchase.Verification.Data.PackageName;
string productId = purchaseResponse.Purchase.Verification.Data.ProductId;
string purchaseToken = purchaseResponse.Purchase.Verification.Data.PurchaseToken;
bool isValid = await VerifyPurchaseOnServer(packageName, productId, purchaseToken);
}
Implement the VerifyPurchaseOnServer
method according to your server’s logic to complete the server-side validation.
Server
Using the parameters retrieved on the client and passed to your server, you can construct the following GET request URL to call our API:
GET https://api.catappult.io/product/8.20191001/google/inapp/v3/applications/**packageName**/purchases/products/**productId**/tokens/**token**?platform=IOS
Description: Web service to validate the purchase and consumption status of an in-app item.
Parameters:
packageName
: The bundle ID of the application where the product was purchased (eg. "com.appcoins.trivialdrivesample")productId
: The in-app product SKU (eg. "gas")purchaseToken
: The token provided to the user's device when the product was purchased.
Our purchase token always starts with catappult.inapp.purchase.
Query Parameters:
You should indicate that this is an iOS purchase by adding the query parameter platform
and setting it to IOS
.
Below there are some snippets in several languages of how one would perform this request:
def validate_purchase(self, package_name: str, sku: str,
purchase_token: str, access_token: str) -> bool:
api_purchase_url = "https://api.catappult.io/product/8.20191001/google/inapp/v3/" \
"applications/{packageName}/purchases/products/{productId}/tokens/" \
"{purchaseToken}"
response = requests.get(api_purchase_url
.format(packageName=package_name, productId=sku,
purchaseToken=purchase_token),
params={'platform': 'iOS'})
if response.status_code == 200:
return True
else:
return False
private boolean validatePurchase(String packageName, String sku,
String purchaseToken, String accessToken
) throws Exception {
String apiPurchaseUrl = String.format("https://api.catappult.io/product/8.20191001/" +
"inapp/google/v3/applications/%s/purchases/products/%s/tokens/%s",
packageName, sku, purchaseToken);
// Add the query parameter `platform=iOS` to the URL
String urlWithParams = apiPurchaseUrl + "?platform=iOS";
Request request = new Request.Builder()
.url(urlWithParams)
.build();
try (Response response = httpClient.newCall(request).execute()) {
return response.isSuccessful();
}
}
function validatePurchase($packageName, $sku,
$purchaseToken, $accessToken) {
$curl = curl_init();
$apiPurchaseUrl =
'https://api.catappult.io/product/8.20191001/inapp/google/v3/applications/' .
$packageName . '/purchases/products/' . $sku . '/tokens/' .
$purchaseToken . '?platform=iOS';
curl_setopt($curl, CURLOPT_URL, $apiPurchaseUrl);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_NOBODY, true);
$response = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpcode == 200) {
return true;
} else {
return false;
}
}
Response
If you get a status code 200 OK
from the request it means the purchase was successfully validated.
In the response, you have multiple fields providing a variety of information regarding the transaction. Here's a sample response with an explanation for each parameter.
{
"resource": {
"kind": "androidpublisher#productPurchase",
"purchaseTimeMillis": long,
"purchaseState": integer,
"consumptionState": integer,
"developerPayload": string,
"orderId": string,
"acknowledgementState": integer,
"purchaseToken": string,
"productId": string,
"regionCode": string
}
}
Here is the explanation of each field:
- kind: Represents a productPurchase.
- purchaseTimeMillis: The time the product was purchased in milliseconds.
- purchaseState: The purchase state of the order.
Possible values are:- 0 (Purchased)
- 1 (Canceled)
- consumptionState: The consumption state of the in-app product.
Possible values are:- 0 (Yet to be consumed)
- 1 (Consumed)
- developerPayload: A developer-specified string that contains supplemental information about an order.
- orderId: The order id associated with the purchase of the in-app product.
- acknowledgementState: The acknowledgment state of the in-app product.
Possible values are:- 0 (Yet to be acknowledged)
- 1 (Acknowledged)
- purchaseToken: The token provided to the user's device when the product was purchased.
- productID: The product ID of the product being purchased
- regionCode: The region code for the place where the purchase was made.
Updated about 2 months ago