Payments

QR payments

Every payment intent comes with a Solana Pay QR code. Any compatible wallet can scan it, and Muny finds the payment by its unique reference key.

The URI#

payment.solana_pay_url is a Solana Pay transfer request. It encodes everything a wallet needs: recipient, token mint, exact amount and the reference.

solana_pay_url (line breaks added)
solana:7hjnUGHeqsFda6MXRuYEku7mN4Ywv58q4kC2yh2vGMz
  ?amount=249
  &spl-token=<MUNY mint>
  &reference=9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM
  &label=Creator%20Hub
  &message=Pro%20subscription
  &memo=muny%3A3f1c9a52-7d0e-4c1b-9b8e-6a2f1d5c0e47
ParameterValue
recipientThe settlement wallet owner (your receiving wallet).
amountWhole-token decimal string, e.g. 249.
spl-tokenThe MUNY mint for the active network.
referenceA unique, random public key created for this payment (reference_key).
label / messageYour display name and the payment description.
memomuny:<payment id> for traceability. Public on chain: never put personal data here.

Why the reference matters#

The paying wallet adds the reference key to the transfer as a read-only account. It doesn't move any funds, but it makes the transaction findable: Muny searches the chain for signatures that include that key, then verifies the transfer. This is how a QR payment completes even if the payer never comes back to the checkout page.

A transfer without the reference cannot be attributed to a payment. Paying the right amount by hand still shows up in your wallet, but Muny will not mark the payment intent as paid. See Verify payments.

Render your own QR#

ts
import QRCode from "qrcode";
import { parseSolanaPayUrl } from "@muny/types";

const payment = await muny.paymentIntents.create({ amount: "249", reference: "TABLE-12" });

// Render your own QR (POS screen, printed receipt…)
const svg = await QRCode.toString(payment.solana_pay_url, { type: "svg", margin: 1 });

// Parsing is shared with the API and the Muny mobile app
const req = parseSolanaPayUrl(payment.solana_pay_url);
// → { recipient, amount: "249", splToken, references: [reference_key], label, message, memo }
  • The QR on hosted checkout and the downloadable QR for payment links use the same encoder.
  • A QR code is valid until the payment expires. For a QR code you can reuse (a counter sign, a printed menu), use a payment link.

Scanning with the Muny app#

The planned Muny mobile wallet scans the same codes: scan, review the amount and merchant, confirm with biometrics, and the app signs on device. Merchants don't need to change anything.