6 · Pay and get the BEEF
Alice pays the invoice. Her wallet picks coins, builds and signs the transaction, and returns it as a BEEF. A BEEF is the transaction together with the parent transactions and merkle proofs Bob needs to check it.
The payment is not broadcast. Your app hands the BEEF to Bob over whatever transport it uses (a QR code, HTTP, a chat message). Bob validates it and broadcasts it in the next step.
// Step 6: Alice pays it. The payment comes back as a BEEF, unbroadcast. final payment = await coordinator.ask(PayInvoiceCommand( walletId: 'alice', invoiceId: invoice.invoiceId, addresses: [invoice.addresses.first], amount: invoice.amount, )); print('Alice built ${payment.txid}: ${payment.beefBytes.length} BEEF bytes, ' '${payment.ancestorCount} ancestors');Alice built c5013d51885cc8e9115b2bdd1865c35866d77e165c6cc25dd564d13f0fa489f5: 533 BEEF bytes, 1 ancestorsThe reply is a PaymentReadyEvent. It carries txid, beefBytes, amountPaid, changeAmount and ancestorCount. The one ancestor here is the faucet transaction, with the merkle proof you imported in step 4.
Alice’s balance now reads 0
Section titled “Alice’s balance now reads 0”If you query Alice’s balance now, it reads 0 sats. That’s deliberate. A payment handed to the payee is a deferred payment: until the network has it, Alice’s wallet holds its inputs, reserved with no expiry, so no other payment can spend them. The change appears once the hold ends. That happens when Arcade reports the transaction SEEN_ON_NETWORK or MINED. The hold also ends if the payment is rejected, cancelled or reclaimed.
You’ll see the change come back in step 8. Deferred payments covers the rest: deadlines, cancelling, and reclaiming a payment the payee never broadcast.