Integration Examples
How to embed components in React, Vue, vanilla JS, and other frameworks.
Quick Integration
<!DOCTYPE html>
<html>
<head>
<script src="https://sdk.embed.visa.com/acceptance/v1"></script>
</head>
<body>
<div id="transactions" style="min-height: 600px;"></div>
<script>
VisaAcceptance.init({
auth: { type: 'api-key', apiKey: 'YOUR_API_KEY' },
locale: 'en-US',
theme: { preset: 'anet', mode: 'light' },
});
VisaAcceptance.render('transactions', '#transactions');
</script>
</body>
</html>import { useEffect, useRef } from 'react';
export function EmbeddedTransactions({ apiKey }: { apiKey: string }) {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!ref.current || typeof window.VisaAcceptance === 'undefined') return;
VisaAcceptance.init({
auth: { type: 'api-key', apiKey },
theme: { preset: 'anet' },
});
const instance = VisaAcceptance.render('transactions', ref.current);
return () => instance.destroy();
}, [apiKey]);
return <div ref={ref} className="min-h-[600px]" />;
}<template>
<div ref="container" style="min-height: 600px" />
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
const props = defineProps({ apiKey: String });
const container = ref(null);
let instance = null;
onMounted(() => {
if (!window.VisaAcceptance) return;
VisaAcceptance.init({
auth: { type: 'api-key', apiKey: props.apiKey },
});
instance = VisaAcceptance.render('transactions', container.value);
});
onUnmounted(() => {
instance?.destroy();
});
</script>'use client';
import { useEffect, useRef } from 'react';
import Script from 'next/script';
export default function TransactionsPage() {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!ref.current || typeof window.VisaAcceptance === 'undefined') return;
VisaAcceptance.init({
auth: {
type: 'oauth',
getToken: () => fetch('/api/embed-token').then(r => r.json()).then(d => d.token),
},
});
const instance = VisaAcceptance.render('transactions', ref.current);
return () => instance.destroy();
}, []);
return (
<>
<Script
src="https://sdk.embed.visa.com/acceptance/v1"
strategy="beforeInteractive"
/>
<div ref={ref} className="min-h-[600px]" />
</>
);
}Best Practices
1. Initialize Once
Call init() once at app startup, not per component mount:
// app.ts — run once
VisaAcceptance.init({ auth: myAuth, theme: myTheme });
// components.ts — render as needed
VisaAcceptance.render('transactions', '#t');
VisaAcceptance.render('invoices', '#i');2. Always Destroy on Unmount
Leaking instances causes memory issues and duplicate event listeners:
// React
useEffect(() => {
const instance = VisaAcceptance.render('payment', ref.current);
return () => instance.destroy(); // cleanup
}, []);3. Handle Loading States
The component takes time to load. Show a skeleton while waiting:
VisaAcceptance.init({
onEvent: (type) => {
if (type === 'component_ready') hideSpinner();
if (type === 'component_error') showError();
},
});4. Use OAuth for Production
Session auth is deprecated for cross-origin contexts. Use OAuth with a backend token exchange:
VisaAcceptance.init({
auth: {
type: 'oauth',
getToken: async () => {
const res = await fetch('/api/embed-token', { credentials: 'include' });
const { token } = await res.json();
return token;
},
},
});Never expose raw API keys or secrets in client-side code for production. Use OAuth with a backend token exchange endpoint.