iapiab 0.1.0

iapiab verifies the purchase receipt via AppStore or GooglePlayStore.
Documentation
use crate::appstore::model::{IAPRequest, IAPResponse};
use async_trait::async_trait;

// SANDBOX_URL is the endpoint for sandbox environment.
const SANDBOX_URL: &str = "https://sandbox.itunes.apple.com/verifyReceipt";
// PRODUCTION_URL is the endpoint for production environment.
const PRODUCTION_URL: &str = "https://buy.itunes.apple.com/verifyReceipt";

#[async_trait]
pub trait IAPVerifier {
    async fn verify(&self, req_body: &IAPRequest) -> Result<IAPResponse, reqwest::Error>;
}

pub struct IAPClient {
    client: reqwest::Client,
}

impl IAPClient {
    pub fn new(client: reqwest::Client) -> IAPClient {
        IAPClient { client }
    }
}

#[async_trait]
impl IAPVerifier for IAPClient {
    async fn verify(&self, req_body: &IAPRequest) -> Result<IAPResponse, reqwest::Error> {
        let response: IAPResponse = self
            .client
            .post(PRODUCTION_URL)
            .json(req_body)
            .send()
            .await?
            .json()
            .await?;

        //https://developer.apple.com/documentation/appstorereceipts/verifyreceipt
        if response.status != 21007 {
            return Ok(response);
        }

        let sandbox_response: IAPResponse = self
            .client
            .post(SANDBOX_URL)
            .json(req_body)
            .send()
            .await?
            .json()
            .await?;

        return Ok(sandbox_response);
    }
}