Skip to content

Commit 70c76e4

Browse files
committed
Add error codes to topup
1 parent abb5de0 commit 70c76e4

File tree

1 file changed

+169
-2
lines changed

1 file changed

+169
-2
lines changed

crow/src/lib.rs

Lines changed: 169 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,31 @@ pub enum TopupStatus {
2121
SETTLED,
2222
}
2323

24+
#[derive(Clone, Debug, PartialEq, Eq)]
25+
pub enum TemporaryFailureCode {
26+
NoRoute,
27+
InvoiceExpired,
28+
Unexpected,
29+
}
30+
31+
#[derive(Clone, Debug, PartialEq, Eq)]
32+
pub enum PermanentFailureCode {
33+
ThresholdExceeded,
34+
OrderInactive,
35+
CompaniesUnsupported,
36+
CountryUnsupported,
37+
OtherRiskDetected,
38+
CustomerRequested,
39+
AccountNotMatching,
40+
PayoutExpired,
41+
}
42+
43+
#[derive(PartialEq, Eq, Debug, Clone)]
44+
pub enum TopupError {
45+
TemporaryFailure { code: TemporaryFailureCode },
46+
PermanentFailure { code: PermanentFailureCode },
47+
}
48+
2449
pub struct TopupInfo {
2550
pub id: String,
2651
pub status: TopupStatus,
@@ -33,6 +58,7 @@ pub struct TopupInfo {
3358

3459
pub expires_at: SystemTime,
3560
pub lnurlw: String,
61+
pub error: Option<TopupError>,
3662
}
3763

3864
pub struct OfferManager {
@@ -146,6 +172,12 @@ fn to_topup_info(topup: ListUncompletedTopupsTopup) -> graphql::Result<TopupInfo
146172
}
147173
};
148174

175+
let error = match topup.status {
176+
topup_status_enum::FAILED => to_topup_error(topup.additional_info),
177+
topup_status_enum::REFUNDED => to_topup_error(topup.additional_info),
178+
_ => None,
179+
};
180+
149181
Ok(TopupInfo {
150182
id: topup.id,
151183
status,
@@ -158,14 +190,81 @@ fn to_topup_info(topup: ListUncompletedTopupsTopup) -> graphql::Result<TopupInfo
158190

159191
expires_at,
160192
lnurlw,
193+
error,
194+
})
195+
}
196+
197+
pub fn from_topup_error(error: Option<TopupError>) -> Option<String> {
198+
error.map(|e| {
199+
match e {
200+
TopupError::TemporaryFailure { code } => match code {
201+
TemporaryFailureCode::NoRoute => "no_route",
202+
TemporaryFailureCode::InvoiceExpired => "invoice_expired",
203+
TemporaryFailureCode::Unexpected => "error",
204+
},
205+
TopupError::PermanentFailure { code } => match code {
206+
PermanentFailureCode::ThresholdExceeded => "threshold_exceeded",
207+
PermanentFailureCode::OrderInactive => "order_inactive",
208+
PermanentFailureCode::CompaniesUnsupported => "companies_unsupported",
209+
PermanentFailureCode::CountryUnsupported => "country_unsupported",
210+
PermanentFailureCode::OtherRiskDetected => "other_risk_detected",
211+
PermanentFailureCode::CustomerRequested => "customer_requested",
212+
PermanentFailureCode::AccountNotMatching => "account_not_matching",
213+
PermanentFailureCode::PayoutExpired => "payout_expired",
214+
},
215+
}
216+
.to_string()
217+
})
218+
}
219+
220+
pub fn to_topup_error(code: Option<String>) -> Option<TopupError> {
221+
code.map(|c| match &*c {
222+
"no_route" => TopupError::TemporaryFailure {
223+
code: TemporaryFailureCode::NoRoute,
224+
},
225+
"invoice_expired" => TopupError::TemporaryFailure {
226+
code: TemporaryFailureCode::InvoiceExpired,
227+
},
228+
"error" => TopupError::TemporaryFailure {
229+
code: TemporaryFailureCode::Unexpected,
230+
},
231+
"threshold_exceeded" => TopupError::PermanentFailure {
232+
code: PermanentFailureCode::ThresholdExceeded,
233+
},
234+
"order_inactive" => TopupError::PermanentFailure {
235+
code: PermanentFailureCode::OrderInactive,
236+
},
237+
"companies_unsupported" => TopupError::PermanentFailure {
238+
code: PermanentFailureCode::CompaniesUnsupported,
239+
},
240+
"country_unsupported" => TopupError::PermanentFailure {
241+
code: PermanentFailureCode::CountryUnsupported,
242+
},
243+
"other_risk_detected" => TopupError::PermanentFailure {
244+
code: PermanentFailureCode::OtherRiskDetected,
245+
},
246+
"customer_requested" => TopupError::PermanentFailure {
247+
code: PermanentFailureCode::CustomerRequested,
248+
},
249+
"account_not_matching" => TopupError::PermanentFailure {
250+
code: PermanentFailureCode::AccountNotMatching,
251+
},
252+
"payout_expired" => TopupError::PermanentFailure {
253+
code: PermanentFailureCode::PayoutExpired,
254+
},
255+
_ => TopupError::TemporaryFailure {
256+
code: TemporaryFailureCode::Unexpected,
257+
},
161258
})
162259
}
163260

164261
#[cfg(test)]
165262
mod tests {
166263
use std::time::SystemTime;
167264

168-
use crate::{to_topup_info, TopupStatus};
265+
use crate::{
266+
to_topup_info, PermanentFailureCode, TemporaryFailureCode, TopupError, TopupStatus,
267+
};
169268
use graphql::schema::list_uncompleted_topups::{topup_status_enum, ListUncompletedTopupsTopup};
170269

171270
const LNURL: &str = "LNURL1DP68GURN8GHJ7UR0VD4K2ARPWPCZ6EMFWSKHXARPVA5KUEEDWPHKX6M9W3SHQUPWWEJHYCM9DSHXZURS9ASHQ6F0D3H82UNV9AMKJARGV3EXZAE0XVUNQDNYVDJRGTF4XGEKXTF5X56NXTTZX3NRWTT9XDJRJEP4VE3XGD3KXVXTX4LS";
@@ -215,6 +314,74 @@ mod tests {
215314
assert_eq!(expires_at, 1695314361);
216315
assert_eq!(topup_info.lnurlw, LNURL);
217316

218-
assert_eq!(topup_info.status, TopupStatus::READY)
317+
assert_eq!(topup_info.status, TopupStatus::READY);
318+
319+
let topup = ListUncompletedTopupsTopup {
320+
additional_info: Some("no_route".to_string()),
321+
amount_sat: 42578,
322+
amount_user_currency,
323+
created_at: "2023-07-21T16:39:21.271+00:00".to_string(),
324+
exchange_fee_rate: 0.014999999664723873,
325+
exchange_fee_user_currency: 0.11999999731779099,
326+
exchange_rate: 18507.0,
327+
expires_at: "2023-09-21T16:39:21.919+00:00".to_string(),
328+
id: "1707e09e-ebe1-4004-abd7-7a64604501b3".to_string(),
329+
lightning_fee_user_currency: 0.0,
330+
lnurl: LNURL.to_string(),
331+
node_pub_key: "0233786a3f5c79d25508ed973e7a37506ddab49d41a07fcb3d341ab638000d69cf"
332+
.to_string(),
333+
status: topup_status_enum::FAILED,
334+
user_currency: "eur".to_string(),
335+
};
336+
337+
let topup_info = to_topup_info(topup).unwrap();
338+
339+
match topup_info.error {
340+
None => {
341+
panic!("Expected topup to have error code, was None")
342+
}
343+
Some(e) => match e {
344+
TopupError::TemporaryFailure { code } => {
345+
assert_eq!(code, TemporaryFailureCode::NoRoute)
346+
}
347+
TopupError::PermanentFailure { .. } => {
348+
panic!("Expected topup to have temporary failure, was permanent")
349+
}
350+
},
351+
}
352+
353+
let topup = ListUncompletedTopupsTopup {
354+
additional_info: Some("customer_requested".to_string()),
355+
amount_sat: 42578,
356+
amount_user_currency,
357+
created_at: "2023-07-21T16:39:21.271+00:00".to_string(),
358+
exchange_fee_rate: 0.014999999664723873,
359+
exchange_fee_user_currency: 0.11999999731779099,
360+
exchange_rate: 18507.0,
361+
expires_at: "2023-09-21T16:39:21.919+00:00".to_string(),
362+
id: "1707e09e-ebe1-4004-abd7-7a64604501b3".to_string(),
363+
lightning_fee_user_currency: 0.0,
364+
lnurl: LNURL.to_string(),
365+
node_pub_key: "0233786a3f5c79d25508ed973e7a37506ddab49d41a07fcb3d341ab638000d69cf"
366+
.to_string(),
367+
status: topup_status_enum::REFUNDED,
368+
user_currency: "eur".to_string(),
369+
};
370+
371+
let topup_info = to_topup_info(topup).unwrap();
372+
373+
match topup_info.error {
374+
None => {
375+
panic!("Expected topup to have error code, was None")
376+
}
377+
Some(e) => match e {
378+
TopupError::TemporaryFailure { .. } => {
379+
panic!("Expected topup to have permanent failure, was temporary")
380+
}
381+
TopupError::PermanentFailure { code } => {
382+
assert_eq!(code, PermanentFailureCode::CustomerRequested)
383+
}
384+
},
385+
}
219386
}
220387
}

0 commit comments

Comments
 (0)