# Solana Pay

> Source: https://docs.barcoder.ai/docs/standards/solana-pay
> research date 2026-06-04 · extracted at 2026-10-03
> Publisher: Barcoder — encyclopedia of QR, barcode and payment-code standards

Specifications:
- [Solana Pay Specification](https://docs.solanapay.com/spec)
- [solana-pay/SPEC.md (source spec)](https://github.com/anza-xyz/solana-pay/blob/master/SPEC.md)

## Overview

**Solana Pay** is a URL/URI standard for encoding Solana payment and transaction requests so they can be presented to a wallet — most commonly rendered as a [QR Code](https://docs.barcoder.ai/docs/standards/qr-code) for scan-to-pay.<sup>[1][1]</sup><sup>[2][2]</sup> The scheme uses the `solana:` URI prefix and comes in two flavours: a **transfer request**, a static, non-interactive URI describing a SOL or SPL-token transfer that the wallet composes locally, and a **transaction request**, an interactive form in which the URI points at an HTTPS endpoint that the wallet calls to obtain a server-built transaction.<sup>[1][1]</sup><sup>[2][2]</sup> The specification explicitly draws on Bitcoin's [BIP-21](https://docs.barcoder.ai/docs/standards/bip-21) and Ethereum's EIP-681 for its URI design.<sup>[1][1]</sup><sup>[2][2]</sup>

## History

Solana Pay was introduced as an open standard for encoding Solana transaction requests within URLs.<sup>[1][1]</sup> The reference repository was originally published under the Solana Foundation and is now maintained in the `anza-xyz/solana-pay` repository (Rust-majority, ~1.7k stars, active 2026).<sup>[2][2]</sup> The spec records that "rough consensus" on the format had been reached with early implementations in wallets such as Phantom, FTX and Slope, and notes that the design was inspired by [BIP-21](https://docs.barcoder.ai/docs/standards/bip-21) and EIP-681.<sup>[1][1]</sup>

## Technical specification

### Transfer request (non-interactive)

A transfer-request URI has the form:<sup>[1][1]</sup>

```
solana:<recipient>?amount=<amount>&spl-token=<spl-token>&reference=<reference>&label=<label>&message=<message>&memo=<memo>
```

| Field | Required | Meaning / constraints |
|-------|----------|-----------------------|
| `recipient` | yes (path) | base58-encoded public key of a **native SOL account** (not an associated token account) |
| `amount` | optional | non-negative integer or decimal in *user* units (SOL, or the token's display units — not lamports); leading `0` required for values < 1; no scientific notation; if absent the wallet prompts |
| `spl-token` | optional | base58 SPL-Token **mint** address; presence makes the transfer an SPL-token transfer and triggers associated-token-account derivation |
| `reference` | optional, repeatable | base58 32-byte values used as read-only keys so the transaction can later be located via `getSignaturesForAddress` |
| `label` | optional | URL-encoded UTF-8 string identifying the request source (brand, store, person) |
| `message` | optional | URL-encoded UTF-8 string describing the transfer (item, order ID, note) |
| `memo` | optional | URL-encoded UTF-8 string placed in an SPL Memo instruction in the transaction |

The wallet builds the transaction locally, appending a `SystemProgram.Transfer` (for SOL) or a `TokenProgram` `Transfer`/`TransferChecked` (for SPL tokens) as the final instruction.<sup>[1][1]</sup>

### Transaction request (interactive)

A transaction-request URI wraps a single HTTPS link:<sup>[1][1]</sup>

```
solana:<link>
```

where `<link>` is a (conditionally URL-encoded) HTTPS URL. The wallet then performs a two-step HTTP exchange with that endpoint:<sup>[1][1]</sup>

1. **GET** → the application returns `{"label": "<string>", "icon": "<url>"}`, where `icon` is an SVG, PNG or WebP image, so the wallet can show who it is about to transact with.
2. **POST** with body `{"account": "<base58 pubkey>"}` (the user's chosen account) → the application returns `{"transaction": "<base64>", "message": "<optional string>"}`, a fully serialized Solana transaction.

For an unsigned transaction (empty signatures) the wallet overrides the `feePayer` and `recentBlockhash`; for a presigned (partially signed) transaction it verifies the existing signatures and rejects the request if they are invalid or if a non-account signer is required. The wallet signs only with the requested account.<sup>[1][1]</sup> This server round-trip lets a merchant return *any* transaction — not just a simple transfer — which is the key difference from the static transfer request.<sup>[1][1]</sup><sup>[3][3]</sup>

## Use cases

- **Merchant point-of-sale QR**: a store renders a `solana:` transfer-request as a [QR Code](https://docs.barcoder.ai/docs/standards/qr-code); the customer scans and pays in SOL or a stablecoin SPL token.<sup>[1][1]</sup><sup>[3][3]</sup>
- **Interactive checkout / mints**: transaction-request URIs let a backend compose arbitrary transactions (NFT mint, multi-instruction checkout, discounts) on demand.<sup>[1][1]</sup><sup>[3][3]</sup>
- **Transaction indexing**: the `reference` keys let a merchant detect that a specific invoice has been paid without putting identifying data on-chain in a readable field.<sup>[1][1]</sup>

## Implementations

- **anza-xyz/solana-pay** — the reference specification and JS/Rust libraries; Rust-majority, ~1.7k stars, active 2026.<sup>[2][2]</sup>
- **Wallets**: the spec cites early support in Phantom, FTX and Slope; Solana Pay is widely supported across the Solana wallet ecosystem.<sup>[1][1]</sup>

## Comparison

- **Solana Pay vs static URIs**: the transfer request is a static, self-contained URI (like [BIP-21](https://docs.barcoder.ai/docs/standards/bip-21)), but the transaction request adds an interactive server flow with no analogue in [BIP-21](https://docs.barcoder.ai/docs/standards/bip-21) — the wallet fetches a server-built transaction rather than constructing it from URI fields alone.<sup>[1][1]</sup><sup>[2][2]</sup>
- **Solana Pay vs [BIP-21](https://docs.barcoder.ai/docs/standards/bip-21) / EIP-681**: Solana Pay borrows the `scheme:recipient?params` shape from [BIP-21](https://docs.barcoder.ai/docs/standards/bip-21) and EIP-681 but targets Solana's account/SPL-token model and adds the `reference` indexing keys and the transaction-request callback.<sup>[1][1]</sup>
- **vs Lightning request formats**: where [BOLT11](https://docs.barcoder.ai/docs/standards/bolt11) / LNURL encode a single Lightning invoice or a callback to obtain one, Solana Pay encodes either a self-contained transfer or a callback that returns a complete signed-or-unsigned Solana transaction.<sup>[1][1]</sup>

## Status

Solana Pay is an active, openly specified standard with wallet support across the Solana ecosystem and an actively maintained reference repository (2026).<sup>[1][1]</sup><sup>[2][2]</sup>

## Sources

[1]: https://docs.solanapay.com/spec
[2]: https://github.com/anza-xyz/solana-pay
[3]: https://docs.solanapay.com/core/overview

[1] [Solana Pay Specification](https://docs.solanapay.com/spec) — Solana Pay Docs, 2026
[2] [anza-xyz/solana-pay](https://github.com/anza-xyz/solana-pay) — GitHub, 2026
[3] [Solana Pay Overview](https://docs.solanapay.com/core/overview) — Solana Pay Docs, 2026

## Deployments

_No country reports mention this standard by name._

## Regions / aggregations not mapped to a single country

- Universal
