Tài liệu SolanaThông số kỹ thuật

Đặc tả Solana Pay v1

Tóm tắt

Một giao thức tiêu chuẩn để mã hóa các yêu cầu giao dịch Solana trong URL nhằm hỗ trợ thanh toán và các trường hợp sử dụng khác.

Tiêu chuẩn này lấy cảm hứng từ BIP 21EIP 681.

Động lực

Một giao thức URL tiêu chuẩn để yêu cầu chuyển SOL gốc, chuyển SPL Token và các giao dịch Solana cho phép trải nghiệm người dùng tốt hơn trên các ứng dụng và ví trong hệ sinh thái Solana.

Các URL này có thể được mã hóa trong mã QR hoặc thẻ NFC, hoặc được gửi giữa người dùng và ứng dụng để yêu cầu thanh toán và soạn thảo giao dịch.

Các ứng dụng nên đảm bảo rằng một giao dịch đã được xác nhận và hợp lệ trước khi phát hành hàng hóa hoặc dịch vụ đang bán, hoặc cấp quyền truy cập vào các đối tượng hoặc sự kiện.

Các ví di động nên đăng ký xử lý lược đồ URL để cung cấp trải nghiệm liền mạch nhưng an toàn khi gặp các URL Solana Pay trong môi trường.

Bằng cách tiêu chuẩn hóa một phương pháp đơn giản để giải quyết các vấn đề này, chúng tôi đảm bảo khả năng tương thích cơ bản của các ứng dụng và ví để các nhà phát triển có thể tập trung vào các lớp trừu tượng cấp cao hơn.

Đặc tả: Yêu cầu Chuyển khoản

URL yêu cầu chuyển khoản Solana Pay mô tả một yêu cầu không tương tác để chuyển SOL hoặc SPL Token.

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

Yêu cầu này không tương tác vì các tham số trong URL được ví sử dụng để soạn thảo trực tiếp một giao dịch.

Người nhận

Một trường recipient duy nhất được yêu cầu làm pathname. Giá trị phải là khóa công khai được mã hóa base58 của một tài khoản SOL gốc. Không được sử dụng associated token account.

Thay vào đó, để yêu cầu chuyển SPL Token, trường spl-token phải được sử dụng để chỉ định một SPL Token mint, từ đó địa chỉ token liên kết của người nhận phải được suy ra.

Số lượng

Một trường amount duy nhất được phép làm tham số truy vấn tùy chọn. Giá trị phải là một số nguyên không âm hoặc số thập phân tính theo đơn vị "người dùng". Đối với SOL, đó là SOL chứ không phải lamport. Đối với token, hãy sử dụng uiAmountString chứ không phải amount.

0 là một giá trị hợp lệ. Nếu giá trị là số thập phân nhỏ hơn 1, nó phải có 0 đứng trước .. Ký hiệu khoa học bị cấm.

Nếu không cung cấp giá trị, ví phải nhắc người dùng nhập số lượng. Nếu số chữ số thập phân vượt quá mức được hỗ trợ cho SOL (9) hoặc SPL Token (tùy theo mint cụ thể), ví phải từ chối URL vì không đúng định dạng.

SPL Token

Một trường spl-token duy nhất được phép làm tham số truy vấn tùy chọn. Giá trị phải là pubkey được mã hóa base58 của một mint account SPL Token.

Nếu trường này được cung cấp, quy ước Associated Token Account phải được sử dụng, và ví phải bao gồm một lệnh TokenProgram.Transfer hoặc TokenProgram.TransferChecked làm lệnh cuối cùng của giao dịch.

Nếu trường này không được cung cấp, URL mô tả việc chuyển SOL gốc, và ví phải bao gồm một lệnh SystemProgram.Transfer làm lệnh cuối cùng của giao dịch.

Ví phải suy ra địa chỉ ATA từ các trường recipientspl-token. Việc chuyển đến các token account phụ không được hỗ trợ.

Tham chiếu

Nhiều trường reference được phép làm tham số truy vấn tùy chọn. Các giá trị phải là mảng 32 byte được mã hóa base58. Những giá trị này có thể là hoặc không phải là pubkey, nằm trên hoặc ngoài đường cong, và có thể tương ứng hoặc không tương ứng với các tài khoản trên Solana.

Nếu các giá trị được cung cấp, ví phải bao gồm chúng theo thứ tự đã cho dưới dạng khóa chỉ đọc, không ký vào lệnh SystemProgram.Transfer hoặc TokenProgram.Transfer/TokenProgram.TransferChecked trong giao dịch thanh toán. Các giá trị có thể là duy nhất hoặc không duy nhất đối với yêu cầu thanh toán, và có thể tương ứng hoặc không tương ứng với một tài khoản trên Solana.

Vì các validator Solana lập chỉ mục giao dịch theo các khóa tài khoản này, các giá trị reference có thể được sử dụng làm ID khách hàng (ID có thể sử dụng trước khi biết giao dịch thanh toán cuối cùng). Phương thức RPC getSignaturesForAddress có thể được sử dụng để xác định vị trí giao dịch theo cách này.

Nhãn

Một trường label duy nhất được cho phép làm tham số truy vấn tùy chọn. Giá trị phải là một chuỗi UTF-8 được mã hóa URL mô tả nguồn gốc của yêu cầu chuyển khoản.

Ví dụ, đây có thể là tên của một thương hiệu, cửa hàng, ứng dụng hoặc người đưa ra yêu cầu. Ví nên giải mã URL giá trị và hiển thị giá trị đã giải mã cho người dùng.

Tin nhắn

Một trường message duy nhất được cho phép làm tham số truy vấn tùy chọn. Giá trị phải là một chuỗi UTF-8 được mã hóa URL mô tả bản chất của yêu cầu chuyển khoản.

Ví dụ, đây có thể là tên của một mặt hàng đang được mua, ID đơn hàng hoặc một lời cảm ơn. Ví nên giải mã URL giá trị và hiển thị giá trị đã giải mã cho người dùng.

Ghi chú

Một trường memo duy nhất được cho phép làm tham số truy vấn tùy chọn. Giá trị phải là một chuỗi UTF-8 được mã hóa URL mà phải được bao gồm trong lệnh SPL Memo trong giao dịch thanh toán.

Ví phải giải mã URL giá trị và nên hiển thị giá trị đã giải mã cho người dùng. Ghi chú sẽ được ghi lại bởi các validator và không nên bao gồm thông tin riêng tư hoặc nhạy cảm.

Nếu trường này được cung cấp, ví phải bao gồm một lệnh MemoProgram làm lệnh thứ hai từ cuối của giao dịch, ngay trước lệnh chuyển SOL hoặc SPL Token, để tránh sự nhầm lẫn với các lệnh khác trong giao dịch.

Ví dụ

URL mô tả yêu cầu chuyển khoản 1 SOL

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

URL mô tả yêu cầu chuyển khoản 0.01 USDC

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

URL mô tả yêu cầu chuyển khoản SOL (người dùng được yêu cầu nhập số tiền)

solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?label=Michael

Đặc tả: Yêu cầu Giao dịch

URL yêu cầu giao dịch Solana Pay mô tả một yêu cầu tương tác cho bất kỳ giao dịch Solana nào.

solana:<link>

Yêu cầu này mang tính tương tác vì các tham số trong URL được ví sử dụng để thực hiện yêu cầu HTTP nhằm soạn thảo giao dịch.

Liên kết

Một trường link duy nhất là bắt buộc làm đường dẫn. Giá trị phải là một URL HTTPS tuyệt đối được mã hóa URL có điều kiện.

Nếu URL chứa các tham số truy vấn, nó phải được mã hóa URL. Các tham số truy vấn giao thức có thể được thêm vào đặc tả này. Việc mã hóa URL giá trị này ngăn ngừa xung đột với các tham số giao thức.

Nếu URL không chứa các tham số truy vấn, nó không nên được mã hóa URL. Điều này tạo ra URL ngắn hơn và mã QR ít dày đặc hơn.

Trong cả hai trường hợp, ví phải giải mã URL giá trị này. Việc này không có hiệu lực nếu giá trị chưa được mã hóa URL. Nếu giá trị đã giải mã không phải là URL HTTPS tuyệt đối, ví phải từ chối nó vì sai định dạng.

Yêu cầu GET

Ví nên thực hiện yêu cầu JSON HTTP GET đến URL. Yêu cầu này không nên xác định ví hoặc người dùng.

Ví nên thực hiện yêu cầu với Accept-Encoding header, và ứng dụng nên phản hồi với Content-Encoding header để nén HTTP.

Ví phải hiển thị tên miền của URL trong khi yêu cầu đang được thực hiện.

Phản hồi GET

Ví phải xử lý các phản hồi HTTP lỗi phía client, lỗi phía server, và chuyển hướng. Ứng dụng phải phản hồi với các mã này, hoặc với phản hồi JSON HTTP OK có body như sau:

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

Giá trị <label> phải là chuỗi UTF-8 mô tả nguồn gốc của yêu cầu giao dịch. Ví dụ, đây có thể là tên thương hiệu, cửa hàng, ứng dụng, hoặc người thực hiện yêu cầu.

Giá trị <icon> phải là URL HTTP hoặc HTTPS tuyệt đối của hình ảnh biểu tượng. Tệp phải là ảnh SVG, PNG, hoặc WebP, nếu không ví phải từ chối nó là không hợp lệ.

Ví không nên lưu cache phản hồi trừ khi được chỉ định bởi HTTP caching trong response headers.

Ví nên hiển thị nhãn và render hình ảnh biểu tượng cho người dùng.

Yêu cầu POST

Ví phải thực hiện yêu cầu JSON HTTP POST đến URL với body như sau:

{ "account": "<account>" }

Giá trị <account> phải là public key được mã hóa base58 của tài khoản có thể ký giao dịch.

Ví nên thực hiện yêu cầu với Accept-Encoding header, và ứng dụng nên phản hồi với Content-Encoding header để nén HTTP.

Ví nên hiển thị tên miền của URL trong khi yêu cầu đang được thực hiện. Nếu một yêu cầu GET đã được thực hiện, ví cũng nên hiển thị nhãn và render hình ảnh biểu tượng từ phản hồi.

Phản hồi POST

Ví phải xử lý các phản hồi HTTP lỗi phía client, lỗi phía server, và chuyển hướng. Ứng dụng phải phản hồi với các mã này, hoặc với phản hồi JSON HTTP OK có body như sau:

{ "transaction": "<transaction>" }

Giá trị <transaction> phải là một giao dịch được tuần tự hóa được mã hóa base64. Ví phải giải mã base64 giao dịch và giải tuần tự hóa nó.

Ứng dụng có thể phản hồi với một giao dịch đã được ký một phần hoặc hoàn toàn. Ví phải xác thực giao dịch như không đáng tin cậy.

Chữ Ký Trống

Nếu signatures của giao dịch trống:

  • Ứng dụng nên đặt feePayer thành account trong yêu cầu, hoặc giá trị bằng không (new PublicKey(0) hoặc new PublicKey("11111111111111111111111111111111")).
  • Ứng dụng nên đặt recentBlockhash thành blockhash mới nhất, hoặc giá trị bằng không (new PublicKey(0).toBase58() hoặc "11111111111111111111111111111111").
  • Ví phải bỏ qua feePayer trong giao dịch và đặt feePayer thành account trong yêu cầu.
  • Ví phải bỏ qua recentBlockhash trong giao dịch và đặt recentBlockhash thành blockhash mới nhất.

Chữ Ký Không Trống

Nếu signatures của giao dịch không trống:

Ví chỉ được ký giao dịch với account trong yêu cầu, và chỉ được làm như vậy nếu một chữ ký cho account trong yêu cầu được yêu cầu.

Nếu có bất kỳ chữ ký nào ngoài chữ ký cho account trong yêu cầu được yêu cầu, ví phải từ chối giao dịch vì độc hại.

Trường Thông Điệp Tùy Chọn

Ứng dụng cũng có thể bao gồm một trường message tùy chọn trong nội dung phản hồi:

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

Giá trị <message> phải là một chuỗi UTF-8 mô tả bản chất của phản hồi giao dịch.

Ví dụ, đây có thể là tên của một mặt hàng đang được mua, giảm giá được áp dụng cho giao dịch mua, hoặc một lời cảm ơn. Ví nên hiển thị giá trị này cho người dùng.

Ví và ứng dụng nên cho phép các trường bổ sung trong nội dung yêu cầu và nội dung phản hồi, có thể được thêm vào bởi các đặc tả trong tương lai.

Các Ví Dụ

URL mô tả một yêu cầu giao dịch

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

URL mô tả một yêu cầu giao dịch với các tham số truy vấn

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

Ví Dụ Yêu Cầu GET

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

Ví Dụ Phản Hồi GET

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"}

Ví Dụ Yêu Cầu POST

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"}

Ví Dụ Phản Hồi POST

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"}

Các Phần Mở Rộng

Các định dạng và trường bổ sung có thể được tích hợp vào đặc tả này để kích hoạt các trường hợp sử dụng mới trong khi đảm bảo tương thích với các ứng dụng và ví.

Vui lòng mở một Github issue để đề xuất các thay đổi cho đặc tả nhằm thu thập phản hồi từ các nhà phát triển ứng dụng và ví.

Một ví dụ thực tế về đề xuất như vậy.

Xem Thêm

Is this page helpful?

Quản lý bởi

© 2026 Solana Foundation.
Đã đăng ký bản quyền.
Kết nối