File tree Expand file tree Collapse file tree
phoenix-android/src/main/res/values
phoenix-shared/src/commonMain/kotlin/fr.acinq.phoenix/managers Expand file tree Collapse file tree Original file line number Diff line number Diff line change 177177
178178 <string name =" send_error_invoice_expired" >This invoice is expired.</string >
179179 <string name =" send_error_payment_pending" >This payment is already being processed. Please wait for it to complete.</string >
180- <string name =" send_error_already_paid" >This payment has already been paid.</string >
180+ <string name =" send_error_already_paid" >This invoice has already been paid.</string >
181181 <string name =" send_error_invalid_chain" >This payment does not use the same blockchain as your wallet.</string >
182182 <string name =" send_error_lnurl_invalid" >Failed to process this LNURL link. Make sure it is valid.</string >
183183 <string name =" send_error_lnurl_unsupported" >This type of LNURL is not supported yet.</string >
Original file line number Diff line number Diff line change @@ -214,22 +214,24 @@ class SendManager(
214214 return BadRequestReason .ChainMismatch (expected = chain)
215215 }
216216
217- if (invoice.isExpired(currentTimestampSeconds())) {
218- return BadRequestReason .Expired (invoice.timestampSeconds, invoice.expirySeconds ? : Bolt11Invoice .DEFAULT_EXPIRY_SECONDS .toLong())
219- }
220-
221217 val db = databaseManager.databases.filterNotNull().first()
222218 val similarPayments = db.payments.listLightningOutgoingPayments(invoice.paymentHash)
223219 // we MUST raise an error if this payment hash has already been paid, or is being paid.
224220 // parallel pending payments on the same payment hash can trigger force-closes
225221 // FIXME: this check should be done in lightning-kmp, not in Phoenix
226- return when {
222+ // Note: check payment history before expiry so that "already paid" takes priority over "expired".
223+ when {
227224 similarPayments.any { it.status is LightningOutgoingPayment .Status .Succeeded || it.parts.any { part -> part.status is LightningOutgoingPayment .Part .Status .Succeeded } } ->
228- BadRequestReason .AlreadyPaidInvoice
225+ return BadRequestReason .AlreadyPaidInvoice
229226 similarPayments.any { it.status is LightningOutgoingPayment .Status .Pending || it.parts.any { part -> part.status is LightningOutgoingPayment .Part .Status .Pending } } ->
230- BadRequestReason .PaymentPending
231- else -> null
227+ return BadRequestReason .PaymentPending
232228 }
229+
230+ if (invoice.isExpired(currentTimestampSeconds())) {
231+ return BadRequestReason .Expired (invoice.timestampSeconds, invoice.expirySeconds ? : Bolt11Invoice .DEFAULT_EXPIRY_SECONDS .toLong())
232+ }
233+
234+ return null
233235 }
234236
235237 private fun processOffer (
You can’t perform that action at this time.
0 commit comments