Checkout SDK
Framework integrations
Use the Checkout SDK in React, Vue, Angular, and vanilla JavaScript.
The Checkout SDK is framework-neutral. Use ZippyPay.create() for imperative control, or the <zippy-pay-checkout> web component for declarative integrations. Always set clientToken via JavaScript — never as an HTML attribute.
Vanilla JavaScript
main.js
javascriptimport { ZippyPay } from "@zippypay/checkout";
const checkout = ZippyPay.create({
environment: "production",
sessionId: "550e8400-e29b-41d4-a716-446655440000",
clientToken: "zps_REDACTED",
mode: "inline",
container: "#zippy-checkout",
onComplete: (session) => {
console.log("Paid:", session.transactionId);
},
onError: (error) => {
console.error(error.code, error.detail);
},
});
window.addEventListener("beforeunload", () => checkout.destroy());React
Use the web component with a ref, or call ZippyPay.create() imperatively inside useEffect.
Web component (Next.js App Router)
tsx"use client";
import { useEffect, useRef } from "react";
import "@zippypay/checkout";
import type { PaymentSession } from "@zippypay/checkout";
type Props = {
environment: "production" | "staging" | "development";
sessionId: string;
clientToken: string;
};
export function ZippyCheckout({ environment, sessionId, clientToken }: Props) {
const ref = useRef<HTMLElement & { clientToken: string }>(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
el.clientToken = clientToken;
const onComplete = (e: Event) => {
const session = (e as CustomEvent<PaymentSession>).detail;
console.log("Paid", session.transactionId);
};
el.addEventListener("zippy-complete", onComplete);
return () => el.removeEventListener("zippy-complete", onComplete);
}, [clientToken]);
return (
<zippy-pay-checkout
ref={ref}
environment={environment}
session-id={sessionId}
mode="inline"
theme-primary="#2563eb"
/>
);
}Imperative
tsx"use client";
import { useEffect, useRef } from "react";
import { ZippyPay } from "@zippypay/checkout";
type Props = {
sessionId: string;
clientToken: string;
};
export function ZippyCheckout({ sessionId, clientToken }: Props) {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!containerRef.current) return;
const checkout = ZippyPay.create({
environment: "production",
sessionId,
clientToken,
mode: "inline",
container: containerRef.current,
onComplete: (s) => console.log(s.transactionId),
});
return () => checkout.destroy();
}, [sessionId, clientToken]);
return <div ref={containerRef} />;
}Vue 3
ZippyCheckout.vue
vue<template>
<zippy-pay-checkout
ref="checkoutEl"
environment="production"
:session-id="sessionId"
mode="inline"
theme-primary="#2563eb"
@zippy-complete="onComplete"
@zippy-error="onError"
/>
</template>
<script setup lang="ts">
import "@zippypay/checkout";
import { onMounted, ref, watch } from "vue";
import type { PaymentSession, ZippyPayError } from "@zippypay/checkout";
const props = defineProps<{
sessionId: string;
clientToken: string;
}>();
const checkoutEl = ref<{ clientToken: string } | null>(null);
onMounted(() => {
if (checkoutEl.value) {
checkoutEl.value.clientToken = props.clientToken;
}
});
watch(
() => props.clientToken,
(token) => {
if (checkoutEl.value) checkoutEl.value.clientToken = token;
},
);
function onComplete(e: CustomEvent<PaymentSession>) {
console.log("Paid", e.detail.transactionId);
}
function onError(e: CustomEvent<ZippyPayError>) {
console.error(e.detail.code, e.detail.detail);
}
</script>Angular
zippy-checkout.component.ts
typescriptimport "@zippypay/checkout";
import {
Component,
CUSTOM_ELEMENTS_SCHEMA,
ElementRef,
ViewChild,
AfterViewInit,
Input,
} from "@angular/core";
@Component({
selector: "app-zippy-checkout",
template: `
<zippy-pay-checkout
#checkout
[attr.environment]="environment"
[attr.session-id]="sessionId"
mode="inline"
(zippy-complete)="onComplete($event)">
</zippy-pay-checkout>
`,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class ZippyCheckoutComponent implements AfterViewInit {
@Input() environment = "production";
@Input() sessionId = "";
@Input() clientToken = "";
@ViewChild("checkout", { read: ElementRef })
checkoutRef!: ElementRef<{ clientToken: string }>;
ngAfterViewInit() {
this.checkoutRef.nativeElement.clientToken = this.clientToken;
}
onComplete(event: Event) {
const session = (event as CustomEvent).detail;
console.log(session.transactionId);
}
}Web component
Auto-registered on import '@zippypay/checkout'. Mounts on connectedCallback and unmounts on disconnectedCallback. Does not mount until both session-id and clientToken are set.
HTML + module script
html<script type="module">
import "@zippypay/checkout";
</script>
<zippy-pay-checkout
environment="production"
session-id="550e8400-e29b-41d4-a716-446655440000"
mode="inline"
theme-primary="#2563eb"
theme-mode="auto"
></zippy-pay-checkout>
<script type="module">
const el = document.querySelector("zippy-pay-checkout");
el.clientToken = "zps_REDACTED";
el.addEventListener("zippy-complete", (e) => console.log(e.detail));
</script>