React Installation Guide
Integrate Amwal Bank Installment web components and promotional pricing widgets seamlessly into your React, Next.js, or Vite applications.
1. Load SDK Script
In Next.js (App Router), load the script in your app/layout.tsx:
import Script from 'next/script';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<Script
type="module"
src="https://cdn.jsdelivr.net/npm/@amwaljs/checkout-button@latest/dist/checkout/checkout.esm.js"
strategy="lazyOnload"
/>
</head>
<body>{children}</body>
</html>
);
}2. React Wrapper Component
Create a reusable typed wrapper component for the Amwal promotional widget:
'use client';
import React, { useEffect, useRef } from 'react';
interface AmwalWidgetProps {
price: number;
installmentsCount?: number;
currency?: string;
locale?: 'en' | 'ar';
showMonthlyPayment?: boolean;
showGreenBorder?: boolean;
}
export const AmwalInstallmentWidget: React.FC<AmwalWidgetProps> = ({
price,
installmentsCount = 6,
currency = 'SAR',
locale = 'en',
showMonthlyPayment = true,
showGreenBorder = true,
}) => {
const widgetRef = useRef<HTMLElement | null>(null);
useEffect(() => {
if (widgetRef.current) {
// Configure custom element properties
(widgetRef.current as any).config = {
price,
installmentsCount,
currency,
};
(widgetRef.current as any).locale = locale;
(widgetRef.current as any).showMonthlyPayment = showMonthlyPayment;
(widgetRef.current as any).showGreenBorder = showGreenBorder;
}
}, [price, installmentsCount, currency, locale, showMonthlyPayment, showGreenBorder]);
return (
<div className="amwal-widget-container my-4">
{/* @ts-ignore custom web component */}
<amwal-widget ref={widgetRef} id="amwal-widget" />
</div>
);
};3. Checkout Button with Event Listeners
Create a React component for the drop-in checkout button:
'use client';
import React, { useEffect, useRef } from 'react';
interface AmwalCheckoutButtonProps {
amount: number;
currency?: string;
merchantId: string;
onSuccess: (detail: any) => void;
onError: (error: any) => void;
}
export const AmwalCheckoutButton: React.FC<AmwalCheckoutButtonProps> = ({
amount,
currency = 'SAR',
merchantId,
onSuccess,
onError,
}) => {
const buttonRef = useRef<HTMLElement | null>(null);
useEffect(() => {
const el = buttonRef.current;
if (!el) return;
const handleSuccess = (e: Event) => {
const customEvent = e as CustomEvent;
onSuccess(customEvent.detail);
};
const handleError = (e: Event) => {
const customEvent = e as CustomEvent;
onError(customEvent.detail);
};
el.addEventListener('amwal-success', handleSuccess);
el.addEventListener('amwal-error', handleError);
return () => {
el.removeEventListener('amwal-success', handleSuccess);
el.removeEventListener('amwal-error', handleError);
};
}, [onSuccess, onError]);
return (
<div>
{/* @ts-ignore custom web component */}
<amwal-checkout-button
ref={buttonRef}
amount={amount.toString()}
currency={currency}
country-code="SA"
merchant-id={merchantId}
locale="en"
enable-installments="true"
/>
</div>
);
};4. Usage in Product Page
import { AmwalInstallmentWidget } from '@/components/AmwalInstallmentWidget';
import { AmwalCheckoutButton } from '@/components/AmwalCheckoutButton';
export default function ProductPage() {
return (
<div className="product-details">
<h1>Sony WH-1000XM5 Headphones</h1>
<p className="price">1,499.00 SAR</p>
{/* Promotional Widget */}
<AmwalInstallmentWidget price={1499} installmentsCount={6} />
{/* Instant Checkout Button */}
<AmwalCheckoutButton
amount={1499}
merchantId="sandbox_pk_your_key"
onSuccess={(detail) => console.log('Payment Successful:', detail)}
onError={(err) => console.error('Payment Error:', err)}
/>
</div>
);
}