> ## Documentation Index
> Fetch the complete documentation index at: https://docs.corrily.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Paywall JS SDK Integration

> Use Corrily SDK to render a complete Paywall with plans & prices coming from Corrily

Corrily no-code [Paywalls](/paywall-builder/configure) are used to minimize effort required for Pricing Page implementation
by providing ready-to-use front-end Paywall component.
Simply install Corrily SDK and render the complete paywall with a few lines of code.

<Note>
  Please, read [Paywalls Overview](/paywall-builder/configure) before following the integration guide below.
</Note>

Corrily Paywalls works through a ReactJS SDK.
If your use another framework, please, send implementation request to **[hello@corrily.com](mailto:hello@corrily.com)**.

### Integrating ReactJS SDK

1. Install `@corrily/react-sdk` package:

   ```bash theme={null}
   cd front-end
   npm i --save @corrily/react-sdk
   ```

   For React version lower, than 17.0.2:

   ```bash theme={null}
   npm i --save @corrily/react-sdk --legacy-peed-deps
   ```

2. Get Corrily API Key from [Resources page](https://dashboard.corrily.com/resources) and store it in `.env.local`:
   ```
   REACT_APP_CORRILY_API_KEY=...
   ```

3. Embed Paywall into your code:
   ```typescript theme={null}
   import { CorrilyProvider, Paywall } from '@corrily/react-sdk';
   import '@corrily/react-sdk/style.css';

   // Corrily API Key
   const CORRILY_API_KEY = process.env.REACT_APP_CORRILY_API_KEY as string;


   export const App = () => {
     // For authenticated users, provide user_id
     // For unauthenticated, set userId to null
     const userId = 'test-user-id';

     // For authenticated users, provide country User belongs to
     // For unauthenticated, use IP address to let Corrily guess country by IP
     const country = "US";

     const params = {
       user_id: userId,
       country: country,
     };

     return (
       <div className="App">
         <CorrilyProvider
           apiKey={CORRILY_API_KEY}
           params={params}
         >
           <Paywall />
         </CorrilyProvider>
       </div>
     );
   }
   ```

4. Define "on-click" behaviour for selected product in `ProductList.tsx`. To do that replace `<Paywall />` with `PaywallWrapper` in the code above:

   ```typescript theme={null}
   return (
     <div className="App">
       <CorrilyProvider
         apiKey={CORRILY_API_KEY}
         params={params}
       >
         <PaywallWrapper />
       </CorrilyProvider>
     </div>
   );
   ```

   and define `PaywallWrapper` component itself:

   ```typescript theme={null}
   export const PaywallWrapper = () => {
     const handleProductSelected = async (product: Product) => {
       // Redirect to signup page or send API call to create Stripe Checkout Session

       fetch(`https://example.com/api/create-checkout-session`, {
         method: 'POST',
         headers: {
           'Content-Type': 'application/json',
         },
         body: JSON.stringify({
           product_api_id: product.api_id,
           // userId and country of your authenticated user
           user_id: userId,
           country: country,
           success_url: "https://example.com/success",
           cancel_url: "https://example.com/cancel",
         }),
       })
         .then(async (response) => {
           const res = await response.json();
           // Assume checkout session created on back-end, and it's URL returned in response
           window.location.href = res.session_url;
         })
         .catch((err) => {
           console.error(err);
         });
       };

     return (
       <Paywall
         onProductSelected={handleProductSelected}
       />
     );
   };
   ```

## Customization

### Applying custom styles to Paywall elements

Use custom CSS styles to change the appearance of Paywall elements.
All elements inside Paywall have `corrily--` prefix to separate Paywall classes from your front-end classnames.

### Custom Product component

In case you want to change Product card layout, use `CardComponent` property of the `<Paywall />`.
Here is an example:

```typescript theme={null}
import { Product, CardProps } from '@corrily/react-sdk';

const CustomCard = ({
  product,
  previousProduct,
  highlighted,
  buttonCaption,
  buttonColor,
  onProductSelected,
}: CardProps) => {
  return (
    <div className={highlighted ? 'highlighted' : ''}>
      <h1>{product.name}</h1>

      <div>
        {previousProduct && <s>{previousProduct.price}</s>}
        {product.price}
      </div>

      <h3>Features:</h3>
      <ul>
        {product.features.map(feature => (
          <li key={feature.id}>{feature.name}</li>
        ))}
      </ul>

      <button
        onClick={(e) => {onProductSelected && onProductSelected(product)}}
        style={{ backgroundColor: buttonColor }}
      >
        {buttonCaption}
      </button>
    </div>
  );
};

export const PaywallWrapper = () => {
  ...
  return (
    <Paywall
      onProductSelected={handleProductSelected}
      CardComponent={CustomCard}
    />
  );
};
```

### Additional Parameters

Under the hood Paywall SDK will send API request to fetch products and calculate prices for a given user.
In some cases you might want pass additional parameters to that API request.

**Common usecases are:**

* send `"dev": true` at the time of testing to disable DB writes
* send `"experiment_id": ...` to enforce a specific experiment being used
* send `"arm_id": ...` to enforce a specific arm
* send `"override": true` to ignore previously stored user price and recompute prices from scratch

Check the full list of parameters available in [API Reference](/api-reference/calculate-price#body-params) in body params section.

Code example with custom params:

```typescript theme={null}
...

export const App = () => {
  ...

  const params = {
    user_id: userId,
    country: country,
    dev: true,
    experiment_id: 1234,
    arm_id: 5678,
  };

  return (
    <div className="App">
      <CorrilyProvider
        apiKey={CORRILY_API_KEY}
        params={params}
      >
        ...
      </CorrilyProvider>
    </div>
  );
}
```

## Integration Examples

Check the Implementation Examples Repo to see the examples of React SDK usage:
[https://github.com/corrily/integration-examples/tree/main/react-sdk-integration](https://github.com/corrily/integration-examples/tree/main/react-sdk-integration)
