npm package: @recast-sdk/recast-react
Description: The `recast-react` library provides the a SDK for RecastPay for React applications. The SDK allows for a redirect or pop-up flow to be integrated with React applications via the provided context and hooks. The SDK also provides branded components to ease 
Latest version: 1.6.0

# @recast-sdk/recast-react

The `recast-react` library provides the a SDK for RecastPay for React
applications. The SDK allows for a redirect or pop-up flow to be integrated
with React applications via the provided context and hooks. The SDK also
provides branded components to ease integration.

## Installation

Install the package

```bash npm2yarn
npm i @recast-sdk/recast-react
```

Place the `RecastProvider` at the base of the application:

```tsx
import { RecastProvider } from '@recast-sdk/recast-react';

export const App = () => {
  return (
    // set sandbox to true for testing
    <RecastProvider sandbox={true}>
      {/* Other providers, router, etc... */}
    </RecastProvider>
  );
};

export default App;
```

This configures the RecastPay hooks so they can be consumed within the
application.

## Pop-up Flow

The RecastPay Pop-up flow is actioned by calling the `useRecastPopUp` hook,

### Start Purchase

The `useRecastPopUp` hook takes two optional callbacks, `onSuccess` and
`onFailure`, the hook manages the cross `Window` communication and security
required for message passing.

The `onSuccess` callback can do many things, one might be to navigate to to a
new page. The `useRecastJWTVerify` can be used to verify the returned
AccessToken before further action is taken.

```tsx
import {
  useRecastPopUp,
  type FailureResult,
  type SuccessResult,
} from '@recast-sdk/recast-react';

export const PurchaseItem = () => {
  // Get the intentToken from your API
  const { intentToken } = useQuery();
  const { verify } = useRecastJWTVerify();

  // do something onSuccess...
  const onSuccess = useCallback(
    (result: SuccessResult) => {
      const verifiedResult = verify(result.contentAccessToken);
      console.log(verifiedResult);
    },
    [verify]
  );

  // do something onFailure...
  const onFailure = useCallback((result: FailureResult) => {
    console.error(result);
  }, []);

  // Pass the callbacks into the useRecastPopUp
  const { purchase } = useRecastPopUp(onSuccess, onFailure);

  return (
    <div>
      <span>Item Title</span>
      {intentToken ? (
        <button type="button" onClick={() => purchase(intentToken)}>
          Purchase
        </button>
      ) : null}
    </div>
  );
};

export default PurchaseItem;
```

### Safari-safe Popups: `preparePopup`

To ensure popups are not blocked by Safari or other browsers, call the `preparePopup` method from the `useRecastPopUp` hook synchronously in your button's `onClick` handler, before any async work (such as fetching an intent token). Then call `purchase` as usual when ready.

```tsx
import { useRecastPopUp } from '@recast-sdk/recast-react';

export const PurchaseButton = ({ intentToken }: { intentToken: string }) => {
  const { preparePopup, purchase } = useRecastPopUp();

  const handleClick = async () => {
    preparePopup(); // Open popup synchronously
    // ...fetch or compute intentToken asynchronously
    purchase(intentToken);
  };

  return <button onClick={handleClick}>Purchase</button>;
};
```

## Redirect Flow

The RecastPay Redirect flow is actioned by calling the `useRecastRedirect` hook
providing a contextual `purchase` function. The `purchase` function consumes
an `intentToken` and `redirectUri`, the `intentToken` is generated by a call to
the RecastPay API and the `redirectUrl` is used to redirect back to the
application once the RecastPay process is either complete or exited.

**n.b.** the `useRecastRedirect` hook must be used with in a `RecastContext`
provided by a `RecastProvider`.

### Start Purchase

The `redirectUri` must exist in your application and application state must be
maintained by the application if required.

```tsx
import { useRecastRedirect } from '@recast-sdk/recast-react';

export const PurchaseItem = () => {
  // Get the intentToken from your API
  const { intentToken } = useQuery();
  // Get the Purchase call
  const { purchase } = useRecastRedirect();

  return (
    <div>
      <span>Item Title</span>
      {intentToken ? (
        <button
          type="button"
          onClick={() => purchase(intentToken, 'redirectUri')}
        >
          Purchase
        </button>
      ) : null}
    </div>
  );
};

export default PurchaseItem;
```

### Complete Purchase

On purchase completion RecastPay will redirect back to the `redirectUri` with
data passed back via a query string.

```tsx
import {
  useRecastAccessToken,
  useRedirectPurchaseResult,
  SuccessResult,
  FailureResult,
} from '@recast-sdk/recast-react';

export const ViewItem = () => {
  // useRecastAccessToken handles the query string, verifying the Access Token
  // and providing the success state, access token payload and errors
  const { success, accessToken, error } = useRecastAccessToken(location);

  // or using callbacks
  const onSuccess = (result: SuccessResult) => {
    /**/
  };
  const onFailure = (result: FailureResult) => {
    /**/
  };
  useRedirectPurchaseResult(location, onSuccess, onFailure);

  return (
    <div>
      <span>Item Title</span>
      {success ? <div>Item Content</div> : null}
      {error ? <div>Error!</div> : null}
    </div>
  );
};

export default ViewItem;
```