storekit/
app_transaction.rs1use core::ptr;
2
3use serde::Deserialize;
4
5use crate::app_store::{AppStoreEnvironment, AppStorePlatform};
6use crate::error::StoreKitError;
7use crate::ffi;
8use crate::private::{decode_base64, error_from_status, parse_json_ptr};
9use crate::verification_result::{VerificationResult, VerificationResultPayload};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct AppTransaction {
13 pub app_id: Option<u64>,
14 pub app_transaction_id: String,
15 pub app_version: String,
16 pub app_version_id: Option<u64>,
17 pub bundle_id: String,
18 pub environment: AppStoreEnvironment,
19 pub original_app_version: String,
20 pub original_purchase_date: String,
21 pub original_platform: Option<AppStorePlatform>,
22 pub preorder_date: Option<String>,
23 pub json_representation: Vec<u8>,
24}
25
26impl AppTransaction {
27 pub fn shared() -> Result<VerificationResult<Self>, StoreKitError> {
28 let mut result_json = ptr::null_mut();
29 let mut error_message = ptr::null_mut();
30 let status =
31 unsafe { ffi::sk_app_transaction_shared(&mut result_json, &mut error_message) };
32 if status != ffi::status::OK {
33 return Err(unsafe { error_from_status(status, error_message) });
34 }
35 let payload = unsafe {
36 parse_json_ptr::<VerificationResultPayload<AppTransactionPayload>>(
37 result_json,
38 "app transaction",
39 )
40 }?;
41 payload.into_result(AppTransactionPayload::into_app_transaction)
42 }
43
44 pub fn refresh() -> Result<VerificationResult<Self>, StoreKitError> {
45 let mut result_json = ptr::null_mut();
46 let mut error_message = ptr::null_mut();
47 let status =
48 unsafe { ffi::sk_app_transaction_refresh(&mut result_json, &mut error_message) };
49 if status != ffi::status::OK {
50 return Err(unsafe { error_from_status(status, error_message) });
51 }
52 let payload = unsafe {
53 parse_json_ptr::<VerificationResultPayload<AppTransactionPayload>>(
54 result_json,
55 "refreshed app transaction",
56 )
57 }?;
58 payload.into_result(AppTransactionPayload::into_app_transaction)
59 }
60}
61
62#[derive(Debug, Deserialize)]
63pub(crate) struct AppTransactionPayload {
64 #[serde(rename = "appID")]
65 app_id: Option<u64>,
66 #[serde(rename = "appTransactionID")]
67 app_transaction_id: String,
68 #[serde(rename = "appVersion")]
69 app_version: String,
70 #[serde(rename = "appVersionID")]
71 app_version_id: Option<u64>,
72 #[serde(rename = "bundleID")]
73 bundle_id: String,
74 environment: String,
75 #[serde(rename = "originalAppVersion")]
76 original_app_version: String,
77 #[serde(rename = "originalPurchaseDate")]
78 original_purchase_date: String,
79 #[serde(rename = "originalPlatform")]
80 original_platform: Option<String>,
81 #[serde(rename = "preorderDate")]
82 preorder_date: Option<String>,
83 #[serde(rename = "jsonRepresentationBase64")]
84 json_representation_base64: String,
85}
86
87impl AppTransactionPayload {
88 pub(crate) fn into_app_transaction(self) -> Result<AppTransaction, StoreKitError> {
89 Ok(AppTransaction {
90 app_id: self.app_id,
91 app_transaction_id: self.app_transaction_id,
92 app_version: self.app_version,
93 app_version_id: self.app_version_id,
94 bundle_id: self.bundle_id,
95 environment: AppStoreEnvironment::from_raw(self.environment),
96 original_app_version: self.original_app_version,
97 original_purchase_date: self.original_purchase_date,
98 original_platform: self.original_platform.map(AppStorePlatform::from_raw),
99 preorder_date: self.preorder_date,
100 json_representation: decode_base64(
101 &self.json_representation_base64,
102 "app transaction JSON representation",
103 )?,
104 })
105 }
106}