Widget
Events
The widget tells your page what the customer is doing, so you can update your UI. It can't tell your server who has paid.
The events
The element dispatches these on itself. Each one's detail is shown below. In React, they arrive as the callbacks alongside.
| Event | React callback | When | detail |
|---|---|---|---|
| solloop:connected | onConnected | A wallet connected. | { address } |
| solloop:subscribing | onSubscribing | The customer approved, and the transaction is on its way. | {} |
| solloop:subscribed | onSubscribed | The subscription confirmed on-chain. | { signature, subscriptionPda } |
| solloop:error | onError | Something the customer needs to act on, such as too little USDC. | { code, message } |
| solloop:cancelled | onCancelled | The customer declined in their wallet. | {} |
Listening
const widget = document.querySelector('solloop-subscribe');
widget.addEventListener('solloop:connected', (event) => {
// The customer's wallet address. Keep it: your server checks it next.
wallet = event.detail.address;
});
widget.addEventListener('solloop:subscribed', async () => {
// A hint for your UI, not proof of payment. Ask your server to check.
await fetch('/api/solloop/claim', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ wallet }),
});
});<SolLoopSubscribe
plan="plan_8xK2m"
onConnected={({ address }) => setWallet(address)}
onSubscribed={() => claimAccess(wallet)}
onError={({ code, message }) => report(code, message)}
/>solloop:error's code is stable, so you can switch on it. The widget already shows the customer what went wrong, so you only need to handle it if you want to, for example to log it.
Don't grant access from an event
Events are a hint for your interface, not proof that anyone paid. Anyone can dispatch solloop:subscribed from the browser console. Grant access only after your server has checked, as Grant access shows.