@upayments-kw/web-sdk
v1.0.0-beta.4
Published
Official Web Payment SDK for UPayments — accept Apple Pay and web payments with ease
Readme
@upayments-kw/web-sdk — Unified Web Payment SDK
The official UPayments Web SDK for integrating online payments into web applications. Accept Apple Pay and Apple Pay KNET with modern React components, Next.js App Router support, or zero-build Vanilla JavaScript / CDN.
Supported Payment Methods
- Apple Pay (
apple_pay): One-touch checkout for Apple devices (Safari on iOS & macOS). - Apple Pay KNET (
apple_pay_knet): Apple Pay tailored specifically for Kuwait National Electronic Transfer (KNET) debit card processing. - Credit/Debit Cards & Direct KNET: Coming Soon in next release.
Merchant Examples Repository
For complete, runnable merchant examples (React + Vite, Next.js 14 App Router, and Vanilla HTML/CDN), check out the official examples repository:
https://github.com/upaymentskwt/web-sdk-examples
Requirements & Prerequisites
Before integrating the SDK, ensure your environment meets the following requirements:
| Requirement | Minimum Version / Specification | Details |
|---|---|---|
| Node.js | >= 18.0.0 | Required for building modern web applications. |
| Browsers | Safari 13+ (macOS / iOS) | Required for Apple Pay. Standard browsers supported for web checkout. |
| HTTPS Protocol | Valid SSL / TLS Certificate | Apple Pay strictly requires HTTPS (except localhost during development). |
| Domain Association | Apple Merchant ID Association | File must be accessible at https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association. |
| Merchant Credentials | API Bearer Token | Issued via the UPayments Merchant Dashboard. |
Installation
For React & Next.js Applications
If you are building with React or Next.js, install @upayments-kw/react. You do not need to install @upayments-kw/web-sdk separately, as @upayments-kw/react re-exports all SDK classes, methods, and types.
npm install @upayments-kw/react
# or
pnpm add @upayments-kw/react
# or
yarn add @upayments-kw/reactFor Vanilla JavaScript & HTML (CDN or npm)
npm install @upayments-kw/web-sdkOr via script tag:
<script src="https://cdn.jsdelivr.net/npm/@upayments-kw/web-sdk/dist/upayments.js"></script>UI Component Previews
1. Group Payment Container (<PaymentMethods />)
Displays all payment methods currently enabled and verified for the merchant and device. Additional methods (Credit Card, KNET) will automatically appear as they become available on your merchant account.
┌───────────────────────────────────────────────────────────┐
│ Payment Methods │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Pay │ │ <-- Apple Pay
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Pay | KNET │ │ <-- Apple Pay KNET
│ └─────────────────────────────────────────────────────┘ │
│ │
│ [ Credit / Debit Card (Coming Soon) ] │
└───────────────────────────────────────────────────────────┘2. Standalone Apple Pay Button (<ApplePayButton />)
Direct branded button for dedicated Apple Pay integration.
┌───────────────────────────────────────────────┐
│ Pay │ (Default / Black)
└───────────────────────────────────────────────┘
┌───────────────────────────────────────────────┐
│ Pay │ (White with line)
└───────────────────────────────────────────────┘Quickstart Guide
1. React & Vite Integration
React users only need to import from @upayments-kw/react. The SDK automatically handles Bearer authorization internally.
Option A: Group Payments Usage (<PaymentMethods />)
import React, { useEffect, useState } from 'react';
import {
UPayments,
PaymentMethods,
type PaymentMethodId,
type BoundPayHandler,
} from '@upayments-kw/react';
export const GroupCheckout = () => {
const [sdk, setSdk] = useState<UPayments | null>(null);
const [availableMethods, setAvailableMethods] = useState<PaymentMethodId[]>([]);
useEffect(() => {
async function init() {
// 1. Initialize SDK — token is automatically handled as Bearer.
// Returns exact type UApiPayments by default!
const instance = UPayments.create({
environment: 'sandbox', // 'sandbox' or 'production'
token: 'YOUR_MERCHANT_API_TOKEN',
});
// 2. Perform backend handshake and discover available methods
await instance.initialize();
setSdk(instance);
setAvailableMethods(instance.getAvailablePaymentMethods());
}
init();
}, []);
const handlePay = async (method: PaymentMethodId, pay: BoundPayHandler) => {
if (!sdk) return;
try {
const payload = {
amount: 25.0,
products: [
{ name: 'Running Shoes', price: 25.0, quantity: 1 },
],
order: {
id: `ORD_${Date.now()}`,
description: 'Payment for Order #10024',
currency: 'KWD',
amount: 25.0,
},
customer: {
uniqueId: 'cust_101',
name: 'Salem Al-Otaibi',
mobile: '+96560000000',
email: '[email protected]',
},
returnUrl: `${window.location.origin}/orders/success`,
cancelUrl: `${window.location.origin}/orders/cancel`,
notificationUrl: 'https://api.yourstore.com/webhooks/upayments',
};
// Executes payment directly inside the active user gesture
const result = await pay({ payload });
console.log('Payment Success:', result);
} catch (error) {
console.error('Payment Failed:', error);
}
};
return (
<div style={{ maxWidth: 460, margin: '2rem auto' }}>
<h2>Checkout</h2>
{sdk ? (
<PaymentMethods
sdk={sdk}
availableMethods={availableMethods}
onMethodSelected={handlePay}
/>
) : (
<p>Loading payment options...</p>
)}
</div>
);
};Option B: Standalone Payment Method Usage (<ApplePayButton />)
import React, { useEffect, useState } from 'react';
import {
UPayments,
ApplePayButton,
type BoundPayHandler,
} from '@upayments-kw/react';
export const StandaloneApplePay = () => {
const [sdk, setSdk] = useState<UPayments | null>(null);
useEffect(() => {
async function init() {
const instance = UPayments.create({
environment: 'sandbox',
token: 'YOUR_MERCHANT_API_TOKEN',
});
await instance.initialize();
setSdk(instance);
}
init();
}, []);
const handleApplePay = async (pay: BoundPayHandler) => {
if (!sdk) return;
const payload = {
amount: 15.0,
products: [{ name: 'Espresso Beans', price: 15.0, quantity: 1 }],
order: {
id: `ORD_${Date.now()}`,
currency: 'KWD',
amount: 15.0,
},
customer: {
name: 'Sara Ahmad',
mobile: '+96590000000',
email: '[email protected]',
},
returnUrl: `${window.location.origin}/orders/success`,
cancelUrl: `${window.location.origin}/orders/cancel`,
};
// Executes Apple Pay sheet within active user gesture
await pay({ payload });
};
return (
<div>
<h3>Express Checkout</h3>
<ApplePayButton
sdk={sdk}
paymentMethod="apple_pay"
type="buy"
buttonStyle="black"
height={52}
borderRadius={12}
onClick={handleApplePay}
/>
</div>
);
};Apple Pay Button Customization Guide
The SDK's Apple Pay button (available as <ApplePayButton /> in React and <upay-apple-pay-button> in HTML/Lit) is fully customisable according to Apple's Human Interface Guidelines (HIG):
- 16 Button Types (
type):'plain'(default),'buy','set-up','donate','check-out','book','subscribe','reload','add-money','top-up','order','rent','support','contribute','tip','continue'. - 3 Visual Styles (
buttonStyle/variant):'black'(default, white lettering on black),'white'(black lettering on white),'white-outline'(white with fine black border line). - Dimensions: Supports
width(min 140px),height(min 30px, standard 44px–64px; default 48px),borderRadius(e.g.8px,50pxfor pill),padding,boxSizing. - CSS Custom Properties: Standard
--apple-pay-button-width,--apple-pay-button-height,--apple-pay-button-border-radius,--apple-pay-button-padding,--apple-pay-button-box-sizing. - Multi-Language: Supports BCP 47 language tags (e.g.
locale="ar"with automatic RTL layout and Arabic text).
2. Next.js (App Router) & SSR Compatibility
SSR Compatibility
The SDK contains built-in SSR guards preventing HTMLElement or window undefined reference errors during Node.js server pre-rendering. However, payment processing sheets (such as window.ApplePaySession) and Custom Element DOM rendering are client-side only.
In Next.js App Router, load the checkout component using next/dynamic with { ssr: false }:
// app/page.tsx
'use client';
import dynamic from 'next/dynamic';
const CheckoutClient = dynamic(
() => import('../components/CheckoutClient').then((mod) => mod.CheckoutClient),
{
ssr: false,
loading: () => <p>Loading checkout...</p>,
}
);
export default function Page() {
return (
<main>
<CheckoutClient />
</main>
);
}3. Vanilla JavaScript & HTML (CDN)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>UPayments Checkout</title>
<!-- Load UPayments Web SDK -->
<script src="https://cdn.jsdelivr.net/npm/@upayments-kw/web-sdk/dist/upayments.js"></script>
</head>
<body>
<!-- Container Element -->
<upay-payment-methods id="payment-methods"></upay-payment-methods>
<script>
async function initCheckout() {
// 1. Initialize SDK (returns UApiPayments by default)
const sdk = window.UPayments.create({
environment: 'sandbox',
token: 'YOUR_MERCHANT_API_TOKEN', // Automatically handled as Bearer
});
await sdk.initialize();
// 2. Connect SDK to web component
const container = document.getElementById('payment-methods');
container.sdk = sdk;
container.availableMethods = sdk.getAvailablePaymentMethods();
// 3. Handle payment method selection
container.addEventListener('upay:method-selected', async (event) => {
const { paymentMethod, pay } = event.detail;
try {
// Executes inside active user gesture
const result = await pay({
payload: {
amount: 50.0,
products: [{ name: 'Leather Bag', price: 50.0, quantity: 1 }],
order: { id: 'ORD_' + Date.now(), currency: 'KWD', amount: 50.0 },
customer: {
name: 'Fatima Al-Kandari',
email: '[email protected]',
mobile: '+96590000000'
},
returnUrl: window.location.origin + '/success',
cancelUrl: window.location.origin + '/cancel'
}
});
console.log('Payment successful:', result);
} catch (err) {
console.error('Payment error:', err);
}
});
}
initCheckout();
</script>
</body>
</html>Events & Callbacks Reference
Listen to lifecycle events using sdk.on(eventName, callback):
| Event Name | Trigger Condition | Payload Details |
|---|---|---|
| upay:ready | Fired when the SDK has successfully verified merchant credentials and identified available payment methods. | { availablePaymentMethods: PaymentMethodId[] } |
| upay:payment-methods-loaded | Fired when the backend returns available payment capabilities for the merchant account. | { availablePaymentMethods: PaymentMethodId[], merchantId: string } |
| upay:payment-started | Fired immediately when sdk.pay() is invoked and the checkout transaction begins. | { paymentMethod: PaymentMethodId } |
| upay:payment-method-opened | Fired when the interactive payment interface (e.g. Apple Pay native sheet) is presented to the customer. | { paymentMethod: PaymentMethodId } |
| upay:payment-processing | Fired after the customer authorizes payment and the token is submitted to the gateway for capture. | { paymentMethod: PaymentMethodId } |
| upay:payment-success | Fired when the transaction is successfully captured and completed. | { paymentMethod: PaymentMethodId, result: PaymentResult } |
| upay:payment-failed | Fired when a payment attempt is declined by the gateway/bank, or an error occurs during checkout. | { paymentMethod: PaymentMethodId, error: SDKError } |
| upay:payment-cancelled | Fired when the customer dismisses or cancels the payment sheet without completing payment. | { paymentMethod: PaymentMethodId } |
| upay:error | Fired when an unhandled SDK initialization or runtime error occurs. | SDKError |
Payment Payload Reference
When calling sdk.pay({ paymentMethod, payload }), pass the following parameters:
| Field | Type | Required | Description |
|---|---|---|---|
| amount | number | Yes | Total transaction amount in KWD (e.g. 25.000). |
| order | object | Yes | Order information containing id, currency ("KWD"), and amount. |
| products | array | Yes | Array of items (name, price, quantity, description). |
| customer | object | Yes | Customer contact info (name, email, mobile, uniqueId). |
| returnUrl | string | Yes | URL to redirect customer upon successful payment. |
| cancelUrl | string | Yes | URL to redirect customer if payment is cancelled. |
| notificationUrl | string | No | Server-to-server webhook endpoint for async status notifications. |
| language | string | No | Language code ('en' or 'ar'). Defaults to 'en'. |
| domainName | string | No | Initiating web domain (defaults to window.location.hostname). |
Apple Pay Domain Verification
Apple Pay requires domain registration before transactions can be processed on the web:
- Access the UPayments Merchant Dashboard and register your web domain (e.g.
yourstore.com). - Download the Apple domain association file provided by UPayments.
- Upload the file to your public web server at:
https://yourstore.com/.well-known/apple-developer-merchantid-domain-association - Verify that the file returns raw text over a valid HTTPS connection.
Troubleshooting & FAQ
Why is the Apple Pay button not showing up?
- HTTPS Context: Ensure your local or production environment runs over HTTPS.
- Apple Device: Open the page in Safari on macOS or iOS.
- Active Wallet: Ensure your device has an active credit or debit card configured in Apple Wallet.
- Domain Verification: Verify that your domain is registered in the UPayments Merchant Dashboard.
What is the difference between apple_pay and apple_pay_knet?
apple_pay: Standard international credit and debit card processing via Apple Pay.apple_pay_knet: Kuwait KNET debit card processing via Apple Pay.
How do I switch to live production?
Change environment from 'sandbox' to 'production' in UPayments.create(), and provide your live Bearer API token.
Support & Documentation
- Developer Documentation: https://developers.upayments.com
- Merchant Dashboard: https://merchant.upayments.com
- Technical Support: [email protected]
- Official Website: https://upayments.com
