Solana Pay Specificatie v1

Samenvatting

Een standaardprotocol om Solana-transactieverzoeken te coderen binnen URL's om betalingen en andere gebruikssituaties mogelijk te maken.

Deze standaard is geïnspireerd door BIP 21 en EIP 681.

Motivatie

Een standaard URL-protocol voor het aanvragen van native SOL-overdrachten, SPL Token-overdrachten en Solana-transacties zorgt voor een betere gebruikerservaring binnen apps en wallets in het Solana-ecosysteem.

Deze URL's kunnen worden gecodeerd in QR-codes of NFC-tags, of verzonden tussen gebruikers en applicaties om betaling aan te vragen en transacties samen te stellen.

Applicaties moeten ervoor zorgen dat een transactie is bevestigd en geldig is voordat ze goederen of diensten vrijgeven die worden verkocht, of toegang verlenen tot objecten of evenementen.

Mobiele wallets moeten zich registreren om het URL-schema af te handelen en zo een naadloze maar veilige ervaring te bieden wanneer Solana Pay URL's worden aangetroffen.

Door een eenvoudige aanpak voor het oplossen van deze problemen te standaardiseren, waarborgen we basiscompatibiliteit van applicaties en wallets zodat ontwikkelaars zich kunnen richten op abstracties op een hoger niveau.

Specificatie: Overdrachtverzoek

Een Solana Pay-overdrachtverzoek-URL beschrijft een niet-interactief verzoek voor een SOL- of SPL Token-overdracht.

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

Het verzoek is niet-interactief omdat de parameters in de URL door een wallet worden gebruikt om direct een transactie samen te stellen.

Ontvanger

Een enkel recipient-veld is verplicht als het pathname. De waarde moet de base58-gecodeerde pubkey zijn van een native SOL-account. Associated token accounts mogen niet worden gebruikt.

Om in plaats daarvan een SPL Token-overdracht aan te vragen, moet het spl-token-veld worden gebruikt om een SPL Token mint te specificeren, waarvan het associated token account-adres van de ontvanger moet worden afgeleid.

Bedrag

Een enkel amount veld is toegestaan als optionele queryparameter. De waarde moet een niet-negatief geheel getal of decimaal getal zijn in "gebruikers"-eenheden. Voor SOL, betekent dat SOL en niet lamports. Voor tokens, gebruik uiAmountString en niet amount.

0 is een geldige waarde. Als de waarde een decimaal getal is kleiner dan 1, moet het een voorloopnul 0 hebben vóór de .. Wetenschappelijke notatie is niet toegestaan.

Als er geen waarde wordt opgegeven, moet de wallet de gebruiker om het bedrag vragen. Als het aantal decimalen groter is dan wat ondersteund wordt voor SOL (9) of het SPL Token (mint-specifiek), moet de wallet de URL als onjuist geformatteerd afwijzen.

SPL Token

Een enkel spl-token veld is toegestaan als optionele queryparameter. De waarde moet de base58-gecodeerde publieke sleutel zijn van een SPL Token mint account.

Als het veld is opgegeven, moet de Associated Token Account conventie worden gebruikt, en moet de wallet een TokenProgram.Transfer of TokenProgram.TransferChecked instructie opnemen als laatste instructie van de transactie.

Als het veld niet is opgegeven, beschrijft de URL een native SOL-overdracht, en moet de wallet in plaats daarvan een SystemProgram.Transfer instructie opnemen als laatste instructie van de transactie.

De wallet moet het ATA-adres afleiden uit de recipient en spl-token velden. Overdrachten naar aanvullende token accounts worden niet ondersteund.

Referentie

Meerdere reference velden zijn toegestaan als optionele queryparameters. De waarden moeten base58-gecodeerde 32-byte arrays zijn. Deze kunnen al dan niet publieke sleutels zijn, op of buiten de curve, en kunnen al dan niet overeenkomen met accounts op Solana.

Als de waarden worden verstrekt, moet de wallet deze in de opgegeven volgorde opnemen als alleen-lezen, niet-ondertekende sleutels in de SystemProgram.Transfer of TokenProgram.Transfer/TokenProgram.TransferChecked instructie in de betalingstransactie. De waarden kunnen al dan niet uniek zijn voor het betalingsverzoek en kunnen al dan niet overeenkomen met een account op Solana.

Omdat Solana-validators transacties indexeren op deze accountsleutels, kunnen reference waarden worden gebruikt als client-ID's (ID's die bruikbaar zijn voordat de uiteindelijke betalingstransactie bekend is). De getSignaturesForAddress RPC-methode kan worden gebruikt om transacties op deze manier te lokaliseren.

Label

Een enkel label veld is toegestaan als optionele queryparameter. De waarde moet een URL-gecodeerde UTF-8 string zijn die de bron van het overdrachtverzoek beschrijft.

Dit kan bijvoorbeeld de naam zijn van een merk, winkel, applicatie of persoon die het verzoek doet. De wallet moet de waarde URL-decoderen en de gedecodeerde waarde aan de gebruiker tonen.

Bericht

Een enkel message veld is toegestaan als optionele queryparameter. De waarde moet een URL-gecodeerde UTF-8 string zijn die de aard van het overdrachtverzoek beschrijft.

Dit kan bijvoorbeeld de naam zijn van een artikel dat wordt gekocht, een order-ID of een bedankje. De wallet moet de waarde URL-decoderen en de gedecodeerde waarde aan de gebruiker tonen.

Memo

Een enkel memo veld is toegestaan als optionele queryparameter. De waarde moet een URL-gecodeerde UTF-8 string zijn die moet worden opgenomen in een SPL Memo instructie in de betalingstransactie.

De wallet moet de waarde URL-decoderen en zou de gedecodeerde waarde aan de gebruiker moeten tonen. De memo wordt geregistreerd door validators en mag geen privé- of gevoelige informatie bevatten.

Als het veld wordt verstrekt, moet de portemonnee een MemoProgram instructie opnemen als de op één na laatste instructie van de transactie, direct vóór de SOL- of SPL Token-overdracht instructie, om onduidelijkheid met andere instructies in de transactie te voorkomen.

Voorbeelden

URL die een overdrachtverzoek voor 1 SOL beschrijft

solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?amount=1&label=Michael&message=Thanks%20for%20all%20the%20fish&memo=OrderId12345

URL die een overdrachtverzoek voor 0,01 USDC beschrijft

solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?amount=0.01&spl-token=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v

URL die een overdrachtverzoek voor SOL beschrijft (gebruiker wordt gevraagd om bedrag)

solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?label=Michael

Specificatie: Transactieverzoek

Een Solana Pay transactieverzoek-URL beschrijft een interactief verzoek voor elke Solana-transactie.

solana:<link>

Het verzoek is interactief omdat de parameters in de URL door een portemonnee worden gebruikt om een HTTP-verzoek te doen voor het samenstellen van een transactie.

Een enkel link veld is vereist als het pad. De waarde moet een voorwaardelijk URL-gecodeerde absolute HTTPS-URL zijn.

Als de URL queryparameters bevat, moet deze URL-gecodeerd zijn. Protocolqueryparameters kunnen aan deze specificatie worden toegevoegd. URL-codering van de waarde voorkomt conflicten met protocolparameters.

Als de URL geen queryparameters bevat, hoeft deze niet URL-gecodeerd te zijn. Dit levert een kortere URL en een minder dichte QR-code op.

In beide gevallen moet de portemonnee de waarde URL-decoderen. Dit heeft geen effect als de waarde niet URL-gecodeerd is. Als de gedecodeerde waarde geen absolute HTTPS-URL is, moet de portemonnee deze als onjuist gevormd afwijzen.

GET-verzoek

De portemonnee moet een HTTP GET JSON-verzoek naar de URL doen. Het verzoek mag de portemonnee of de gebruiker niet identificeren.

De portemonnee moet het verzoek doen met een Accept-Encoding header, en de applicatie moet reageren met een Content-Encoding header voor HTTP-compressie.

De wallet moet het domein van de URL weergeven terwijl het verzoek wordt gedaan.

GET Respons

De wallet moet HTTP client error, server error, en redirect responses afhandelen. De applicatie moet hiermee reageren, of met een HTTP OK JSON respons met een body van:

{ "label": "<label>", "icon": "<icon>" }

De <label> waarde moet een UTF-8 string zijn die de bron van het transactieverzoek beschrijft. Dit kan bijvoorbeeld de naam zijn van een merk, winkel, applicatie of persoon die het verzoek doet.

De <icon> waarde moet een absolute HTTP of HTTPS URL zijn van een pictogramafbeelding. Het bestand moet een SVG, PNG of WebP afbeelding zijn, of de wallet moet dit als onjuist geformatteerd afwijzen.

De wallet mag de respons niet cachen, behalve zoals geïnstrueerd door HTTP caching respons headers.

De wallet moet het label weergeven en de pictogramafbeelding aan de gebruiker tonen.

POST Verzoek

De wallet moet een HTTP POST JSON verzoek maken naar de URL met een body van:

{ "account": "<account>" }

De <account> waarde moet de base58-gecodeerde publieke sleutel zijn van een account dat de transactie mag ondertekenen.

De wallet moet het verzoek doen met een Accept-Encoding header, en de applicatie moet reageren met een Content-Encoding header voor HTTP compressie.

De wallet moet het domein van de URL weergeven terwijl het verzoek wordt gedaan. Als een GET verzoek is gedaan, moet de wallet ook het label weergeven en het pictogram uit de respons tonen.

POST Respons

De wallet moet HTTP client error, server error, en redirect responses afhandelen. De applicatie moet hiermee reageren, of met een HTTP OK JSON respons met een body van:

{ "transaction": "<transaction>" }

De <transaction> waarde moet een base64-gecodeerde geserialiseerde transactie zijn. De wallet moet de transactie base64-decoderen en deserialiseren.

De applicatie kan reageren met een gedeeltelijk of volledig ondertekende transactie. De wallet moet de transactie valideren als niet vertrouwd.

Lege handtekeningen

Als de transactie signatures leeg zijn:

  • De applicatie moet de feePayer instellen op de account in het verzoek, of de nulwaarde (new PublicKey(0) of new PublicKey("11111111111111111111111111111111")).
  • De applicatie moet de recentBlockhash instellen op de nieuwste blockhash, of de nulwaarde (new PublicKey(0).toBase58() of "11111111111111111111111111111111").
  • De wallet moet de feePayer in de transactie negeren en de feePayer instellen op de account in het verzoek.
  • De wallet moet de recentBlockhash in de transactie negeren en de recentBlockhash instellen op de nieuwste blockhash.

Niet-lege handtekeningen

Als de transactie signatures niet leeg zijn:

De wallet mag de transactie alleen ondertekenen met de account in het verzoek, en mag dit alleen doen als een handtekening voor de account in het verzoek wordt verwacht.

Als een andere handtekening dan een handtekening voor de account in het verzoek wordt verwacht, moet de wallet de transactie afwijzen als kwaadaardig.

Optioneel Berichtveld

De applicatie kan ook een optioneel message veld opnemen in de responsbody:

{ "message": "<message>", "transaction": "<transaction>" }

De <message> waarde moet een UTF-8 string zijn die de aard van het transactierespons beschrijft.

Dit kan bijvoorbeeld de naam zijn van een artikel dat wordt gekocht, een korting die op de aankoop wordt toegepast, of een bedankbericht. De wallet moet de waarde aan de gebruiker tonen.

De wallet en applicatie moeten aanvullende velden in de request body en response body toestaan, die door toekomstige specificaties kunnen worden toegevoegd.

Voorbeelden

URL die een transactieverzoek beschrijft

solana:https://example.com/solana-pay

URL die een transactieverzoek met queryparameters beschrijft

solana:https%3A%2F%2Fexample.com%2Fsolana-pay%3Forder%3D12345

Voorbeeld van een GET-verzoek

GET /solana-pay?order=12345 HTTP/1.1
Host: example.com
Connection: close
Accept: application/json
Accept-Encoding: br, gzip, deflate

Voorbeeld van een GET-respons

HTTP/1.1 200 OK
Connection: close
Content-Type: application/json
Content-Length: 62
Content-Encoding: gzip
{"label":"Michael Vines","icon":"https://example.com/icon.svg"}

Voorbeeld van een POST-verzoek

POST /solana-pay?order=12345 HTTP/1.1
Host: example.com
Connection: close
Accept: application/json
Accept-Encoding: br, gzip, deflate
Content-Type: application/json
Content-Length: 57
{"account":"mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN"}

Voorbeeld van een POST-respons

HTTP/1.1 200 OK
Connection: close
Content-Type: application/json
Content-Length: 298
Content-Encoding: gzip
{"message":"Thanks for all the fish","transaction":"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAECC4JMKqNplIXybGb/GhK1ofdVWeuEjXnQor7gi0Y2hMcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQECAAAMAgAAAAAAAAAAAAAA"}

Uitbreidingen

Aanvullende formats en velden kunnen in deze specificatie worden opgenomen om nieuwe gebruiksscenario's mogelijk te maken, terwijl compatibiliteit met apps en wallets wordt gewaarborgd.

Open een Github-issue om wijzigingen in de specificatie voor te stellen en zo feedback van applicatie- en walletontwikkelaars te verzamelen.

Een concreet voorbeeld van zo'n voorstel.

Zie ook

Is this page helpful?

Beheerd door

© 2026 Solana Foundation.
Alle rechten voorbehouden.
Blijf Verbonden