This guide walks through implementing a donation page using TodaQ’s micropayment system integrated into a Vite + React + TypeScript application. The page loads payment elements via npm package and handles payment success events with React Router navigation. You can find the public repo here.
Reminder:
Install the TodaQ Micro Payment Package and other necessary dependencies:
npm install @todaqmicro/payment-js
npm install --save-dev events
npm install react-router-dom
Update your vite.config.ts with the following minimal configuration:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'events': 'events' // Alias events module for browser compatibility
}
}
})
Create a .env file in your project root with your payment configuration:
VITE_TODAQ_PUBLIC_SECRET=your_public_secret_here
VITE_TODAQ_HASH_5=your_commodity_hash_for_5_dollars
VITE_TODAQ_HASH_05=your_commodity_hash_for_50_cents
VITE_TODAQ_HASH_005=your_commodity_hash_for_5_cents
Security Note:
public_secret and commodity_hash values are public and will be exposed in your client-side bundle regardless of how you store themclient_secret - that should only be used in server-side codeReact useEffect hook - equivalent to DOM Content Loaded in TRIE site implementation guide:
import { loadMicroPayments } from "@todaqmicro/payment-js";
useEffect(() => {
const initialize = async () => {
try {
const micro = await loadMicroPayments(
import.meta.env.VITE_TODAQ_PUBLIC_SECRET, // Merchant ID | public secret
{
apiVersion: "main", // API version
}
);
setMicro(micro);
console.log("Payment engine initialized:", micro);
} catch (error) {
console.error("Failed to initialize payment engine:", error);
} finally {
setLoading(false);
}
};
initialize();
}, []);
Returns promise that resolves to a micro object containing the payment engine instance:
const micro = await loadMicroPayments(
import.meta.env.VITE_TODAQ_PUBLIC_SECRET, // Merchant ID | public secret
{
apiVersion: "main", // API version
}
);
Returns an elements object with methods to create different payment UI components:
const elements = micro.elements();
The script creates three payment elements with different amounts using environment variables.
Donation Element:
const element = await elements.create('payment', {
hash,
theme: 'light',
styles: {
colorPrimary: "#000000",
colorBackground: "#a39f96ff",
borderRadius: "1rem",
},
});
const container = document.getElementById(containerId);
if (container) element.mount(container);
To create multiple payment elements, dynamically generate unique container IDs using a hash like this::
const containerId = `payment-element-container-${hash}`;
The donation element then repeats for $0.50 and $0.05 - each uses different hashes from environment variables, and retains identical styling for consistency.
Global event listener for successful payments:
// Global event listener for successful payments
document.addEventListener('payment', async (event) => {
navigate(`/thank-you?amount=${amount}`); // Redirect to thank you page based on amount
});
The PaymentButton component receives props from Donation.tsx with environment variables and configuration:
<PaymentButton
amount={5.0}
hash={HASH_5}
engine={micro}
title="Grand Benefactor"
description="Depollution of the Shades of Pembereley"
buttonClass="is-success"
/>
Environment Variables: All payment configuration uses environment variables (this is based on preference as trie.site does not use them)
VITE_TODAQ_PUBLIC_SECRET - for merchant/user identificationVITE_TODAQ_HASH_* for unique payment identifiersInitialization Flow:
useEffectEvent Handling:
payment eventsStyling Consistency:
borderRadius: "1rem")PaymentButton component with props@todaqmicro/payment-js npm package (v0.3.3+)events package (dev dependency) for browser compatibilityThis implementation guide demonstrates the core concepts covered in the Getting Started guide, showing how to integrate multiple payment options with consistent styling and proper event handling in a modern Vite + React + TypeScript application.