Skip to content
Blog

QR Code Payments

QR code payments shine when the user’s wallet lives on a different device, typically a phone. Generate a Solana Pay QR code, let them scan it with any compatible wallet app, and the transaction goes through. This approach feels especially natural for in-person scenarios or when someone is browsing on a laptop but paying from their mobile wallet.

This renders a QR code with the Tribe logo directly into a container element you specify:

import { Tribe } from "@tribecloud/sdk";
const payment = await tribe.renderPaymentQrCode({
mint: "SOL",
amount: "0.5",
memo: "Order #123",
container: document.getElementById("qr-container"),
width: 300, // optional, default 300
height: 300, // optional, default 300
});

If you’d rather use your own QR library or do something custom with the URL, grab it directly:

const payment = await tribe.getPaymentUrl({
mint: "SOL",
amount: "0.5",
memo: "Order #123",
});
// payment.paymentUrl — a solana: URL to encode as a QR code
// payment.id — use to check payment status
// payment.expiresAt — payment expires after 10 minutes

Once the QR code is on screen, poll verifyPayment() to find out when the user actually pays:

const status = await tribe.verifyPayment(payment.id);
// status.status — "pending" | "confirmed" | "expired"
// status.txSignature — Solana transaction signature (when confirmed)
function PayWithQR({ mint, amount, memo }) {
const containerRef = useRef(null);
const [payment, setPayment] = useState(null);
const [status, setStatus] = useState("pending");
useEffect(() => {
if (!containerRef.current) return;
tribe
.renderPaymentQrCode({ mint, amount, memo, container: containerRef.current })
.then(setPayment);
}, [mint, amount, memo]);
// Poll for confirmation
useEffect(() => {
if (!payment || status !== "pending") return;
const interval = setInterval(async () => {
const result = await tribe.verifyPayment(payment.id);
if (result.status !== "pending") {
setStatus(result.status);
clearInterval(interval);
}
}, 3000);
return () => clearInterval(interval);
}, [payment, status]);
if (status === "confirmed") return <p>Payment confirmed!</p>;
if (status === "expired") return <p>Payment expired. Please try again.</p>;
return (
<div>
<div ref={containerRef} />
<p>Scan with a Solana wallet to pay</p>
</div>
);
}