Peer-to-Peer Payments
Sometimes the payment isn’t going to you, it’s going between your users. P2P payments let one user send crypto to another while your site automatically collects a fee on each transaction. Under the hood, this produces a single Solana transaction with two transfers: one to the recipient and one to your treasury wallet. The fee is deducted from the payment amount, so the sender pays exactly what they expect.
- Go to the Tribe dashboard
- Open your site’s Settings → Payments
- Enter your treasury wallet address, the wallet where fees will be collected
- Toggle on P2P payments
- Set your fee rate as a percentage (e.g. 1 for 1%)
- Make sure you have at least one accepted token configured
How fees work
Section titled “How fees work”The fee is calculated as amount × feeRate and rounded up to the token’s decimal precision. The recipient gets the remainder.
For example, with a 1% fee rate on a 2.5 SOL payment:
- Fee to treasury: 2.5 × 0.01 = 0.025 SOL
- Recipient receives: 2.5 - 0.025 = 2.475 SOL
The sender’s wallet is debited 2.5 SOL total. Both transfers happen atomically in a single transaction, so there’s no risk of one going through without the other.
Basic usage
Section titled “Basic usage”Payment URL
Section titled “Payment URL”import { Tribe } from "@tribecloud/sdk";
const payment = await tribe.getPaymentUrl({ mint: "SOL", amount: "2.5", recipientWallet: "RecipientWalletAddressHere", memo: "Payment for design work",});// payment.paymentUrl — solana: URL for QR codes or deep links// payment.id — use to verify payment status// payment.expiresAt — expires after 10 minutesWallet payment
Section titled “Wallet payment”For users with a browser wallet, sendViaWallet() handles the entire flow in one call:
const result = await tribe.sendViaWallet({ mint: "SOL", amount: "2.5", recipientWallet: "RecipientWalletAddressHere", memo: "Payment for design work",});// result.status — "confirmed" | "pending" | "expired"// result.txSignature — Solana transaction signatureComplete example
Section titled “Complete example”function SendPayment() { const [recipient, setRecipient] = useState(""); const [amount, setAmount] = useState(""); const [status, setStatus] = useState("idle");
const send = async () => { setStatus("loading"); try { const result = await tribe.sendViaWallet({ mint: "SOL", amount, recipientWallet: recipient, }); setStatus(result.status === "confirmed" ? "confirmed" : "error"); } catch (err) { console.error(err); setStatus("error"); } };
return ( <div> <input placeholder="Recipient wallet address" value={recipient} onChange={(e) => setRecipient(e.target.value)} /> <input type="number" placeholder="Amount" value={amount} onChange={(e) => setAmount(e.target.value)} /> <button onClick={send} disabled={status === "loading"}> {status === "loading" ? "Sending..." : status === "confirmed" ? "Sent!" : `Send ${amount || "0"} SOL`} </button> </div> );}<input id="recipient" placeholder="Recipient wallet address" /><input id="amount" type="number" placeholder="Amount" /><button id="send-btn">Send SOL</button>
<script src="https://api.tribe.utopian.build/sdk.js?site=YOUR_SITE_ID" defer></script><script defer> document.getElementById("send-btn").addEventListener("click", async () => { const recipient = document.getElementById("recipient").value; const amount = document.getElementById("amount").value; try { const result = await Tribe.sendViaWallet({ mint: "SOL", amount, recipientWallet: recipient, }); if (result.status === "confirmed") { alert("Payment confirmed! Tx: " + result.txSignature); } } catch (err) { alert("Payment failed: " + err.message); } });</script>QR code payments
Section titled “QR code payments”P2P works with QR codes too. Just add recipientWallet to the options:
const payment = await tribe.renderPaymentQrCode({ mint: "SOL", amount: "1.0", recipientWallet: "RecipientWalletAddressHere", container: document.getElementById("qr-container"),});
// Poll for confirmationconst interval = setInterval(async () => { const result = await tribe.verifyPayment(payment.id); if (result.status !== "pending") { clearInterval(interval); console.log("Payment", result.status); }}, 3000);Check P2P configuration
Section titled “Check P2P configuration”Before showing P2P payment options, confirm the site has P2P enabled:
const config = await tribe.getPaymentConfig();if (config.p2pPaymentsEnabled) { // Show P2P payment UI}