Skip to main content
Create a payment request link or QR code using Solana Pay that users can scan to pay you. This recipe shows how to use the Phantom SDK to get your wallet address and create payment requests.
import { PhantomProvider, useSolana, useAccounts, usePhantom, darkTheme } from "@phantom/react-sdk";
import { AddressType } from "@phantom/browser-sdk";
import { encodeURL, createQR } from "@solana/pay";
import { PublicKey, Keypair } from "@solana/web3.js";
import { useEffect, useRef } from "react";
import BigNumber from "bignumber.js";

// USDC mint address
const USDC_MINT = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");

function App() {
  return (
    <PhantomProvider
      config={{
        providers: ["google", "apple", "injected"],
        appId: "your-app-id",
        addressTypes: [AddressType.solana],
        authOptions: {
          redirectUrl: "https://yourapp.com/auth/callback",
        },
      }}
      theme={darkTheme}
      appName="Your Store"
    >
      <PaymentRequest />
    </PhantomProvider>
  );
}

function PaymentRequest() {
  const { solana } = useSolana();
  const addresses = useAccounts();
  const { isConnected } = usePhantom();
  const qrRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!isConnected || !addresses?.[0]) return;

    // Get your wallet address from the SDK
    const recipient = new PublicKey(addresses[0].address);
    const amount = new BigNumber(10); // 10 USDC
    const reference = new PublicKey(Keypair.generate().publicKey); // Unique identifier
    const label = "Your Store";
    const message = "Thanks for your purchase!";

    // Create the payment URL
    const url = encodeURL({
      recipient,
      amount,
      splToken: USDC_MINT,
      reference,
      label,
      message,
    });

    // Generate QR code
    const qr = createQR(url, 300, "transparent");

    if (qrRef.current) {
      qrRef.current.innerHTML = "";
      qr.append(qrRef.current);
    }
  }, [isConnected, addresses]);

  if (!isConnected) {
    return <div>Please connect your wallet to generate a payment request</div>;
  }

  return (
    <div>
      <h2>Scan to pay 10 USDC</h2>
      <p>Your wallet: {addresses?.[0]?.address}</p>
      <div ref={qrRef} />
    </div>
  );
}

Install dependencies

npm install @solana/pay bignumber.js @phantom/react-sdk
# or
npm install @solana/pay bignumber.js @phantom/browser-sdk

Verify payment

After a user pays, verify the payment on your backend:
import { findReference, validateTransfer } from "@solana/pay";
import { Connection, PublicKey } from "@solana/web3.js";
import BigNumber from "bignumber.js";

const USDC_MINT = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");

async function verifyPayment(reference: PublicKey, recipient: PublicKey, amount: BigNumber) {
  const connection = new Connection("https://api.mainnet-beta.solana.com");

  // Find the transaction
  const signatureInfo = await findReference(connection, reference);

  // Validate it matches our request
  await validateTransfer(connection, signatureInfo.signature, {
    recipient,
    amount,
    splToken: USDC_MINT,
  });

  return signatureInfo.signature;
}