React Hooks
The monterrey.app React SDK provides hooks for building custom payment UIs with full control over the user experience.
usePayment
The primary hook for creating and managing payments.
import { usePayment } from "@monterrey/react";
function CheckoutForm() {
const {
payment,
isLoading,
error,
createPayment,
cancelPayment,
} = usePayment();
const handleSubmit = async () => {
const newPayment = await createPayment({
merchantRef: "order_12345",
amount: "1000000",
currency: "USDC",
chain: "polygon",
});
console.log("Payment address:", newPayment.address);
};
if (isLoading) return <div>Creating payment...</div>;
if (error) return <div>Error: {error.message}</div>;
if (payment) {
return (
<div>
<p>Send {payment.amount} {payment.currency} to:</p>
<code>{payment.address}</code>
<p>Status: {payment.status}</p>
</div>
);
}
return (
<button onClick={handleSubmit}>
Create Payment
</button>
);
}Return Values
| Property | Type | Description |
|---|---|---|
payment | Payment | null | Current payment object |
isLoading | boolean | True while creating payment |
error | Error | null | Error if payment creation failed |
createPayment | function | Create a new payment |
cancelPayment | function | Cancel the current payment |
usePaymentStatus
Subscribe to real-time payment status updates via WebSocket.
import { usePaymentStatus } from "@monterrey/react";
function PaymentWatcher({ paymentId }: { paymentId: string }) {
const { status, txHash, confirmedAt } = usePaymentStatus(paymentId);
useEffect(() => {
if (status === "confirmed") {
// Payment successful!
confetti();
router.push("/order/success");
}
}, [status]);
return (
<div>
<p>Status: {status}</p>
{status === "detecting" && (
<p>Transaction detected! Waiting for confirmations...</p>
)}
{status === "confirmed" && (
<p>Confirmed! Tx: {txHash}</p>
)}
</div>
);
}useQuote
Get real-time price quotes for currency conversions.
import { useQuote } from "@monterrey/react";
function PriceDisplay({ usdAmount }: { usdAmount: string }) {
const { quote, isLoading, refresh } = useQuote({
fromCurrency: "USD",
toCurrency: "ETH",
amount: usdAmount,
});
if (isLoading) return <span>Loading...</span>;
return (
<div>
<p>${usdAmount} USD = {quote?.toAmount} ETH</p>
<p>Rate: {quote?.rate}</p>
<p>Valid for: {quote?.validUntil}</p>
<button onClick={refresh}>Refresh Quote</button>
</div>
);
}useChains
Get available chains and their supported tokens.
import { useChains } from "@monterrey/react";
function ChainSelector({ onSelect }) {
const { chains, isLoading } = useChains();
if (isLoading) return <div>Loading chains...</div>;
return (
<select onChange={(e) => onSelect(e.target.value)}>
{chains.map((chain) => (
<option key={chain.id} value={chain.id}>
{chain.name}
</option>
))}
</select>
);
}useTokens
Get supported tokens for a specific chain.
import { useTokens } from "@monterrey/react";
function TokenSelector({ chain, onSelect }) {
const { tokens, isLoading } = useTokens(chain);
if (isLoading) return <div>Loading tokens...</div>;
return (
<select onChange={(e) => onSelect(e.target.value)}>
{tokens.map((token) => (
<option key={token.symbol} value={token.symbol}>
{token.name} ({token.symbol})
</option>
))}
</select>
);
}Custom Payment Flow Example
import {
usePayment,
usePaymentStatus,
useQuote,
useChains,
useTokens,
} from "@monterrey/react";
import { useState } from "react";
function CustomCheckout({ orderId, amount }) {
const [chain, setChain] = useState("polygon");
const [token, setToken] = useState("USDC");
const { chains } = useChains();
const { tokens } = useTokens(chain);
const { quote } = useQuote({
fromCurrency: "USD",
toCurrency: token,
amount,
});
const { payment, createPayment, isLoading } = usePayment();
const status = usePaymentStatus(payment?.id);
const handlePay = async () => {
await createPayment({
merchantRef: orderId,
amount: quote.toAmount,
currency: token,
chain,
});
};
if (status?.status === "confirmed") {
return <div>Payment successful!</div>;
}
if (payment) {
return (
<div>
<h3>Send {payment.amount} {payment.currency}</h3>
<p>To: {payment.address}</p>
<p>Status: {status?.status || "pending"}</p>
</div>
);
}
return (
<div>
<h3>Pay ${amount}</h3>
<label>
Chain:
<select value={chain} onChange={(e) => setChain(e.target.value)}>
{chains.map((c) => (
<option key={c.id} value={c.id}>{c.name}</option>
))}
</select>
</label>
<label>
Token:
<select value={token} onChange={(e) => setToken(e.target.value)}>
{tokens.map((t) => (
<option key={t.symbol} value={t.symbol}>{t.symbol}</option>
))}
</select>
</label>
{quote && (
<p>You'll pay: {quote.toAmount} {token}</p>
)}
<button onClick={handlePay} disabled={isLoading || !quote}>
{isLoading ? "Creating..." : "Pay Now"}
</button>
</div>
);
}Next Steps
- React Components - Pre-built UI components
- Webhooks - Server-side payment handling