085-transfer-status.rst (3840B)
1 DD 85: Transfer status 2 ###################### 3 4 :Design status: Draft 5 :Implementation status: Not started 6 :DD shepherd: TBD 7 :Historical contributors: Antoine A 8 :First published: 2026-02-16 9 :Last substantive change: 2026-02-16 10 11 Summary 12 ======= 13 14 We need a way to handle wire gateway incoming and outgoing transfer failures. 15 Automatically when possible with fallbacks to manual resolution. 16 17 Motivation 18 ========== 19 20 Right now when we make a deposit the wallet show confirmation before the transfer is actually made. 21 In case of failure nothing is done automatically and the user has no way to see it from it's wallet. 22 23 We already have a transfer status API in place but it's not suitable for automation as it's expose a paginated list of transfers and we need a pagniated list of transfer status changes. 24 25 I think the Wire Gateway API should expose a transfer status history endpoint and the logic for failure resolution should be done at a higher level in the exchange. 26 27 We also need an API for incoming transactions that are malformed but cannot be bounce. 28 29 Proposed Solution 30 ================= 31 32 Database 33 -------- 34 35 For each transfer we would store a list of all status it whent through. 36 37 TODO 38 39 Wire Gateway API 40 ---------------- 41 42 .. http:get:: /transfers-status 43 44 Return a list of transfers status changes. 45 46 **Request:** 47 48 :query limit: *Optional.* 49 At most return the given number of results. Negative for descending by 50 ``row_id``, positive for ascending by ``row_id``. Defaults to ``-20``. 51 :query offset: *Optional.* 52 Starting ``row_id`` for :ref:`pagination <row-id-pagination>`. 53 :query status: *Optional*. 54 Filters by status. 55 :query transfer_id: *Optional* 56 Only list statuses for a specific transfer. 57 58 **Response:** 59 60 :http:statuscode:`200 OK`: 61 JSON object of type ``TransferStatusList``. 62 :http:statuscode:`204 No content`: 63 There are no transfers statuses to report (under the given filter). 64 :http:statuscode:`400 Bad request`: 65 Request malformed. 66 :http:statuscode:`401 Unauthorized`: 67 Authentication failed, likely the credentials are wrong. 68 :http:statuscode:`404 Not found`: 69 The endpoint is wrong or the user name is unknown. 70 71 **Details:** 72 73 .. ts:def:: TransferStatusList 74 75 interface TransferStatusList { 76 // Array of transfers statuses 77 statuses: TransferListStatus[]; 78 } 79 80 .. ts:def:: TransferStatus 81 82 interface TransferStatus { 83 // Opaque ID of the status change. 84 // It is different from the /transfers 85 row_id: SafeUint64; 86 87 // Opaque ID of the wire transfer initiation performed by the bank. 88 // It is different from the /history endpoints row_id. 89 transfer_id: SafeUint64; 90 91 // Status of the transfer at this time 92 // pending: the transfer is in progress 93 // transient_failure: the transfer has failed but may succeed later 94 // permanent_failure: the transfer has failed permanently and will never appear in the outgoing history 95 // success: the transfer has succeeded and appears in the outgoing history 96 status: "pending" | "transient_failure" | "permanent_failure" | "success"; 97 98 // Timestamp that indicates when this status was reached. 99 timestamp: Timestamp; 100 } 101 102 Exchange aggregation 103 -------------------- 104 105 I think all this information should be stored and aggregated within the exchange. Wire adapters should only contain code to abstract the underlying system internal workings, but the remediation logic should be at another level. 106 107 The exchange should read the status anyway to refund in case of failure, but if we want to add more complex rules and manual remediation, we could create another component that I could maintain if it makes life easier for Christian. 108 109 Test Plan 110 ========= 111 112 113 Alternatives 114 ============ 115 116 117 Drawbacks 118 ========= 119 120 121 Discussion / Q&A 122 ================