> 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).

# Share rewards

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

`contactsViral`is **A share reward feature that lets users share a mini app with friends and receive rewards based on the result**This is. When the user completes sharing, the event is delivered through the app bridge, and based on this event **whether rewards are issued and the payout 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" %}
**Caution**

* This feature is **Toss app 5.223.0 or later**only supported in. On lower versions, `undefined`is returned.
* To use this feature, **mini app approval**is required. In unapproved status, `Internal Server Error`occurs.
* Share rewards operate based on the **reward ID registered in the console** .
* Reward payout conditions, quantity, and unit are set in the **Appintos Console**.
  {% endhint %}

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

* In the sandbox app, the actual share UI is not displayed, but **an empty screen**is shown.
* In the sandbox, rewards are not actually issued.
* Be sure to add it **The QR code provided in the console**Please use it to test in the Toss app.
* The friend list may vary depending on the conditions below.
  * Whether marketing notifications are enabled
  * Whether nighttime marketing notifications are enabled
  * Whether the 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 details on the type, see `ContactsViralParams` .

**Return value**

* () => void

  Returns the app bridge cleanup function. When the sharing feature ends, be sure to call this function to release resources.

**Example: Share and receive rewards**

The example below shows the basic flow for running share rewards and handling the 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 friends 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 friends and get rewards</Button>;
}
```

{% endtab %}
{% endtabs %}

**Try the example 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

  A unique ID in UUID format that identifies the share reward. You can find it in the Appintos Console's **Mini app > Share reward** menu.

**`ContactsViralParams`**

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

**Signature**

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

**Properties**

* **options** · Required

  An option object used for the sharing feature. For the detailed type, refer to the \[ContactsViralOption]\(/pages/jNMtkgvrarYfZ4oqNamT) documentation.
* **onEvent** · Required

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

  A function that runs when an unexpected error occurs. The error object has the type `unknown`.

**`ContactsViralSuccessEvent`**

`ContactsViralSuccessEvent` is the event object passed when the contact sharing module closes normally. Along with the close reason, it provides related information such as reward status and remaining friend count.

**Signature**

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

**Properties**

* **type** · Required

  It is the type of the event. When the share module closes `close` it returns with a value.
* **data** · Required

  Contains detailed information related to module closure.

  * **data.closeReason** · Required

    The reason the module closed.

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

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

    The total reward amount the user received. 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 completed sharing with.
  * **data.rewardUnit**

    The unit of the reward. It contains the `heart`, `gem` names set in the Appintos Console. Passed optionally.

**Example**

Handle module close events

```ts
contactsViral({
  options: { moduleId: 'your-module-id' },
  onEvent: (event) => {
    if (event.type === 'close') {
      console.log('Close reason:', 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 reward information to be issued when sharing with friends is completed. Using this type lets you 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

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

  It contains information about the reward to be issued.

  * **data.rewardAmount** · Required

    The amount of reward to be issued. This is the quantity and amount value set in the Appintos Console.
  * **data.rewardUnit** · Required

    The unit of the reward. It includes reward names set in the Appintos Console, such as `'heart'`, `'gem'` and so on.

**Example**

Handle reward information after sharing is completed

```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 operate based on the **Available for both game and non-game mini apps**.
* The reward policy and payout conditions are determined by the **console settings, not the SDK**.
* 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.
