npm package: @gaian_dev/payment-widget
Description: Payment widget sdk
Author: gaian
Latest version: 0.0.34

# Payment Widget Integration

## Introduction

The Payment Widget is a React-based component designed to facilitate QR code scanning and invoice status display for payment processing. Built with TypeScript and styled using Tailwind CSS, it provides a seamless integration experience for developers. This widget is part of the Gaian Network ecosystem and requires the `@gaian_dev/payment-widget` package.

## Table of Contents

- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Components](#components)
  - [PaymentProvider](#paymentprovider)
  - [ButtonScan](#buttonscan)
  - [Invoice](#invoice)
- [Usage](#usage)
- [Configuration](#configuration)
- [File Structure](#file-structure)
- [Development](#development)
- [Email Requirement for Invoices](#email-requirement-for-invoices)
- [Testing](#testing)
- [Error Handling](#error-handling)
- [Dependencies](#dependencies)
- [Versioning](#versioning)
- [License](#license)
- [Contributing](#contributing)
- [Contact/Support](#contactsupport)

## Prerequisites

Before integrating the Payment Widget, ensure you have the following:

- **Node.js**: >= 18.x
- **React**: >= 18.x
- **TypeScript**: >= 5.x
- **Tailwind CSS**: Configured in your project
- **Package**: `@gaian_dev/payment-widget`

## Installation

1. Install the required package:

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

2. Configure Tailwind CSS in your `tailwind.config.js`:

   ```javascript
   module.exports = {
     content: ["./src/**/*.{js,ts,jsx,tsx}"],
     theme: { extend: {} },
     plugins: [],
   }
   ```

   **Note**: Ensure Tailwind CSS is properly set up in your project for styling to work correctly.

## Components

The Payment Widget consists of three main components:

- **PaymentProvider**: A provider component that wraps the payment widget and supplies necessary configuration keys.
- **ButtonScan**: A component that triggers QR code scanning.
- **Invoice**: A component that displays the status of an invoice.

### PaymentProvider

Wraps the payment widget and provides configuration.

#### Props:

- `mode`: `"dev" | "prod"` - Environment mode ("dev" for sandbox testing).
- `partnerCode`: `string` - Unique partner identifier (e.g., "GAIAN_NETWORK").
- `sandBoxKey`: `string` - Sandbox API key.
- `sandBoxSecretKey`: `string` - Sandbox secret key.

#### Example:

```jsx
<PaymentProvider
  mode="dev"
  partnerCode="GAIAN_NETWORK"
  sandBoxKey="SANDBOX_KEY"
  sandBoxSecretKey="SANDBOX_SECRET_KEY"
>
  <ButtonScan />
  <div className="fixed bottom-0 left-0 right-0">
    <Invoice id={153} onBack={() => {}} />
  </div>
</PaymentProvider>
```

### ButtonScan

Triggers QR code scanning using the `useScanQR` hook.

#### Features:

- Initiates QR code scanning on button click.
- Handles success and error callbacks.

#### Example:

```jsx
import { useScanQR } from "@gaian_dev/payment-widget";

export default function ButtonScan() {
  const { onScan } = useScanQR({
    onSuccess: (data) => console.log("Scan QR Success:", data),
    onError: (error) => console.error("Scan QR Error:", error),
  });

  return (
    <div className="h-full w-full">
      <button onClick={onScan} className="px-4 py-2 bg-blue-600 text-white rounded">
        Scan
      </button>
    </div>
  );
}
```

### Invoice

Displays the status of an invoice based on the provided ID.

#### Props:

- `id`: `number` - Invoice ID (e.g., 153).
- `onBack`: `() => void` - Callback for back navigation.

#### Example:

```jsx
<Invoice id={153} onBack={() => {}} />
```

## Usage

To use the Payment Widget, wrap your application with `PaymentProvider` and include `ButtonScan` and `Invoice` as needed.

### Full Example (`src/app.tsx`):

```jsx
import { PaymentProvider } from "@gaian_dev/payment-widget";
import ButtonScan from "./components/button-scan";
import Invoice from "./components/invoice";

export default function App() {
  return (
    <PaymentProvider
      mode="dev"
      partnerCode="GAIAN_NETWORK"
      sandBoxKey="SANDBOX_KEY"
      sandBoxSecretKey="SANDBOX_SECRET_KEY"
    >
      <ButtonScan />
      <div className="fixed bottom-0 left-0 right-0">
        <Invoice id={153} onBack={() => {}} />
      </div>
    </PaymentProvider>
  );
}
```

## Configuration

- **Environment**: Use `mode="dev"` for sandbox testing or `mode="prod"` for production.
- **API Keys**: Obtain `sandBoxKey` and `sandBoxSecretKey` from the [Gaian Network Dashboard](https://dashboard.gaian.network).
- **Partner Code**: Ensure `partnerCode` matches your assigned identifier (e.g., "GAIAN_NETWORK").

## File Structure

```
src/
├── components/
│   ├── button-scan.tsx
│   ├── invoice.tsx
├── app.tsx
├── tailwind.config.js
```

- `components/button-scan.tsx`: Contains the `ButtonScan` component.
- `components/invoice.tsx`: Contains the `Invoice` component.
- `app.tsx`: Main entry point combining `PaymentProvider`, `ButtonScan`, and `Invoice`.

## Development

- **Styling**: Utilizes Tailwind CSS for mobile-first, responsive design.
- **TypeScript**: Strictly typed with interfaces for props.
- **Performance**:
  - Lazy load components with Next.js `dynamic`:

    ```jsx
    import dynamic from "next/dynamic";
    const ButtonScan = dynamic(() => import("./components/button-scan"), { ssr: false });
    ```

  - Wrap components in `Suspense` for better UX:

    ```jsx
    import { Suspense } from "react";
    <Suspense fallback={<div>Loading...</div>}>
      <ButtonScan />
    </Suspense>
    ```

## Email Requirement for Invoices

To create an invoice, a valid user email is **mandatory**. The `@gaian_dev/payment-widget` package provides the `useEmailDialog` hook to manage email input and dialog state for invoice creation.

### Using `useEmailDialog`

The `useEmailDialog` hook provides the following properties and methods:

- `email`: `string` - The user's email input.
- `open`: `boolean` - Controls the visibility of the email input dialog.
- `setEmail`: `(email: string) => void` - Updates the email state.
- `setOpen`: `(open: boolean) => void` - Toggles the dialog visibility.

#### Example:

```jsx
import { useEmailDialog } from "@gaian_dev/payment-widget";

export default function EmailInput() {
  const { email, open, setEmail, setOpen } = useEmailDialog();

  return (
    <div className="p-4">
      <button
        onClick={() => setOpen(true)}
        className="px-4 py-2 bg-blue-600 text-white rounded"
      >
        Enter Email
      </button>
      {open && (
        <div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50">
          <div className="bg-white p-6 rounded shadow-lg">
            <h2 className="text-lg font-semibold mb-4">Enter Your Email</h2>
            <input
              type="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              className="w-full p-2 border rounded mb-4"
              placeholder="Enter your email"
            />
            <div className="flex justify-end gap-2">
              <button
                onClick={() => setOpen(false)}
                className="px-4 py-2 bg-gray-300 rounded"
              >
                Cancel
              </button>
              <button
                onClick={() => {
                  if (email) {
                    console.log("Email submitted:", email);
                    setOpen(false);
                  } else {
                    alert("Email is required to create an invoice.");
                  }
                }}
                className="px-4 py-2 bg-blue-600 text-white rounded"
              >
                Submit
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
```

#### Integration with Invoice Creation

Before rendering the `Invoice` component, ensure the email is collected using `useEmailDialog`. The email must be submitted to the Gaian Network backend to associate it with the invoice. Without a valid email, the invoice creation will fail.

#### Example Workflow:

1. Prompt the user to input their email using the dialog.
2. Validate the email format (handled by `useEmailDialog`).
3. Submit the email to the Gaian Network API when creating the invoice.
4. Render the `Invoice` component with the returned invoice ID.

## Testing

When `mode` is set to `"dev"`, the widget operates in sandbox mode, allowing you to test QR scanning, email input, and invoice status without affecting production data. Use test API keys and a test partner code for sandbox testing.

## Error Handling

The `ButtonScan` component provides an `onError` callback to handle scanning errors. For email input, ensure proper validation using `useEmailDialog`. Common errors include:

- Camera access denied.
- Invalid QR code format.
- Invalid or missing email.
- Network issues when verifying the QR code or submitting the email.

Implement appropriate error messages or retry mechanisms in your application.

## Dependencies

- `@gaian_dev/payment-widget`: The main package for the payment widget.
- `react`: >= 18.x
- `react-dom`: >= 18.x
- `tailwindcss`: Configured in the project.

## Versioning

Ensure you are using the latest version of `@gaian_dev/payment-widget`. Check for updates regularly.

## License

This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

## Contributing

Contributions are welcome! Please read the [contributing guidelines](CONTRIBUTING.md) before submitting a pull request.

## Contact/Support

For support or to report issues, contact us at [support@gaian.network](mailto:support@gaian.network) or open an issue on our [GitHub repository](https://github.com/gaian-network/payment-widget).