npm package: @payloqa/payment-widget
Description: Payment widget for Payloqa
Author: Payloqa Team
Latest version: 1.0.6

# 💳 Payloqa Payment Widget

A React payment widget for processing mobile money payments. Easily integrate secure payment processing into your React applications.

## ✨ Features

- 📱 Mobile money payment processing (MTN, Telecel, AirtelTigo)
- 🔐 OTP verification for secure transactions
- 📱 Fully responsive design
- 🎨 Customizable branding with primary color
- ⚡ Easy integration with React
- 🔄 Real-time payment status updates
- ⏱️ Automatic timeout handling

## 🚀 Getting Started

### 1. Get Your API Credentials

Visit [https://developer.payloqa.com/](https://developer.payloqa.com/) to:

- Login with your phone number (simple phone number authentication)
- Go to the **API Keys** page
- Create your **API Key** and get your **Platform ID**
- Request payment access by filling out the KYC form
- Once approved, you'll be notified and can start processing payments

### 2. Install the Package

```bash
npm install @payloqa/payment-widget
```

### 3. Import and Use

```jsx
import { PaymentWidget } from "@payloqa/payment-widget";
import "@payloqa/payment-widget/dist/payment-widget.css";

function App() {
  const [isOpen, setIsOpen] = useState(false);

  const config = {
    apiKey: "your-api-key",
    platformId: "your-platform-id",
    amount: 10.00,
    currency: "GHS", // Optional, defaults to "GHS"
    primaryColor: "#3B82F6", // Optional, your brand color
    displayMode: "modal", // "modal" | "inline" | "fullpage"
    redirect_url: "https://yoursite.com/callback", // Required
    webhookUrl: "https://yoursite.com/webhook", // Required
    orderId: "order-123", // Optional
    metadata: { // Optional
      customField: "value",
    },
  };

  const handleSuccess = (payment) => {
    console.log("Payment successful!", payment);
    console.log("Payment ID:", payment.payment_id);
    console.log("Status:", payment.status);
    console.log("Amount:", payment.amount);
  };

  const handleError = (error) => {
    console.error("Payment failed:", error.message);
    alert(`Error: ${error.message}`);
  };

  return (
    <div>
      <button onClick={() => setIsOpen(true)}>Pay Now</button>
      
      <PaymentWidget
        config={config}
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        onSuccess={handleSuccess}
        onError={handleError}
      />
    </div>
  );
}
```

## ⚙️ Configuration

### Required Configuration

```typescript
interface PaymentWidgetConfig {
  apiKey: string;        // Your Payloqa API key
  platformId: string;   // Your platform ID
  amount: number;        // Payment amount (e.g., 10.00)
  currency?: string;    // Currency code (default: "GHS")
  displayMode?: string; // "modal" | "inline" | "fullpage" (default: "modal")
  primaryColor?: string; // Your brand color in hex (e.g., "#3B82F6")
  logoUrl?: string;     // Optional logo URL to display in header
  redirect_url: string; // Required: HTTPS URL for redirect after payment
  webhookUrl: string;   // Required: Webhook URL for server notifications
  orderId?: string;     // Optional order identifier
  metadata?: object;    // Optional metadata object
  onSuccess?: (payment: PaymentData) => void;
  onError?: (error: PaymentError) => void;
}
```

### PaymentWidget Props

```typescript
interface PaymentWidgetProps {
  config: PaymentWidgetConfig;
  isOpen: boolean;      // Controls widget visibility
  onClose?: () => void; // Called when widget is closed
}
```

### Callbacks

```typescript
// Success callback - called when payment succeeds
onSuccess: (payment: PaymentData) => void

// Error callback - called when payment fails
onError: (error: PaymentError) => void

// Close callback - called when widget is closed
onClose: () => void
```

## 📱 Display Modes

The widget supports three display modes:

### Modal (Default)
```jsx
<PaymentWidget
  config={{ ...config, displayMode: "modal" }}
  isOpen={isOpen}
  onClose={() => setIsOpen(false)}
/>
```
Displays as a centered modal overlay with backdrop.

### Inline
```jsx
<PaymentWidget
  config={{ ...config, displayMode: "inline" }}
  isOpen={isOpen}
  onClose={() => setIsOpen(false)}
/>
```
Displays inline within your page layout.

### Fullpage
```jsx
<PaymentWidget
  config={{ ...config, displayMode: "fullpage" }}
  isOpen={isOpen}
  onClose={() => setIsOpen(false)}
/>
```
Displays as a full-page experience.

## 💳 Supported Networks

The widget supports mobile money payments for:

- **MTN** - MTN Mobile Money
- **Telecel** - Telecel Cash (formerly Vodafone)
- **AirtelTigo** - AirtelTigo Money

## 🔄 Payment Flow

1. **Phone Input** - User enters phone number and selects network
2. **OTP Verification** - User receives and enters 4-digit OTP code
3. **Processing** - Payment is processed and status is polled
4. **Completion** - Success or error screen is shown

## 📝 Sample Responses

### Success Response

```typescript
{
  payment_id: "pay_abc123",
  status: "completed",
  amount: 10.00,
  currency: "GHS",
  payment_method: "mobile_money",
  phone_number: "+233XXXXXXXXX",
  network: "mtn",
  created_at: "2024-01-24T12:00:00Z",
  updated_at: "2024-01-24T12:01:00Z",
  paid_at: "2024-01-24T12:01:00Z"
}
```

### Error Response

```typescript
{
  message: "Invalid OTP code",
  code: "INVALID_OTP"
}
```

## 🔧 Development

### Prerequisites

- Node.js 16+
- npm or yarn

### Setup

```bash
# Install dependencies
npm install

# Start development server
npm run dev

# Build for production
npm run build

# Type checking
npm run type-check
```

## 🐛 Troubleshooting

### Widget doesn't open

- Ensure `isOpen` prop is set to `true`
- Check browser console for errors
- Verify React and ReactDOM are loaded

### Payment processing fails

- Verify your API key and platform ID are correct
- Check that you have payment access enabled
- Ensure your account has completed KYC verification
- Check network connectivity
- Review error messages in console

### OTP not received

- Verify phone number is correct and in E.164 format
- Check that the selected network matches the phone number
- Ensure you have sufficient balance for the transaction
- Check spam folder for OTP messages

## 📄 API Reference

### PaymentData

```typescript
interface PaymentData {
  payment_id: string;
  status: "pending" | "processing" | "completed" | "failed" | "cancelled" | "expired";
  amount: number | string;
  currency: string;
  payment_method: "mobile_money";
  phone_number?: string;
  network?: "mtn" | "vodafone" | "airteltigo";
  reference?: string;
  created_at: string;
  updated_at: string;
  paid_at?: string;
  metadata?: Record<string, any>;
}
```

### PaymentError

```typescript
interface PaymentError {
  message: string;
  code?: string;
  details?: any;
}
```

## 🆘 Support

- 📧 Email: support@payloqa.com
- 📖 Documentation: [docs.payloqa.com](https://payloqa.com/developer-docs)
- 🐛 Issues: [GitHub Issues](https://github.com/kobbycoder/payloqa-widgets/issues)

---

Built with ❤️ by the Payloqa Team