Back to YATORI CHECKOUT

DOCUMENTATION

Complete API reference and integration examples

Dialog Behavior

By default, the component uses a dialog mode on desktop devices:

  • Desktop with useDialog=true (default): Shows a "YATORI PAY" button. Clicking it opens a centered modal dialog with the QR code and a close button.
  • Desktop with useDialog=false: Displays the QR code directly without a dialog.
  • Mobile devices: Always shows the "YATORI PAY" button with deeplink functionality (dialog setting is ignored).
<yatori-checkout
  wallet="G8RtxPyG2pdrAhrNRMgg7Hia8imCofdCYxvyWiNG14hx"
  amount="9.99"
  useDialog="false"
></yatori-checkout>

Props/Attributes

AttributeTypeRequiredDefaultDescription
walletstringYes-Recipient wallet address (Solana). Must have at least 0.01 USDC already deposited for rent (USDC PDA).
amountnumberYes-Payment amount in USD decimal format (e.g., 9.99, must be between 0.01 and 9999.99)
useDialogbooleanNotrueWhen true and not on mobile, displays a "YATORI PAY" button that opens a centered dialog with the QR code. When false, displays the QR code directly. On mobile devices, always shows the deeplink button regardless of this setting.

Events

yatori-confirmed

Fired when payment is confirmed via WebSocket.

element.addEventListener('yatori-confirmed', (event) => {
  const { signature, status } = event.detail
  // Handle payment confirmation
})

yatori-animation-complete

Fired 5 seconds after payment confirmation, when the payment complete animation finishes. This is useful for hiding the component or updating UI after the animation completes.

element.addEventListener('yatori-animation-complete', (event) => {
  const { signature, status } = event.detail
  // Animation is complete, component can be hidden or UI updated
})

Shadow DOM CSS Custom Properties

The component uses Shadow DOM, but you can customize the button styling using CSS custom properties (CSS variables) with the --yp- prefix. These variables can be set on the yatori-checkout element or any parent element.

Available Custom Properties

VariableDefaultDescription
--yp-button-border-width1pxBorder width of the button
--yp-button-border-colorblackBorder color of the button
--yp-button-border-radius0pxBorder radius of the button
--yp-button-height48pxHeight of the button (minimum: 44px)
--yp-button-width100%Width of the button (minimum: 200px)

Note: The button has minimum size constraints to ensure usability. The minimum width is 200px and minimum height is 44px. Values below these minimums will be automatically clamped.

Example Usage

<style>
  yatori-checkout {
    --yp-button-border-radius: 2px;
    --yp-button-border-color: #007bff;
    --yp-button-border-width: 2px;
    --yp-button-height: 52px;
    --yp-button-width: 200px;
  }
</style>

<yatori-checkout
  wallet="G8RtxPyG2pdrAhrNRMgg7Hia8imCofdCYxvyWiNG14hx"
  amount="9.99"
></yatori-checkout>
/* In your CSS file */
yatori-checkout {
  --yp-button-border-radius: 12px;
  --yp-button-border-color: #333;
  --yp-button-border-width: 2px;
  --yp-button-height: 52px;
  --yp-button-width: 300px;
}

Vanilla HTML Example

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Yatori Checkout Example</title>
</head>
<body>
  <h1>Payment Checkout</h1>
  
  <yatori-checkout
    wallet="G8RtxPyG2pdrAhrNRMgg7Hia8imCofdCYxvyWiNG14hx"
    amount="9.99"
  ></yatori-checkout>

  <script type="module">
    import 'yatori-checkout'
    
    const checkout = document.querySelector('yatori-checkout')
    checkout.addEventListener('yatori-confirmed', (event) => {
      console.log('Payment confirmed!', event.detail)
      alert('Payment successful!')
    })
  </script>
</body>
</html>

Vue.js Example

First, configure Vue to recognize yatori-checkout as a custom element in your vite.config.js:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [
    vue({
      template: {
        compilerOptions: {
          isCustomElement: (tag) => tag.startsWith('yatori-')
        }
      }
    })
  ]
})

Then use it in your component:

<template>
  <yatori-checkout
    wallet="G8RtxPyG2pdrAhrNRMgg7Hia8imCofdCYxvyWiNG14hx"
    amount="9.99"
    @yatori-confirmed="handlePayment"
  ></yatori-checkout>
</template>

<script setup>
import 'yatori-checkout'

function handlePayment(event) {
  console.log('Payment confirmed!', event.detail)
  // event.detail contains: { signature, status }
}
</script>

React Example

import "./App.css";
import { YatoriCheckout } from "yatori-checkout/react";

function App() {
  return (
    <>
      <div>
        <YatoriCheckout
          wallet="G8RtxPyG2pdrAhrNRMgg7Hia8imCofdCYxvyWiNG14hx"
          amount={0.01}
        />
      </div>
    </>
  );
}

export default App;

Next.js Example

When using in a Next.js application, use dynamic import to ensure client-side rendering:

"use client";

import dynamic from "next/dynamic";

const YatoriCheckout = dynamic(
  () => import("yatori-checkout/react").then((mod) => mod.YatoriCheckout),
  {
    ssr: false,
    loading: () => (
      <div className="w-full flex justify-center items-center h-[300px]">
        <div className="animate-pulse">
          <div className="h-10 bg-gray-300 rounded w-48"></div>
        </div>
      </div>
    ),
  }
);

export default function MyYatoriCheckout() {
  return (
    <YatoriCheckout
      wallet="G8RtxPyG2pdrAhrNRMgg7Hia8imCofdCYxvyWiNG14hx"
      amount={10}
      onYatoriConfirmed={(event) => {
        console.log("Payment confirmed", event.detail);
      }}
      onYatoriAnimationComplete={(event) => {
        console.log("Animation complete", event.detail);
      }}
    />
  );
}