sift_science/webhooks.rs
1//! Receive notifications about events in Sift.
2//!
3//! When one of the events is triggered, Sift will send a JSON payload to the webhook's specified
4//! URL. Webhooks can be used to update your own support tool, data warehouses, and more.
5
6use crate::common::deserialize_ms;
7use crate::error::Error;
8use serde::{Deserialize, Serialize};
9use std::fmt;
10use std::time::SystemTime;
11
12/// The header sift science will attach to each webhook invocation.
13///
14/// This should be used to verify that the request originates from Sift's servers.
15pub const SIGNATURE_HEADER: &str = "X-Sift-Science-Signature";
16
17/// Options when creating a new [Webhook].
18///
19/// See <https://sift.com/developers/docs/curl/webhooks-api/create> for examples.
20#[derive(Debug, Serialize)]
21pub struct WebhookRequest {
22 /// The type of webhook payload
23 pub payload_type: PayloadType,
24
25 /// The webhook status.
26 pub status: Status,
27
28 /// The URL of the webhook endpoint.
29 ///
30 /// This must be HTTPS.
31 pub url: String,
32
33 /// The list of events to enable for this endpoint.
34 ///
35 /// These correspond to the Reserved Events in the [Events API].
36 ///
37 /// [Events API]: https://sift.com/developers/docs/curl/events-api/overview
38 pub enabled_events: Vec<EnabledEvent>,
39
40 /// A name you specify for this webhook.
41 pub name: Option<String>,
42
43 /// A description about what the webhook is used for.
44 pub description: Option<String>,
45}
46
47/// Webhook data
48///
49/// See <https://sift.com/developers/docs/curl/webhooks-api/create> for examples.
50#[derive(Debug, Deserialize, Serialize)]
51pub struct Webhook {
52 /// The id of the webhook.
53 pub id: u64,
54
55 /// The name of the webhook
56 #[serde(default)]
57 pub name: Option<String>,
58
59 /// The description of the webhook
60 #[serde(default)]
61 pub description: Option<String>,
62
63 /// The type of payload.
64 pub payload_type: PayloadType,
65
66 /// The webhook status.
67 pub status: Status,
68
69 /// The URL of the webhook endpoint.
70 ///
71 /// This must be HTTPS.
72 pub url: String,
73
74 /// The list of events to enable for this endpoint.
75 ///
76 /// These correspond to the Reserved Events in the [Events API].
77 ///
78 /// [Events API]: https://sift.com/developers/docs/curl/events-api/overview
79 pub enabled_events: Vec<EnabledEvent>,
80
81 /// The time at which the webhook was created
82 #[serde(skip_serializing, deserialize_with = "deserialize_ms")]
83 pub created: SystemTime,
84
85 /// The time at which the webhook was updated
86 #[serde(skip_serializing, deserialize_with = "deserialize_ms")]
87 pub last_updated: SystemTime,
88}
89
90/// The type of webhook payload.
91#[derive(Debug, Serialize, Deserialize)]
92pub enum PayloadType {
93 /// This payload type provides an order data response.
94 ///
95 /// See the [order object](https://sift.com/developers/docs/curl/orders-api/order).
96 #[serde(rename = "ORDER_V1_0")]
97 OrderV10,
98}
99
100/// The webhook status.
101#[derive(Debug, Serialize, Deserialize)]
102#[serde(rename_all = "UPPERCASE")]
103pub enum Status {
104 /// Indicates the webhook is in a draft state.
105 ///
106 /// No webhooks are sent.
107 Draft,
108
109 /// Indicates the webhook is active.
110 ///
111 /// The webhook is live.
112 Active,
113}
114
115/// The event to be included as enabled for a webhook.
116///
117/// These correspond to the Reserved Events in the [Events API].
118///
119/// [Events API]: https://sift.com/developers/docs/curl/events-api/overview
120#[derive(Debug, Serialize, Deserialize)]
121pub enum EnabledEvent {
122 /// Occurs whenever a [Event::CreateOrder] event is tracked.
123 ///
124 /// [Event::CreateOrder]: crate::events::Event::CreateOrder
125 #[serde(rename = "$create_order")]
126 CreateOrder,
127
128 /// Occurs whenever a [Event::UpdateOrder] event is tracked.
129 ///
130 /// [Event::UpdateOrder]: crate::events::Event::UpdateOrder
131 #[serde(rename = "$update_order")]
132 UpdateOrder,
133
134 /// Occurs whenever a [Event::OrderStatus] event is tracked.
135 ///
136 /// [Event::OrderStatus]: crate::events::Event::OrderStatus
137 #[serde(rename = "$order_status")]
138 OrderStatus,
139
140 /// Occurs whenever a [Event::Transaction] event is tracked.
141 ///
142 /// [Event::Transaction]: crate::events::Event::Transaction
143 #[serde(rename = "$transaction")]
144 Transaction,
145
146 /// Occurs whenever a [Event::Chargeback] event is tracked.
147 ///
148 /// [Event::Chargeback]: crate::events::Event::Chargeback
149 #[serde(rename = "$chargeback")]
150 Chargeback,
151}
152
153#[derive(Deserialize)]
154#[serde(untagged)]
155pub(crate) enum WebhooksResponse {
156 Error(Error),
157 Webhooks { data: Vec<Webhook> },
158}
159
160#[derive(Deserialize)]
161#[serde(untagged)]
162pub(crate) enum WebhookResponse {
163 Error(Error),
164 Webhook(Webhook),
165}
166
167/// Webhook API version
168#[derive(Copy, Clone, Debug)]
169pub enum ApiVersion {
170 /// Version 3
171 V3,
172}
173
174impl fmt::Display for ApiVersion {
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 match self {
177 ApiVersion::V3 => write!(f, "v3"),
178 }
179 }
180}