diff --git a/plugins/fetchinvoice.c b/plugins/fetchinvoice.c index 8882a8f0a..6d1b01067 100644 --- a/plugins/fetchinvoice.c +++ b/plugins/fetchinvoice.c @@ -253,8 +253,11 @@ static struct command_result *handle_invreq_response(struct command *cmd, if ((badfield = field_diff(sent->invreq, inv, payer_info))) goto badinv; - /* Get the amount we expected. */ - if (sent->offer->amount && !sent->offer->currency) { + /* Get the amount we expected: firstly, if that's what we sent, + * secondly, if specified in the invoice. */ + if (sent->invreq->amount) { + expected_amount = tal_dup(tmpctx, u64, sent->invreq->amount); + } else if (sent->offer->amount && !sent->offer->currency) { expected_amount = tal(tmpctx, u64); *expected_amount = *sent->offer->amount; diff --git a/tests/test_pay.py b/tests/test_pay.py index 8e870723b..433e35e1b 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -4158,6 +4158,15 @@ def test_fetchinvoice(node_factory, bitcoind): with pytest.raises(RpcError, match="Remote node sent failure message.*Amount must be at least 2msat"): l1.rpc.call('fetchinvoice', {'offer': offer1['bolt12'], 'msatoshi': 1}) + # If no amount is specified in offer, one must be in invoice. + offer_noamount = l3.rpc.call('offer', {'amount': 'any', + 'description': 'any amount test'}) + with pytest.raises(RpcError, match="msatoshi parameter required"): + l1.rpc.call('fetchinvoice', {'offer': offer_noamount['bolt12']}) + inv1 = l1.rpc.call('fetchinvoice', {'offer': offer_noamount['bolt12'], 'msatoshi': 100}) + # But amount won't appear in changes + assert 'msat' not in inv1['changes'] + # Single-use invoice can be fetched multiple times, only paid once. offer2 = l3.rpc.call('offer', {'amount': '1msat', 'description': 'single-use test',