> For the complete documentation index, see [llms.txt](https://developers-apps-in-toss.toss.im/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers-apps-in-toss.toss.im/documentation/api-and-sdk-en/common/growth/share/reward.md).

# Sharing Rewards

For service introduction and console setup instructions, [Share Reward Introduction Document](https://developers-apps-in-toss.toss.im/guide/marketing/share-reward)please refer to.

`contactsViral`is **A share reward feature that lets users share a mini app with friends and grant rewards based on the result**When the user completes sharing, the event is delivered through the app bridge, and based on this event **whether the reward is issued and the reward details**can be checked.

Share rewards are used for the following purposes.

* Friend-invitation-based **Viral acquisition**
* Referrer rewards / invitation rewards
* Mini app growth campaigns
* **Game** · `Common promotions for non-game mini apps`

{% hint style="info" %}
**Please note**

* This feature is **Toss app 5.223.0 or later**is supported only. On lower versions, `undefined`is returned.
* To use the feature, **mini app approval**is required. In an unapproved state, `Internal Server Error`occurs.
* Share rewards **the reward ID registered in the console** is used as the basis.
* The reward issuance conditions, quantity, and unit are **Apps in Toss console**configured.
  {% endhint %}

{% hint style="info" %}
**Test environment guide**

* In the sandbox app, the actual share UI is not shown, and **a blank screen**is displayed.
* In the sandbox, rewards are not actually issued.
* It must be added **the QR code provided in the console**to test in the Toss app.
* The friend list may vary depending on the following conditions.
  * Whether marketing consent has been given
  * Whether nighttime marketing consent has been given
  * Whether a push token is registered
  * Whether contact notifications are blocked
    {% endhint %}

***

### Flow

**Game**

**Non-game**

***

**Signature**

```ts
function contactsViral(params: ContactsViralParams): () => void;
```

**Parameters**

* **params** · Required

  These are the parameters used when running the contact sharing feature. They include option settings and event handlers. For the detailed type, `ContactsViralParams` Please refer to it.

**Return value**

* () => void

  It returns the app bridge cleanup function. When the sharing feature ends, you must call this function to release resources.

**Example: Share and get rewards**

The example below shows the basic flow for running share rewards and handling share-completion or module-termination events.

{% tabs %}
{% tab title="js" %}

```js
import { contactsViral } from '@apps-in-toss/web-framework';

function handleContactsViral(moduleId) {
  const cleanup = contactsViral({
    options: { moduleId: moduleId.trim() },
    onEvent: (event) => {
      if (event.type === 'sendViral') {
        console.log('Reward issued:', event.data.rewardAmount, event.data.rewardUnit);
      } else if (event.type === 'close') {
        console.log('Module closed:', event.data.closeReason);
        cleanup();
      }
    },
    onError: (error) => {
      console.error('Error occurred:', error);
      cleanup?.();
    },
  });
}
```

{% endtab %}

{% tab title="React" %}

```tsx
import { contactsViral } from '@apps-in-toss/web-framework';
import { Button } from '@toss/tds-mobile';
import { useCallback } from 'react';

function ContactsViralButton({ moduleId }: { moduleId: string }) {
  const handleContactsViral = useCallback(() => {
    try {
      const cleanup = contactsViral({
        options: { moduleId: moduleId.trim() },
        onEvent: (event) => {
          if (event.type === 'sendViral') {
            console.log('Reward issued:', event.data.rewardAmount, event.data.rewardUnit);
          } else if (event.type === 'close') {
            console.log('Module closed:', event.data.closeReason);
            cleanup();
          }
        },
        onError: (error) => {
          console.error('Error occurred:', error);
          cleanup?.();
        },
      });
    } catch (error) {
      console.error('Error during execution:', error);
    }
  }, [moduleId]);

  return <Button onClick={handleContactsViral}>Share with a friend and get rewards</Button>;
}
```

{% endtab %}

{% tab title="React Native" %}

```tsx
import { contactsViral } from '@apps-in-toss/framework';
import { Button } from '@toss/tds-react-native';
import { useCallback } from 'react';

function ContactsViralButton({ moduleId }: { moduleId: string }) {
  const handleContactsViral = useCallback(() => {
    try {
      const cleanup = contactsViral({
        options: { moduleId: moduleId.trim() },
        onEvent: (event) => {
          if (event.type === 'sendViral') {
            console.log('Reward issued:', event.data.rewardAmount, event.data.rewardUnit);
          } else if (event.type === 'close') {
            console.log('Module closed:', event.data.closeReason);
            cleanup();
          }
        },
        onError: (error) => {
          console.error('Error occurred:', error);
          cleanup?.();
        },
      });
    } catch (error) {
      console.error('Error during execution:', error);
    }
  }, [moduleId]);

  return <Button onPress={handleContactsViral}>Share with a friend and get rewards</Button>;
}
```

{% endtab %}
{% endtabs %}

**Try the sample app**

[apps-in-toss-examples](https://github.com/toss/apps-in-toss-examples) from the repository [with-contacts-viral](https://github.com/toss/apps-in-toss-examples/tree/main/with-contacts-viral) Download the code, or scan the QR code below to try it yourself.

QR code link: intoss\://with-contacts-viral

***

**Type definitions: `ContactsViralOption`**

**Signature**

```ts
type ContactsViralOption = {
  moduleId: string;
};
```

**Properties**

* **moduleId** · Required

  This is a unique UUID-formatted ID that distinguishes share rewards. In the Apps in Toss console, **Mini app > Share rewards** you can find it in the menu.

**`ContactsViralParams`**

`ContactsViralParams` is `contactsViral` This is the parameter type used when running the function. You can configure options and specify event and error handling callbacks.

**Signature**

```ts
interface ContactsViralParams {
  options: ContactsViralOption;
  onEvent: (event: ContactsViralEvent) => void;
  onError: (error: unknown) => void;
}
```

**Properties**

* **options** · Required

  This is the options object used for the sharing feature. For the detailed type, refer to the \[ContactsViralOption]\(/pages/jNMtkgvrarYfZ4oqNamT) document.
* **onEvent** · Required

  This function runs when a share event occurs. An event object of type \[RewardFromContactsViralEvent]\(/pages/jNMtkgvrarYfZ4oqNamT) or \[ContactsViralSuccessEvent]\(/pages/jNMtkgvrarYfZ4oqNamT) is passed in.
* **onError** · Required

  This function runs when an unexpected error occurs. The error object is of type `unknown`.

**`ContactsViralSuccessEvent`**

`ContactsViralSuccessEvent` is the event object delivered when the contact-sharing module closes normally. It provides related information such as the reason for closing, reward status, and the number of friends remaining.

**Signature**

```ts
type ContactsViralSuccessEvent = {
  type: 'close';
  data: {
    closeReason: 'clickBackButton' | 'noReward';
    sentRewardAmount?: number;
    sendableRewardsCount?: number;
    sentRewardsCount: number;
    rewardUnit?: string;
  };
};
```

**Properties**

* **type** · Required

  This is the event type. When the sharing module closes, `close` it returns with this value.
* **data** · Required

  It contains detailed information related to module termination.

  * **data.closeReason** · Required

    The reason the module was closed.

    `clickBackButton`: when the user closes it by pressing the back button

    `noReward`: when it closed because there were no rewards available
  * **data.sentRewardAmount**

    The total reward amount received by the user. Passed optionally.
  * **data.sendableRewardsCount**

    The number of friends that can still be shared with. Passed optionally.
  * **data.sentRewardsCount** · Required

    The number of friends the user has finished sharing with.
  * **data.rewardUnit**

    The reward unit. The reward name set in the Apps in Toss console, `Heart`, `Gem` and similar names are used. Passed optionally.

**Example**

Handle module close events

```ts
contactsViral({
  options: { moduleId: 'your-module-id' },
  onEvent: (event) => {
    if (event.type === 'close') {
      console.log('Reason for closing:', event.data.closeReason);
      console.log('Number of friends shared with:', event.data.sentRewardsCount);
    }
  },
  onError: (error) => {
    console.error('Error occurred:', error);
  },
});
```

**`RewardFromContactsViralEvent`**

`RewardFromContactsViralEvent` is the type that contains the reward information to be issued when sharing with friends is completed. Using this type, you can check the reward information to be issued when sharing is completed.

**Signature**

```ts
type RewardFromContactsViralEvent = {
  type: 'sendViral';
  data: {
    rewardAmount: number;
    rewardUnit: string;
  };
};
```

**Properties**

* **type** · Required

  This is the event type. When sharing with a friend is completed, `'sendViral'` it returns with this value.
* **data** · Required

  it contains the reward information to be issued.

  * **data.rewardAmount** · Required

    The amount of rewards to issue. This is the quantity and amount value configured in the Apps in Toss console.
  * **data.rewardUnit** · Required

    The reward unit. This is the reward name set in the Apps in Toss console, `'Heart'`, `'Gem'` and so on.

**Example**

Handling reward information after sharing is complete

```ts
contactsViral({
  options: { moduleId: 'your-module-id' },
  onEvent: (event) => {
    if (event.type === 'sendViral') {
      console.log('Reward issued:', event.data.rewardAmount, event.data.rewardUnit);
    }
  },
  onError: (error) => {
    console.error('Error occurred:', error);
  },
});
```

### Notes

* Share rewards **Available for both game and non-game mini apps**.
* The reward policy and issuance conditions are **console settings, not the SDK**determined by.
* After handling the event, be sure to call the cleanup function.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers-apps-in-toss.toss.im/documentation/api-and-sdk-en/common/growth/share/reward.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
