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 {
14 pub app_id: Option<u64>,
16 pub app_transaction_id: String,
18 pub app_version: String,
20 pub app_version_id: Option<u64>,
22 pub bundle_id: String,
24 pub environment: AppStoreEnvironment,
26 pub original_app_version: String,
28 pub original_purchase_date: String,
30 pub original_platform: Option<AppStorePlatform>,
32 pub preorder_date: Option<String>,
34 pub json_representation: Vec<u8>,
36}
37
38impl AppTransaction {
39 pub fn shared() -> Result<VerificationResult<Self>, StoreKitError> {
41 let mut result_json = ptr::null_mut();
42 let mut error_message = ptr::null_mut();
43 let status =
44 unsafe { ffi::sk_app_transaction_shared(&mut result_json, &mut error_message) };
45 if status != ffi::status::OK {
46 return Err(unsafe { error_from_status(status, error_message) });
47 }
48 let payload = unsafe {
49 parse_json_ptr::<VerificationResultPayload<AppTransactionPayload>>(
50 result_json,
51 "app transaction",
52 )
53 }?;
54 payload.into_result(AppTransactionPayload::into_app_transaction)
55 }
56
57 pub fn refresh() -> Result<VerificationResult<Self>, StoreKitError> {
59 let mut result_json = ptr::null_mut();
60 let mut error_message = ptr::null_mut();
61 let status =
62 unsafe { ffi::sk_app_transaction_refresh(&mut result_json, &mut error_message) };
63 if status != ffi::status::OK {
64 return Err(unsafe { error_from_status(status, error_message) });
65 }
66 let payload = unsafe {
67 parse_json_ptr::<VerificationResultPayload<AppTransactionPayload>>(
68 result_json,
69 "refreshed app transaction",
70 )
71 }?;
72 payload.into_result(AppTransactionPayload::into_app_transaction)
73 }
74}
75
76#[derive(Debug, Deserialize)]
77pub(crate) struct AppTransactionPayload {
78 #[serde(rename = "appID")]
79 app_id: Option<u64>,
80 #[serde(rename = "appTransactionID")]
81 app_transaction_id: String,
82 #[serde(rename = "appVersion")]
83 app_version: String,
84 #[serde(rename = "appVersionID")]
85 app_version_id: Option<u64>,
86 #[serde(rename = "bundleID")]
87 bundle_id: String,
88 environment: String,
89 #[serde(rename = "originalAppVersion")]
90 original_app_version: String,
91 #[serde(rename = "originalPurchaseDate")]
92 original_purchase_date: String,
93 #[serde(rename = "originalPlatform")]
94 original_platform: Option<String>,
95 #[serde(rename = "preorderDate")]
96 preorder_date: Option<String>,
97 #[serde(rename = "jsonRepresentationBase64")]
98 json_representation_base64: String,
99}
100
101impl AppTransactionPayload {
102 pub(crate) fn into_app_transaction(self) -> Result<AppTransaction, StoreKitError> {
103 Ok(AppTransaction {
104 app_id: self.app_id,
105 app_transaction_id: self.app_transaction_id,
106 app_version: self.app_version,
107 app_version_id: self.app_version_id,
108 bundle_id: self.bundle_id,
109 environment: AppStoreEnvironment::from_raw(self.environment),
110 original_app_version: self.original_app_version,
111 original_purchase_date: self.original_purchase_date,
112 original_platform: self.original_platform.map(AppStorePlatform::from_raw),
113 preorder_date: self.preorder_date,
114 json_representation: decode_base64(
115 &self.json_representation_base64,
116 "app transaction JSON representation",
117 )?,
118 })
119 }
120}