@@ -21,6 +21,31 @@ pub enum TopupStatus {
21
21
SETTLED ,
22
22
}
23
23
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
+
24
49
pub struct TopupInfo {
25
50
pub id : String ,
26
51
pub status : TopupStatus ,
@@ -33,6 +58,7 @@ pub struct TopupInfo {
33
58
34
59
pub expires_at : SystemTime ,
35
60
pub lnurlw : String ,
61
+ pub error : Option < TopupError > ,
36
62
}
37
63
38
64
pub struct OfferManager {
@@ -146,6 +172,12 @@ fn to_topup_info(topup: ListUncompletedTopupsTopup) -> graphql::Result<TopupInfo
146
172
}
147
173
} ;
148
174
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
+
149
181
Ok ( TopupInfo {
150
182
id : topup. id ,
151
183
status,
@@ -158,14 +190,81 @@ fn to_topup_info(topup: ListUncompletedTopupsTopup) -> graphql::Result<TopupInfo
158
190
159
191
expires_at,
160
192
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
+ } ,
161
258
} )
162
259
}
163
260
164
261
#[ cfg( test) ]
165
262
mod tests {
166
263
use std:: time:: SystemTime ;
167
264
168
- use crate :: { to_topup_info, TopupStatus } ;
265
+ use crate :: {
266
+ to_topup_info, PermanentFailureCode , TemporaryFailureCode , TopupError , TopupStatus ,
267
+ } ;
169
268
use graphql:: schema:: list_uncompleted_topups:: { topup_status_enum, ListUncompletedTopupsTopup } ;
170
269
171
270
const LNURL : & str = "LNURL1DP68GURN8GHJ7UR0VD4K2ARPWPCZ6EMFWSKHXARPVA5KUEEDWPHKX6M9W3SHQUPWWEJHYCM9DSHXZURS9ASHQ6F0D3H82UNV9AMKJARGV3EXZAE0XVUNQDNYVDJRGTF4XGEKXTF5X56NXTTZX3NRWTT9XDJRJEP4VE3XGD3KXVXTX4LS" ;
@@ -215,6 +314,74 @@ mod tests {
215
314
assert_eq ! ( expires_at, 1695314361 ) ;
216
315
assert_eq ! ( topup_info. lnurlw, LNURL ) ;
217
316
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
+ }
219
386
}
220
387
}
0 commit comments