npm package: @payonify/react
Description: React-compatible SDK for Payonify payment integration with hooks and components
Author: Payonify Team
Latest version: 1.0.3

# Payonify React SDK

A React-compatible SDK for integrating Payonify payment processing into your React applications.

## Features

- 🚀 React hooks for easy integration
- 🎯 Component-based payment forms
- 📱 Responsive payment iframes
- 🔄 Automatic cleanup and lifecycle management
- 🎨 Customizable styling and theming
- 📦 Tree-shakable bundle

## Installation

```bash
npm install @payonify/sdk-react
```

## Quick Start

### 1. Provider Setup

Wrap your app with the PayonifyProvider:

```tsx
import { PayonifyProvider } from "@payonify/sdk-react";

function App() {
  return (
    <PayonifyProvider config={{ publishableKey: "your_publishable_key" }}>
      <YourApp />
    </PayonifyProvider>
  );
}
```

### 2. Using the Checkout Component

```tsx
import { PayonifyCheckout } from "@payonify/sdk-react";

function CheckoutPage() {
  const handleSuccess = (data) => {
    console.log("Payment successful:", data);
    // Redirect to success page
  };

  const handleError = (error) => {
    console.error("Payment failed:", error);
    // Handle error
  };

  return (
    <PayonifyCheckout
      payment={{
        amount: 1000, // Amount in cents
        currency: "USD",
        reference: "order-123",
        customer: { email: "customer@example.com" },
        clientSecret: "your_client_secret",
      }}
      onSuccess={handleSuccess}
      onError={handleError}
      className="my-checkout"
    />
  );
}
```

### 3. Using the Payment Hook

```tsx
import { usePayonifyPayment } from "@payonify/sdk-react";

function CustomCheckout() {
  const { mount, unmount, isLoading, error } = usePayonifyPayment();
  const containerRef = useRef(null);

  const handlePayment = async () => {
    try {
      const result = await mount({
        amount: 1000,
        currency: "USD",
        reference: "order-123",
        customer: { email: "customer@example.com" },
        container: containerRef.current,
        clientSecret: "your_client_secret",
      });
      console.log("Payment successful:", result);
    } catch (err) {
      console.error("Payment failed:", err);
    }
  };

  return (
    <div>
      <button onClick={handlePayment} disabled={isLoading}>
        {isLoading ? "Processing..." : "Pay Now"}
      </button>
      <div ref={containerRef} style={{ minHeight: "200px" }} />
      {error && <p>Error: {error}</p>}
    </div>
  );
}
```

## API Reference

### PayonifyProvider

Provider component that initializes the Payonify SDK.

**Props:**

- `config`: SDKConfig - Configuration object with publishableKey
- `children`: React.ReactNode - Child components

### PayonifyCheckout

Component that renders a complete payment form.

**Props:**

- `payment`: PaymentConfig & { clientSecret: string } - Payment configuration
- `onSuccess?`: (data: any) => void - Success callback
- `onError?`: (error: any) => void - Error callback
- `onClose?`: () => void - Close callback
- `className?`: string - CSS class name
- `style?`: React.CSSProperties - Inline styles

### usePayonifyPayment

Hook for manual payment mounting control.

**Returns:**

- `mount`: (config: PaymentConfig & { clientSecret: string }) => Promise<any>
- `unmount`: () => boolean
- `isMounted`: boolean
- `isLoading`: boolean
- `error`: string | null

### usePayonify

Hook to access the Payonify SDK instance directly.

**Returns:**

- `sdk`: PayonifySDK instance
- `isInitialized`: boolean
- `error`: string | null

### usePayonifyErrorHandler

Hook for handling and formatting payment errors.

**Returns:**

- `createError`: (message: string, code?: string, details?: any) => PayonifyError
- `handlePaymentError`: (error: any) => PayonifyError
- `isRetryableError`: (error: PayonifyError) => boolean
- `getErrorMessage`: (error: PayonifyError) => string

## Utilities

### validatePaymentConfig(config)

Validates payment configuration before mounting.

```tsx
import {
  validatePaymentConfig,
  PayonifyValidationError,
} from "@payonify/sdk-react";

try {
  validatePaymentConfig(paymentConfig);
  // Config is valid
} catch (error) {
  if (error instanceof PayonifyValidationError) {
    console.log(`Field ${error.field}: ${error.message}`);
  }
}
```

### formatCurrency(amount, currency)

Formats amount and currency for display.

```tsx
import { formatCurrency } from "@payonify/sdk-react";

console.log(formatCurrency(2999, "USD")); // "$29.99"
```

### formatPaymentSummary(config)

Creates a human-readable payment summary.

```tsx
import { formatPaymentSummary } from "@payonify/sdk-react";

const summary = formatPaymentSummary({
  amount: 4999,
  currency: "USD",
  reference: "order-123",
});
// "USD 49.99 for order-123"
```

### generateReference(prefix?)

Generates a unique payment reference.

```tsx
import { generateReference } from "@payonify/sdk-react";

const ref = generateReference("inv"); // "INV_1A2B3C_4D5E6F"
```

### sanitizeConfig(config)

Sanitizes and normalizes payment configuration.

```tsx
import { sanitizeConfig } from "@payonify/sdk-react";

const cleanConfig = sanitizeConfig({
  amount: 1000,
  currency: "usd", // Will be converted to 'USD'
  reference: "  order-123  ", // Will be trimmed
  customer: { email: "  USER@EXAMPLE.COM  " }, // Will be normalized
  clientSecret: "cs_123",
});
```

### usePayonify

Hook to access the Payonify SDK instance directly.

**Returns:**

- `sdk`: PayonifySDK instance
- `isInitialized`: boolean
- `error`: string | null

## TypeScript Support

The SDK is fully typed. Import types as needed:

```tsx
import type {
  SDKConfig,
  PaymentConfig,
  PayonifyProviderProps,
  PayonifyCheckoutProps,
} from "@payonify/sdk-react";
```

## Styling

The payment iframe is responsive by default. You can customize the appearance:

```tsx
<PayonifyCheckout
  payment={paymentConfig}
  className="custom-checkout"
  style={{
    border: "1px solid #ccc",
    borderRadius: "8px",
    padding: "20px",
  }}
/>
```

## Error Handling

All payment operations return promises that reject on failure:

```tsx
try {
  const result = await mount(paymentConfig);
  // Handle success
} catch (error) {
  // Handle error
  console.error("Payment failed:", error);
}
```

## Browser Support

- Chrome 60+
- Firefox 60+
- Safari 12+
- Edge 79+

## License

MIT