Merchant Integration
This section describes how a merchant can integrate Solana Pay transfer requests into their payments flow. It shows how to create a payment request link, encode it into a QR code, find the transaction, and validate it.
This guide walks through an example of a QR code-based Point of Sale system that accepts payments via Solana Pay.
The complete example code can be found here.
Requirements
Before you can receive payments, you'll need to obtain a native SOL address. This doesn't cost anything, and you can use any wallet to get started.
If you want to receive USDC or another SPL token on Solana, you'll need to create a token account, which may require a small amount of SOL.
One way to do both is to use FTX / FTX.us, which will provide a native SOL deposit address and an associated USDC token account to receive payments.
1. Set up Solana Pay
Install the packages and import them in your code.
npm
npm install @solana/pay @solana/web3.js bignumber.js --save
yarn
yarn add @solana/pay @solana/web3.js bignumber.js
1.1 Import necessary modules
Import the modules used to work with Solana Pay.
import { Cluster, clusterApiUrl, Connection, PublicKey } from '@solana/web3.js';
import { encodeURL, createQR } from '@solana/pay';
import BigNumber from 'bignumber.js';
1.2 Establish a connection
When working on Solana, you will need to connect to the network. For our example, we will connect to devnet
.
Establish a connection to the devnet
network
async function main() {
// Variable to keep state of the payment status
let paymentStatus: string;
// Connecting to devnet for this example
console.log('1. ✅ Establish connection to the network');
const connection = new Connection(clusterApiUrl('devnet'), 'confirmed');
}
2. Create a payment request link
Solana Pay uses a standard URL scheme across wallets for native SOL and SPL Token payments. Several parameters are encoded within the link representing an intent to collect payment from a customer.
Create a payment request link with a recipient
, amount
, label
, message
, memo
and reference
.
Optional. SPL token transfer
For SPL Token transfers, use the spl-token
parameter. The spl-token
is the mint address of the SPL token.
See code snippet
3. Encode link into a QR code
Now that you've created a payment link, you need a way to show it to your customers.
Encode the link into a QR code.
3.1 Add the QR code to your payment page
The QR code needs to be visible on your payment page.
Add the QR code to an element on the payment page
Instructions on integrating with your framework of choice can be found here.
4. Show a payment status page
With the payment link set up and shown to the customer, you will need to ensure that the customer has paid for the item before shipping their order.
When a customer approves the payment request in their wallet, this transaction exists on-chain. You can use any references encoded into the payment link to find the exact transaction on-chain.
Use findReference
to find the on-chain transaction. Provide a reference
to this function that identifies the transaction associated with the order.
4.1 Retries
If a transaction with the given reference can't be found, the findReference
function will throw an error. There are a few reasons why this could be:
- Transaction is not yet confirmed
- Customer is yet to approve/complete the transaction
You can implement a polling strategy to query for the transaction periodically.
4.2 Validating the transaction
Once the findReference
function returns a signature, it confirms that a transaction that references the order has been recorded on-chain. But it doesn't guarantee that a valid transfer with the expected amount and recipient happened.
validateTransfer
allows you to validate that the transaction signature found matches the transaction that you expected.
Best practices
We recommend handling a customer session in a secure environment. Building a secure integration with Solana Pay requires a payment flow as follows:
- Customer goes to the payment page
- Merchant frontend (client) sends order information to the backend
- Merchant backend (server) generates a reference public key and stores it in a database with the expected amount for the shopping cart / pending purchase (unique to each customer's checkout session).
- Merchant backend redirects the user to the confirmation page with the generated reference public key.
- The confirmation page redirects to the merchant with the transaction signature.
- Merchant backend checks that the transaction is valid for the checkout session by validating the transaction with the reference and amount stored in step 3.
The steps outlined above prevents:
- A different transaction from being used to trick the merchant
- The frontend from being manipulated to show a confirmed transaction