npm package: @orchestrapay/react
Description: Official Orchestrapay React SDK for embedding payment forms
Author: Orchestrapay
Latest version: 1.2.1

# @orchestrapay/react

Official Orchestrapay React SDK for embedding payment forms in your React applications.

[![npm version](https://img.shields.io/npm/v/@orchestrapay/react.svg)](https://www.npmjs.com/package/@orchestrapay/react)



## Features

✅ **React-First Design** - Built specifically for React with hooks and components  
✅ **TypeScript Support** - Full TypeScript definitions included  
✅ **Automatic Script Loading** - Handles orchestrapay.js loading automatically  
✅ **Enhanced State Management** - Track payment success, failure, and processing states  
✅ **SSR Compatible** - Works with Next.js and other SSR frameworks  
✅ **Customizable Styling** - Theme presets and custom CSS support  
✅ **Zero Dependencies** - Only requires React as a peer dependency  

## Installation

```bash
npm install @orchestrapay/react
# or
yarn add @orchestrapay/react
# or
pnpm add @orchestrapay/react
```

## Quick Start

```tsx
import { PaymentForm } from '@orchestrapay/react';

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

  const handleFailure = (data) => {
    console.error('Payment failed:', data);
    // Show error message
  };

  return (
    <div>
      <h1>Complete Your Payment</h1>
      <PaymentForm
        publicKey="pk_test_xxx"
        paymentIntent="pi_xxx"
        onPaymentSuccess={handleSuccess}
        onPaymentFailure={handleFailure}
      />
    </div>
  );
}
```

## Components

### `<PaymentForm />`

The main component for embedding Orchestrapay payment forms.

#### Props

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `publicKey` | `string` | ✅ | Your Orchestrapay public API key |
| `paymentIntent` | `string` | ✅ | Payment intent ID from your server |
| `paymentForm` | `string` | ❌ | Optional payment form ID for custom forms |
| `apiVersion` | `string` | ❌ | API version (default: 'v202502') |
| `saveCardsOnFile` | `'never' \| 'ask' \| 'always'` | ❌ | Card save preference |
| `isDemo` | `boolean` | ❌ | Enable demo mode |
| `style` | `OrchestrapayStyle` | ❌ | Styling configuration |
| `onReady` | `(ms: number) => void` | ❌ | Called when iframe is ready |
| `onLoaded` | `(ms: number) => void` | ❌ | Called when form is fully loaded |
| `onPaymentSuccess` | `(data: PaymentSuccessData) => void` | ❌ | Called on successful payment |
| `onPaymentFailure` | `(data: PaymentFailureData) => void` | ❌ | Called on payment failure |
| `className` | `string` | ❌ | CSS class for container |
| `containerStyle` | `React.CSSProperties` | ❌ | Inline styles for container |
| `scriptUrl` | `string` | ❌ | Custom script URL (defaults to CDN) |

#### Example with All Options

```tsx
<PaymentForm
  publicKey="pk_test_xxx"
  paymentIntent="pi_xxx"
  paymentForm="form_xxx"
  apiVersion="v202502"
  saveCardsOnFile="ask"
  style={{
    theme: 'default',
    poweredBy: true,
    custom: {
      base: {
        fontFamily: 'Arial, sans-serif',
        fontSize: '16px',
      },
      invalid: {
        borderColor: '#ff0000',
      },
    },
  }}
  onReady={(ms) => console.log(`Ready in ${ms}ms`)}
  onLoaded={(ms) => console.log(`Loaded in ${ms}ms`)}
  onPaymentSuccess={(data) => {
    console.log('Success!', data.transactionId);
  }}
  onPaymentFailure={(data) => {
    console.error('Failed:', data.message);
  }}
  className="my-payment-form"
/>
```

## Hooks

### `useOrchestrapay(config, scriptUrl?)`

Advanced hook for fine-grained control over the payment flow.

#### Returns

| Property | Type | Description |
|----------|------|-------------|
| `isReady` | `boolean` | Iframe is ready and config sent |
| `isLoaded` | `boolean` | Payment form fully loaded |
| `isSuccessful` | `boolean` | Payment succeeded |
| `isFailed` | `boolean` | Payment failed |
| `isProcessing` | `boolean` | Payment in progress |
| `paymentData` | `PaymentSuccessData \| null` | Success data if payment succeeded |
| `errorData` | `PaymentFailureData \| null` | Error data if payment failed |
| `element` | `OrchestrapayElement \| null` | Element instance reference |
| `reset` | `() => void` | Reset payment state |

#### Example

```tsx
import { useOrchestrapay } from '@orchestrapay/react';
import { useRef, useEffect } from 'react';

function AdvancedCheckout() {
  const containerRef = useRef<HTMLDivElement>(null);
  
  const {
    isLoaded,
    isSuccessful,
    isFailed,
    paymentData,
    errorData,
    reset,
  } = useOrchestrapay({
    publicKey: 'pk_test_xxx',
    paymentIntent: 'pi_xxx',
    onPaymentSuccess: (data) => {
      console.log('Payment successful!', data);
    },
  });

  useEffect(() => {
    if (isSuccessful) {
      // Redirect after 2 seconds
      setTimeout(() => {
        window.location.href = '/success';
      }, 2000);
    }
  }, [isSuccessful]);

  if (!isLoaded) {
    return <div>Loading payment form...</div>;
  }

  if (isSuccessful) {
    return (
      <div>
        <h2>Payment Successful!</h2>
        <p>Transaction ID: {paymentData?.transactionId}</p>
      </div>
    );
  }

  if (isFailed) {
    return (
      <div>
        <h2>Payment Failed</h2>
        <p>{errorData?.message}</p>
        <button onClick={reset}>Try Again</button>
      </div>
    );
  }

  return <div ref={containerRef} />;
}
```

## Styling

### Theme Presets

```tsx
<PaymentForm
  {...props}
  style={{ theme: 'default' }} // or 'minimalist' or 'detached'
/>
```

### Custom Styling

```tsx
<PaymentForm
  {...props}
  style={{
    custom: {
      base: {
        fontSize: '16px',
        fontFamily: 'Arial, sans-serif',
        color: '#32325d',
        borderColor: '#e0e0e0',
        borderRadius: '4px',
      },
      invalid: {
        borderColor: '#fa755a',
        iconColor: '#fa755a',
      },
    },
  }}
/>
```

## TypeScript

Full TypeScript support is included. Import types as needed:

```tsx
import type {
  PaymentFormProps,
  PaymentSuccessData,
  PaymentFailureData,
  OrchestrapayStyle,
} from '@orchestrapay/react';
```

## Server-Side Setup

Before using the React SDK, you need to create a payment intent on your server:

```typescript
// Server-side (Node.js/Express)
import { Orchestrapay } from '@orchestrapay/sdk';

const orchestrapay = new Orchestrapay({
  apiKey: process.env.ORCHESTRAPAY_SECRET_KEY,
  apiVersion: 'v202502',
});

app.post('/create-payment', async (req, res) => {
  const { amount, currency } = req.body;
  
  const paymentIntent = await orchestrapay.paymentIntents.create({
    amount,
    currency: currency || 'USD',
  });
  
  res.json({ paymentIntent: paymentIntent.id });
});
```

Then use it in your React app:

```tsx
function CheckoutPage() {
  const [paymentIntent, setPaymentIntent] = useState<string | null>(null);

  useEffect(() => {
    // Fetch payment intent from your server
    fetch('/create-payment', {
      method: 'POST',
      body: JSON.stringify({ amount: 5000, currency: 'USD' }),
    })
      .then(res => res.json())
      .then(data => setPaymentIntent(data.paymentIntent));
  }, []);

  if (!paymentIntent) return <div>Loading...</div>;

  return (
    <PaymentForm
      publicKey="pk_test_xxx"
      paymentIntent={paymentIntent}
      onPaymentSuccess={handleSuccess}
    />
  );
}
```

## Next.js Integration

Works seamlessly with Next.js (App Router or Pages Router):

```tsx
// app/checkout/page.tsx (App Router)
'use client';

import { PaymentForm } from '@orchestrapay/react';

export default function CheckoutPage() {
  return (
    <PaymentForm
      publicKey={process.env.NEXT_PUBLIC_ORCHESTRAPAY_PUBLIC_KEY!}
      paymentIntent="pi_xxx"
      onPaymentSuccess={(data) => {
        console.log('Success!', data);
      }}
    />
  );
}
```

## Best Practices

### 1. Use Stable Callbacks

Use `useCallback` to avoid unnecessary re-renders:

```tsx
const handleSuccess = useCallback((data: PaymentSuccessData) => {
  // Handle success
}, []);

<PaymentForm {...props} onPaymentSuccess={handleSuccess} />
```

### 2. Environment Variables

Store API keys in environment variables:

```bash
# .env.local
NEXT_PUBLIC_ORCHESTRAPAY_PUBLIC_KEY=pk_test_xxx
```

### 3. Error Handling

Always handle both success and failure cases:

```tsx
<PaymentForm
  {...props}
  onPaymentSuccess={(data) => {
    // Show success message, redirect, etc.
  }}
  onPaymentFailure={(data) => {
    // Show error message, log error, etc.
  }}
/>
```

## Browser Support

- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
- Mobile browsers (iOS Safari, Chrome Mobile)

## Requirements

- React 16.8.0 or higher (hooks support)
- Modern browser with ES2020 support

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute.

## License

MIT © Orchestrapay

## Support

- 📧 Email: support@orchestrapay.com
- 📚 Documentation: https://docs.orchestrapay.com
- 🐛 Issues: https://github.com/orchestrapay/npm-react/issues

## Related Packages

- [@orchestrapay/sdk](https://www.npmjs.com/package/@orchestrapay/sdk) - Node.js SDK for server-side integration
- [@orchestrapay/config](https://www.npmjs.com/package/@orchestrapay/config) - Payment gateway configurations