1#[cfg(test)]
2mod fake_stripe_client;
3mod real_stripe_client;
4
5use std::collections::HashMap;
6use std::sync::Arc;
7
8use anyhow::Result;
9use async_trait::async_trait;
10
11#[cfg(test)]
12pub use fake_stripe_client::*;
13pub use real_stripe_client::*;
14use serde::{Deserialize, Serialize};
15
16#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display, Serialize)]
17pub struct StripeCustomerId(pub Arc<str>);
18
19#[derive(Debug, Clone)]
20pub struct StripeCustomer {
21 pub id: StripeCustomerId,
22 pub email: Option<String>,
23}
24
25#[derive(Debug)]
26pub struct CreateCustomerParams<'a> {
27 pub email: Option<&'a str>,
28}
29
30#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display)]
31pub struct StripeSubscriptionId(pub Arc<str>);
32
33#[derive(Debug, PartialEq, Clone)]
34pub struct StripeSubscription {
35 pub id: StripeSubscriptionId,
36 pub customer: StripeCustomerId,
37 // TODO: Create our own version of this enum.
38 pub status: stripe::SubscriptionStatus,
39 pub current_period_end: i64,
40 pub current_period_start: i64,
41 pub items: Vec<StripeSubscriptionItem>,
42 pub cancel_at: Option<i64>,
43 pub cancellation_details: Option<StripeCancellationDetails>,
44}
45
46#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display)]
47pub struct StripeSubscriptionItemId(pub Arc<str>);
48
49#[derive(Debug, PartialEq, Clone)]
50pub struct StripeSubscriptionItem {
51 pub id: StripeSubscriptionItemId,
52 pub price: Option<StripePrice>,
53}
54
55#[derive(Debug, Clone, PartialEq)]
56pub struct StripeCancellationDetails {
57 pub reason: Option<StripeCancellationDetailsReason>,
58}
59
60#[derive(Debug, PartialEq, Eq, Clone, Copy)]
61pub enum StripeCancellationDetailsReason {
62 CancellationRequested,
63 PaymentDisputed,
64 PaymentFailed,
65}
66
67#[derive(Debug)]
68pub struct StripeCreateSubscriptionParams {
69 pub customer: StripeCustomerId,
70 pub items: Vec<StripeCreateSubscriptionItems>,
71}
72
73#[derive(Debug)]
74pub struct StripeCreateSubscriptionItems {
75 pub price: Option<StripePriceId>,
76 pub quantity: Option<u64>,
77}
78
79#[derive(Debug, Clone)]
80pub struct UpdateSubscriptionParams {
81 pub items: Option<Vec<UpdateSubscriptionItems>>,
82 pub trial_settings: Option<StripeSubscriptionTrialSettings>,
83}
84
85#[derive(Debug, PartialEq, Clone)]
86pub struct UpdateSubscriptionItems {
87 pub price: Option<StripePriceId>,
88}
89
90#[derive(Debug, PartialEq, Clone)]
91pub struct StripeSubscriptionTrialSettings {
92 pub end_behavior: StripeSubscriptionTrialSettingsEndBehavior,
93}
94
95#[derive(Debug, PartialEq, Clone)]
96pub struct StripeSubscriptionTrialSettingsEndBehavior {
97 pub missing_payment_method: StripeSubscriptionTrialSettingsEndBehaviorMissingPaymentMethod,
98}
99
100#[derive(Debug, PartialEq, Eq, Clone, Copy)]
101pub enum StripeSubscriptionTrialSettingsEndBehaviorMissingPaymentMethod {
102 Cancel,
103 CreateInvoice,
104 Pause,
105}
106
107#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display)]
108pub struct StripePriceId(pub Arc<str>);
109
110#[derive(Debug, PartialEq, Clone)]
111pub struct StripePrice {
112 pub id: StripePriceId,
113 pub unit_amount: Option<i64>,
114 pub lookup_key: Option<String>,
115 pub recurring: Option<StripePriceRecurring>,
116}
117
118#[derive(Debug, PartialEq, Clone)]
119pub struct StripePriceRecurring {
120 pub meter: Option<String>,
121}
122
123#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display, Deserialize)]
124pub struct StripeMeterId(pub Arc<str>);
125
126#[derive(Debug, Clone, Deserialize)]
127pub struct StripeMeter {
128 pub id: StripeMeterId,
129 pub event_name: String,
130}
131
132#[derive(Debug, Serialize)]
133pub struct StripeCreateMeterEventParams<'a> {
134 pub identifier: &'a str,
135 pub event_name: &'a str,
136 pub payload: StripeCreateMeterEventPayload<'a>,
137 pub timestamp: Option<i64>,
138}
139
140#[derive(Debug, Serialize)]
141pub struct StripeCreateMeterEventPayload<'a> {
142 pub value: u64,
143 pub stripe_customer_id: &'a StripeCustomerId,
144}
145
146#[derive(Debug, Default)]
147pub struct StripeCreateCheckoutSessionParams<'a> {
148 pub customer: Option<&'a StripeCustomerId>,
149 pub client_reference_id: Option<&'a str>,
150 pub mode: Option<StripeCheckoutSessionMode>,
151 pub line_items: Option<Vec<StripeCreateCheckoutSessionLineItems>>,
152 pub payment_method_collection: Option<StripeCheckoutSessionPaymentMethodCollection>,
153 pub subscription_data: Option<StripeCreateCheckoutSessionSubscriptionData>,
154 pub success_url: Option<&'a str>,
155}
156
157#[derive(Debug, PartialEq, Eq, Clone, Copy)]
158pub enum StripeCheckoutSessionMode {
159 Payment,
160 Setup,
161 Subscription,
162}
163
164#[derive(Debug, PartialEq, Clone)]
165pub struct StripeCreateCheckoutSessionLineItems {
166 pub price: Option<String>,
167 pub quantity: Option<u64>,
168}
169
170#[derive(Debug, PartialEq, Eq, Clone, Copy)]
171pub enum StripeCheckoutSessionPaymentMethodCollection {
172 Always,
173 IfRequired,
174}
175
176#[derive(Debug, PartialEq, Clone)]
177pub struct StripeCreateCheckoutSessionSubscriptionData {
178 pub metadata: Option<HashMap<String, String>>,
179 pub trial_period_days: Option<u32>,
180 pub trial_settings: Option<StripeSubscriptionTrialSettings>,
181}
182
183#[derive(Debug)]
184pub struct StripeCheckoutSession {
185 pub url: Option<String>,
186}
187
188#[async_trait]
189pub trait StripeClient: Send + Sync {
190 async fn list_customers_by_email(&self, email: &str) -> Result<Vec<StripeCustomer>>;
191
192 async fn get_customer(&self, customer_id: &StripeCustomerId) -> Result<StripeCustomer>;
193
194 async fn create_customer(&self, params: CreateCustomerParams<'_>) -> Result<StripeCustomer>;
195
196 async fn list_subscriptions_for_customer(
197 &self,
198 customer_id: &StripeCustomerId,
199 ) -> Result<Vec<StripeSubscription>>;
200
201 async fn get_subscription(
202 &self,
203 subscription_id: &StripeSubscriptionId,
204 ) -> Result<StripeSubscription>;
205
206 async fn create_subscription(
207 &self,
208 params: StripeCreateSubscriptionParams,
209 ) -> Result<StripeSubscription>;
210
211 async fn update_subscription(
212 &self,
213 subscription_id: &StripeSubscriptionId,
214 params: UpdateSubscriptionParams,
215 ) -> Result<()>;
216
217 async fn cancel_subscription(&self, subscription_id: &StripeSubscriptionId) -> Result<()>;
218
219 async fn list_prices(&self) -> Result<Vec<StripePrice>>;
220
221 async fn list_meters(&self) -> Result<Vec<StripeMeter>>;
222
223 async fn create_meter_event(&self, params: StripeCreateMeterEventParams<'_>) -> Result<()>;
224
225 async fn create_checkout_session(
226 &self,
227 params: StripeCreateCheckoutSessionParams<'_>,
228 ) -> Result<StripeCheckoutSession>;
229}