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)]
31pub struct UpdateCustomerParams<'a> {
32 pub email: Option<&'a str>,
33}
34
35#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display)]
36pub struct StripeSubscriptionId(pub Arc<str>);
37
38#[derive(Debug, PartialEq, Clone)]
39pub struct StripeSubscription {
40 pub id: StripeSubscriptionId,
41 pub customer: StripeCustomerId,
42 // TODO: Create our own version of this enum.
43 pub status: stripe::SubscriptionStatus,
44 pub current_period_end: i64,
45 pub current_period_start: i64,
46 pub items: Vec<StripeSubscriptionItem>,
47 pub cancel_at: Option<i64>,
48 pub cancellation_details: Option<StripeCancellationDetails>,
49}
50
51#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display)]
52pub struct StripeSubscriptionItemId(pub Arc<str>);
53
54#[derive(Debug, PartialEq, Clone)]
55pub struct StripeSubscriptionItem {
56 pub id: StripeSubscriptionItemId,
57 pub price: Option<StripePrice>,
58}
59
60#[derive(Debug, Clone, PartialEq)]
61pub struct StripeCancellationDetails {
62 pub reason: Option<StripeCancellationDetailsReason>,
63}
64
65#[derive(Debug, PartialEq, Eq, Clone, Copy)]
66pub enum StripeCancellationDetailsReason {
67 CancellationRequested,
68 PaymentDisputed,
69 PaymentFailed,
70}
71
72#[derive(Debug)]
73pub struct StripeCreateSubscriptionParams {
74 pub customer: StripeCustomerId,
75 pub items: Vec<StripeCreateSubscriptionItems>,
76 pub automatic_tax: Option<StripeAutomaticTax>,
77}
78
79#[derive(Debug)]
80pub struct StripeCreateSubscriptionItems {
81 pub price: Option<StripePriceId>,
82 pub quantity: Option<u64>,
83}
84
85#[derive(Debug, Clone)]
86pub struct UpdateSubscriptionParams {
87 pub items: Option<Vec<UpdateSubscriptionItems>>,
88 pub trial_settings: Option<StripeSubscriptionTrialSettings>,
89}
90
91#[derive(Debug, PartialEq, Clone)]
92pub struct UpdateSubscriptionItems {
93 pub price: Option<StripePriceId>,
94}
95
96#[derive(Debug, PartialEq, Clone)]
97pub struct StripeSubscriptionTrialSettings {
98 pub end_behavior: StripeSubscriptionTrialSettingsEndBehavior,
99}
100
101#[derive(Debug, PartialEq, Clone)]
102pub struct StripeSubscriptionTrialSettingsEndBehavior {
103 pub missing_payment_method: StripeSubscriptionTrialSettingsEndBehaviorMissingPaymentMethod,
104}
105
106#[derive(Debug, PartialEq, Eq, Clone, Copy)]
107pub enum StripeSubscriptionTrialSettingsEndBehaviorMissingPaymentMethod {
108 Cancel,
109 CreateInvoice,
110 Pause,
111}
112
113#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display)]
114pub struct StripePriceId(pub Arc<str>);
115
116#[derive(Debug, PartialEq, Clone)]
117pub struct StripePrice {
118 pub id: StripePriceId,
119 pub unit_amount: Option<i64>,
120 pub lookup_key: Option<String>,
121 pub recurring: Option<StripePriceRecurring>,
122}
123
124#[derive(Debug, PartialEq, Clone)]
125pub struct StripePriceRecurring {
126 pub meter: Option<String>,
127}
128
129#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display, Deserialize)]
130pub struct StripeMeterId(pub Arc<str>);
131
132#[derive(Debug, Clone, Deserialize)]
133pub struct StripeMeter {
134 pub id: StripeMeterId,
135 pub event_name: String,
136}
137
138#[derive(Debug, Serialize)]
139pub struct StripeCreateMeterEventParams<'a> {
140 pub identifier: &'a str,
141 pub event_name: &'a str,
142 pub payload: StripeCreateMeterEventPayload<'a>,
143 pub timestamp: Option<i64>,
144}
145
146#[derive(Debug, Serialize)]
147pub struct StripeCreateMeterEventPayload<'a> {
148 pub value: u64,
149 pub stripe_customer_id: &'a StripeCustomerId,
150}
151
152#[derive(Debug, PartialEq, Eq, Clone, Copy)]
153pub enum StripeBillingAddressCollection {
154 Auto,
155 Required,
156}
157
158#[derive(Debug, PartialEq, Clone)]
159pub struct StripeCustomerUpdate {
160 pub address: Option<StripeCustomerUpdateAddress>,
161 pub name: Option<StripeCustomerUpdateName>,
162 pub shipping: Option<StripeCustomerUpdateShipping>,
163}
164
165#[derive(Debug, PartialEq, Eq, Clone, Copy)]
166pub enum StripeCustomerUpdateAddress {
167 Auto,
168 Never,
169}
170
171#[derive(Debug, PartialEq, Eq, Clone, Copy)]
172pub enum StripeCustomerUpdateName {
173 Auto,
174 Never,
175}
176
177#[derive(Debug, PartialEq, Eq, Clone, Copy)]
178pub enum StripeCustomerUpdateShipping {
179 Auto,
180 Never,
181}
182
183#[derive(Debug, Default)]
184pub struct StripeCreateCheckoutSessionParams<'a> {
185 pub customer: Option<&'a StripeCustomerId>,
186 pub client_reference_id: Option<&'a str>,
187 pub mode: Option<StripeCheckoutSessionMode>,
188 pub line_items: Option<Vec<StripeCreateCheckoutSessionLineItems>>,
189 pub payment_method_collection: Option<StripeCheckoutSessionPaymentMethodCollection>,
190 pub subscription_data: Option<StripeCreateCheckoutSessionSubscriptionData>,
191 pub success_url: Option<&'a str>,
192 pub billing_address_collection: Option<StripeBillingAddressCollection>,
193 pub customer_update: Option<StripeCustomerUpdate>,
194 pub tax_id_collection: Option<StripeTaxIdCollection>,
195}
196
197#[derive(Debug, PartialEq, Eq, Clone, Copy)]
198pub enum StripeCheckoutSessionMode {
199 Payment,
200 Setup,
201 Subscription,
202}
203
204#[derive(Debug, PartialEq, Clone)]
205pub struct StripeCreateCheckoutSessionLineItems {
206 pub price: Option<String>,
207 pub quantity: Option<u64>,
208}
209
210#[derive(Debug, PartialEq, Eq, Clone, Copy)]
211pub enum StripeCheckoutSessionPaymentMethodCollection {
212 Always,
213 IfRequired,
214}
215
216#[derive(Debug, PartialEq, Clone)]
217pub struct StripeCreateCheckoutSessionSubscriptionData {
218 pub metadata: Option<HashMap<String, String>>,
219 pub trial_period_days: Option<u32>,
220 pub trial_settings: Option<StripeSubscriptionTrialSettings>,
221}
222
223#[derive(Debug, PartialEq, Clone)]
224pub struct StripeTaxIdCollection {
225 pub enabled: bool,
226}
227
228#[derive(Debug, Clone)]
229pub struct StripeAutomaticTax {
230 pub enabled: bool,
231}
232
233#[derive(Debug)]
234pub struct StripeCheckoutSession {
235 pub url: Option<String>,
236}
237
238#[async_trait]
239pub trait StripeClient: Send + Sync {
240 async fn list_customers_by_email(&self, email: &str) -> Result<Vec<StripeCustomer>>;
241
242 async fn get_customer(&self, customer_id: &StripeCustomerId) -> Result<StripeCustomer>;
243
244 async fn create_customer(&self, params: CreateCustomerParams<'_>) -> Result<StripeCustomer>;
245
246 async fn update_customer(
247 &self,
248 customer_id: &StripeCustomerId,
249 params: UpdateCustomerParams<'_>,
250 ) -> Result<StripeCustomer>;
251
252 async fn list_subscriptions_for_customer(
253 &self,
254 customer_id: &StripeCustomerId,
255 ) -> Result<Vec<StripeSubscription>>;
256
257 async fn get_subscription(
258 &self,
259 subscription_id: &StripeSubscriptionId,
260 ) -> Result<StripeSubscription>;
261
262 async fn create_subscription(
263 &self,
264 params: StripeCreateSubscriptionParams,
265 ) -> Result<StripeSubscription>;
266
267 async fn update_subscription(
268 &self,
269 subscription_id: &StripeSubscriptionId,
270 params: UpdateSubscriptionParams,
271 ) -> Result<()>;
272
273 async fn cancel_subscription(&self, subscription_id: &StripeSubscriptionId) -> Result<()>;
274
275 async fn list_prices(&self) -> Result<Vec<StripePrice>>;
276
277 async fn list_meters(&self) -> Result<Vec<StripeMeter>>;
278
279 async fn create_meter_event(&self, params: StripeCreateMeterEventParams<'_>) -> Result<()>;
280
281 async fn create_checkout_session(
282 &self,
283 params: StripeCreateCheckoutSessionParams<'_>,
284 ) -> Result<StripeCheckoutSession>;
285}