Worth adding for readers: a Solana Pay transfer request (solana:recipient?amount=...) needs no backend since the wallet composes the SystemProgram.Transfer itself, whereas a transaction request requires a server returning a serialized transaction. Also, amount must be written 0.5 rather than .5, label/message need percent-encoding, the URL does not pin a cluster, and scanning a QR is not a payment, so include a reference pubkey and verify with getSignaturesForAddress.