Solana Pay Specificatie v1.1

Samenvatting

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

Er is een ruwe consensus bereikt over deze specificatie, en implementaties bestaan in Phantom, FTX en Slope.

Deze standaard is geïnspireerd op 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 worden 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 én 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 basis- compatibiliteit van applicaties en wallets, zodat ontwikkelaars zich kunnen richten op abstraties op hoger niveau.

Specificatie: Overdrachtsverzoek

Een Solana Pay overdrachtsverzoek-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 vereist als het pathname. De waarde moet de base58-gecodeerde pubkey zijn van een native SOL account. Associated token accounts mogen niet worden gebruikt.

In plaats daarvan moet het spl-token veld worden gebruikt om een SPL Token mint op te geven, waarvan het bijbehorende tokenadres 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 is 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 leidende 0 voor de . hebben. Wetenschappelijke notatie is niet toegestaan.

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

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 wordt opgegeven, moet de Associated Token Account conventie worden gebruikt, en moet de wallet een TokenProgram.Transfer of TokenProgram.TransferChecked instructie opnemen als de laatste instructie van de transactie.

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

De wallet moet het ATA-adres afleiden uit de recipient en spl-token velden. Overdrachten naar auxiliaire tokenaccounts 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 aangegeven volgorde opnemen als alleen-lezen, niet-ondertekende sleutels voor 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 basis van 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 op deze manier worden gebruikt om transacties te lokaliseren.

Label

Een enkel label veld is toegestaan als optionele queryparameter. De waarde moet een URL-gecodeerde UTF-8 tekenreeks zijn die de bron van het overdrachtsverzoek 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 tekenreeks zijn die de aard van het overdrachtsverzoek 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 tekenreeks 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 door validators vastgelegd en mag geen privé- of gevoelige informatie bevatten.

Als het veld is opgegeven, moet de wallet 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 dubbelzinnigheid 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 wallet worden gebruikt om een HTTP-verzoek te doen om een transactie samen te stellen.

Een enkel link veld is vereist als pathname. 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 wallet 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 wallet deze als onjuist geformatteerd afwijzen.

GET-verzoek

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

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.

GET Response

De wallet moet HTTP client errors, server errors en redirect responses afhandelen. De applicatie moet hiermee reageren, of met een HTTP OK JSON response 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 icon afbeelding. Het bestand moet een SVG, PNG of WebP afbeelding zijn, anders moet de wallet het als malformed afwijzen.

De wallet mag de response niet cachen, behalve zoals aangegeven door HTTP caching response headers.

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

POST Request

De wallet moet een HTTP POST JSON request doen 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 request is gedaan, moet de wallet ook het label weergeven en de icon afbeelding uit de response tonen.

POST Response

De wallet moet HTTP client errors, server errors en redirect responses afhandelen. De applicatie moet hiermee reageren, of met een HTTP OK JSON response 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 laatste 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 laatste blockhash.

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.

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

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

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

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

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

Voorbeeld

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
GET-verzoek
GET /solana-pay?order=12345 HTTP/1.1
Host: example.com
Connection: close
Accept: application/json
Accept-Encoding: br, gzip, deflate
GET-antwoord
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"}
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"}
POST-antwoord
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 use cases 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 wallet-ontwikkelaars te verkrijgen.

Een daadwerkelijk voorbeeld van zo'n voorstel.

Is this page helpful?

Beheerd door

© 2026 Solana Foundation.
Alle rechten voorbehouden.
Blijf Verbonden