Apps in Toss Examples

repository·main·Indexed 41 days ago

https://github.com/toss/apps-in-toss-examples

Reference implementations and examples for developers building mini-apps within the Apps in Toss ecosystem. Includes guides and SDK usage for common system APIs (Storage, Environment, File), device permissions (camera, location, contacts), user data retrieval via getConsentedUserData, growth tools (promotions, sharing, analytics), and in-app ad integration.

Tokens
19.1K
Snippets
68
Records
97
Agent score
43%

What's inside Apps in Toss

  1. Overview of Growth SDK features

    main

    The Growth example demonstrates the following capabilities:

    • Promotion: Use grantPromotionReward to issue Toss Point promotions in non-game mini-apps.
    • Review Request: Use requestReview to prompt users for reviews at optimal moments.
    • Smart Messaging: Use requestNotificationAgreement to request notification consent and view server API message payloads.
    • Shared Rewards: Use contactsViral to execute friend sharing flows and handle reward events.
    • Sharing: Use getTossShareLink and share to generate Toss app deep links and open the native sharing sheet.
    • Analytics: Use Analytics.screen and Analytics.click to record analytics events including referrers.
  2. Overview of Apps in Toss Examples

    main
    Apps in Toss is a mini-app ecosystem that allows merchants to host their services within the Toss app. This repository provides various examples to assist in the development of Apps in Toss. You can download and test these example files directly. For detailed implementation instructions, refer to the README.md file located within each specific example directory.
  3. Integrate In-App Ads in Apps in Toss WebView

    main

    This package provides examples for integrating Interstitial, Rewarded, and Banner ads within the Apps in Toss WebView.

    Supported Ad Types:

    • Interstitial Ads: Preload using loadFullScreenAd and display at a user-selected moment using showFullScreenAd.
    • Rewarded Ads: Rewards must only be granted when the userEarnedReward event is triggered.
    • Banner Ads: Initialize once via TossAds.initialize and attach to empty DOM slots using TossAds.attachBanner.

    Note on Compatibility: In-app ads are not supported in sandbox apps. isSupported() may return false or ads may not appear in standard browsers or sandbox environments. Use the Apps in Toss Console QR test environment for verification.

  4. What is User Identification in Apps in Toss?

    main

    User Identification allows Apps in Toss WebView to obtain a unique user identification key (a hash) without requiring separate authentication screens or server integration. This hash is unique to each mini-app and can be used as a stable internal identifier to track the same user across sessions within that specific mini-app.

    Important Notes:

    • The returned hash is not a token for calling Toss server APIs.
    • In sandbox environments, mock data may be returned. For real behavior, test using the Toss app via QR code.
    • The hash is intended for internal use, such as managing user rankings, save data, or anonymous user records.
  5. How Toss Login works in Apps in Toss WebView

    main

    Toss Login requires both a client (WebView) and a partner server. The client's role is limited to receiving an authorization code via the appLogin function from @apps-in-toss/web-framework.

    Crucial Security Rule: All sensitive operations—exchanging the authorization code for tokens, refreshing tokens, fetching user information, and logging out—must be performed on the server side. Do not store authorization codes, AccessTokens, or RefreshTokens on the client for extended periods.

    The typical flow is:

    1. Client calls appLogin() to get an authorizationCode and referrer.
    2. Client sends the code to the partner server.
    3. Server calls the Toss Login API to exchange the code for an AccessToken and RefreshToken.
    4. Server handles user info retrieval and logout requests.
    // Client-side: Only receives the authorization code
    import { appLogin } from '@apps-in-toss/web-framework';
    
    const { authorizationCode, referrer } = await appLogin();
    // Then, send authorizationCode to your server
  6. Ad Placement and Policy Compliance

    main

    Violating ad policies can lead to ad exposure restrictions, payment holds, or service suspension.

    Prohibited Patterns (Abuse Detection):

    • Misleading Content: Do not disguise ads as content, recommended services, or financial tips. Maintain the Ad label and SDK UI.
    • Critical Flow Interference: Do not place ads on screens where users are performing core tasks (e.g., payments, authentication, account opening, or order completion).
    • Accidental Click Induction: Do not place ads immediately next to CTAs, close buttons, game controls, or input fields.
    • Duplicate Formats: Do not place two or more ads of the same format on a single screen.
    • Reward Abuse: Do not make clicking an ad a condition for a reward. Rewards must only be granted via the userEarnedReward event.
    • Event Manipulation: Do not manually create or bypass SDK events like Click, Impression, or Viewable.
    • Manual Refresh: Do not use timers to periodically refresh ad areas; use the SDK's built-in automatic refresh flow.
    • Forced Exposure: Do not show Interstitial/Rewarded ads at unpredictable times (e.g., immediately upon app entry, blocking the 'back' button, or at dead-end screens).
  7. Compare Game vs Non-Game User Identification SDKs

    main

    The SDK provides two distinct functions depending on the category of your mini-app. Using the wrong function for your app category will result in an 'INVALID_CATEGORY' error.

    Mini-app TypeSDK FunctionDescription
    GamegetUserKeyForGameRetrieves a user identification key specifically for game mini-apps.
    Non-GamegetAnonymousKeyRetrieves a user identification key specifically for non-game mini-apps.
  8. Implement Product Granting and Fulfillment Safely

    main

    When implementing in-app purchases, follow these critical safety patterns:

    1. Handle processProductGrant Correctly

    processProductGrant is the callback used to grant the product after a successful payment.

    • Timeout: You must return the success/failure status within 30 seconds.
    • Idempotency: Your partner server must process product granting idempotently based on the orderId. Do not grant the same item twice for the same order.
    • Sequence: Only call IAP.completeProductGrant after the product has been successfully granted to the user. Calling it before may result in a completed order without the user receiving the item.

    2. Recover Pending Orders

    If processProductGrant returns false or fails mid-process, the order may remain in a 'pending' state. You must implement a recovery flow using IAP.getPendingOrders when the app starts to find and complete these orders.

    3. Server-Side Order Status Checks

    To check the status of an order, your partner server should call the status API.

    • Security: The order status check must be performed by your partner server using mTLS certificates.
    • Warning: Never call the order status API directly from the Mini App client.
    • Endpoint Example: /api-partner/v1/apps-in-toss/order/get-order-status
  9. Handle User Identification SDK responses

    main

    When calling the User Identification SDK functions, you should implement logic to handle the following response scenarios:

    1. undefined: The app is unsupported or the SDK version is incompatible.
    2. 'INVALID_CATEGORY': The current mini-app category does not match the function called (e.g., calling getUserKeyForGame in a non-game app).
    3. 'ERROR': An unknown error occurred.
    4. { type: 'HASH', hash: '...' }: Success. Use the provided hash value as your internal user identification key.
  10. Implementation details for Device APIs

    main

    When implementing device APIs, keep the following patterns and technical details in mind:

    • Images: Camera and album images are retrieved with the base64: true option. To display these in an <img> tag, prepend the data:image/jpeg;base64, prefix.
    • Contacts: Use offset and nextOffset to handle paginated contact retrieval.
    • Location: For a balance between accuracy and battery consumption, use values corresponding to Accuracy.Balanced.
    • Location Cleanup: The startUpdateLocation method returns a cleanup function that stops location detection. This function should be called when a component unmounts or when the user clicks a stop button.
  11. Configure Production Ad Group IDs

    main

    To transition from testing to production, you must obtain real Ad Group IDs from the Apps in Toss Console:

    1. Select your mini-app in the Apps in Toss Console.
    2. Apply for In-App Ads in the In-App Ads menu.
    3. Create Interstitial, Rewarded, and Banner ad groups to receive your IDs.
    4. Replace the TEST_AD_GROUP_IDS values in src/ads/policy.ts with your actual IDs.

    If using a Console MCP server, you can request an agent to "Apply for in-app ads for this mini-app and create interstitial/rewarded/banner ad groups."