Crate iap[][src]

iap is a rust library for verifying receipt information for purchases made through the Google Play Store or the Apple App Store.

Current Features

  • Validating receipt data received from Unity's IAP plugin to verify subscriptions and if they are valid and not expired
  • Helper functions to receive response data from Google/Apple for more granular error handling or validation

Supported Transaction Types

  • Subscriptions

Coming Features

  • Non-subscription purchase types
  • Manual input of data for verification not received through Unity IAP

Usage

For simple validation of Unity IAP receipts

You can receive a PurchaseResponse which will simply tell you if a purchase is valid (and not expired if a subscription) by creating a UnityPurchaseValidator.

use iap::*;

const APPLE_SECRET: &str = "<APPLE SECRET>";
const GOOGLE_KEY: &str = "<GOOGLE KEY JSON>";

#[tokio::main]
pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let validator = UnityPurchaseValidator::default()
        .set_apple_secret(APPLE_SECRET.to_string())
        .set_google_service_account_key(GOOGLE_KEY.to_string())?;

    // RECEIPT_INPUT would be the Json string containing the store, transaction id, and payload
    // from Unity IAP. ie:
    // "{ \"Store\": \"GooglePlay\", \"TransactionID\": \"<Txn ID>\", \"Payload\": \"<Payload>\" }"
    let unity_receipt = UnityPurchaseReceipt::from(&std::env::var("RECEIPT_INPUT")?)?;

    let response = validator.validate(&unity_receipt).await?;

    println!("PurchaseResponse is valid: {}", response.valid);

    Ok(())
}

If you wanted more granular control and access to the response from the store's endpoint, we provide helper functions to do so.

For the Play Store:

pub async fn validate(receipt: &UnityPurchaseReceipt) -> error::Result<PurchaseResponse> {
    let response = fetch_google_receipt_data(receipt, "<GOOGLE_KEY>").await?;

    // debug or validate on your own with the data in the response
    println!("Expiry data: {}", response.expiry_time);

    // or just simply validate the response
    validate_google_subscription(&response)
}

For the App Store:

pub async fn validate(receipt: &UnityPurchaseReceipt) -> error::Result<PurchaseResponse> {
    let response = fetch_apple_receipt_data(receipt, "<APPLE_SECRET>").await?;

    // was this purchase made in the production or sandbox environment
    println!("Environment: {}", response.environment.clone().unwrap());

    Ok(validate_apple_subscription(&response))
}

Modules

error

Convenience types for lib specific error handling

Structs

AppleResponse

See https://developer.apple.com/documentation/appstorereceipts/responsebody for more details on each field

AppleUrls

Convenience struct for storing our production and sandbox URLs. Best practice is to attempt to verify against production, and if that fails, to then request verification from the sandbox. See: https://developer.apple.com/documentation/appstorereceipts/verifyreceipt

GoogleResponse

See https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.subscriptions#SubscriptionPurchase and https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.products#ProductPurchase for details on each field.

PurchaseResponse

A simple validation response returned by any of the validate methods which tells us if the receipt represents a valid purchase and/or active subscription.

UnityPurchaseReceipt

Represents the deserialized contents of the Json string delivered by Unity IAP.

UnityPurchaseValidator

Validator which stores our needed secrets for being able to authenticate against the stores' endpoints, and performs our validation.

Enums

Platform

This is the platform on which the purchase that created the unity receipt was made.

Traits

ReceiptDataFetcher

Trait which allows us to retrieve receipt data from an object's own secrets.

ReceiptValidator

Convenience trait which combines ReceiptDataFetcher and Validator traits.

Validator

The base trait for implementing a validator. Mock Validators can be made for running local tests by implementing this trait.

Functions

fetch_apple_receipt_data

Retrieves the responseBody data from Apple

fetch_apple_receipt_data_with_urls

Response call with AppleUrls parameter for tests

fetch_google_receipt_data

Retrieves the response body from google

fetch_google_receipt_data_with_uri

Retrieves the google response with a specific uri, useful for running tests.

validate_apple_subscription

Simply validates based on whether or not the subscription's expiration has passed.

validate_google_subscription

Simply validates based on whether or not the subscription's expiration has passed.