Skip to main content

storekit/
refund.rs

1use core::ptr;
2
3use crate::error::StoreKitError;
4use crate::ffi;
5use crate::private::{cstring_from_str, error_from_status, take_string};
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8/// Represents the result returned by a `StoreKit` refund request.
9pub enum RefundRequestStatus {
10    /// The `StoreKit` operation succeeded.
11    Success,
12    /// The person cancelled the `StoreKit` flow.
13    UserCancelled,
14    /// Preserves an unrecognized `StoreKit` case.
15    Unknown(String),
16}
17
18impl RefundRequestStatus {
19    /// Returns the raw `StoreKit` string for this refund request status.
20    pub fn as_str(&self) -> &str {
21        match self {
22            Self::Success => "success",
23            Self::UserCancelled => "userCancelled",
24            Self::Unknown(value) => value.as_str(),
25        }
26    }
27
28    fn from_raw(raw: String) -> Self {
29        match raw.as_str() {
30            "success" => Self::Success,
31            "userCancelled" => Self::UserCancelled,
32            _ => Self::Unknown(raw),
33        }
34    }
35}
36
37#[derive(Debug, Clone, Copy, Default)]
38/// Helpers backed by `StoreKit` refund request APIs.
39pub struct Refund;
40
41impl Refund {
42    /// Begins a `StoreKit` refund request for the supplied transaction identifier.
43    pub fn begin_for_transaction_id(
44        transaction_id: u64,
45    ) -> Result<RefundRequestStatus, StoreKitError> {
46        let transaction_id = cstring_from_str(&transaction_id.to_string(), "transaction id")?;
47        let mut status_ptr = ptr::null_mut();
48        let mut error_message = ptr::null_mut();
49        let status = unsafe {
50            ffi::sk_refund_begin_request_for_transaction_id(
51                transaction_id.as_ptr(),
52                &mut status_ptr,
53                &mut error_message,
54            )
55        };
56        if status != ffi::status::OK {
57            return Err(unsafe { error_from_status(status, error_message) });
58        }
59
60        let raw_status = unsafe { take_string(status_ptr) }
61            .ok_or_else(|| StoreKitError::Unknown("missing refund status payload".to_owned()))?;
62        Ok(RefundRequestStatus::from_raw(raw_status))
63    }
64}