# About Session Metadata Source: https://docs.appcharge.com/api-reference/about-session-metadata Appcharge supports the use of the sessionMetadata field in most of our APIs to include contextual information about a player's session. We recommend using sessionMetadata for any additional data that is not strictly required by Appcharge to execute a flow, but which can help publishers add context, assist with debugging, or store custom attributes. The sessionMetadata entity is JSON-based and provides a flexible container for storing relevant session details. **Checkout Only Solution Flow** 1. The publisher sends sessionMetadata when calling the [Create Checkout Session API](./checkout/checkout-session/create-checkout-session). 2. Appcharge stores the sessionMetadata in the Player Checkout Session. 3. The sessionMetadata is returned to the publisher in the [Grant Award Callback](./checkout/orders/player-order-reporting-webhook) and in player session-related [Order Events](./events/v2/order/order_created) **Web Store Solution Flow** 1. The sessionMetadata is included in the response to the [Authenticate Player Callback](./webstore/player-authentication/authenticate-player-callback) 2. Appcharge stores the sessionMetadata in the Player Session. 3. The sessionMetadata can be overridden by the response from the [Personalize Web Store Callback ](/../../api-reference/webstore/personalization/personalize-webstore-callback) 4. The sessionMetadata is returned to the publisher in the [Grant Award Callback](./checkout/orders/player-order-reporting-webhook) and in other player session-related events. .. # Appcharge to Publisher Secure Communication Source: https://docs.appcharge.com/api-reference/appcharge-publisher-secure-communication All communications between the publisher and the Appcharge system are authenticated and secure using HTTPS and authentication methods. Appcharge uses signature hashing for secure communication between the two platforms. The main key can be found in the Appcharge dashboard, Admin panel, and Integration tab. In every webhook coming from Appcharge, 2 HTTP headers will be added: 1. "x-publisher-token": The publisher token found in the Publisher Dashboard under **Settings > Integration**. It can be used for multiple Appcharge accounts. 2. "signature": The HTTP payload signed (hashed) using the below description: * The schema consists of 2 parts: * Time in UNIX timestamp format * Time is in UTC Now * Verify that the time sent in the payload is at the last 1-5 minutes * The HTTP payload sign using sha256 and the main key. Formatting the output in hex encoding ``` static signPayload(currentTimestamp: Date, data: string, secretKey: string): string { const hmac = crypto.createHmac("sha256", secretKey); const tAndData = currentTimestamp + "." + data; hmac.update(tAndData); return hmac.digest("hex"); // hex encoding } const currentTimestamp = new Date().getTime(); // UNIX timestamp const sign = signPayload(currentTimestamp, httpPayload, mainKey); // HTTP payload signing const signature: `t=${currentTimestamp},v1=${sign}`, ``` Validating the signature * Take the currentTimestamp from the provided header * Run the same algorithm as above to create the signature using the currentTimestamp from the header * Validate that the currentTimestamp is not older then \~5 minutes to prevent replay attack # Grant Award Callback Source: https://docs.appcharge.com/api-reference/checkout/awards/grant-award-callback openapi-grant-award.json post /{YOUR_GRANT_AWARD_ENDPOINT} > **Note:** This is a callback API. Appcharge calls this endpoint on your server when specific events occur. Notifies your system to grant an award to a customer. Appcharge calls this endpoint after a customer payment is finalized or when a free offer is collected. When your server responds with a valid `publisherPurchaseId`, Appcharge redirects the customer to the success page confirming their purchase. > **Warning:** The `playerEmail`, `createdByIp`, and `zipCode` properties are deprecated. They will continue to be included in callback payloads for backward compatibility until **November 27, 2026**, but we recommend removing any logic that reads or stores these values as soon as possible. After this date, these properties will be removed from the payload and won't be supported or accessible. ```bash Grant Award - Paid Order theme={"system"} curl -X POST \ 'https://{YOUR_GRANT_AWARD_ENDPOINT}' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -H 'signature: ' \ -d '{ "orderId": "12345678", "purchaseId": "abc123xyz789", "appChargePaymentId": "pay_9876543210", "purchaseDateAndTimeUtc": "2024-07-21T14:17:27.329Z", "playerId": "player_12345", "bundleName": "Starter Pack", "bundleId": "684044555ed01178ed2c0b3b", "sku": "starterpack", "products": [ { "amount": 1000, "sku": "prod22224448763533", "name": "Gold Coins" } ], "priceInDollar": 999, "priceInCents": 999, "subTotal": 850, "tax": 149, "taxRate": 17.5, "taxInDollar": 149, "currency": "USD", "currencyExchangeCost": 0, "action": "purchase", "actionStatus": "completed", "originalPriceInDollar": 1499, "paymentPriceInDollar": 999, "paymentMethod": "card", "countryCode2": "US", "priceTotalInDollar": 1148, "playerEmail": "john.doe@example.com", "sessionMetadata": "{ "userId": "12345", "level":10 }", "receiptId": "receipt_abc123", "estimatedPublisherNetAmount": 850.50, "estimatedAppchargeFee": 148.50, "pricePointMetadata": 999, "createdByIp": "192.168.1.1", "zipCode": "10001", "awardFlow": "auto", "promoCodeName": "SUMMER2024", "discount": 100.0, "discountRatePoints": "10", "storeMetadata": { "productsSequenceIndex": 1, "offerType": "Bundle", "utms": { "utmSource": "Facebook", "utmMedium": "email", "utmCampaign": "spring_sale" } } }' ``` ```bash Grant Award - Free Order theme={"system"} curl -X POST \ 'https://{YOUR_GRANT_AWARD_ENDPOINT}' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -H 'signature: ' \ -d '{ "orderId": "662345678", "purchaseId": "6abc123xyz789", "appChargePaymentId": "pay_6876543210", "purchaseDateAndTimeUtc": "", "playerId": "player_12345", "bundleName": "First Daily Bonus", "bundleId": "664044555ed01178ed2c0b36", "sku": "first-daily-bonus", "products": [ { "amount": 400, "sku": "prod62224448763536", "name": "Gold Coins" } ], "priceInDollar": 0, "priceInCents": 0, "subTotal": 0, "tax": 0, "taxRate": 0, "taxInDollar": 0, "currency": "USD", "currencyExchangeCost": 0, "action": "bonus", "actionStatus": "completed", "originalPriceInDollar": 0, "paymentPriceInDollar": 0, "paymentMethod": "", "playerIp": "192.0.2.1", "priceTotalInDollar": 0, "playerEmail": "john.doe@example.com", "sessionMetadata": "{ "userId": "12345", "level":10 }", "receiptId": "receipt_6abc123", "estimatedPublisherNetAmount": 0, "estimatedAppchargeFee": 148.50, "createdByIp": "192.168.1.1", "zipCode": "10001", "awardFlow": "auto", "discount": 0, "discountRatePoints": "0", "storeMetadata": { "productsSequenceIndex": 1, "offerType:" "PopUp" } }' ``` ```json Grant Award - Paid Order theme={"system"} { "publisherPurchaseId": "222673459829966773354378" } ``` ```json Grant Award - Free Order theme={"system"} { "publisherPurchaseId": "662673459829966773354378" } ``` ```json 400 theme={"system"} { "publisherErrorMessage": "Unable to grant the award because the player ID is invalid." } ``` ```json 500 theme={"system"} { "publisherErrorMessage": "Unable to grant the award because the inventory service is unavailable." } ``` # Introduction Source: https://docs.appcharge.com/api-reference/checkout/awards/introduction The Awards API service allows you to manage the awards lifecycle for your app. Awards are how customers get the items or bonuses they purchase or earn with Appcharge. When a customer places an order, whether free or paid, Appcharge processes the transaction, verifies the payment if required, and then calls an API endpoint on your server with the order details. This callback notifies your server to deliver the award to the customer. Once your server responds with the purchase ID, Appcharge assumes the award has been granted and redirects the customer to the success page confirming that the purchase was completed. Learn more about the [Awards feature](/../../guides/checkout/awards/about-awards). With Awards API service, you can: * Get notified when to [grant an award](./grant-award-callback) to your customer. ## Before you begin Review the following before you begin: * Make sure you've completed the [award notifications setup](/../../guides/checkout/awards/set-up-award-notifications) in the Publisher Dashboard. * Align the transaction by pairing the Order ID provided by Appcharge, `orderId` with your purchase ID, `publisherPurchaseId`, for each transaction. ## Retry mechanism When Appcharge sends award requests to your endpoint, it retries failed delivery attempts to handle transient network or server issues, using the following intervals: | Attempt | Delay from previous attempt | | - | - | | Initial delivery | Immediate | | 1st retry | 10 seconds | | 2nd retry | 10 seconds | If your endpoint returns an error (`4XX` or `5XX`), the response body must include a `publisherErrorMessage` field explaining the failure. This allows Appcharge to surface meaningful error context for each failed attempt. If all delivery attempts fail, you can still award the player manually from the Publisher Dashboard: 1. In the sidebar menu, go to **Dashboard > Orders**. You'll see a list of orders. 2. Click the order in which you want to award the player. 3. In the top right corner, click **Retry Award**. # Cancel Checkout Session Source: https://docs.appcharge.com/api-reference/checkout/checkout-session/cancel-checkout-session openapi-cancel-checkout-session.json POST /checkout/v3/cancel Cancels a checkout session. Cancel a checkout session to prevent additional payments from using the same checkout URL. Canceling a checkout session doesn't affect the associated order. To monitor the order status, use [order events](../../events/introduction#order-events) or [view orders](/../../guides/publisher-dashboard/view-orders) in the Publisher Dashboard. ## How cancellation works 1. A player visits your web store and selects an offer to purchase. 2. Your web store calls the [Create Checkout Session](./create-checkout-session) endpoint to create a checkout session. 3. The player is redirected to Appcharge Checkout. 4. The player exits checkout without completing the purchase. For example, the player clicks the **X** button in checkout, navigates away from the checkout page, or closes the browser tab. 5. After the player exits, call the Cancel Checkout Session endpoint to cancel the session. 6. Appcharge notifies your web store with `{"isOrderCancelled": true}`. ## Response behavior `{"isOrderCancelled": true}` means the session reference is no longer active. This response is also returned when the authorization header is invalid or missing. To confirm that the checkout session was canceled, try to complete a payment using the same checkout URL: * A canceled session returns an error. * An active session doesn't return an error. Check that you're sending the correct authorization header. # Create Checkout Session API Source: https://docs.appcharge.com/api-reference/checkout/checkout-session/create-checkout-session openapi-create-checkout-session.json POST /checkout/v1/session Creates a checkout session. # Checkout Webhooks Source: https://docs.appcharge.com/api-reference/checkout/checkout-webhooks The Appcharge Checkout solution offers a range of webhooks to help publishers monitor and manage player activities, orders, and financial events in real-time. These webhooks provide valuable insights into player interactions and the financial flow of transactions within the platform: **Grant Award Callback:** This webhook provides periodic reports on all player orders, including detailed summaries of the transactions, to help publishers track order trends and manage inventory.) * Link to [Grant Award Callback](./orders/player-order-reporting-webhook) # Bulk Create Promo Codes Source: https://docs.appcharge.com/api-reference/checkout/coupons/bulk-create-promo-codes openapi-coupons.json post /coupons/coupon/{couponName}/promo-codes Creates multiple promo codes for a specific coupon. Maximum of 1,000 promo codes allowed per request. ```bash Bulk Create Promo Codes theme={"system"} curl -X POST \ 'https://api.appcharge.com/coupons/coupon/summer26/promo-codes' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "promoCodes": [ { "name": "swx1", "maxRedemptions": 1, "active": true }, { "name": "swx2", "maxRedemptions": 1, "active": true } ] }' ``` ```json Bulk Create Promo Codes theme={"system"} { "promoCodes": [ { "name": "swx1", "active": true, "maxRedemptions": 1, "createdAt": "2025-01-22T15:58:24.116Z", "updatedAt": "2025-01-25T08:44:26.668Z" }, { "name": "swx2", "active": true, "maxRedemptions": 1, "createdAt": "2025-01-22T15:58:24.116Z", "updatedAt": "2025-01-25T08:44:26.668Z" } ] } ``` ```json 400 theme={"system"} { "error": "Invalid coupon name. Use only English letters and numbers." } ``` ```json 400 theme={"system"} { "error": "Invalid promo code name. Use only English letters and numbers." } ``` ```json 400 theme={"system"} { "error": "Promo codes count must be at least 1." } ``` ```json 400 theme={"system"} { "error": "Promo codes count must not exceed 1000." } ``` ```json 400 theme={"system"} { "error": "Some promo codes in the request are duplicated: swx1, swx2." } ``` ```json 400 theme={"system"} { "error": "maxRedemptions must not be less than 1." } ``` ```json 400 theme={"system"} { "error": "Missing required field: promoCodes." } ``` ```json 404 theme={"system"} { "error": "Coupon not found." } ``` ```json 409 theme={"system"} { "error": "Some promo codes are already active on other coupon: swx1, swx2." } ``` ```json 500 theme={"system"} { "error": "Unexpected error. Please contact support." } ``` # Bulk Set Promo Codes Activation Source: https://docs.appcharge.com/api-reference/checkout/coupons/bulk-set-promo-codes-activation openapi-coupons.json patch /coupons/coupon/{couponName}/promo-codes/set-activation Activates or deactivates promo codes for a specific coupon. Maximum of 1,000 promo code names allowed per request. ```bash Bulk Set Promo Codes Activation theme={"system"} curl -X PATCH \ 'https://api.appcharge.com/coupons/coupon/summer26/promo-codes/set-activation' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "active": false, "promoCodeNames": ["swx1", "swx2", "swx3"] }' ``` ```json Bulk Set Promo Codes Activation theme={"system"} { "promoCodes": [ { "name": "swx1", "active": false, "maxRedemptions": 100, "createdAt": "2025-01-22T15:58:24.116Z", "updatedAt": "2025-03-05T10:00:00.000Z", "redemptions": 28 }, { "name": "swx2", "active": false, "maxRedemptions": 200, "createdAt": "2025-01-22T15:58:24.116Z", "updatedAt": "2025-03-05T10:00:00.000Z", "redemptions": 80 }, { "name": "swx3", "active": false, "maxRedemptions": 250, "createdAt": "2025-01-22T15:58:24.116Z", "updatedAt": "2025-03-05T10:00:00.000Z", "redemptions": 30 } ] } ``` ```json 400 theme={"system"} { "error": "Promo code names count must be at least 1." } ``` ```json 400 theme={"system"} { "error": "Promo code names count must not exceed 1000." } ``` ```json 404 theme={"system"} { "error": "Coupon not found." } ``` ```json 500 theme={"system"} { "error": "Unexpected error. Please contact support." } ``` # Create Coupon Source: https://docs.appcharge.com/api-reference/checkout/coupons/create-coupon openapi-coupons.json post /coupons/coupon Creates a coupon. ```bash Create Coupon theme={"system"} curl -X POST \ 'https://api.appcharge.com/coupons/coupon' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "name": "summer26", "discountPercentage": 10, "maxRedemptionsPerCustomer": 2, "allowedPlayers": ["player123", "player456", "player789"], "supportedOfferExternalIds": ["bundle1", "rollingoffer3"], "expiredBy": "2025-04-02T06:54:51.670Z", "startsAt": "2025-02-02T06:54:51.670Z" }' ``` ```json Create Coupon theme={"system"} { "name": "summer26", "active": true, "discountPercentage": 10, "maxRedemptionsPerCustomer": 2, "expiredBy": "2025-04-02T06:54:51.670Z", "startsAt": "2025-02-02T06:54:51.670Z", "supportedOfferExternalIds": ["bundle1", "rollingoffer3"], "firstTimePurchase": false, "allowedPlayers": ["player123", "player456", "player789"] } ``` ```json 400 theme={"system"} { "error": "Invalid coupon name. Use only English letters and numbers." } ``` ```json 400 theme={"system"} { "error": "Missing required field: discountPercentage." } ``` ```json 400 theme={"system"} { "error": "startsAt must be in the future." } ``` ```json 400 theme={"system"} { "error": "expiredBy must be after startsAt." } ``` ```json 400 theme={"system"} { "error": "discountPercentage must be between 1 and 99." } ``` ```json 409 theme={"system"} { "error": "Coupon name 'summer26' is already in use" } ``` ```json 500 theme={"system"} { "error": "Unexpected error. Please contact support." } ``` # Get Coupon By Name Source: https://docs.appcharge.com/api-reference/checkout/coupons/get-coupon-by-name openapi-coupons.json get /coupons/coupon/{couponName} Retrieves a specific coupon by name. ```bash Get Coupon By Name theme={"system"} curl -X GET \ 'https://api.appcharge.com/coupons/coupon/summer26' \ -H 'x-publisher-token: ' ``` ```json Get Coupon By Name theme={"system"} { "name": "summer26", "active": true, "discountPercentage": 10, "maxRedemptionsPerCustomer": 2, "expiredBy": "2025-04-02T06:54:51.670Z", "startsAt": "2025-02-02T06:54:51.670Z", "supportedOfferExternalIds": ["bundle1", "rollingoffer3"], "firstTimePurchase": false, "allowedPlayers": ["player123", "player456", "player789"] } ``` ```json 400 theme={"system"} { "error": "Invalid coupon name. Use only English letters and numbers." } ``` ```json 404 theme={"system"} { "error": "Coupon not found." } ``` ```json 500 theme={"system"} { "error": "Unexpected error. Please contact support." } ``` # Get Promo Code Source: https://docs.appcharge.com/api-reference/checkout/coupons/get-promo-code openapi-coupons.json get /coupons/coupon/{couponName}/promo-code/{promoCodeName} Retrieves a specific promo code. ```bash Get Promo Code theme={"system"} curl -X GET \ 'https://api.appcharge.com/coupons/coupon/summer26/promo-code/swx1' \ -H 'x-publisher-token: ' ``` ```json Get Promo Code theme={"system"} { "name": "swx1", "active": true, "maxRedemptions": 250, "createdAt": "2025-01-22T15:58:24.116Z", "updatedAt": "2025-01-25T08:44:26.668Z", "redemptions": 100, } ``` ```json 400 theme={"system"} { "error": "Invalid coupon name. Use only English letters and numbers." } ``` ```json 400 theme={"system"} { "error": "Invalid promo code name. Use only English letters and numbers." } ``` ```json 404 theme={"system"} { "error": "Coupon not found." } ``` ```json 404 theme={"system"} { "error": "Promo code not found." } ``` ```json 500 theme={"system"} { "error": "Unexpected error. Please contact support." } ``` # Introduction Source: https://docs.appcharge.com/api-reference/checkout/coupons/introduction The Coupons API service allows you to create and manage coupons and promo codes to offer discounts to players during checkout. Use coupons to run promotional campaigns, reward loyal players, or incentivize first-time purchases. Learn more about the [Coupons feature](/../../guides/checkout/coupons/about-coupons). With the Coupons API service, you can: * [Create a coupon](./create-coupon) with customizable discount percentages and restrictions. * [Retrieve a coupon](./get-coupon-by-name) by name to view its details and settings. * [Update an existing coupon](./update-coupon). * [Bulk create promo codes](./bulk-create-promo-codes) for a coupon to distribute to players. * [Retrieve a promo code](./get-promo-code). * [Retrieve a list of all promo codes](./list-promo-codes). * [Activate or deactivate promo codes](./bulk-set-promo-codes-activation) for a specific coupon. ## Before you begin Review the following before you begin: * A coupon must be created before you can create promo codes for it. * When using the Create Coupon API, you can restrict the coupon by setting: * `supportedOfferExternalIds`: Limits the coupon to specific offers. Value must be the existing offer's External ID. * `allowedPlayers`: Limits the coupon to specific players. * `firstTimePurchase`: Limits the coupon to first-time buyers in the web store. ## Terminology * **Coupon**: A discount configuration that defines the discount percentage and rules such as expiration dates, allowed players, and supported offers. * **Promo code**: A unique code associated with a coupon that players enter at checkout to receive the discount. Each promo code can have its own redemption limit. # List Promo Codes Source: https://docs.appcharge.com/api-reference/checkout/coupons/list-promo-codes openapi-coupons.json get /coupons/coupon/{couponName}/promo-codes Retrieves a paginated list of up to 1,000 promo codes for a specific coupon. ```bash List Promo Codes theme={"system"} curl -X GET \ 'https://api.appcharge.com/coupons/coupon/summer26/promo-codes?limit=1000&sortDirection=desc&isActive=true&page=1' \ -H 'x-publisher-token: ' ``` ```json List Promo Codes theme={"system"} { "promoCodes": [ { "name": "swx1", "active": false, "maxRedemptions": 1, "createdAt": "2025-01-22T15:58:24.116Z", "updatedAt": "2025-01-22T15:58:24.116Z", "redemptions": 100 }, { "name": "swx2", "active": true, "maxRedemptions": 1, "createdAt": "2025-01-22T15:58:24.116Z", "updatedAt": "2025-01-25T08:44:26.668Z", "redemptions": 50 } ], "totalCount": 2, "totalPages": 1, "hasNextPage": false, "page": 1, "limit": 1000 } ``` ```json 404 theme={"system"} { "error": "Coupon not found." } ``` # Update Coupon Source: https://docs.appcharge.com/api-reference/checkout/coupons/update-coupon openapi-coupons.json patch /coupons/coupon/{couponName} Updates an existing coupon. Only the fields provided in the request body will be updated. ```bash Update Coupon theme={"system"} curl -X PATCH \ 'https://api.appcharge.com/coupons/coupon/summer26' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "active": false, "maxRedemptionsPerCustomer": null, "expiredBy": null, "startsAt": "2026-06-16T09:30:53.378Z", "supportedOfferExternalIds": ["1", "3"], "firstTimePurchase": false, "allowedPlayers": ["player123", "player456"] }' ``` ```json Update Coupon theme={"system"} { "name": "summer26", "active": false, "discountPercentage": 10, "maxRedemptionsPerCustomer": null, "expiredBy": null, "startsAt": "2026-06-16T09:30:53.378Z", "supportedOfferExternalIds": ["1", "3"], "firstTimePurchase": false, "allowedPlayers": ["player123", "player456"] } ``` ```json 400 theme={"system"} { "error": "startsAt must be a time in the future." } ``` ```json 400 theme={"system"} { "error": "expiredBy must be a time later than startsAt." } ``` ```json 400 theme={"system"} { "error": "Trying to update fields that can’t be updated." } ``` ```json 404 theme={"system"} { "error": "Coupon not found." } ``` ```json 500 theme={"system"} { "error": "Unexpected error. Please contact support." } ``` # Analytics Reporting API Source: https://docs.appcharge.com/api-reference/checkout/finance-and-analytics/analytics-reporting-api openapi-analytics.json GET /reporting/analytics/stats > **Note:** You can read more about the [Reporting Analytics API](/../../guides/publisher-dashboard/view-analytics) in the Guides section. | Metric | Description | Type | | - | - | - | | **`totalRevenue`** | Total revenue including tax | Monetary (USD) | | **`totalRevenueWithoutTax`** | Total revenue excluding tax | Monetary (USD) | | **`deposits`** | Number of User Deposits | Integer | | **`arppu`** | Average revenue per paying user | Monetary (USD) | | **`averageDepositsPerDepositor`** | Average deposits per depositor | Monetary (USD) | | **`depositors`** | Total unique depositors | Integer | | **`arpu`** | Average revenue per user | Monetary (USD) | | **`activeUsers`** | Total unique active users | Integer | | **`sessions`** | Total unique active users | Integer | | **`dau`** | Average daily active users | Integer | ### Additional Events Custom metrics can be added upon request. Contact support for integration. # Financial Reporting API Source: https://docs.appcharge.com/api-reference/checkout/finance-and-analytics/financial-reporting-api openapi-financial-rep.json POST /reporting/reports/orders When a player makes a purchase, Appcharge processes the transaction. After the player is charged, Appcharge sends an update to the publisher with all the transaction details using a predefined webhook. ### Statuses Parameter Options This table lists the possible values for the `statuses` parameter, each representing a different stage or outcome of a transaction. The values range from the initial creation of a transaction to the various stages of payment, refund, charge, and dispute processes. | Status | Description | | - | - | | **created** | The order has been created. | | **payment\_pending** | The transaction has been initiated, but payment information has not yet been submitted. | | **payment\_expired** | The checkout session has expired after being open for 1 hour. | | **payment\_failed** | Failed to initiate a payment, and the award was not granted. | | **payment\_refund\_pending** | Refund has been requested and is awaiting processing. | | **payment\_refund\_requires\_action** | Additional action is needed to process the refund. | | **payment\_refunded** | Refund has been successfully processed. | | **payment\_refund\_failed** | Refund attempt was unsuccessful. | | **payment\_refund\_canceled** | Refund process has been canceled. | | **payment\_canceled** | Payment has been canceled. | | **charge\_pending** | The award is being processed but is not yet completed. | | **charge\_succeed** | Payment was successful, and the award was granted. | | **charge\_failed** | The award attempt was unsuccessful. | | **payment\_dispute\_open** | A dispute has been opened against the payment. | | **payment\_dispute\_lost** | The dispute has been resolved in favor of the customer. | | **payment\_dispute\_won** | The dispute has been resolved in favor of the merchant. | | **payment\_dispute\_evidence\_submitted** | Evidence has been submitted for the dispute. | | **payment\_dispute\_inquiry\_open** | An inquiry has been opened regarding a potential dispute. | | **payment\_dispute\_inquiry\_evidence\_submitted** | Evidence has been submitted for the dispute inquiry. | | **payment\_dispute\_inquiry\_won** | The inquiry has been resolved in favor of the merchant. | # Get Transactions Source: https://docs.appcharge.com/api-reference/checkout/finance-and-analytics/get-transactions openapi-get-transactions.json GET /reporting/financial-data/transactions Retrieves transaction data for a given time period. ```bash Get Transactions theme={"system"} curl -X GET \ 'https://api.appcharge.com/reporting/financial-data/transactions?startDate=2025-05-26T00:00:00Z&endDate=2025-07-24T23:59:59Z&limit=100&sortDirection=asc' \ -H 'x-publisher-token: ' ``` ```json Get Transactions theme={"system"} { "totalCount": 245, "nextCursor": "eyJpZCI6IjY0YzkidQ==", "nextPageQuery": "?startDate=2025-05-26T00:00:00Z&endDate=2025-07-24T23:59:59Z&limit=100&sortDirection=asc&cursor=eyJpZCI6IjY0YzkidQ==", "results": [ { "orderId": "ac_order_98f3pb4", "purchaseId": "pr-1234-5678-9012-34567", "publisherTransactionId": "ca-9832-custom", "timestamp": "2025-05-26T14:30:00.000Z", "customerDetails": { "id": "jane-doe", "email": "jan.doe@example.com" }, "geolocation": { "countryCode2": "US", "region": "CA", "ipAddress": "192.168.1.10", "zipCode": "94107" }, "device": { "osType": "Mac OS", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "offerDetails": { "offerId": "offer_7890", "offerName": "Gem Pack", "type": "Bundle", "products": [ { "name": "Gems", "sku": "gems_100", "quantity": 100 } ] }, "transactionDetails": { "id": "64c9f6a12e1b4a3d9c7a5f1ef", "type": "paid", "amount": 999, "amountUsd": 999, "totalTaxAmount": 90, "totalTaxAmountUsd": 90, "currencyExchangeCostUsd": 15, "chargebackFeeUsd": 0, "transactionFeeUsd": 35, "publisherNetAmountUsd": 859, "currencyCode": "USD", "currencySymbol": "$", "paymentMethod": "credit_card" } }, { "orderId": "6981ddaac658821c7960ca0b", "purchaseId": "pr_9a9aaea0318d409ebb9afdc37df37a62", "publisherTransactionId": "123456789012", "timestamp": "2026-02-03T11:41:42.155Z", "customerDetails": { "id": "jim-jardashian", "email": "jim.jardashian@example.com" }, "geolocation": { "countryCode2": "US", "region": "NY", "ipAddress": "192.168.1.11", "zipCode": "10025" }, "device": { "osType": "iOS", "osVersion": "18", "browserType": null, "browserVersion": null }, "offerDetails": { "offerId": "692ed6a00dffce88151a9575", "offerName": "Treasure Pack", "type": "Bundle", "products": [ { "name": "Coins", "sku": "coins_555", "quantity": 55 } ] }, "transactionDetails": { "id": "6981def652cf42968c4ba2d3c", "type": "refund", "amount": -500, "amountUsd": -500, "totalTaxAmount": -76, "totalTaxAmountUsd": -76, "currencyExchangeCostUsd": 0, "chargebackFeeUsd": 0, "transactionFeeUsd": 55, "publisherNetAmountUsd": -424, "currencyCode": "USD", "currencySymbol": "$", "paymentMethod": "Credit Card" } } ] } ``` ```json 400 - Date validation error theme={"system"} { "statusCode": 400, "error": "Bad Request", "message": [ { "validationErrorNumber": 1, "error": "endDate must be after startDate" } ], "requestUrl": "/reporting/financial-data/transactions?startDate=2025-07-24T00:00:00Z&endDate=2025-05-26T23:59:59Z" } ``` ```json 400 - Invalid sort direction theme={"system"} { "statusCode": 400, "error": "Bad Request", "message": [ { "validationErrorNumber": 1, "error": "sortDirection must be either \"asc\" or \"desc\"" } ], "requestUrl": "/reporting/financial-data/transactions?startDate=2025-05-26T00:00:00Z&endDate=2025-07-24T23:59:59Z&sortDirection=invalid" } ``` ```json 401 - Missing publisher token theme={"system"} { "statusCode": 401, "error": "Unauthorized", "message": [ { "validationErrorNumber": 1, "error": "Publisher token is required" } ], "requestUrl": "/reporting/financial-data/transactions?startDate=2025-05-26T00:00:00Z&endDate=2025-07-24T23:59:59Z" } ``` ```json 401 - Invalid publisher token theme={"system"} { "statusCode": 401, "error": "Unauthorized", "message": [ { "validationErrorNumber": 1, "error": "Publisher not found" } ], "requestUrl": "/reporting/financial-data/transactions?startDate=2025-05-26T00:00:00Z&endDate=2025-07-24T23:59:59Z" } ``` ```json 500 - Server error theme={"system"} { "statusCode": 500, "error": "Internal Server Error", "message": [ { "validationErrorNumber": 1, "error": "Failed to get transactions" } ], "requestUrl": "/reporting/financial-data/transactions?startDate=2025-05-26T00:00:00Z&endDate=2025-07-24T23:59:59Z" } ``` # Create Price Point Source: https://docs.appcharge.com/api-reference/checkout/price-localization/create-price-point openapi-price-points.json post /v1/price-points Creates a price point from a base price in USD cents. When you pass the base price, Appcharge generates and returns localized prices for that price point in every supported currency. Learn more about [how localized prices are calculated](./introduction#how-localized-prices-are-calculated). To override automatically calculated prices for specific countries, pass the `priceOverrides` property with the relevant country codes and your custom prices. ```bash Create Price Point theme={"system"} curl -X POST \ 'https://api.appcharge.com/v1/price-points' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ -d '{ "priceInUsdCents": 999, "priceOverrides": [ { "countryCode2": "BR", "price": 29.99 } ] }' ``` ```json Create Price Point theme={"system"} { "priceInUsdCents": 999, "lastUpdate": "2026-03-01T10:00:00.000Z", "priceByCountry": [ { "price": 9.99, "currencyCode": "USD", "isOverridden": false, "taxModel": "Excluded", "taxRate": 0, "country": "United States", "countryCode2": "US", "usdExchangeRateOnCalc": 1, "exchangeRateDrift": "0%" }, { "price": 7.99, "currencyCode": "GBP", "isOverridden": false, "taxModel": "Included", "taxRate": 20, "country": "United Kingdom", "countryCode2": "GB", "usdExchangeRateOnCalc": 0.79, "exchangeRateDrift": "-1.2%" }, { "price": 29.99, "currencyCode": "BRL", "isOverridden": true, "taxModel": "Excluded", "taxRate": 0, "country": "Brazil", "countryCode2": "BR", "usdExchangeRateOnCalc": 5.05, "exchangeRateDrift": "2.3%" }, { "price": 8.99, "currencyCode": "EUR", "isOverridden": false, "taxModel": "Included", "taxRate": 19, "country": "Germany", "countryCode2": "DE", "usdExchangeRateOnCalc": 0.92, "exchangeRateDrift": "-0.5%" } ] } ``` ```json 400 Schema Validation Error theme={"system"} { "message": "Invalid request body." } ``` ```json 400 Invalid Country Code theme={"system"} { "message": "Country code ZZ not found in existing custom pricing." } ``` ```json 409 theme={"system"} { "message": "Cannot create new pricing. The price point already exists." } ``` # Delete Price Point Source: https://docs.appcharge.com/api-reference/checkout/price-localization/delete-price-point openapi-price-points.json delete /v1/price-points/{priceInUsdCents} Deletes a specific price point. ```bash Delete Price Point theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/v1/price-points/999' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ ``` ```json Delete Price Point theme={"system"} { "priceInUsdCents": 999, "lastUpdate": "2026-03-01T10:00:00.000Z", "priceByCountry": [ { "price": 9.99, "currencyCode": "USD", "isOverridden": false, "taxModel": "Excluded", "taxRate": 0, "country": "United States", "countryCode2": "US", "usdExchangeRateOnCalc": 1, "exchangeRateDrift": "0%" }, { "price": 7.99, "currencyCode": "GBP", "isOverridden": false, "taxModel": "Included", "taxRate": 20, "country": "United Kingdom", "countryCode2": "GB", "usdExchangeRateOnCalc": 0.79, "exchangeRateDrift": "-1.2%" }, { "price": 29.99, "currencyCode": "BRL", "isOverridden": true, "taxModel": "Excluded", "taxRate": 0, "country": "Brazil", "countryCode2": "BR", "usdExchangeRateOnCalc": 5.05, "exchangeRateDrift": "2.3%" }, { "price": 8.99, "currencyCode": "EUR", "isOverridden": false, "taxModel": "Included", "taxRate": 19, "country": "Germany", "countryCode2": "DE", "usdExchangeRateOnCalc": 0.92, "exchangeRateDrift": "-0.5%" } ] } ``` ```json 404 theme={"system"} { "message": "Price point 999 not found." } ``` # Price Localization Errors Source: https://docs.appcharge.com/api-reference/checkout/price-localization/error-messages This articles outlines error messages that might be issued when calling endpoints of the Price Localization API. ## Create Price Point errors The [Create Price Point](./create-price-point) endpoint might issue the following error messages: | Error code | Error Message | Description | | - | - | - | | `400` | `Invalid request body` | The request body failed schema validation. | | `400` | `Country code ZZ not found in existing custom pricing.` | The country code doesn't exist in custom pricing. | | `409` | `Cannot create new pricing. The price point already exists.` | The price point already exists. | ## Get Price Point errors The [Get Price Point](./get-price-point) endpoint might issue the following error messages: | Error code | Error Message | Description | | - | - | - | | `404` | `Price point 999 not found.` | The requested price point wasn't found. | ## Get Price Points for a Country errors The [Get Price Points for a Country](./get-price-points-for-a-country) endpoint might issue the following error messages: | Error code | Error Message | Description | | - | - | - | | `400` | `Too many price points used, maximum is 50` | More than 50 `pricesInUsdCents` values. | | `400` | `Invalid priceInUsdCents value: must be a positive integer [invalid1, invalid2].` | Invalid `pricesInUsdCents` value. | | `400` | `Invalid countryCode2: must be ISO 3166-1 alpha-2.` | Invalid `countryCode2` value. | | `400` | `countryCode2 XX is not supported.` | `countryCode2` not supported. | | `401` | `Unauthorized` | The publisher token is missing or invalid. | | `429` | `Rate limit exceeded.` | The request exceeded the rate limit of 5,000 requests per minute. | ## Update Price Point errors The [Update Price Point](./update-price-point) endpoint might issue the following error messages: | Error code | Error Message | Description | | - | - | - | | `400` | `Invalid request body` | The request body failed schema validation. | | `400` | `Country code ZZ not found in existing custom pricing.` | The country code doesn't exist in custom pricing. | | `404` | `Price point 999 not found.` | The requested price point wasn't found. | | `409` | `Cannot create new pricing. The price point already exists.` | The price point already exists. | ## Delete Price Point errors The [Delete Price Point](./delete-price-point) endpoint might issue the following error messages: | Error code | Error Message | Description | | - | - | - | | `404` | `Price point 999 not found.` | The requested price point wasn't found. | # Get All Price Points Source: https://docs.appcharge.com/api-reference/checkout/price-localization/get-all-price-points openapi-price-points.json get /v1/price-points Retrieves a list of all price points in USD cents. ```bash Get All Price Points theme={"system"} curl -X GET \ 'https://api.appcharge.com/v1/price-points' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ ``` ```json Get All Price Points theme={"system"} { "pricePoints": [ { "priceInUsdCents": 499, "lastUpdate": "2026-02-15T08:30:00.000Z" }, { "priceInUsdCents": 999, "lastUpdate": "2026-03-01T10:00:00.000Z" }, { "priceInUsdCents": 1999, "lastUpdate": "2026-01-20T14:45:00.000Z" } ] } ``` # Get Price Point Source: https://docs.appcharge.com/api-reference/checkout/price-localization/get-price-point openapi-price-points.json get /v1/price-points/{priceInUsdCents} Retrieves a specific price point by its base price in USD cents. The API returns localized prices for this price point. ```bash Get Price Point theme={"system"} curl -X GET \ 'https://api.appcharge.com/v1/price-points/999' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ ``` ```json Get Price Point theme={"system"} { "priceInUsdCents": 999, "lastUpdate": "2026-03-01T10:00:00.000Z", "priceByCountry": [ { "price": 9.99, "currencyCode": "USD", "isOverridden": false, "taxModel": "Excluded", "taxRate": 0, "country": "United States", "countryCode2": "US", "usdExchangeRateOnCalc": 1, "exchangeRateDrift": "0%", "realTimePrice": 9.99 }, { "price": 7.99, "currencyCode": "GBP", "isOverridden": false, "taxModel": "Included", "taxRate": 20, "country": "United Kingdom", "countryCode2": "GB", "usdExchangeRateOnCalc": 0.79, "exchangeRateDrift": "-1.2%", "realTimePrice": 8.12 }, { "price": 29.99, "currencyCode": "BRL", "isOverridden": true, "taxModel": "Excluded", "taxRate": 0, "country": "Brazil", "countryCode2": "BR", "usdExchangeRateOnCalc": 5.05, "exchangeRateDrift": "2.3%", "realTimePrice": 29.99 }, { "price": 8.99, "currencyCode": "EUR", "isOverridden": false, "taxModel": "Included", "taxRate": 19, "country": "Germany", "countryCode2": "DE", "usdExchangeRateOnCalc": 0.92, "exchangeRateDrift": "-0.5%", "realTimePrice": 9.05 } ] } ``` ```json 404 theme={"system"} { "message": "Price point 999 not found." } ``` # Get Price Points for a Country Source: https://docs.appcharge.com/api-reference/checkout/price-localization/get-price-points-for-a-country openapi-price-points.json post /v1/price-points/localized/lookup Retrieves price points localized for a specific country. Pass price points in USD cents and a country code. The API returns each requested price point with its localized price in the currency for that country. ```bash Get Price Points by Country theme={"system"} curl -X POST \ 'https://api.appcharge.com/v1/price-points/localized/lookup' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "pricesInUsdCents": [699, 4550, 9999], "countryCode2": "DE" }' ``` ```json Get Price Points for a Country theme={"system"} { "currencyCode": "EUR", "pricePoints": { "699": { "price": 664, "displayPrice": "6,64 €" }, "4550": { "price": 4323, "displayPrice": "43,23 €" }, "9999": { "price": 9499, "displayPrice": "94,99 €" } } } ``` ```json 400 theme={"system"} { "message": "Invalid countryCode2: must be ISO 3166-1 alpha-2." } ``` ```json 401 theme={"system"} { "message": "Unauthorized." } ``` ```json 429 theme={"system"} { "message": "Rate limit exceeded." } ``` # Introduction Source: https://docs.appcharge.com/api-reference/checkout/price-localization/introduction The Price Localization API service allows you to localize prices across all supported currencies by creating and managing price points. A price point represents the price at which a product or service is offered for sale. Each price point is defined by a base price in USD cents, from which Appcharge calculates localized prices in supported currencies. You can also override these generated prices for specific countries when needed. Learn more about the [Price Points](/../../guides/checkout/price-localization/set-up-price-points) feature. With the Price Localization API service, you can: * [Create a price point](./create-price-point). * [Retrieve a list of all price points](./get-all-price-points). * [Retrieve a specific price point](./get-price-point) by price in USD cents. * [Get price points for a country](./get-price-points-for-a-country). * [Update a price point](./update-price-point). * [Delete a price point](./delete-price-point). ## Currency configuration and display behavior Appcharge generates localized prices for all supported currencies. These prices are displayed in the web store and checkout only if the currency is enabled in the Publisher Dashboard. By default, all currencies are enabled. **If a currency isn't enabled:** * Prices aren't converted to that country’s local currency, and the USD price is displayed instead. * If you provide a country-specific override using `priceOverrides`, the override value is treated as a USD amount and displayed in USD. It is not converted. **To enable or disable currencies:** 1. In the Publisher Dashboard, go to **Management > Pricing**. 2. In the **Settings** tab, scroll to **Currencies to Localize**. 3. Check the currencies you want to display, and uncheck the ones you don't want to display. ## How localized prices are calculated For each supported currency, the localized price is calculated as follows: 1. The base USD price is multiplied by the current exchange rate. 2. Tax is applied by multiplying the converted price by the applicable tax rate only if both of the following conditions are met:

To check whether a country’s tax model includes tax: 1. In the Publisher Dashboard, go to **Management > Pricing**. 2. Click **Add new price point**, or click the ellipses next to an existing price point and select **Edit**. 3. Review the value in the **Tax model** column for each country. 4. If the value is **Included**, the country’s tax is included in the price. To enable this option: 1. Go to **Management > Pricing**. 2. In the **Settings** tab, scroll to **Display Tax-Inclusive Prices**. 3. Turn on the toggle. If a country’s tax model excludes tax from the price, Appcharge adds the applicable tax during checkout. 3. Rounding rules are applied if enabled in the Publisher Dashboard. To enable this option: 1. Go to **Management > Pricing**. 2. In the **Settings** tab, scroll to **Rounding Rules**. 3. Turn on the toggle. Decimal currencies are rounded to attractive decimal endings, while zero-decimal currencies (such as JPY, KRW, and VND) are rounded to natural denominations. Learn more about [rounding rules](/../../guides/checkout/price-localization/set-up-price-points#rounding-rules). # Update Price Point Source: https://docs.appcharge.com/api-reference/checkout/price-localization/update-price-point openapi-price-points.json put /v1/price-points/{priceInUsdCents} Updates a price point. When a price point is updated, Appcharge recalculates all localized prices. If both `updatedPriceInUsdCents` and `priceOverrides` are provided in the same request, Appcharge first recalculates localized prices from the updated base price and then applies the override values. ```bash Update Price Point theme={"system"} curl -X PUT \ 'https://api.appcharge.com/v1/price-points/999' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ -d '{ "priceOverrides": [ { "countryCode2": "BR", "price": 34.99 }, { "countryCode2": "IN", "price": 499 } ] }' ``` ```json Update Price Point theme={"system"} { "priceInUsdCents": 999, "lastUpdate": "2026-03-01T12:00:00.000Z", "priceByCountry": [ { "price": 9.99, "currencyCode": "USD", "isOverridden": false, "taxModel": "Excluded", "taxRate": 0, "country": "United States", "countryCode2": "US", "usdExchangeRateOnCalc": 1, "exchangeRateDrift": "0%" }, { "price": 7.99, "currencyCode": "GBP", "isOverridden": false, "taxModel": "Included", "taxRate": 20, "country": "United Kingdom", "countryCode2": "GB", "usdExchangeRateOnCalc": 0.79, "exchangeRateDrift": "-1.2%" }, { "price": 34.99, "currencyCode": "BRL", "isOverridden": true, "taxModel": "Excluded", "taxRate": 0, "country": "Brazil", "countryCode2": "BR", "usdExchangeRateOnCalc": 5.05, "exchangeRateDrift": "2.3%" }, { "price": 8.99, "currencyCode": "EUR", "isOverridden": false, "taxModel": "Included", "taxRate": 19, "country": "Germany", "countryCode2": "DE", "usdExchangeRateOnCalc": 0.92, "exchangeRateDrift": "-0.5%" }, { "price": 499, "currencyCode": "INR", "isOverridden": true, "taxModel": "Included", "taxRate": 18, "country": "India", "countryCode2": "IN", "usdExchangeRateOnCalc": 83.12, "exchangeRateDrift": "0.8%" } ] } ``` ```json 400 Schema Validation Error theme={"system"} { "message": "Invalid request body." } ``` ```json 400 Invalid Country Code theme={"system"} { "message": "Country code ZZ not found in existing custom pricing." } ``` ```json 404 theme={"system"} { "message": "Price point 999 not found." } ``` ```json 409 theme={"system"} { "message": "Cannot create new pricing. The price point already exists." } ``` # Initiate Refund Source: https://docs.appcharge.com/api-reference/checkout/refunds/initiate-refund openapi-initiate-refund.json POST /checkout/api/v1/order/{orderId}/refund Initiates a full refund for a specified order. Once the API call is successful, the refund process begins. The result of the refund, whether it succeeds or fails, is communicated asynchronously when the order status updates to `Refunded` or `Refund Failed`. You can track the order status in the **Orders** tab of the Publisher Dashboard. If the refund is completed successfully, the total order amount is reimbursed, and the [Order Refunded](../../events/v2/order/order_refunded) event is triggered. **Note:** This action is final and can't be undone. # Invalid Property Error Source: https://docs.appcharge.com/api-reference/events/v1/error/invalid_property_error An event triggered when the web store receives malformed or invalid data in the session or offer configuration, typically due to incorrect formatting or missing required fields. **Event Data** The time when the event occurred. Example: `1632345000` Details about the event failure. A unique identifier (UUID v4) for the request. Example: `550e8400-e29b-41d4-a716-446655440000` The player ID returned during authentication. Example: `player_12345` The publisher offer ID, if applicable. Example: `offer_56789` The reason for the error in JSON stringified format. Example: `{"error": "Invalid property 'price'"}` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "data": { "requestId": "550e8400-e29b-41d4-a716-446655440000", "playerId": "player_12345", "offerExternalId": "offer_56789", "reason": "{\"error\": \"Invalid property 'price'\"}" } } ``` # Introduction Source: https://docs.appcharge.com/api-reference/events/v1/introduction Events deliver structured, near real-time data that allows publishers to monitor and respond to critical activities such as player logins, store interactions, and payment processing. For a detailed guide on configuring the event webhook, refer to the [Events Guide](/../../guides/events/about-the-events-center). ## Event Types ### Login Events Login events track player authentication and navigation through the login flow. **Includes:** * `Login Land` * `Login Method Selected` * `Login Canceled` * `Login Resolved` * `Shop Land` [View Login Events](./login/login_land) ### Store Interaction Events These events capture player interactions with offers in the Web Store. **Includes:** * `Offers Loaded` * `Offers Shown` * `Approval Request Displayed` * `Approval Request Closed` [View Store Interaction Events](./store-interaction/offers_loaded) ### Error Events Error events provide technical insights to identify and troubleshoot issues. **Includes:** * `Invalid Property Error` [View Error Events](./error/invalid_property_error) ### Order Events Order events track the full lifecycle of orders, from creation to completion or cancellation. **Includes:** * `Order Created` * `Payment Intent Success` * `Payment Intent Failed` * `Order Completed Success` * `Order Completed Failed` * `Order Canceled` [View Order Events](./order/order_created) ### Dispute Events Dispute events manage post-purchase activities, such as refunds and chargebacks. **Includes:** * `Order Refunded` * `Order Dispute Open` * `Order Dispute Won` * `Order Dispute Lost` [View Dispute Events](./refund-dispute/order_refunded) ## Retry Mechanism If the Events Webhook fails to deliver an event due to a server-side error on the publisher's end, Appcharge retries delivery up to 3 times. Each retry occurs after a 5 minute delay. ## Session ID A Session ID identifies the player’s current session. A session begins when the player logs in or returns to the web store, and it ends after 30 minutes of inactivity or when the player logs out. If the player opens the web store in different browsers or on separate devices at the same time, each instance generates a unique Session ID. However, opening the store in multiple tabs within the same browser will use the same Session ID. You can use the Session ID to track and analyze player activity. This supports both behavioral analysis and debugging. # Login Canceled Source: https://docs.appcharge.com/api-reference/events/v1/login/login_canceled An event triggered when the player closes or leaves the login process before completing it. **Event Data** The time when the event occurred. Example: `1632345000` The type of player authentication event. In this case, login\_canceled. Example: `login_canceled` The device platform used by the player. Example: `mobile` The interface through which the player accessed the login page. Supported values: * `browser app`: Mobile or desktop browser. * `webview`: An in-app webview. * `homescreen bookmark`: A saved home screen shortcut or bookmark. The two-letter country code of the player. Example: `US` The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05` The authentication method selected by the player in the main login screen. Optional Values: facebook, google, apple, user\_name, OTP. Example: `facebook` Identifies the source of your traffic. Optional Values: google, facebook, instagram. Example: `google` Specifies the medium through which the traffic arrived. Optional Values: cpc, email, social, referral. Example: `cpc` Identifies the marketing campaign associated with the traffic. Optional Values: spring\_sale, retargeting, black\_friday. Example: `spring_sale` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "event": "login_canceled", "platform": "mobile", "source": "webview", "countryCode2": "US", "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "loginMethod": "facebook", "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale" } ``` # Login Land Source: https://docs.appcharge.com/api-reference/events/v1/login/login_land An event triggered when the player lands on the login page of the web store. Used to track login funnel entry. **Event Data** The time when the event occurred. Example: `1632345000` The type of player authentication event. In this case, login\_land. Example: `login_land` The device platform used by the player. Example: `mobile` The interface through which the player accessed the login page. Supported values: * `browser app`: Mobile or desktop browser. * `webview`: An in-app webview. * `homescreen bookmark`: A saved home screen shortcut or bookmark. The two-letter country code of the player. Example: `US` The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05` Identifies the source of your traffic. Optional Values: google, facebook, instagram. Example: `google` Specifies the medium through which the traffic arrived. Optional Values: cpc, email, social, referral. Example: `cpc` Identifies the marketing campaign associated with the traffic. Optional Values: spring\_sale, retargeting, black\_friday. Example: `spring_sale` Paid search keyword or term that generated the traffic. Example: `buy+coins` A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `ad1` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "event": "login_land", "platform": "mobile", "source": "webview", "countryCode2": "US", "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" } ``` # Login Method Selected Source: https://docs.appcharge.com/api-reference/events/v1/login/login_method_selected An event triggered when the player selects a specific login method. For example, a social media platform. **Event Data** The time when the event occurred. Example: `1632345000` The type of player authentication event. In this case, login\_method\_selected. Example: `login_method_selected` The device platform used by the player. Example: `mobile` The interface through which the player accessed the login page. Supported values: * `browser app`: Mobile or desktop browser. * `webview`: An in-app webview. * `homescreen bookmark`: A saved home screen shortcut or bookmark. The two-letter country code of the player. Example: `US` The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05` The authentication method selected by the player in the main login screen. Optional Values: facebook, google, apple, user\_name, OTP. Example: `facebook` Identifies the source of your traffic. Optional Values: google, facebook, instagram. Example: `google` Specifies the medium through which the traffic arrived. Optional Values: cpc, email, social, referral. Example: `cpc` Identifies the marketing campaign associated with the traffic. Optional Values: spring\_sale, retargeting, black\_friday. Example: `spring_sale` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "event": "login_method_selected", "platform": "mobile", "source": "webview", "countryCode2": "US", "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "loginMethod": "facebook", "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale" } ``` # Login Resolved Source: https://docs.appcharge.com/api-reference/events/v1/login/login_resolved An event triggered when the player successfully completes the login process and is authenticated. **Event Data** The time when the event occurred. Example: `1632345000` The type of player authentication event. In this case, login\_resolved. Example: `login_resolved` The device platform used by the player. Example: `mobile` The interface through which the player accessed the login page. Supported values: * `browser app`: Mobile or desktop browser. * `webview`: An in-app webview. * `homescreen bookmark`: A saved home screen shortcut or bookmark. The two-letter country code of the player. Example: `US` The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05` The authentication method selected by the player in the main login screen. Optional Values: facebook, google, apple, user\_name, OTP. Example: `facebook` The result of the login\_resolved event. Example: `success` Optional. The reason for the login\_resolved failure. Example: `invalid_credentials` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` Identifies the source of your traffic. Optional Values: google, facebook, instagram. Example: `google` Specifies the medium through which the traffic arrived. Optional Values: cpc, email, social, referral. Example: `cpc` Identifies the marketing campaign associated with the traffic. Optional Values: spring\_sale, retargeting, black\_friday. Example: `spring_sale` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "event": "login_resolved", "platform": "mobile", "source": "webview", "countryCode2": "US", "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "loginMethod": "facebook", "result": "success", "reason": "invalid_credentials", "sessionMetadata": { "metadata": "data" }, "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale" } ``` # Shop Land Source: https://docs.appcharge.com/api-reference/events/v1/login/shop_land An event triggered when the player lands on the main web store page after login or when navigating directly to the web store. **Event Data** The time when the event occurred. Example: `1632345000` The type of player authentication event. In this case, shop\_land. Example: `shop_land` The device platform used by the player. Example: `mobile` The interface through which the player accessed the login page. Supported values: * `browser app`: Mobile or desktop browser. * `webview`: An in-app webview. * `homescreen bookmark`: A saved home screen shortcut or bookmark. The two-letter country code of the player. Example: `US` The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05` The player's ID. Example: `player_001` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` Identifies the source of your traffic. Optional Values: google, facebook, instagram. Example: `google` Specifies the medium through which the traffic arrived. Optional Values: cpc, email, social, referral. Example: `cpc` Identifies the marketing campaign associated with the traffic. Optional Values: spring\_sale, retargeting, black\_friday. Example: `spring_sale` Paid search keyword or term that generated the traffic. Example: `buy+coins` A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `ad1` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "event": "shop_land", "platform": "mobile", "source": "webview", "countryCode2": "US", "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "playerId": "player_001", "sessionMetadata": { "metadata": "data" }, "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" } ``` # Order Cancelled Source: https://docs.appcharge.com/api-reference/events/v1/order/order_cancelled An event triggered when an order is cancelled by the player or through a system timeout before completion. **Event Data** The time when the event occurred. Example: `1632345000` The Appcharge payment ID for the event. Example: `pay_12345` The Appcharge order ID for the event. Example: `order_12345` The unique identifier of the player involved in the order. Example: `player_12345` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` Details on offer-related metadata. The index of the offer. Example: `{"productsSequenceIndex": 1}` The payment method used for the transaction. Example: `credit_card` Error reason in case of a failure. Example: `insufficient_funds` The base price of the price point in USD cents. Example: `800` Details about the offer associated with the order. The name of the offer. Example: `Special Bundle` The Appcharge offer ID. Example: `offer_12345` The publisher's offer ID. Example: `ext_offer_12345` The base price of the offer in USD. Example: `10.00` The ISO 3166-1 alpha-2 country code of the player. Example: `US` The ISO 4217 currency code used for the payment. Example: `USD` The paid price without taxes, converted to USD in real-time. Example: `8.00` The paid price in local currency (in cents). Example: `800` The price paid by the player in local currency, excluding taxes. Example: `750` The tax amount paid by the player (in cents of local currency). Example: `50` The name of the promo code being applied. Example: `PROMO10` The discount amount in the currency the order was placed in. Example: `1.00` The rate of the discount as a percentage. Example: `10%` A list of products included in the offer. The name of the product. Example: `Deluxe Skin` The publisher's product ID. Example: `prod_12345` The quantity of the purchased product. Example: `1` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "appChargePaymentId": "pay_12345", "appChargeOrderId": "order_12345", "playerId": "player_12345", "sessionMetadata": { "device": "mobile", "region": "US" }, "storeMetadata": { "productsSequenceIndex": 1 }, "paymentMethod": "credit_card", "reason": "insufficient_funds", "pricePointMetadata": "The base price of the price point." "offer": { "offerName": "Special Bundle", "offerInternalId": "offer_12345", "offerExternalId": "ext_offer_12345", "originalPriceInDollar": 10.00, "country": "US", "currency": "USD", "priceInDollar": 8.00, "priceInCents": 800, "subtotal": 750, "tax": 50, "promoCodeName": "PROMO10", "discount": 1.00, "discountRatePoints": "10%", "products": [ { "name": "Deluxe Skin", "sku": "prod_12345", "amount": 1 } ] } } ``` # Order Completed Failed Source: https://docs.appcharge.com/api-reference/events/v1/order/order_completed_failed An event triggered when an order completion fails due to a payment error, timeout, or other technical issue. **Event Data** The time when the event occurred. Example: `1632345000` The Appcharge payment ID for the event. Example: `pay_12345` The Appcharge order ID for the event. Example: `order_12345` The unique identifier of the player involved in the order. Example: `player_12345` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` Details on offer-related metadata. The index of the offer. Example: `{"productsSequenceIndex": 1}` The payment method used for the transaction. Example: `credit_card` Error reason in case of a failure. Example: `insufficient_funds` The base price of the price point in USD cents. Example: `800` Details about the offer associated with the order. The name of the offer. Example: `Special Bundle` The Appcharge offer ID. Example: `offer_12345` The publisher's offer ID. Example: `ext_offer_12345` The base price of the offer in USD. Example: `10.00` The ISO 3166-1 alpha-2 country code of the player. Example: `US` The ISO 4217 currency code used for the payment. Example: `USD` The paid price without taxes, converted to USD in real-time. Example: `8.00` The paid price in local currency (in cents). Example: `800` The price paid by the player in local currency, excluding taxes. Example: `750` The tax amount paid by the player (in cents of local currency). Example: `50` The name of the promo code being applied. Example: `PROMO10` The discount amount in the currency the order was placed in. Example: `1.00` The rate of the discount as a percentage. Example: `10%` A list of products included in the offer. The name of the product. Example: `Deluxe Skin` The publisher's product ID. Example: `prod_12345` The quantity of the purchased product. Example: `1` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "appChargePaymentId": "pay_12345", "appChargeOrderId": "order_1", "playerId": "player_12345", "sessionMetadata": { "device": "mobile", "region": "US" }, "storeMetadata": { "productsSequenceIndex": 1 }, "paymentMethod": "card", "reason": "insufficient_funds", "pricePointMetadata": "800", "offer": { "offerName": "Special Bundle", "offerInternalId": "offer_12345", "offerExternalId": "ext_offer_12345", "originalPriceInDollar": 10.00, "country": "US", "currency": "USD", "priceInDollar": 8.00, "priceInCents": 800, "subtotal": 750, "tax": 50, "promoCodeName": "PROMO10", "discount": 1.00, "discountRatePoints": "10%", "products": [ { "name": "Deluxe Skin", "sku": "prod_12345", "amount": 1 } ] } } ``` # Order Completed Success Source: https://docs.appcharge.com/api-reference/events/v1/order/order_completed_success An event triggered when an order is successfully paid and processed, and confirmation is sent to the publisher or game. **Event Data** The time when the event occurred. Example: `1632345000` The Appcharge payment ID for the event. Example: `pay_12345` The Appcharge order ID for the event. Example: `order_12345` The unique identifier of the player involved in the order. Example: `player_12345` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` Details on offer-related metadata. The index of the offer. Example: `{"productsSequenceIndex": 1}` The payment method used for the transaction. Example: `credit_card` The estimated amount the publisher receives after all deductions. Example: `7.50` The estimated Appcharge fee for the transaction. Example: `0.50` Indicates if a player used/tried to use a saved card to pay in the checkout. Example: `true` Whether a player has saved or tried to save a new card during payment. Example: `true` Error reason in case of a failure. Example: `insufficient_funds` The base price of the price point in USD cents. Example: `800` Details about the offer associated with the order. The name of the offer. Example: `Special Bundle` The Appcharge offer ID. Example: `offer_12345` The publisher's offer ID. Example: `ext_offer_12345` The base price of the offer in USD. Example: `10.00` The ISO 3166-1 alpha-2 country code of the player. Example: `US` The ISO 4217 currency code used for the payment. Example: `USD` The paid price without taxes, converted to USD in real-time. Example: `8.00` The paid price in local currency (in cents). Example: `800` The price paid by the player in local currency, excluding taxes. Example: `750` The tax amount paid by the player (in cents of local currency). Example: `50` The name of the promo code being applied. Example: `PROMO10` The discount amount in the currency the order was placed in. Example: `1.00` The rate of the discount as a percentage. Example: `10%` A list of products included in the offer. The name of the product. Example: `Deluxe Skin` The publisher's product ID. Example: `prod_12345` The quantity of the purchased product. Example: `1` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "appChargePaymentId": "pay_12345", "appChargeOrderId": "order_1", "playerId": "player_12345", "sessionMetadata": { "device": "mobile", "region": "US" }, "storeMetadata": { "productsSequenceIndex": 1 }, "paymentMethod": "card", "estimatedPublisherNetAmount": "7.50", "estimatedAppchargeFee": "0.50", "isSavedPaymentMethodUsed": "True", "isNewPaymentMethodSaved": "True", "reason": "insufficient_funds", "pricePointMetadata": "800", "offer": { "offerName": "Special Bundle", "offerInternalId": "offer_12345", "offerExternalId": "ext_offer_12345", "originalPriceInDollar": 10.00, "country": "US", "currency": "USD", "priceInDollar": 8.00, "priceInCents": 800, "subtotal": 750, "tax": 50, "promoCodeName": "PROMO10", "discount": 1.00, "discountRatePoints": "10%", "products": [ { "name": "Deluxe Skin", "sku": "prod_12345", "amount": 1 } ] } } ``` # Order Created Source: https://docs.appcharge.com/api-reference/events/v1/order/order_created An event triggered when a new order session is initialized, either from the web store or via direct API call. **Event Data** The time when the event occurred. Example: `1632345000` The Appcharge payment ID for the event. Example: `pay_12345` The Appcharge order ID for the event. Example: `order_12345` The unique identifier of the player involved in the order. Example: `player_12345` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` Details on offer-related metadata. The index of the offer. Example: `{"productsSequenceIndex": 1}` The payment method used for the transaction. Example: `credit_card` Error reason in case of a failure. Example: `insufficient_funds` The base price of the price point in USD cents. Example: `800` Details about the offer associated with the order. The name of the offer. Example: `Special Bundle` The Appcharge offer ID. Example: `offer_12345` The publisher's offer ID. Example: `ext_offer_12345` The base price of the offer in USD. Example: `10.00` The ISO 3166-1 alpha-2 country code of the player. Example: `US` The ISO 4217 currency code used for the payment. Example: `USD` The paid price without taxes, converted to USD in real-time. Example: `8.00` The paid price in local currency (in cents). Example: `800` The price paid by the player in local currency, excluding taxes. Example: `750` The tax amount paid by the player (in cents of local currency). Example: `50` The name of the promo code being applied. Example: `PROMO10` The discount amount in the currency the order was placed in. Example: `1.00` The rate of the discount as a percentage. Example: `10%` A list of products included in the offer. The name of the product. Example: `Deluxe Skin` The publisher's product ID. Example: `prod_12345` The quantity of the purchased product. Example: `1` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "appChargePaymentId": "pay_12345", "appChargeOrderId": "order_12345", "playerId": "player_12345", "sessionMetadata": { "device": "mobile", "region": "US" }, "storeMetadata": { "productsSequenceIndex": 1 }, "paymentMethod": "credit_card", "reason": "insufficient_funds", "pricePointMetadata": "The base price of the price point." "offer": { "offerName": "Special Bundle", "offerInternalId": "offer_12345", "offerExternalId": "ext_offer_12345", "originalPriceInDollar": 10.00, "country": "US", "currency": "USD", "priceInDollar": 8.00, "priceInCents": 800, "subtotal": 750, "tax": 50, "promoCodeName": "PROMO10", "discount": 1.00, "discountRatePoints": "10%", "products": [ { "name": "Deluxe Skin", "sku": "prod_12345", "amount": 1 } ] } } ``` # Payment Intent Failed Source: https://docs.appcharge.com/api-reference/events/v1/order/payment_intent_failed An event triggered when the initiation of a payment method fails. **Event Data** The time when the event occurred. Example: `1632345000` The Appcharge payment ID for the event. Example: `pay_12345` The Appcharge order ID for the event. Example: `order_12345` The unique identifier of the player involved in the order. Example: `player_12345` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` Details on offer-related metadata. The index of the offer. Example: `{"productsSequenceIndex": 1}` The payment method used for the transaction. Example: `credit_card` Indicates if a player used/tried to use a saved card to pay in the checkout. Example: `true` Whether a player has saved or tried to save a new card during payment. Example: `true` Error reason in case of a failure. Example: `insufficient_funds` The base price of the price point in USD cents. Example: `800` Details about the offer associated with the order. The name of the offer. Example: `Special Bundle` The Appcharge offer ID. Example: `offer_12345` The publisher's offer ID. Example: `ext_offer_12345` The base price of the offer in USD. Example: `10.00` The ISO 3166-1 alpha-2 country code of the player. Example: `US` The ISO 4217 currency code used for the payment. Example: `USD` The paid price without taxes, converted to USD in real-time. Example: `8.00` The paid price in local currency (in cents). Example: `800` The price paid by the player in local currency, excluding taxes. Example: `750` The tax amount paid by the player (in cents of local currency). Example: `50` The name of the promo code being applied. Example: `PROMO10` The discount amount in the currency the order was placed in. Example: `1.00` The rate of the discount as a percentage. Example: `10%` A list of products included in the offer. The name of the product. Example: `Deluxe Skin` The publisher's product ID. Example: `prod_12345` The quantity of the purchased product. Example: `1` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "appChargePaymentId": "pay_12345", "appChargeOrderId": "order_1", "playerId": "player_12345", "sessionMetadata": { "device": "mobile", "region": "US" }, "storeMetadata": { "productsSequenceIndex": 1 }, "paymentMethod": "card", "isSavedPaymentMethodUsed": "True", "isNewPaymentMethodSaved": "True", "reason": "insufficient_funds", "pricePointMetadata": "800", "offer": { "offerName": "Special Bundle", "offerInternalId": "offer_12345", "offerExternalId": "ext_offer_12345", "originalPriceInDollar": 10.00, "country": "US", "currency": "USD", "priceInDollar": 8.00, "priceInCents": 800, "subtotal": 750, "tax": 50, "promoCodeName": "PROMO10", "discount": 1.00, "discountRatePoints": "10%", "products": [ { "name": "Deluxe Skin", "sku": "prod_12345", "amount": 1 } ] } } ``` # Payment Intent Success Source: https://docs.appcharge.com/api-reference/events/v1/order/payment_intent_success An event triggered when a payment method is successfully initiated. **Event Data** The time when the event occurred. Example: `1632345000` The Appcharge payment ID for the event. Example: `pay_12345` The Appcharge order ID for the event. Example: `order_12345` The unique identifier of the player involved in the order. Example: `player_12345` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` Details on offer-related metadata. The index of the offer. Example: `{"productsSequenceIndex": 1}` The payment method used for the transaction. Example: `credit_card` The estimated amount the publisher receives after all deductions. Example: `7.50` The estimated Appcharge fee for the transaction. Example: `0.50` Indicates if a player used/tried to use a saved card to pay in the checkout. Example: `true` Whether a player has saved or tried to save a new card during payment. Example: `true` Error reason in case of a failure. Example: `insufficient_funds` The base price of the price point in USD cents. Example: `800` Details about the offer associated with the order. The name of the offer. Example: `Special Bundle` The Appcharge offer ID. Example: `offer_12345` The publisher's offer ID. Example: `ext_offer_12345` The base price of the offer in USD. Example: `10.00` The ISO 3166-1 alpha-2 country code of the player. Example: `US` The ISO 4217 currency code used for the payment. Example: `USD` The paid price without taxes, converted to USD in real-time. Example: `8.00` The paid price in local currency (in cents). Example: `800` The price paid by the player in local currency, excluding taxes. Example: `750` The tax amount paid by the player (in cents of local currency). Example: `50` The name of the promo code being applied. Example: `PROMO10` The discount amount in the currency the order was placed in. Example: `1.00` The rate of the discount as a percentage. Example: `10%` A list of products included in the offer. The name of the product. Example: `Deluxe Skin` The publisher's product ID. Example: `prod_12345` The quantity of the purchased product. Example: `1` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "appChargePaymentId": "pay_12345", "appChargeOrderId": "order_1", "playerId": "player_12345", "sessionMetadata": { "device": "mobile", "region": "US" }, "storeMetadata": { "productsSequenceIndex": 1 }, "paymentMethod": "card", "estimatedPublisherNetAmount": "7.50", "estimatedAppchargeFee": "0.50", "isSavedPaymentMethodUsed": "True", "isNewPaymentMethodSaved": "True", "reason": "insufficient_funds", "pricePointMetadata": "800", "offer": { "offerName": "Special Bundle", "offerInternalId": "offer_12345", "offerExternalId": "ext_offer_12345", "originalPriceInDollar": 10.00, "country": "US", "currency": "USD", "priceInDollar": 8.00, "priceInCents": 800, "subtotal": 750, "tax": 50, "promoCodeName": "PROMO10", "discount": 1.00, "discountRatePoints": "10%", "products": [ { "name": "Deluxe Skin", "sku": "prod_12345", "amount": 1 } ] } } ``` # Order Dispute Lost Source: https://docs.appcharge.com/api-reference/events/v1/refund-dispute/order_dispute_lost Triggered when the dispute is resolved in favor of the player, resulting in a chargeback or refund. **Event Data** The time when the event occurred. Example: `1632345000` The Appcharge payment ID for the event. Example: `pay_12345` The Appcharge order ID for the event. Example: `order_12345` The unique identifier of the player involved in the order. Example: `player_12345` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` The payment method used for the transaction. Example: `credit_card` Error reason in case of a failure. Example: `insufficient_funds` Details about the offer associated with the order. The name of the offer. Example: `Special Bundle` The Appcharge offer ID. Example: `offer_12345` The publisher's offer ID. Example: `ext_offer_12345` The base price of the offer in USD. Example: `10.00` The ISO 3166-1 alpha-2 country code of the player. Example: `US` The ISO 4217 currency code used for the payment. Example: `USD` The paid price without taxes, converted to USD in real-time. Example: `8.00` The paid price in local currency (in cents). Example: `800` The price paid by the player in local currency, excluding taxes. Example: `750` The tax amount paid by the player (in cents of local currency). Example: `50` The name of the promo code being applied. Example: `PROMO10` The discount amount in the currency the order was placed in. Example: `1.00` The rate of the discount as a percentage. Example: `10%` A list of products included in the offer. The name of the product. Example: `Deluxe Skin` The publisher's product ID. Example: `prod_12345` The quantity of the purchased product. Example: `1` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "appChargePaymentId": "pay_12345", "appChargeOrderId": "order_12345", "playerId": "player_12345", "sessionMetadata": { "device": "mobile", "region": "US" }, "paymentMethod": "credit_card", "reason": "insufficient_funds", "offer": { "offerName": "Special Bundle", "offerInternalId": "offer_12345", "offerExternalId": "ext_offer_12345", "originalPriceInDollar": 10.00, "country": "US", "currency": "USD", "priceInDollar": 8.00, "priceInCents": 800, "subtotal": 750, "tax": 50, "promoCodeName": "PROMO10", "discount": 1.00, "discountRatePoints": "10%", "products": [ { "name": "Deluxe Skin", "sku": "prod_12345", "amount": 1 } ] } } ``` # Order Dispute Open Source: https://docs.appcharge.com/api-reference/events/v1/refund-dispute/order_dispute_open An event triggered when a payment dispute, for example, a chargeback is initiated by the player with their payment provider. **Event Data** The time when the event occurred. Example: `1632345000` The Appcharge payment ID for the event. Example: `pay_12345` The Appcharge order ID for the event. Example: `order_12345` The unique identifier of the player involved in the order. Example: `player_12345` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` The payment method used for the transaction. Example: `credit_card` Error reason in case of a failure. Example: `insufficient_funds` Details about the offer associated with the order. The name of the offer. Example: `Special Bundle` The Appcharge offer ID. Example: `offer_12345` The publisher's offer ID. Example: `ext_offer_12345` The base price of the offer in USD. Example: `10.00` The ISO 3166-1 alpha-2 country code of the player. Example: `US` The ISO 4217 currency code used for the payment. Example: `USD` The paid price without taxes, converted to USD in real-time. Example: `8.00` The paid price in local currency (in cents). Example: `800` The price paid by the player in local currency, excluding taxes. Example: `750` The tax amount paid by the player (in cents of local currency). Example: `50` The name of the promo code being applied. Example: `PROMO10` The discount amount in the currency the order was placed in. Example: `1.00` The rate of the discount as a percentage. Example: `10%` A list of products included in the offer. The name of the product. Example: `Deluxe Skin` The publisher's product ID. Example: `prod_12345` The quantity of the purchased product. Example: `1` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "appChargePaymentId": "pay_12345", "appChargeOrderId": "order_12345", "playerId": "player_12345", "sessionMetadata": { "device": "mobile", "region": "US" }, "paymentMethod": "credit_card", "reason": "insufficient_funds", "offer": { "offerName": "Special Bundle", "offerInternalId": "offer_12345", "offerExternalId": "ext_offer_12345", "originalPriceInDollar": 10.00, "country": "US", "currency": "USD", "priceInDollar": 8.00, "priceInCents": 800, "subtotal": 750, "tax": 50, "promoCodeName": "PROMO10", "discount": 1.00, "discountRatePoints": "10%", "products": [ { "name": "Deluxe Skin", "sku": "prod_12345", "amount": 1 } ] } } ``` # Order Dispute Won Source: https://docs.appcharge.com/api-reference/events/v1/refund-dispute/order_dispute_won An event triggered when a dispute is resolved in favor of the publisher or Appcharge. **Event Data** The time when the event occurred. Example: `1632345000` The Appcharge payment ID for the event. Example: `pay_12345` The Appcharge order ID for the event. Example: `order_12345` The unique identifier of the player involved in the order. Example: `player_12345` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` The payment method used for the transaction. Example: `credit_card` Error reason in case of a failure. Example: `insufficient_funds` Details about the offer associated with the order. The name of the offer. Example: `Special Bundle` The Appcharge offer ID. Example: `offer_12345` The publisher's offer ID. Example: `ext_offer_12345` The base price of the offer in USD. Example: `10.00` The ISO 3166-1 alpha-2 country code of the player. Example: `US` The ISO 4217 currency code used for the payment. Example: `USD` The paid price without taxes, converted to USD in real-time. Example: `8.00` The paid price in local currency (in cents). Example: `800` The price paid by the player in local currency, excluding taxes. Example: `750` The tax amount paid by the player (in cents of local currency). Example: `50` The name of the promo code being applied. Example: `PROMO10` The discount amount in the currency the order was placed in. Example: `1.00` The rate of the discount as a percentage. Example: `10%` A list of products included in the offer. The name of the product. Example: `Deluxe Skin` The publisher's product ID. Example: `prod_12345` The quantity of the purchased product. Example: `1` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "appChargePaymentId": "pay_12345", "appChargeOrderId": "order_12345", "playerId": "player_12345", "sessionMetadata": { "device": "mobile", "region": "US" }, "paymentMethod": "credit_card", "reason": "insufficient_funds", "offer": { "offerName": "Special Bundle", "offerInternalId": "offer_12345", "offerExternalId": "ext_offer_12345", "originalPriceInDollar": 10.00, "country": "US", "currency": "USD", "priceInDollar": 8.00, "priceInCents": 800, "subtotal": 750, "tax": 50, "promoCodeName": "PROMO10", "discount": 1.00, "discountRatePoints": "10%", "products": [ { "name": "Deluxe Skin", "sku": "prod_12345", "amount": 1 } ] } } ``` # Order Refunded Source: https://docs.appcharge.com/api-reference/events/v1/refund-dispute/order_refunded An event triggered when an order is refunded, either manually or automatically. **Event Data** The time when the event occurred. Example: `1632345000` The Appcharge payment ID for the event. Example: `pay_12345` The Appcharge order ID for the event. Example: `order_12345` The unique identifier of the player involved in the order. Example: `player_12345` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` The payment method used for the transaction. Example: `credit_card` Error reason in case of a failure. Example: `insufficient_funds` Details about the offer associated with the order. The name of the offer. Example: `Special Bundle` The Appcharge offer ID. Example: `offer_12345` The publisher's offer ID. Example: `ext_offer_12345` The base price of the offer in USD. Example: `10.00` The ISO 3166-1 alpha-2 country code of the player. Example: `US` The ISO 4217 currency code used for the payment. Example: `USD` The paid price without taxes, converted to USD in real-time. Example: `8.00` The paid price in local currency (in cents). Example: `800` The price paid by the player in local currency, excluding taxes. Example: `750` The tax amount paid by the player (in cents of local currency). Example: `50` The name of the promo code being applied. Example: `PROMO10` The discount amount in the currency the order was placed in. Example: `1.00` The rate of the discount as a percentage. Example: `10%` A list of products included in the offer. The name of the product. Example: `Deluxe Skin` The publisher's product ID. Example: `prod_12345` The quantity of the purchased product. Example: `1` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "appChargePaymentId": "pay_12345", "appChargeOrderId": "order_12345", "playerId": "player_12345", "sessionMetadata": { "device": "mobile", "region": "US" }, "paymentMethod": "credit_card", "reason": "insufficient_funds", "offer": { "offerName": "Special Bundle", "offerInternalId": "offer_12345", "offerExternalId": "ext_offer_12345", "originalPriceInDollar": 10.00, "country": "US", "currency": "USD", "priceInDollar": 8.00, "priceInCents": 800, "subtotal": 750, "tax": 50, "promoCodeName": "PROMO10", "discount": 1.00, "discountRatePoints": "10%", "products": [ { "name": "Deluxe Skin", "sku": "prod_12345", "amount": 1 } ] } } ``` # Approval Request Closed Source: https://docs.appcharge.com/api-reference/events/v1/store-interaction/approval_request_closed An event triggered when the Approval Request is closed. The time when the event occurred. Example: `1632345000` The unique identifier of the player involved in the event. Example: `12345` The game version. Example: `1.0.0` The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` Indicates why the popup was closed. Optional Values: approve, not\_me Example: `approve` A list of offers related to the event. Unique identifier for the offer. Example: `offer123` Type of the offer. Optional Values: Bundle, SpecialOffer, PopUp Example: `SpecialOffer` The subtype of the offer. Example: `checkout_link` The name of the offer. Example: `offer_name` A unique offer ID, automatically generated by Appcharge. Example: `67d6b74285b58f462adbebcb` The index of the offer in the list. Represents the day sequence of the daily bonus. Example: `1` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "playerId": "12345", "appVersion": "1.0.0", "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "sessionMetadata": { "metadata": "data" }, "reason": "approve", "offers": [ { "publisherOfferId": "offer123", "offerType": "deep_link", "offerSubType": "checkout_link", "offerName": "offer_name", "offerId": "67d6b74285b58f462adbebcb", "offerIndex": 1 } ] } ``` # Approval Request Displayed Source: https://docs.appcharge.com/api-reference/events/v1/store-interaction/approval_request_displayed An event triggered when the Approval Request is displayed. This event occurs when a player opens a [Checkout Link Offer](). The time when the event occurred. Example: `1632345000` The unique identifier of the player involved in the event. Example: `12345` The game version. Example: `1.0.0` The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` A list of offers related to the event. Unique identifier for the offer. Example: `offer123` Type of the offer. Optional Values: Bundle, SpecialOffer, PopUp Example: `SpecialOffer` The subtype of the offer. Example: `checkout_link` The name of the offer. Example: `offer_name` A unique offer ID, automatically generated by Appcharge. Example: `67d6b74285b58f462adbebcb` The index of the offer in the list. Represents the day sequence of the daily bonus. Example: `1` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "playerId": "12345", "appVersion": "1.0.0", "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "sessionMetadata": { "metadata": "data" }, "offers": [ { "publisherOfferId": "offer123", "offerType": "deep_link", "offerSubType": "checkout_link", "offerName": "offer_name", "offerId": "67d6b74285b58f462adbebcb", "offerIndex": 1 } ] } ``` # Offers Loaded Source: https://docs.appcharge.com/api-reference/events/v1/store-interaction/offers_loaded An event triggered when the backend successfully returns the list of offers configured to be shown to the player. This event confirms that the offers are ready to be rendered on the page. **Event Data** The time when the event occurred. Example: `1632345000` The unique identifier of the player involved in the event. Example: `12345` The game version. Example: `1.0.0` The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` A list of offers related to the event. Unique identifier for the offer. Example: `offer123` Type of the offer. Optional Values: Bundle, SpecialOffer, PopUp Example: `SpecialOffer` The index of the offer in the list. Represents the day sequence of the daily bonus. Example:` 1` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "playerId": "12345", "appVersion": "1.0.0", "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "sessionMetadata": { "metadata": "data" }, "offers": [ { "publisherOfferId": "offer123", "offerType": "SpecialOffer", "offerIndex": 1 } ] } ``` # Offers Shown Source: https://docs.appcharge.com/api-reference/events/v1/store-interaction/offers_shown An event triggered when 100% of an offer's visual element is visible to the player. Events are batched every second and include only newly shown offers, excluding previously reported ones. The list resets after a page refresh. **Event Data** The time when the event occurred. Example: `1632345000` The unique identifier of the player involved in the event. Example: `12345` The game version. Example: `1.0.0` The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05` Relevant only to Personalization API users, the player session metadata object received from the Personalization API. Example: `{ "metadata": "data" }` A list of offers related to the event. Unique identifier for the offer. Example: `offer123` Type of the offer. Optional Values: Bundle, SpecialOffer, PopUp Example: `SpecialOffer` The index of the offer in the list. Represents the day sequence of the daily bonus. Example: `1` The index of the sub-offer currently available to be collected in a rolling offer. Example: `4` ```json Event Payload theme={"system"} { "timestamp": 1632345000, "playerId": "12345", "appVersion": "1.0.0", "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "sessionMetadata": { "metadata": "data" }, "offers": [ { "publisherOfferId": "offer123", "offerType": "SpecialOffer", "offerIndex": 1, "indexToCollect": 4 } ] } ``` # Introduction Source: https://docs.appcharge.com/api-reference/events/v2/introduction Appcharge provides real-time, structured webhook events that report on key player activities such as logins, web store interactions, and orders. These events allow you to monitor behavior and trigger backend logic, such as initiating a workflow when an order is completed. ## Webhook setup To begin receiving events, you must: 1. Create a webhook endpoint for the signature following the format described below. 2. [Register the webhook](/../../guides/events/about-the-events-center#configure-the-webhook) with Appcharge via the Publisher Dashboard. 3. [Select and enable the events you want to receive](/../../guides/events/about-the-events-center#choose-which-events-to-receive) in the **Events Center**. Once configured, Appcharge will send `HTTPS POST` requests to your endpoint containing JSON payloads that describe each event. ## Event payload structure Webhook events are sent as structured JSON objects, and the fields included can vary depending on the event type. Some fields may be optional, so your integration should account for missing fields gracefully to maintain reliability. This approach ensures compatibility as the event schema evolves and new fields are introduced. ## Webhook signature verification To ensure the authenticity and integrity of webhook events, Appcharge signs each request using a cryptographic signature. Only requests with valid signatures should be accepted. Signature validation protects you from: * Forged or malicious requests. * Payload tampering. * Replay attacks with outdated data. * Unauthorized access to internal systems. ### Signature generation We use HMAC-SHA256 with the following components: * **Timestamp**: Unix timestamp in milliseconds. * **Payload**: The full JSON body of the webhook. * **Secret**: Your private signing key. ### Signature format The signature is included in the `signature` header using this format: ```js theme={"system"} signature=t={timestamp},v1={signature} ``` ### Headers included in the request * `Content-Type: application/json` * `signature: t={timestamp},v1={signature}` * `x-project-id: 1234`: Project ID. Located in the Publisher Dashboard under **Settings > Company > Project ID**. * `x-publisher-token: xxxxx`: Publisher token found in the Publisher Dashboard under **Settings > Integration**. ### Signature algorithm details * **Algorithm:** HMAC-SHA256 * **Input Format**: `{timestamp}.{json_payload}` * **Output**: Hex-encoded string * **Timestamp**: Unix timestamp in milliseconds ### Signature validation process These steps demonstrate how you can validate the webhook before processing: #### Step 1 | Extract signature components ```js theme={"system"} const signatureHeader = req.headers['signature']; const [timestamp, signature] = signatureHeader.split(','); const timestampValue = timestamp.split('=')[1]; const signatureValue = signature.split('=')[1]; ``` #### Step 2 | Validate timestamp (replay protection) We recommend using a 5-minute tolerance window. Adjust this window according to your network conditions and security requirements. ```js theme={"system"} const currentTime = Date.now(); const requestTime = parseInt(timestampValue); const timeDiff = Math.abs(currentTime - requestTime); const maxAge = 5 * 60 * 1000; // 5 minutes in milliseconds if (timeDiff > maxAge) { throw new Error('The request is expired - possible replay attack.'); } ``` #### Step 3 | Reconstruct expected signature ```js theme={"system"} const payloadToSign = `${timestampValue}.${JSON.stringify(req.body)}`; const expectedSignature = crypto .createHmac('sha256', yourSecretKey) .update(payloadToSign) .digest('hex'); ``` #### Step 4 | Compare signatures ```js theme={"system"} if (signatureValue !== expectedSignature) { throw new Error('Invalid signature'); } ``` #### Complete code example ```js theme={"system"} const crypto = require('crypto'); function validateWebhookSignature(req, secretKey) { try { // Get signature header const signatureHeader = req.headers['signature']; if (!signatureHeader) { throw new Error('Missing signature header'); } // Parse signature components const parts = signatureHeader.split(','); const timestampPart = parts.find(part => part.startsWith('t=')); const signaturePart = parts.find(part => part.startsWith('v1=')); if (!timestampPart || !signaturePart) { throw new Error('Invalid signature format'); } const timestamp = timestampPart.split('=')[1]; const signature = signaturePart.split('=')[1]; // Validate timestamp (prevent replay attacks) // PUBLISHER RESPONSIBILITY: Adjust tolerance based on your needs const currentTime = Date.now(); const requestTime = parseInt(timestamp); const timeDiff = Math.abs(currentTime - requestTime); const maxAge = 5 * 60 * 1000; // 5 minutes - ADJUST AS NEEDED if (timeDiff > maxAge) { throw new Error('The request is expired - possible replay attack.'); } // Reconstruct expected signature const payloadToSign = `${timestamp}.${JSON.stringify(req.body)}`; const expectedSignature = crypto .createHmac('sha256', secretKey) .update(payloadToSign) .digest('hex'); // Compare signatures if (signature !== expectedSignature) { throw new Error('Invalid signature'); } // Get project ID const projectId = req.headers['x-project-id']; console.log(`Valid webhook from project: ${projectId}`); return true; } catch (error) { console.error('Webhook validation failed:', error.message); return false; } } // Usage example app.post('/webhook', (req, res) => { // PUBLISHER RESPONSIBILITY: Always validate before processing const isValid = validateWebhookSignature(req, 'your-secret-key'); if (!isValid) { return res.status(401).json({ error: 'Invalid signature' }); } // Only process webhook after successful validation console.log('Processing webhook:', req.body); res.status(200).json({ status: 'ok' }); }); ``` ## Retry mechanism When a webhook delivery fails, for example, your endpoint doesn't return a `2xx` response, Appcharge will schedule up to three additional delivery attempts, using the following intervals: | Attempt | Delay from previous attempt | | - | - | | Initial delivery | Immediate | | 1st retry | 15 seconds | | 2nd retry | 15 seconds | | 3rd retry | 15 minutes | If the 4th delivery attempt also fails, Appcharge won't try again. Ensure your endpoint responds with a `2xx` status code promptly to acknowledge receipt and avoid unnecessary retries. ## Security best practices * Always validate webhook signatures before processing. * Keep your secret key private, and never expose it in frontend or logs. * Use HTTPS for all webhook communication. * Set an appropriate timestamp tolerance. Start with 5 minutes and adjust as needed. * Use realistic validation during development to prevent unsafe patterns. ## Session ID Some webhook events include a `sessionId` property that identifies the player’s current session. This value helps track player behavior across interactions such as logins, purchases, or visits to the web store. A session begins when a player logs in or returns to the web store, and it ends either after 30 minutes of inactivity or when the player logs out. If the player opens the store in multiple tabs within the same browser, those tabs will share the same `sessionId`. However, accessing the store in a different browser or on another device will generate a new session ID. Use the `sessionId` to group related events and gain insight into player activity within a single session. # Order Canceled Source: https://docs.appcharge.com/api-reference/events/v2/order/order_canceled An event triggered when an order is canceled by the player or through a system timeout before completion. **Event Data** Event name: `order.canceled`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Supported values: `canceled`, `canceled_by_user`. Reason for the event result. When `result` is `canceled`, this field returns `Expired`. When `result` is `canceled_by_user`, this field returns `Canceled by user`. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Customer ID. **Deprecated.** Player's email address. **Deprecated.** Reserved for the player's name in future versions. Information about the offer. External ID of the offer as configured in the Publisher Dashboard. Offer type. Offer subtype. Offer name. The index of the offer. **Deprecated.** Reserved for the index to collect in future versions. **Deprecated.** Reserved for the Publisher Dashboard tab name in future versions. Price point of the offer in USD cents. Price in lowest currency unit. For example, cents for USD, and whole yen for JPY. For a list of of supported currencies, their minor unit types, and applicable pricing limitations, see [Supported Currencies](/../../merchant-of-record/finance/supported-currencies#supported-currencies). Currency code of the offer in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. List of products in an offer. Display name of the product. External ID of the product as configured in the Publisher Dashboard. The quantity of the product. Must be a minimum 0 and equal to or less than 24 digits long. Order ID. Order type. Example: `Paid`. Total order amount in the player's local currency, excluding taxes and discounts. Discount amount calculated on the tax-exclusive price, in USD cents. Always negative, representing a reduction. Example: `-7770` Total amount paid by the player, including discounts and taxes in the player's local currency. Tax amount in the player's local currency. Currency code in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. Currency symbol. Payment method used for the order. The price point in USD cents. Example: `77700`. Whether a player attempted to pay using a saved payment method. Whether a player attempted to save a new payment method in the checkout. Index of the sub-offer within an offer. Offer type. Information about the coupon. Coupon name. Promo code name. Discount amount calculated on the tax-exclusive price, in USD cents. Always negative, representing a reduction. Example: `-7770` Discount percentage. Information about the player's device. Device platform. Currently returns `null`. Device model. Currently returns `null`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "order.canceled", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": "canceled", "reason": "Expired", "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "offer": { "externalId": "22ae81bb-55ef-428b-97ba-f67783971e4a", "type": "PopUp", "subType": "DailyBonus", "name": "Spring Is Here", "offerIndex": 1, "indexToCollect": 1, "tab": "Tab 1", "pricePoint": 800, "price": 800, "currencyCode": "USD", "products": [ { "displayName": "Gold Coins", "productExternalId": "31ae81bb-55ef-428b-97ba-f67783971e553", "productQuantity": "1000" }, { "displayName": "Silver Shield", "productExternalId": "9af1abb-55ef-428b-97ba-f677839716ac9", "productQuantity": "40" } ] }, "order": { "id": "695b72ff0e34d3a514b6eda0", "orderType": "Paid", "subtotal": 77700, "discountAmount": -7770, "totalPayment": 76136, "taxAmount": 6206, "currencyCode": "USD", "currencySymbol": "$", "paymentMethod": "Credit Card", "isSavedPaymentMethodUsed": true, "isNewPaymentMethodSaved": true, "pricePointMetadata": 77700 }, "coupon": { "name": "Birthday Promo", "promoCodeName": "BIRTHDAY10", "discount": -7770, "discountPercentage": 10 }, "storeMetadata": { "offerType": "Bundle", "offersSequenceIndex": 1 }, "device": { "platform": null, "deviceModel": null, "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Order Completed Source: https://docs.appcharge.com/api-reference/events/v2/order/order_completed An event triggered when an order is successfully paid and processed, and confirmation is sent to the publisher or game. **Event Data** Event name: `order.completed`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Supported values: `success`, `failed`. Reason for the event result. When `result` is `success`, this field returns `null`. When `result` is `failed` and the player wasn't charged, this field returns `Checkout failed`. When `result` is `failed` after a successful charge, this field returns `Publisher failed to award`, or `Publisher failed to award:` followed by the publisher error message. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Customer ID. **Deprecated.** Player's email address. **Deprecated.** Reserved for the player's name in future versions. Information about the offer. External ID of the offer as configured in the Publisher Dashboard. Offer type. Offer subtype. Offer name. The index of the offer. **Deprecated.** Reserved for the index to collect in future versions. **Deprecated.** Reserved for the Publisher Dashboard tab name in future versions. Price point of the offer in USD cents. Price in lowest currency unit. For example, cents for USD, and whole yen for JPY. For a list of of supported currencies, their minor unit types, and applicable pricing limitations, see [Supported Currencies](/../../merchant-of-record/finance/supported-currencies#supported-currencies). Currency code of the offer in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. List of products in an offer. Display name of the product. External ID of the product as configured in the Publisher Dashboard. The quantity of the product. Must be a minimum 0 and equal to or less than 24 digits long. Order ID. Order type. Example: `Paid`. Total order amount in the player's local currency, excluding taxes and discounts. Discount amount calculated on the tax-exclusive price, in USD cents. Always negative, representing a reduction. Example: `-7770` Total amount paid by the player, including discounts and taxes in the player's local currency. Tax amount in the player's local currency. Currency code in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. Currency symbol. Payment method used for the order. The price point in USD cents. Example: `77700`. Whether a player attempted to pay using a saved payment method. Whether a player attempted to save a new payment method in the checkout. Index of the sub-offer within an offer. Offer type. URL the player used to land on the web store in the current active session. The URL is propagated as is, from the web store session to the checkout. Example: `https://store.example.com/?myParam=ABC123`. Information about the coupon. Coupon name. Promo code name. Discount amount calculated on the tax-exclusive price, in USD cents. Always negative, representing a reduction. Example: `-7770` Discount percentage. Information about the player's device. Device platform. Currently returns `null`. Device model. Currently returns `null`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Information about each transaction. Purchase ID. Transaction type. Transaction timestamp in [Epoch time](https://www.epoch101.com/). Example: `1754307361396`. Transaction amount in the player's local currency. Transaction amount in USD cents. Example: `76136`. Tax amount in the player's local currency. Tax amount in USD cents. Example: `6206`. Currency exchange fee in USD cents. Chargeback fee in USD cents. Example: `20`. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "order.completed", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": "success", "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "offer": { "externalId": "22ae81bb-55ef-428b-97ba-f67783971e4a", "type": "PopUp", "subType": "DailyBonus", "name": "Spring Is Here", "offerIndex": 1, "indexToCollect": 1, "tab": "Tab 1", "pricePoint": 800, "price": 800, "currencyCode": "USD", "products": [ { "displayName": "Gold Coins", "productExternalId": "31ae81bb-55ef-428b-97ba-f67783971e553", "productQuantity": "1000" }, { "displayName": "Silver Shield", "productExternalId": "9af1abb-55ef-428b-97ba-f677839716ac9", "productQuantity": "40" } ] }, "order": { "id": "695b72ff0e34d3a514b6eda0", "orderType": "Paid", "subtotal": 77700, "discountAmount": -7770, "totalPayment": 76136, "taxAmount": 6206, "currencyCode": "USD", "currencySymbol": "$", "paymentMethod": "Credit Card", "isSavedPaymentMethodUsed": true, "isNewPaymentMethodSaved": true, "pricePointMetadata": 77700 }, "coupon": { "name": "Birthday Promo", "promoCodeName": "BIRTHDAY10", "discount": -7770, "discountPercentage": 10 }, "storeMetadata": { "offerType": "Bundle", "offersSequenceIndex": 1, "landingUrl": "https://store.example.com/?myParam=ABC123" }, "device": { "platform": null, "deviceModel": null, "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "transactions": [ { "purchaseId": "pr_abbd0d529dea49f9a7adde2c3827c576", "type": "paid", "timestamp": 1767600954414, "amount": 76136, "amountUsd": 2506, "totalTaxAmount": 6206, "totalTaxAmountUsd": 6206, "currencyExchangeCostUsd": 0, "chargeBackFeeUsd": 20 } ], "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Order Created Source: https://docs.appcharge.com/api-reference/events/v2/order/order_created An event triggered when a new order session is initialized, either from the web store or via direct API call. **Event Data** Event name: `order.created`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Not in use. Not in use. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Customer ID. **Deprecated.** Player's email address. **Deprecated.** Reserved for the player's name in future versions. Information about the offer. External ID of the offer as configured in the Publisher Dashboard. Offer type. Offer subtype. Offer name. The index of the offer. **Deprecated.** Reserved for the index to collect in future versions. **Deprecated.** Reserved for the Publisher Dashboard tab name in future versions. Price point of the offer in USD cents. Price in lowest currency unit. For example, cents for USD, and whole yen for JPY. For a list of of supported currencies, their minor unit types, and applicable pricing limitations, see [Supported Currencies](/../../merchant-of-record/finance/supported-currencies#supported-currencies). Currency code of the offer in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. List of products in an offer. Display name of the product. External ID of the product as configured in the Publisher Dashboard. The quantity of the product. Must be a minimum 0 and equal to or less than 24 digits long. Order ID. Order type. Example: `Paid`. Total order amount in the player's local currency, excluding taxes and discounts. Discount amount calculated on the tax-exclusive price, in USD cents. Always negative, representing a reduction. Example: `-7770` Total amount paid by the player, including discounts and taxes in the player's local currency. Tax amount in the player's local currency. Currency code in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. Currency symbol. The price point in USD cents. Example: `77700`. Whether a player attempted to pay using a saved payment method. Whether a player attempted to save a new payment method in the checkout. Index of the sub-offer within an offer. Offer type. Information about the player's device. Device platform. Currently returns `null`. Device model. Currently returns `null`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "order.created", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "offer": { "externalId": "22ae81bb-55ef-428b-97ba-f67783971e4a", "type": "PopUp", "subType": "DailyBonus", "name": "Spring Is Here", "offerIndex": 1, "indexToCollect": 1, "tab": "Tab 1", "pricePoint": 800, "price": 800, "currencyCode": "USD", "products": [ { "displayName": "Gold Coins", "productExternalId": "31ae81bb-55ef-428b-97ba-f67783971e553", "productQuantity": "1000" }, { "displayName": "Silver Shield", "productExternalId": "9af1abb-55ef-428b-97ba-f677839716ac9", "productQuantity": "40" } ] }, "order": { "id": "695b72ff0e34d3a514b6eda0", "orderType": "Paid", "subtotal": 77700, "discountAmount": -7770, "totalPayment": 76136, "taxAmount": 6206, "currencyCode": "USD", "currencySymbol": "$", "isSavedPaymentMethodUsed": true, "isNewPaymentMethodSaved": true, "pricePointMetadata": 77700 }, "storeMetadata": { "offerType": "Bundle", "offersSequenceIndex": 1 }, "device": { "platform": null, "deviceModel": null, "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Dispute Opened Source: https://docs.appcharge.com/api-reference/events/v2/order/order_dispute_opened An event triggered when a payment dispute is opened, for example, a chargeback is initiated by the player with their payment provider. **Event Data** Event name: `order.dispute.opened`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Not in use. Not in use. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Customer ID. **Deprecated.** Player's email address. **Deprecated.** Reserved for the player's name in future versions. Information about the offer. External ID of the offer as configured in the Publisher Dashboard. Offer type. Offer subtype. Offer name. The index of the offer. **Deprecated.** Reserved for the index to collect in future versions. **Deprecated.** Reserved for the Publisher Dashboard tab name in future versions. Price point of the offer in USD cents. Price in lowest currency unit. For example, cents for USD, and whole yen for JPY. For a list of of supported currencies, their minor unit types, and applicable pricing limitations, see [Supported Currencies](/../../merchant-of-record/finance/supported-currencies#supported-currencies). Currency code of the offer in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. List of products in an offer. Display name of the product. External ID of the product as configured in the Publisher Dashboard. The quantity of the product. Must be a minimum 0 and equal to or less than 24 digits long. Order ID. Order type. Example: `Paid`. Total order amount in the player's local currency, excluding taxes and discounts. Discount amount calculated on the tax-exclusive price, in USD cents. Always negative, representing a reduction. Example: `-7770` Total amount paid by the player, including discounts and taxes in the player's local currency. Tax amount in the player's local currency. Currency code in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. Currency symbol. Payment method used for the order. The price point in USD cents. Example: `77700`. Whether a player attempted to pay using a saved payment method. Whether a player attempted to save a new payment method in the checkout. Index of the sub-offer within an offer. Offer type. Information about the coupon. Coupon name. Promo code name. Discount amount calculated on the tax-exclusive price, in USD cents. Always negative, representing a reduction. Example: `-7770` Discount percentage. Information about the player's device. Device platform. Currently returns `null`. Device model. Currently returns `null`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Information about each transaction. Purchase ID. Transaction type. Transaction timestamp in [Epoch time](https://www.epoch101.com/). Example: `1754307361396`. Transaction amount in the player's local currency. Transaction amount in USD cents. Example: `76136`. Tax amount in the player's local currency. Tax amount in USD cents. Example: `6206`. Currency exchange fee in USD cents. Chargeback fee in USD cents. Example: `20`. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "order.dispute.opened", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "offer": { "externalId": "22ae81bb-55ef-428b-97ba-f67783971e4a", "type": "PopUp", "subType": "DailyBonus", "name": "Spring Is Here", "offerIndex": 1, "indexToCollect": 1, "tab": "Tab 1", "pricePoint": 800, "price": 800, "currencyCode": "USD", "products": [ { "displayName": "Gold Coins", "productExternalId": "31ae81bb-55ef-428b-97ba-f67783971e553", "productQuantity": "1000" }, { "displayName": "Silver Shield", "productExternalId": "9af1abb-55ef-428b-97ba-f677839716ac9", "productQuantity": "40" } ] }, "order": { "id": "695b72ff0e34d3a514b6eda0", "orderType": "Paid", "subtotal": 77700, "discountAmount": -7770, "totalPayment": 76136, "taxAmount": 6206, "currencyCode": "USD", "currencySymbol": "$", "paymentMethod": "Credit Card", "isSavedPaymentMethodUsed": true, "isNewPaymentMethodSaved": true, "pricePointMetadata": 77700 }, "coupon": { "name": "Birthday Promo", "promoCodeName": "BIRTHDAY10", "discount": -7770, "discountPercentage": 10 }, "storeMetadata": { "offerType": "Bundle", "offersSequenceIndex": 1 }, "device": { "platform": null, "deviceModel": null, "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "transactions": [ { "purchaseId": "pr_abbd0d529dea49f9a7adde2c3827c576", "type": "paid", "timestamp": 1767600954414, "amount": 76136, "amountUsd": 2506, "totalTaxAmount": 6206, "totalTaxAmountUsd": 6206, "currencyExchangeCostUsd": 0, "chargeBackFeeUsd": 0 }, { "purchaseId": "pr_abbd0d529dea49f9a7adde2c3827c576", "type": "dispute_funds_withdrawn", "timestamp": 1771186042504, "amount": -76136, "amountUsd": -2506, "totalTaxAmount": -6206, "totalTaxAmountUsd": -6206, "currencyExchangeCostUsd": 0, "chargeBackFeeUsd": 1500 } ], "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Dispute Resolved Source: https://docs.appcharge.com/api-reference/events/v2/order/order_dispute_resolved An event triggered when a dispute is resolved, regardless of the outcome. **Event Data** Event name: `order.dispute.resolved`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Supported values: `won`, `lost`. Not in use. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Customer ID. **Deprecated.** Player email address. **Deprecated.** Reserved for the player's name in future versions. Information about the offer. External ID of the offer as configured in the Publisher Dashboard. Offer type. Offer subtype. Offer name. The index of the offer. **Deprecated.** Reserved for the index to collect in future versions. **Deprecated.** Reserved for the Publisher Dashboard tab name in future versions. Price point of the offer in USD cents. Price in lowest currency unit. For example, cents for USD, and whole yen for JPY. For a list of of supported currencies, their minor unit types, and applicable pricing limitations, see [Supported Currencies](/../../merchant-of-record/finance/supported-currencies#supported-currencies). Currency code of the offer in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. List of products in an offer. Display name of the product. External ID of the product as configured in the Publisher Dashboard. The quantity of the product. Must be a minimum 0 and equal to or less than 24 digits long. Order ID. Order type. Supported values: `Paid`, `Free`. Total order amount in the player's local currency, excluding taxes and discounts. Discount amount calculated on the tax-exclusive price, in USD cents. Always negative, representing a reduction. Example: `-7770` Total amount paid by the player, including discounts and taxes in the player's local currency. Tax amount in the player's local currency. Currency code in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. Currency symbol. Payment method used for the order. The price point in USD cents. Example: `77700`. Whether a player attempted to pay using a saved payment method. Whether a player attempted to save a new payment method in the checkout. Index of the sub-offer within an offer. Offer type. Information about the coupon. Coupon name. Promo code name. Discount amount calculated on the tax-exclusive price, in USD cents. Always negative, representing a reduction. Example: `-7770` Discount percentage. Information about the player's device. Device platform. Currently returns `null`. Device model. Currently returns `null`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Information about each transaction. Purchase ID. Transaction type. Transaction timestamp in [Epoch time](https://www.epoch101.com/). Example: `1754307361396`. Transaction amount in the player's local currency. Transaction amount in USD cents. Example: `76136`. Tax amount in the player's local currency. Tax amount in USD cents. Example: `6206`. Currency exchange fee in USD cents. Chargeback fee in USD cents. Example: `20`. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "order.dispute.resolved", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": "won", "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "offer": { "externalId": "22ae81bb-55ef-428b-97ba-f67783971e4a", "type": "PopUp", "subType": "DailyBonus", "name": "Spring Is Here", "offerIndex": 1, "indexToCollect": 1, "tab": "Tab 1", "pricePoint": 77700, "price": 77700, "currencyCode": "USD", "products": [ { "displayName": "Gold Coins", "productExternalId": "31ae81bb-55ef-428b-97ba-f67783971e553", "productQuantity": "1000" }, { "displayName": "Silver Shield", "productExternalId": "9af1abb-55ef-428b-97ba-f677839716ac9", "productQuantity": "40" } ] }, "order": { "id": "695b72ff0e34d3a514b6eda0", "orderType": "Paid", "subtotal": 77700, "discountAmount": -7770, "totalPayment": 76136, "taxAmount": 6206, "currencyCode": "USD", "currencySymbol": "$", "paymentMethod": "Credit Card", "isSavedPaymentMethodUsed": true, "isNewPaymentMethodSaved": true, "pricePointMetadata": 77700 }, "coupon": { "name": "Birthday Promo", "promoCodeName": "BIRTHDAY10", "discount": -7770, "discountPercentage": 10 }, "storeMetadata": { "offerType": "Bundle", "offersSequenceIndex": 1 }, "device": { "platform": null, "deviceModel": null, "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "transactions": [ { "purchaseId": "pr_68d67720ad014759b3160a6ba82dbc59", "type": "paid", "timestamp": 1771231549913, "amount": 1550, "amountUsd": 1550, "totalTaxAmount": 236, "totalTaxAmountUsd": 236, "currencyExchangeCostUsd": 0, "chargeBackFeeUsd": 0 }, { "purchaseId": "pr_68d67720ad014759b3160a6ba82dbc59", "type": "dispute_funds_withdrawn", "timestamp": 1771231626684, "amount": -1550, "amountUsd": -1550, "totalTaxAmount": -236, "totalTaxAmountUsd": -236, "currencyExchangeCostUsd": 0, "chargeBackFeeUsd": 1000 }, { "purchaseId": "pr_68d67720ad014759b3160a6ba82dbc59", "type": "dispute_funds_reinstated", "timestamp": 1771231627252, "amount": 1550, "amountUsd": 1550, "totalTaxAmount": 236, "totalTaxAmountUsd": 236, "currencyExchangeCostUsd": 0, "chargeBackFeeUsd": 0 } ], "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Payment Resolved Source: https://docs.appcharge.com/api-reference/events/v2/order/order_payment_resolved An event triggered when a payment is finalized, successfully or unsuccessfully. **Event Data** Event name: `order.payment.resolved`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Supported values: `success`, `failed`. Reason for the event result. When `result` is `success`, this field returns `null`. When `result` is `failed`, this field returns a free-form failure message from the payment provider. In some failure paths, this field returns `please try again later`. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Customer ID. **Deprecated.** Player's email address. **Deprecated.** Reserved for the player's name in future versions. Information about the offer. External ID of the offer as configured in the Publisher Dashboard. Offer type. Offer subtype. Offer name. The index of the offer. **Deprecated.** Reserved for the index to collect in future versions. **Deprecated.** Reserved for the Publisher Dashboard tab name in future versions. Price point of the offer in USD cents. Price in lowest currency unit. For example, cents for USD, and whole yen for JPY. For a list of of supported currencies, their minor unit types, and applicable pricing limitations, see [Supported Currencies](/../../merchant-of-record/finance/supported-currencies#supported-currencies). Currency code of the offer in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. List of products in an offer. Display name of the product. External ID of the product as configured in the Publisher Dashboard. The quantity of the product. Must be a minimum 0 and equal to or less than 24 digits long. Order ID. Order type. Example: `Paid`. Total order amount in the player's local currency, excluding taxes and discounts. Discount amount calculated on the tax-exclusive price, in USD cents. Always negative, representing a reduction. Example: `-7770` Total amount paid by the player, including discounts and taxes in the player's local currency. Tax amount in the player's local currency. Currency code in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. Currency symbol. Payment method used for the order. The price point in USD cents. Example: `77700`. Whether a player attempted to pay using a saved payment method. Whether a player attempted to save a new payment method in the checkout. Index of the sub-offer within an offer. Offer type. Information about the coupon. Coupon name. Promo code name. Discount amount calculated on the tax-exclusive price, in USD cents. Always negative, representing a reduction. Example: `-7770` Discount percentage. Information about the player's device. Device platform. Currently returns `null`. Device model. Currently returns `null`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Information about each transaction. Purchase ID. Transaction type. Transaction timestamp in [Epoch time](https://www.epoch101.com/). Example: `1754307361396`. Transaction amount in the player's local currency. Transaction amount in USD cents. Example: `76136`. Tax amount in the player's local currency. Tax amount in USD cents. Example: `6206`. Currency exchange fee in USD cents. Chargeback fee in USD cents. Example: `20`. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "order.payment.resolved", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": "success", "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "offer": { "externalId": "22ae81bb-55ef-428b-97ba-f67783971e4a", "type": "PopUp", "subType": "DailyBonus", "name": "Spring Is Here", "offerIndex": 1, "indexToCollect": 1, "tab": "Tab 1", "pricePoint": 800, "price": 800, "currencyCode": "USD", "products": [ { "displayName": "Gold Coins", "productExternalId": "31ae81bb-55ef-428b-97ba-f67783971e553", "productQuantity": "1000" }, { "displayName": "Silver Shield", "productExternalId": "9af1abb-55ef-428b-97ba-f677839716ac9", "productQuantity": "40" } ] }, "order": { "id": "695b72ff0e34d3a514b6eda0", "orderType": "Paid", "subtotal": 77700, "discountAmount": -7770, "totalPayment": 76136, "taxAmount": 6206, "currencyCode": "USD", "currencySymbol": "$", "paymentMethod": "Credit Card", "isSavedPaymentMethodUsed": true, "isNewPaymentMethodSaved": true, "pricePointMetadata": 77700 }, "coupon": { "name": "Birthday Promo", "promoCodeName": "BIRTHDAY10", "discount": -7770, "discountPercentage": 10 }, "storeMetadata": { "offerType": "Bundle", "offersSequenceIndex": 1 }, "device": { "platform": null, "deviceModel": null, "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "transactions": [ { "purchaseId": "pr_abbd0d529dea49f9a7adde2c3827c576", "type": "paid", "timestamp": 1767600954414, "amount": 76136, "amountUsd": 2506, "totalTaxAmount": 6206, "totalTaxAmountUsd": 6206, "currencyExchangeCostUsd": 0, "chargeBackFeeUsd": 20 } ], "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Order Refunded Source: https://docs.appcharge.com/api-reference/events/v2/order/order_refunded An event triggered when an order is refunded, either manually or automatically. **Event Data** Event name: `order.refunded`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Supported values: `success`, `failed`. Reason for the event result. When `result` is `success`, this field returns `null`. When `result` is `failed`, this field returns a free-form failure message from the payment or refund provider. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Customer ID. **Deprecated.** Player's email address. **Deprecated.** Reserved for the player's name in future versions. Information about the offer. External ID of the offer as configured in the Publisher Dashboard. Offer type. Offer subtype. Offer name. The index of the offer. **Deprecated.** Reserved for the index to collect in future versions. **Deprecated.** Reserved for the Publisher Dashboard tab name in future versions. Price point of the offer in USD cents. Price in lowest currency unit. For example, cents for USD, and whole yen for JPY. For a list of of supported currencies, their minor unit types, and applicable pricing limitations, see [Supported Currencies](/../../merchant-of-record/finance/supported-currencies#supported-currencies). Currency code of the offer in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. List of products in an offer. Display name of the product. External ID of the product as configured in the Publisher Dashboard. The quantity of the product. Must be a minimum 0 and equal to or less than 24 digits long. Order ID. Order type. Example: `Paid`. Total order amount in the player's local currency, excluding taxes and discounts. Discount amount calculated on the tax-exclusive price, in USD cents. Always negative, representing a reduction. Example: `-7770` Total amount paid by the player, including discounts and taxes in the player's local currency. Tax amount in the player's local currency. Currency code in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. Currency symbol. Payment method used for the order. The price point in USD cents. Example: `77700`. Whether a player attempted to pay using a saved payment method. Whether a player attempted to save a new payment method in the checkout. Index of the sub-offer within an offer. Offer type. Information about the coupon. Coupon name. Promo code name. Discount amount calculated on the tax-exclusive price, in USD cents. Always negative, representing a reduction. Example: `-7770` Discount percentage. Information about the player's device. Device platform. Currently returns `null`. Device model. Currently returns `null`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Information about each transaction. Purchase ID. Transaction type. Transaction timestamp in [Epoch time](https://www.epoch101.com/). Example: `1754307361396`. Transaction amount in the player's local currency. Transaction amount in USD cents. Example: `76136`. Tax amount in the player's local currency. Tax amount in USD cents. Example: `6206`. Currency exchange fee in USD cents. Chargeback fee in USD cents. Example: `20`. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "order.refunded", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": "success", "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "offer": { "externalId": "22ae81bb-55ef-428b-97ba-f67783971e4a", "type": "PopUp", "subType": "DailyBonus", "name": "Spring Is Here", "offerIndex": 1, "indexToCollect": 1, "tab": "Tab 1", "pricePoint": 800, "price": 800, "currencyCode": "USD", "products": [ { "displayName": "Gold Coins", "productExternalId": "31ae81bb-55ef-428b-97ba-f67783971e553", "productQuantity": "1000" }, { "displayName": "Silver Shield", "productExternalId": "9af1abb-55ef-428b-97ba-f677839716ac9", "productQuantity": "40" } ] }, "order": { "id": "695b72ff0e34d3a514b6eda0", "orderType": "Paid", "subtotal": 77700, "discountAmount": -7770, "totalPayment": 76136, "taxAmount": 6206, "currencyCode": "USD", "currencySymbol": "$", "paymentMethod": "Credit Card", "isSavedPaymentMethodUsed": true, "isNewPaymentMethodSaved": true, "pricePointMetadata": 77700 }, "coupon": { "name": "Birthday Promo", "promoCodeName": "BIRTHDAY10", "discount": -7770, "discountPercentage": 10 }, "storeMetadata": { "offerType": "Bundle", "offersSequenceIndex": 1 }, "device": { "platform": null, "deviceModel": null, "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "transactions": [ { "purchaseId": "pr_abbd0d529dea49f9a7adde2c3827c576", "type": "paid", "timestamp": 1767600954414, "amount": 76136, "amountUsd": 2506, "totalTaxAmount": 6206, "totalTaxAmountUsd": 6206, "currencyExchangeCostUsd": 0, "chargeBackFeeUsd": 20 }, { "purchaseId": "pr_abbd0d529dea49f9a7adde2c3827c576", "type": "refund", "timestamp": 1771180700780, "amount": -76136, "amountUsd": -2506, "totalTaxAmount": -6206, "totalTaxAmountUsd": -6206, "currencyExchangeCostUsd": 0, "chargeBackFeeUsd": 0 } ], "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Portal Login Canceled Source: https://docs.appcharge.com/api-reference/events/v2/portal/login/portal_login_canceled An event triggered when the player closes or leaves the game portal login process before completing it. **Event Data** Event name: `portal.login.canceled`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Reserved for the player's name in future versions. **Deprecated.** Player email address. UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Information about the login. Player login method. Example: `Facebook`. Action the player made that triggered the login. For example, in the Game Portal, if a player clicked the login button, or the **Store** page while signed out. The interface through which the player accessed the login page. Supported values: * `browser app`: Mobile or desktop browser. * `webview`: An in-app webview. * `homescreen bookmark`: A saved home screen shortcut or bookmark. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. ```json Event Payload theme={"system"} { "eventName": "portal.login.canceled", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "utm": { "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" }, "login": { "method": "Facebook", "trigger": "Player clicked on the login button while signed out.", "source": "webview" }, "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null } } ``` # Portal Login Completed Source: https://docs.appcharge.com/api-reference/events/v2/portal/login/portal_login_completed An event triggered when the player successfully completes the game portal login process and is authenticated. **Event Data** Event name: `portal.login.completed`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Supported values: `success`, `failed`. Reason for the event result. When `result` is `success`, this field returns `null`. When `result` is `failed`, this field returns a free-form error message, or `unknown` if none is available. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Reserved for the player's name in future versions. **Deprecated.** Player email address. UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Information about the login. Player login method. Example: `Facebook`. Action the player made that triggered the login. For example, in the Game Portal, if a player clicked the login button, or the **Store** page while signed out. The interface through which the player accessed the login page. Supported values: * `browser app`: Mobile or desktop browser. * `webview`: An in-app webview. * `homescreen bookmark`: A saved home screen shortcut or bookmark. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "portal.login.completed", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": "success", "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "utm": { "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" }, "login": { "method": "Facebook", "trigger": "Player clicked on the login button while signed out.", "source": "webview" }, "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Portal Login Displayed Source: https://docs.appcharge.com/api-reference/events/v2/portal/login/portal_login_displayed An event triggered when the login page of the game portal is displayed. Used to track login funnel entry. **Event Data** Event name: `portal.login.displayed`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Information about the login. Player login method. Example: `Facebook`. Action the player made that triggered the login. For example, in the Game Portal, if a player clicked the login button, or the **Store** page while signed out. The interface through which the player accessed the login page. Supported values: * `browser app`: Mobile or desktop browser. * `webview`: An in-app webview. * `homescreen bookmark`: A saved home screen shortcut or bookmark. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. ```json Event Payload theme={"system"} { "eventName": "portal.login.displayed", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "utm": { "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" }, "login": { "method": "Facebook", "trigger": "Player clicked on the login button while signed out.", "source": "webview" }, "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null } } ``` # Portal Login Method Selected Source: https://docs.appcharge.com/api-reference/events/v2/portal/login/portal_login_method_selected An event triggered when a login method is selected in the game portal. For example, a social media platform. **Event Data** Event name: `portal.login.login_method.selected`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Reserved for the player's name in future versions. **Deprecated.** Player email address. UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Information about the login. Player login method. Example: `Facebook`. Action the player made that triggered the login. For example, in the Game Portal, if a player clicked the login button, or the **Store** page while signed out. The interface through which the player accessed the login page. Supported values: * `browser app`: Mobile or desktop browser. * `webview`: An in-app webview. * `homescreen bookmark`: A saved home screen shortcut or bookmark. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. ```json Event Payload theme={"system"} { "eventName": "portal.login.login_method.selected", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "utm": { "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" }, "login": { "method": "Facebook", "trigger": "Player clicked on the login button while signed out.", "source": "webview" }, "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null } } ``` # Portal Approval Request Closed Source: https://docs.appcharge.com/api-reference/events/v2/portal/ui/portal_approval_request_closed An event triggered when the Approval Request in the [checkout link offer](../../../../webstore/offers-v2/checkout-link-offers/introduction) is closed. **Event Data** Event name: `portal.approval_request.closed`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Supported values: `success`, `failed`. Reason for the event result. Example: `invalid_credentials`. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Reserved for the player's name in future versions. **Deprecated.** Player email address. List of offers. External ID of the offer as configured in the Publisher Dashboard. Offer type. Offer subtype. Offer name. The index of the sub-offer currently available to be collected in a rolling offer. List of products in an offer. Display name of the product. External ID of the product as configured in the Publisher Dashboard. The quantity of the product. Must be a minimum 0 and equal to or less than 24 digits long. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "portal.approval_request.closed", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": "success", "reason": "invalid_credentials", "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "offers": [ { "externalId": "22ae81bb-55ef-428b-97ba-f67783971e4a", "type": "PopUp", "subType": "DailyBonus", "name": "Spring Is Here", "indexToCollect": "1", "products": [ { "displayName": "Gold Coins", "productExternalId": "31ae81bb-55ef-428b-97ba-f67783971e553", "productQuantity": "1000" }, { "displayName": "Silver Shield", "productExternalId": "9af1abb-55ef-428b-97ba-f677839716ac9", "productQuantity": "40" } ] } ], "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Portal Approval Request Displayed Source: https://docs.appcharge.com/api-reference/events/v2/portal/ui/portal_approval_request_displayed An event triggered when the Approval Request in the [checkout link offer](../../../../webstore/offers-v2/checkout-link-offers/introduction) is displayed. **Event Data** Event name: `portal.approval_request.displayed`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Supported values: `success`, `failed`. Reason for the event result. Example: `invalid_credentials`. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Reserved for the player's name in future versions. **Deprecated.** Player email address. List of offers. External ID of the offer as configured in the Publisher Dashboard. Offer type. Offer subtype. Offer name. The index of the sub-offer currently available to be collected in a rolling offer. List of products in an offer. Display name of the product. External ID of the product as configured in the Publisher Dashboard. The quantity of the product. Must be a minimum 0 and equal to or less than 24 digits long. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "portal.approval_request.displayed", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": "success", "reason": "invalid_credentials", "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "offers": [ { "externalId": "22ae81bb-55ef-428b-97ba-f67783971e4a", "type": "PopUp", "subType": "DailyBonus", "name": "Spring Is Here", "indexToCollect": "1", "products": [ { "displayName": "Gold Coins", "productExternalId": "31ae81bb-55ef-428b-97ba-f67783971e553", "productQuantity": "1000" }, { "displayName": "Silver Shield", "productExternalId": "9af1abb-55ef-428b-97ba-f677839716ac9", "productQuantity": "40" } ] } ], "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Portal Block Clicked Source: https://docs.appcharge.com/api-reference/events/v2/portal/ui/portal_block_clicked An event triggered when a Game Portal block is clicked. **Event Data** Event name: `portal.block.clicked`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player's current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Example: `23539478-c744-566a-c78c-c4cc7763ff62`. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. Example: `671e81bb-55ef-428b-97ba-f67783971e0d`. **Deprecated.** Reserved for the player's name in future versions. **Deprecated.** Player email address. Example: `john.doe@gmail.com`. UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Apple`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the block. Block type. Example: `image`. Button label text. Applies to: `cta`. URL the player is redirected to when clicking the block. Applies to: `cta`, `image`. Whether the URL redirects to an external web store. Applies to: `cta`. Desktop asset URL for the block. Applies to: `cta`. Mobile asset URL for the block. Applies to: `cta`. Desktop image URL. Applies to: `image`. Mobile image URL. Applies to: `image`. Content item ID. Applies to: `contentsPreview`. Content type. Example: `news`. Applies to: `contentsPreview`. Content title. Applies to: `contentsPreview`. Content subtitle. Applies to: `contentsPreview`. Thumbnail image URL. Applies to: `contentsPreview`. Publication date in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. Example: `2025-12-28T21:52:21.539Z`. Applies to: `contentsPreview`. Content slug. Applies to: `contentsPreview`. List of labels or tags associated with the content. Applies to: `contentsPreview`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. Example: `Florida`. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `192.168.1.1`. **Deprecated.** Zip code. Example: `34997`. Session metadata. An object for passing data to Appcharge to be returned later. Example: `{ "abTest": "group1", "locale": "en-US" }`. ```json Event Payload theme={"system"} { "eventName": "portal.block.clicked", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "utm": { "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" }, "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "block": { "type": "cta", "items": [ { "text": "click me", "redirectUrl": "https://example.com/redirect", "isStoreRedirect": true, "assetUrl": "https://example.com/asset.png", "assetUrlMobile": "https://example.com/asset-mobile.png" } ] }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Portal Content Displayed Source: https://docs.appcharge.com/api-reference/events/v2/portal/ui/portal_content_displayed An event triggered when content on a game portal page is displayed. **Event Data** Event name: `portal.content.displayed`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Reserved for the player's name in future versions. **Deprecated.** Player email address. Information about page content in the game portal. Content ID. Content type. Supported values: * `news` * `article` Content index. Content title. Content slug. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "portal.content.displayed", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "content": [ { "id": "36be81bb55ef428b97baf677", "type": "news", "index": 4, "title": "Spring Update", "slug": "spring-update" } ], "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Portal Footer Clicked Source: https://docs.appcharge.com/api-reference/events/v2/portal/ui/portal_footer_clicked An event triggered when the Game Portal footer is clicked. **Event Data** Event name: `portal.footer.clicked`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Reserved for the player's name in future versions. **Deprecated.** Player email address. Information about the footer. A button in the footer. Supported values: * `support`: A button to contact customer support. * `terms_of_service`: A button to view the Terms & Conditions. * `privacy_policy`: A button to view the Privacy Policy. Button link URL. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "portal.footer.clicked", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "footer": { "button": "support", "url": "https://support.example.com/contact" }, "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Portal Page Displayed Source: https://docs.appcharge.com/api-reference/events/v2/portal/ui/portal_page_displayed An event triggered when a page in the game portal is displayed. **Event Data** Event name: `portal.page.displayed`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Reserved for the player's name in future versions. **Deprecated.** Player email address. Information about the game portal pages. Page URL. Page name. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "portal.page.displayed", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "page": [ { "pageUrl": "https://www.my-game-portal/home", "pageName": "Home" } ], "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Invalid Property Error Source: https://docs.appcharge.com/api-reference/events/v2/webstore/invalid_property **Deprecated:** This event is deprecated and will continue to be supported for backward compatibility. We recommend using the [Personalization Response Error](./personalization_response_error) instead. An event triggered when the web store receives malformed or invalid data in the session or offer configuration, typically due to incorrect formatting or missing required fields. **Event Data** Event name: `webstore.personalization_api.error.invalid_property`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. This field is not currently in use. Reason for the event result. This field returns a free-form JSON string of validation errors. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Reserved for the player's name in future versions. **Deprecated.** Player email address. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "webstore.personalization_api.error.invalid_property", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": "Invalid property value", "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Web Store Login Canceled Source: https://docs.appcharge.com/api-reference/events/v2/webstore/login/webstore_login_canceled An event triggered when the player closes or leaves the web store login process before completing it. **Event Data** Event name: `webstore.login.canceled`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Information about the login. Player login method. Example: `Facebook`. The interface through which the player accessed the login page. Supported values: * `browser app`: Mobile or desktop browser. * `webview`: An in-app webview. * `homescreen bookmark`: A saved home screen shortcut or bookmark. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. ```json Event Payload theme={"system"} { "eventName": "webstore.login.canceled", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "utm": { "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" }, "login": { "method": "Facebook", "source": "webview" }, "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null } } ``` # Web Store Login Completed Source: https://docs.appcharge.com/api-reference/events/v2/webstore/login/webstore_login_completed An event triggered when the player successfully completes the web store login process and is authenticated. **Event Data** Event name: `webstore.login.completed`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Supported values: `success`, `failed`. Reason for the event result. When `result` is `success`, this field returns `null`. When `result` is `failed`, this field returns a free-form error message, or `unknown` if none is available. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Player's email address. **Deprecated.** Reserved for the player's name in future versions. UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Information about the login. Player login method. Example: `Facebook`. The interface through which the player accessed the login page. Supported values: * `browser app`: Mobile or desktop browser. * `webview`: An in-app webview. * `homescreen bookmark`: A saved home screen shortcut or bookmark. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "webstore.login.completed", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": "success", "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "utm": { "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" }, "login": { "method": "Facebook", "source": "webview" }, "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Web Store Login Displayed Source: https://docs.appcharge.com/api-reference/events/v2/webstore/login/webstore_login_displayed An event triggered when the login page of the web store is displayed. Used to track login funnel entry. **Event Data** Event name: `webstore.login.displayed`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Information about the login. Player login method. Example: `Facebook`. The interface through which the player accessed the login page. Supported values: * `browser app`: Mobile or desktop browser. * `webview`: An in-app webview. * `homescreen bookmark`: A saved home screen shortcut or bookmark. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. ```json Event Payload theme={"system"} { "eventName": "webstore.login.displayed", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "utm": { "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" }, "login": { "method": "Facebook", "source": "webview" }, "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null } } ``` # Web Store Login Method Selected Source: https://docs.appcharge.com/api-reference/events/v2/webstore/login/webstore_login_method_selected An event triggered when a login method in the web store is selected. For example, a social media platform. **Event Data** Event name: `webstore.login.login_method.selected`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Information about the login. Player login method. Example: `Facebook`. The interface through which the player accessed the login page. Supported values: * `browser app`: Mobile or desktop browser. * `webview`: An in-app webview. * `homescreen bookmark`: A saved home screen shortcut or bookmark. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. ```json Event Payload theme={"system"} { "eventName": "webstore.login.login_method.selected", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "utm": { "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" }, "login": { "method": "Facebook", "source": "webview" }, "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null } } ``` # Web Store Displayed Source: https://docs.appcharge.com/api-reference/events/v2/webstore/login/webstore_store_displayed An event triggered when the web store page is displayed. **Event Data** Event name: `webstore.store.displayed`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Player's email address. **Deprecated.** Reserved for the player's name in future versions. UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Information about the login. Player login method. Example: `Facebook`. The interface through which the player accessed the login page. Supported values: * `browser app`: Mobile or desktop browser. * `webview`: An in-app webview. * `homescreen bookmark`: A saved home screen shortcut or bookmark. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. URL the player used to land on the web store in the current active session. The URL is propagated as is, from the web store session to the checkout. Example: `https://store.example.com/?myParam=ABC123`. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "webstore.store.displayed", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "utm": { "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" }, "login": { "method": "Facebook", "source": "webview" }, "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "landingUrl": "https://store.example.com/?myParam=ABC123", "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Web Store Approval Request Closed Source: https://docs.appcharge.com/api-reference/events/v2/webstore/offer/approval_request_closed This event is only relevant for the legacy [JWT authentication method](/../../guides/webstore/offers/checkout-link-offers/use-jwt-method). An event triggered when the Approval Request in the [checkout link offer](../../../../webstore/offers-v2/checkout-link-offers/introduction) is closed. **Event Data** Event name: `webstore.approval_request.closed`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Player's email address. **Deprecated.** Reserved for the player's name in future versions. UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "webstore.approval_request.closed", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "utm": { "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" }, "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Web Store Approval Request Displayed Source: https://docs.appcharge.com/api-reference/events/v2/webstore/offer/approval_request_displayed This event is only relevant for the legacy [JWT authentication method](/../../guides/webstore/offers/checkout-link-offers/use-jwt-method). An event triggered when the Approval Request in the [checkout link offer](../../../../webstore/offers-v2/checkout-link-offers/introduction) is displayed. **Event Data** Event name: `webstore.approval_request.displayed`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Player's email address. **Deprecated.** Reserved for the player's name in future versions. UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "webstore.approval_request.displayed", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "utm": { "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" }, "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Offer Popup Closed Source: https://docs.appcharge.com/api-reference/events/v2/webstore/offer/offer_popup_closed An event triggered when a player closes a popup offer in the web store. **Event Data** Event name: `webstore.offers.popup_closed`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player's current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Player's email address. **Deprecated.** Reserved for the player's name in future versions. Offer information. External ID of the offer as configured in the Publisher Dashboard. Offer type. Offer subtype. Offer name. The index of the offer. Position of the sub-offer currently available to be collected in a Rolling offer. Tab name in the Publisher Dashboard associated with the offer. Price point of the offer in USD cents. Price in lowest currency unit. For example, cents for USD, and whole yen for JPY. For a list of of supported currencies, their minor unit types, and applicable pricing limitations, see [Supported Currencies](/../../merchant-of-record/finance/supported-currencies#supported-currencies). Currency code of the offer in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. List of products in an offer. Display name of the product. External ID of the product as configured in the Publisher Dashboard. The quantity of the product. Must be a minimum 0 and equal to or less than 24 digits long. Index of the sub-offer within an offer. Offer type. UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "webstore.offers.popup_closed", "eventId": "d11120c7-00e8-45a3-befe-4b6e4b61d935", "timestamp": 1771163366957, "sessionId": "e8a56ae6-bf1c-45f9-94d0-7768517ff9d4", "requestId": "c48ee942-d707-4300-b326-15274d5a8753", "result": null, "reason": null, "attributes": null, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "offer": { "externalId": "daily-bonus", "type": "PopUp", "subType": "DailyBonus", "name": "daily-bonus", "offerIndex": 1, "indexToCollect": 1, "tab": "1", "pricePoint": 800, "price": 800, "currencyCode": "USD", "products": [ { "displayName": "Gold Coins", "productExternalId": "31ae81bb-55ef-428b-97ba-f67783971e553", "productQuantity": "1000" } ] }, "storeMetadata": { "offersSequenceIndex": 1, "offerType": "Popup" }, "device": { "platform": "DESKTOP", "osType": "Mac", "osVersion": "10.15", "browserType": "Chrome", "browserVersion": "143.0", "deviceModel": "" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "utm": { "utmSource": null, "utmMedium": null, "utmCampaign": null, "utmTerm": null, "utmContent": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Offers Displayed Source: https://docs.appcharge.com/api-reference/events/v2/webstore/offer/offers_displayed An event triggered when 100% of an offer's visual element is visible to the player. Events are batched every second and include only newly shown offers, excluding previously reported ones. The list resets after a page refresh. **Event Data** Event name: `webstore.offers.displayed`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Player email address. **Deprecated.** Reserved for the player's name in future versions. List of offers. External ID of the offer as configured in the Publisher Dashboard. Offer type. Offer subtype. Offer name. Position of the sub-offer that is currently available for collection within the Rolling Offer flow. Position of the next sub-offer that can be collected in the Rolling Offer flow. The name of the tab in the Publisher Dashboard. Price point of the offer in USD cents. Price in lowest currency unit. For example, cents for USD, and whole yen for JPY. For a list of of supported currencies, their minor unit types, and applicable pricing limitations, see [Supported Currencies](/../../merchant-of-record/finance/supported-currencies#supported-currencies). Currency code of the offer in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. List of products in an offer. Display name of the product. External ID of the product as configured in the Publisher Dashboard. The quantity of the product. Must be a minimum 0 and equal to or less than 24 digits long. List of Progress Bars. Progress Bar external ID. Current mission index. Number of points the player has earned so far in the current mission. List of products in the Progress Bar. Product external ID. Product quantity. Total number of points required to complete the current mission. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "webstore.offers.displayed", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "offers": [ { "externalId": "22ae81bb-55ef-428b-97ba-f67783971e4a", "type": "SpecialOffer", "subType": null, "name": "Spring Is Here", "offerIndex": 1, "indexToCollect": 1, "tab": "Knight Guard", "pricePoint": 800, "price": 800, "currencyCode": "USD", "products": [ { "displayName": "Gold Coins", "productExternalId": "31ae81bb-55ef-428b-97ba-f67783971e553", "productQuantity": "1000" }, { "displayName": "Silver Shield", "productExternalId": "9af1abb-55ef-428b-97ba-f677839716ac9", "productQuantity": "40" } ] } ], "progressBars": [ { "progressBarExternalId": "my-progress-bar-1", "missionIndex": 2, "points": 100, "products": [ { "productExternalId": "treasure-12", "productQuantity": "200" } ], "pointsTarget": 500 } ], "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Offers Loaded Source: https://docs.appcharge.com/api-reference/events/v2/webstore/offer/offers_loaded An event triggered when the backend successfully returns the list of offers configured to be shown to the player. This event confirms that the offers are ready to be rendered on the page. **Event Data** Event name: `webstore.offers.loaded`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. Reason for the event result. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Player email address. **Deprecated.** Reserved for the player's name in future versions. List of offers. External ID of the offer as configured in the Publisher Dashboard. Offer type. Offer subtype. Offer name. Position of the sub-offer that is currently available for collection within the Rolling Offer flow. Position of the next sub-offer that can be collected in the Rolling Offer flow. The name of the tab in the Publisher Dashboard. Price point of the offer in USD cents. Price in lowest currency unit. For example, cents for USD, and whole yen for JPY. For a list of of supported currencies, their minor unit types, and applicable pricing limitations, see [Supported Currencies](/../../merchant-of-record/finance/supported-currencies#supported-currencies). Currency code of the offer in [ISO\_4217](https://en.wikipedia.org/wiki/ISO_4217) format. List of products in an offer. Display name of the product. External ID of the product as configured in the Publisher Dashboard. The quantity of the product. Must be a minimum 0 and equal to or less than 24 digits long. List of Progress Bars. Progress Bar external ID. Current mission index. Number of points the player has earned so far in the current mission. List of products in the Progress Bar. Product external ID. Product quantity. Total number of points required to complete the current mission. Information about the player's device. Device platform. Example: `iOS`. Device model. Example: `iPhone 16 Pro`. Operating system type. Example: `Android`. Operating system version. Example: `18`. Browser type. Example: `Google Chrome`. Browser version. Example: `138`. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "webstore.offers.loaded", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "offers": [ { "externalId": "22ae81bb-55ef-428b-97ba-f67783971e4a", "type": "SpecialOffer", "subType": null, "name": "Spring Is Here", "offerIndex": 1, "indexToCollect": 1, "tab": "Knight Guard", "pricePoint": 800, "price": 800, "currencyCode": "USD", "products": [ { "displayName": "Gold Coins", "productExternalId": "31ae81bb-55ef-428b-97ba-f67783971e553", "productQuantity": "1000" }, { "displayName": "Silver Shield", "productExternalId": "9af1abb-55ef-428b-97ba-f677839716ac9", "productQuantity": "40" } ] } ], "progressBars": [ { "progressBarExternalId": "my-progress-bar-1", "missionIndex": 2, "points": 100, "products": [ { "productExternalId": "treasure-12", "productQuantity": "200" } ], "pointsTarget": 500 } ], "device": { "platform": "iOS", "deviceModel": "iPhone 16 Pro", "osType": "Apple", "osVersion": "18", "browserType": "Google Chrome", "browserVersion": "138" }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Progress Bar Mission Completed Source: https://docs.appcharge.com/api-reference/events/v2/webstore/offer/progress_bar_mission_completed An event triggered when a Progress Bar mission is completed. **Event Data** Event name: `webstore.offers.progress_bar.mission.completed`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. This field is not currently in use. Reason for the event result. This field is not .currently in use. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Reserved for the player's name in future versions. **Deprecated.** Player email address. Information about the Progress Bar. Progress Bar external ID. Current mission index. Number of points the player has earned so far in the current mission. List of products in the Progress Bar. Product external ID. Product display name. Product quantity. Total number of points required to complete the current mission. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Session metadata. An object for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "webstore.offers.progress_bar.mission.completed", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "progressBar": { "progressBarExternalId": "my-progress-bar-1", "missionIndex": 2, "points": 100, "products": [ { "productExternalId": "treasure-12", "displayName": "Exclusive Treasure Chest", "productQuantity": "200" } ], "pointsTarget": 500 }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "utm": { "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Progress Bar Mission Started Source: https://docs.appcharge.com/api-reference/events/v2/webstore/offer/progress_bar_mission_started An event triggered when a new Progress Bar mission starts and is revealed to the player. **Event Data** Event name: `webstore.offers.progress_bar.mission.started`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. This field is not currently in use. Reason for the event result. This field is not currently in use. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Player's email address. **Deprecated.** Reserved for the player's name in future versions. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Information about the Progress Bar. Progress Bar external ID. Current mission index. Number of points the player has earned so far in the current mission. List of products in the Progress Bar. Product external ID. Product display name. Product quantity. Total number of points required to complete the current mission. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "webstore.offers.progress_bar.mission.started", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "utm": { "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" }, "progressBar": { "progressBarExternalId": "my-progress-bar-1", "missionIndex": 2, "points": 100, "products": [ { "productExternalId": "treasure-12", "displayName": "Treasure", "productQuantity": "200" } ], "pointsTarget": 500 }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Progress Bar Points Granted Source: https://docs.appcharge.com/api-reference/events/v2/webstore/offer/progress_bar_points_granted An event triggered when a player is granted Progress Bar points. **Event Data** Event name: `webstore.offers.progress_bar.points.granted`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](/../../api-reference/events/v2/introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. This field is not currently in use. Reason for the event result. This field is not currently in use. Number of points granted to the player upon offer purchase or collection. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Player's email address. **Deprecated.** Reserved for the player's name in future versions. Information about the player's geolocation. Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. Example: `US` **Deprecated.** Region or state. **Deprecated.** IP address in [IPv4](https://en.wikipedia.org/wiki/IPv4) format. Example: `80.178.249.122`. **Deprecated.** Zip code. UTM data. Source of the traffic. This is where the player came from before reaching the store. Example: `Google`. Marketing channel used to bring in the traffic. Example: `email`. Identifies the marketing campaign associated with the traffic. Example: `black_friday`. Paid search keyword or term that generated the traffic. Example: `buy+coins`. A label that identifies which version of content a player clicked to reach the web store. Useful for A/B testing and analyzing performance of different ad or link variations within the same campaign. Example: `summer_sale_ad1` Information about the Progress Bar. Progress Bar external ID. Current mission index. Number of points the player has earned so far in the current mission. List of products in the Progress Bar. Product external ID. Product display name. Product quantity. Total number of points required to complete the current mission. Information about the trigger. Trigger type. Supported values: * `purchase`: An offer was purchased. * `collect`: An offer was collected. Reference to the order. Offer external ID. Offer index. Order ID. Session metadata for passing data to Appcharge to be returned later. ```json Event Payload theme={"system"} { "eventName": "webstore.offers.progress_bar.points.granted", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": null, "result": null, "reason": null, "pointsGranted": 20, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "geolocation": { "countryCode2": "US", "region": null, "ipAddress": null, "zipCode": null }, "utm": { "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "spring_sale", "utmTerm": "buy+coins", "utmContent": "ad1" }, "progressBar": { "progressBarExternalId": "my-progress-bar-1", "missionIndex": 2, "points": 100, "products": [ { "productExternalId": "treasure-12", "displayName": "Treasure", "productQuantity": "200" } ], "pointsTarget": 500 }, "trigger": { "type": "purchase", "orderRef": { "offerExternalId": "promo-id", "offerIndex": 1, "orderId": "69b81f12861bf68900b9cdff" } }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` # Personalization Response Error Source: https://docs.appcharge.com/api-reference/events/v2/webstore/personalization_response_error An event triggered when the [Personalization API](/../../api-reference/webstore/personalization/personalization-api) returns an unexpected or invalid response. Typical causes include schema mismatches, incorrect data types, timeouts, empty offer lists, or non-existent external IDs. **Event Data** Event name: `webstore.personalization_api.error`. Event ID. Use this ID to deduplicate re-delivered events. Event timestamp in [Epoch time](https://www.epoch101.com/), represented in milliseconds. Example: `1754307361396`. The [session ID](../introduction#session-id) of the player’s current session. Example: `345397c6-d963-4aa4-a0ba-2aaca6c3ee05`. ID assigned by Appcharge to each request sent to the publisher. Helps the publisher identify and debug failed requests. Event result. This field is not currently in use. Reason for the event result. This field is not currently in use. Error details are returned in the `error` object. A key-value map used to label events for tracking personas or tests. Example: `{ "persona":"non_payer", "blackFridayTest":"Base_group" }` Information about the player. Player ID. **Deprecated.** Player email address. **Deprecated.** Reserved for the player's name in future versions. Session metadata for passing data to Appcharge to be returned later. The `requestId` sent when calling the [Web Store Personalization API service](../../../webstore/personalization/introduction). Information about the error. Error type. Reason for the error. HTTP status code of the error. ```json Event Payload theme={"system"} { "eventName": "webstore.personalization_api.error", "eventId": "3f5bffbc-369e-4599-8c4d-abfe0ae0ef96", "timestamp": 1754307361396, "sessionId": "345397c6-d963-4aa4-a0ba-2aaca6c3ee05", "requestId": "23539478-c744-566a-c78c-c4cc7763ff62", "result": null, "reason": null, "attributes": { "persona": "non_payer", "blackFridayTest": "Base_group" }, "customer": { "id": "671e81bb-55ef-428b-97ba-f67783971e0d", "name": null, "email": null }, "sessionMetadata": { "abTest": "group1", "locale": "en-US" }, "correlationRequestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "error": { "type": "general_error", "reason": "timeout", "httpStatusCode": "504" } } ``` # Create Content Source: https://docs.appcharge.com/api-reference/game-portal/content/create-content openapi-portal-content.json POST /v1/portal-content Creates a new content item. ```bash Create Article theme={"system"} curl -X POST \ 'https://api.appcharge.com/v1/portal-content' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "title": "Welcome to Our Game", "subTitle": "Everything you need to know", "bodyText": "This is the main content body with detailed information about getting started...", "headerImage": "https://cdn.example.com/images/header.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["tutorial", "beginner"], "state": "visible", "contentType": "article", "slug": "welcome-to-our-game", "visibility": "public", "tag": "spring2025", "translations": [ { "isoCode": "fr-FR", "title": "Bienvenue dans notre jeu", "subTitle": "Tout ce que vous devez savoir", "bodyText": "Ceci est le contenu principal de l'\''article en français...", "headerImage": "https://cdn.example.com/images/header-fr.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["tutoriel", "débutant"] } ], "pages": ["6850249eb5bd5c59b9bab7e2", "692eb70d0293e07ab4895518"] }' ``` ```bash Create News theme={"system"} curl -X POST \ 'https://api.appcharge.com/v1/portal-content' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "title": "New Feature Release", "subTitle": "Check out the latest updates", "bodyText": "We are excited to announce new features...", "headerImage": "https://cdn.example.com/images/news-header.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["news", "updates"], "contentType": "news", "visibility": "public", "tag": "spring2025" }' ``` ```bash Create Scheduled Content theme={"system"} curl -X POST \ 'https://api.appcharge.com/v1/portal-content' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "title": "Halloween Event Announcement", "subTitle": "Special event coming soon", "bodyText": "Get ready for our spooky Halloween event...", "headerImage": "https://cdn.example.com/images/halloween-header.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["event", "halloween"], "state": "scheduled", "contentType": "article", "publishDate": "2025-10-31T00:00:00.000Z", "visibility": "public", "tag": "halloween2025", "pages": ["6850249eb5bd5c59b9bab7e2"] }' ``` ```json Create Article theme={"system"} { "id": "507f1f77bcf86cd799439011", "title": "Welcome to Our Game", "subTitle": "Everything you need to know", "bodyText": "This is the main content body with detailed information...", "headerImage": "https://cdn.example.com/images/header.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["tutorial", "beginner"], "state": "visible", "contentType": "article", "slug": "welcome-to-our-game", "visibility": "public", "tag": "spring2025", "createdAt": "2025-10-20T10:30:00.000Z", "updatedAt": "2025-10-20T10:30:00.000Z", "translations": [ { "isoCode": "fr-FR", "title": "Bienvenue dans notre jeu", "subTitle": "Tout ce que vous devez savoir", "bodyText": "Ceci est le contenu principal de l'article en français...", "headerImage": "https://cdn.example.com/images/header-fr.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["tutoriel", "débutant"] } ], "pages": [ { "id": "6850249eb5bd5c59b9bab7e2", "pageName": "FAQs" }, { "id": "692eb70d0293e07ab4895518", "pageName": "Events" } ] } ``` ```json Create News theme={"system"} { "id": "507f1f77bcf86cd799439012", "title": "New Feature Release", "subTitle": "Check out the latest updates", "bodyText": "We are excited to announce new features...", "headerImage": "https://cdn.example.com/images/news-header.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["news", "updates"], "state": "hidden", "contentType": "news", "tag": "spring2025", "visibility": "public", "createdAt": "2025-10-20T10:35:00.000Z", "updatedAt": "2025-10-20T10:35:00.000Z", "translations": [], "pages": [] } ``` ```json Create Scheduled Content theme={"system"} { "id": "507f1f77bcf86cd799439013", "title": "Halloween Event Announcement", "subTitle": "Special event coming soon", "bodyText": "Get ready for our spooky Halloween event...", "headerImage": "https://cdn.example.com/images/halloween-header.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["event", "halloween"], "state": "scheduled", "contentType": "article", "publishDate": "2025-10-31T00:00:00.000Z", "slug": "halloween-event-announcement", "visibility": "public", "tag": "halloween2025", "createdAt": "2025-10-20T10:40:00.000Z", "updatedAt": "2025-10-20T10:40:00.000Z", "translations": [], "pages": [ { "id": "6850249eb5bd5c59b9bab7e2", "pageName": "FAQs" } ] } ``` ```json 400 theme={"system"} { "message": "BAD_REQUEST", "requestUrl": "/v1/portal-content", "body": "Invalid request body or validation error." } ``` ```json 401 theme={"system"} { "message": "UNAUTHORIZED", "requestUrl": "/v1/portal-content", "body": "Invalid or missing publisher token." } ``` ```json 409 theme={"system"} { "message": "CONFLICT", "requestUrl": "/v1/portal-content", "body": "Slug already exists." } ``` ```json 500 theme={"system"} { "message": "INTERNAL_SERVER_ERROR", "requestUrl": "/v1/portal-content", "body": "Server error." } ``` # Delete Content Source: https://docs.appcharge.com/api-reference/game-portal/content/delete-content openapi-portal-content.json DELETE /v1/portal-content/{contentId} Deletes a content item. ```bash Delete Content theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/v1/portal-content/507f1f77bcf86cd799439011' \ -H 'x-publisher-token: ' ``` ```json Delete Content theme={"system"} {} ``` ```json 400 theme={"system"} { "message": "BAD_REQUEST", "requestUrl": "/v1/portal-content/{contentId}", "body": "Invalid content ID or deletion error." } ``` ```json 401 theme={"system"} { "message": "UNAUTHORIZED", "requestUrl": "/v1/portal-content/{contentId}", "body": "Invalid or missing publisher token." } ``` ```json 404 theme={"system"} { "message": "NOT_FOUND", "requestUrl": "/v1/portal-content/{contentId}", "body": "Content not found." } ``` ```json 500 theme={"system"} { "message": "INTERNAL_SERVER_ERROR", "requestUrl": "/v1/portal-content/{contentId}", "body": "Server error." } ``` # Get All Content Source: https://docs.appcharge.com/api-reference/game-portal/content/get-content openapi-portal-content.json GET /v1/portal-content Retrieves a list of all content items. ```bash Get All Content theme={"system"} curl -X GET \ 'https://api.appcharge.com/v1/portal-content' \ -H 'x-publisher-token: ' ``` ```json Get All Content theme={"system"} { "items": [ { "id": "507f1f77bcf86cd799439011", "title": "Welcome to Our Game", "subTitle": "Everything you need to know", "bodyText": "This is the main content body with detailed information...", "headerImage": "https://cdn.example.com/images/header.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["tutorial", "beginner"], "state": "visible", "contentType": "article", "publishDate": "2025-10-20T00:00:00.000Z", "slug": "welcome-to-our-game", "visibility": "public", "tag": "spring2025", "createdAt": "2025-10-15T10:30:00.000Z", "updatedAt": "2025-10-19T14:20:00.000Z", "pages": [ { "id": "6850249eb5bd5c59b9bab7e2", "pageName": "FAQs" }, { "id": "692eb70d0293e07ab4895518", "pageName": "Events" } ] }, { "id": "507f1f77bcf86cd799439012", "title": "New Feature Release", "subTitle": "Check out the latest updates", "bodyText": "We are excited to announce new features that will enhance your gaming experience...", "headerImage": "https://cdn.example.com/images/news-header.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["news", "updates"], "state": "visible", "contentType": "news", "slug": "new-feature-release", "visibility": "public", "createdAt": "2025-10-18T08:15:00.000Z", "updatedAt": "2025-10-20T11:45:00.000Z", "pages": [ { "id": "692eb70d0293e07ab4895518", "pageName": "Events" } ] } ] } ``` ```json 401 theme={"system"} { "message": "UNAUTHORIZED", "requestUrl": "/v1/portal-content", "body": "Invalid or missing publisher token." } ``` ```json 500 theme={"system"} { "message": "INTERNAL_SERVER_ERROR", "requestUrl": "/v1/portal-content", "body": "Server error." } ``` # Get Content By ID Source: https://docs.appcharge.com/api-reference/game-portal/content/get-content-by-id openapi-portal-content.json GET /v1/portal-content/{contentId} Retrieves a specific content item by its ID. ```bash Get Content By ID theme={"system"} curl -X GET \ 'https://api.appcharge.com/v1/portal-content/507f1f77bcf86cd799439011' \ -H 'x-publisher-token: ' ``` ```json Get Content By ID theme={"system"} { "id": "507f1f77bcf86cd799439011", "title": "Welcome to Our Game", "subTitle": "Everything you need to know", "bodyText": "This is the main content body with detailed information...", "headerImage": "https://cdn.example.com/images/header.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["tutorial", "beginner"], "state": "visible", "contentType": "article", "publishDate": "2025-10-20T00:00:00.000Z", "slug": "welcome-to-our-game", "visibility": "public", "tag": "spring2025", "createdAt": "2025-10-15T10:30:00.000Z", "updatedAt": "2025-10-19T14:20:00.000Z", "translations": [ { "isoCode": "fr-FR", "title": "Bienvenue dans notre jeu", "subTitle": "Tout ce que vous devez savoir", "bodyText": "Ceci est le contenu principal de l'article en français...", "headerImage": "https://cdn.example.com/images/header-fr.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["tutoriel", "débutant"] } ], "pages": [ { "id": "6850249eb5bd5c59b9bab7e2", "pageName": "FAQs" }, { "id": "692eb70d0293e07ab4895518", "pageName": "Events" } ] } ``` ```json 401 theme={"system"} { "message": "UNAUTHORIZED", "requestUrl": "/v1/portal-content/{contentId}", "body": "Invalid or missing publisher token." } ``` ```json 404 theme={"system"} { "message": "NOT_FOUND", "requestUrl": "/v1/portal-content/{contentId}", "body": "Content not found." } ``` ```json 500 theme={"system"} { "message": "INTERNAL_SERVER_ERROR", "requestUrl": "/v1/portal-content/{contentId}", "body": "Server error." } ``` # Get Content Translations Source: https://docs.appcharge.com/api-reference/game-portal/content/get-content-translations openapi-portal-content.json GET /v1/portal-content/{contentId}/translations Retrieves all existing translations for a content item. ```bash Get Content Translations theme={"system"} curl -X GET \ 'https://api.appcharge.com/v1/portal-content/507f1f77bcf86cd799439011/translations' \ -H 'x-publisher-token: ' ``` ```json Get Content Translations theme={"system"} { "items": [ { "isoCode": "fr-FR", "title": "Bienvenue dans notre jeu", "subTitle": "Tout ce que vous devez savoir", "bodyText": "Ceci est le contenu principal de l'article en français...", "headerImage": "https://cdn.example.com/images/header-fr.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["tutoriel", "débutant"] }, { "isoCode": "es-ES", "title": "Bienvenido a nuestro juego", "subTitle": "Todo lo que necesitas saber", "bodyText": "Este es el cuerpo principal del artículo en español...", "headerImage": "https://cdn.example.com/images/header-es.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["tutorial", "principiante"] } ] } ``` ```json 401 theme={"system"} { "message": "UNAUTHORIZED", "requestUrl": "/v1/portal-content/{contentId}/translations", "body": "Invalid or missing publisher token." } ``` ```json 404 theme={"system"} { "message": "NOT_FOUND", "requestUrl": "/v1/portal-content/{contentId}/translations", "body": "Content not found." } ``` ```json 500 theme={"system"} { "message": "INTERNAL_SERVER_ERROR", "requestUrl": "/v1/portal-content/{contentId}/translations", "body": "Server error." } ``` # Introduction Source: https://docs.appcharge.com/api-reference/game-portal/content/introduction The Content API service lets you create and manage content items such as articles and news in your Game Portal. You can schedule content, and make it visible to either all or only segmented players. A content item can include translated content. Learn more about the [Game Portal feature](/../../guides/game-portal/about-the-game-portal). With the Portal Content API service, you can: * [Create a content item](./create-content). * [Retrieve a specific content item](./get-content-by-id) by its ID. * [Retrieve all content items](./get-content). * [Retrieve all existing translations for a content item](./get-content-translations) by its ID. * [Create or update a translation for a content item in a specific locale](./upsert-content-translation). * [Update a content item](./update-content). * [Delete a content item](./delete-content). ## Before you begin Review the following before you begin: * **Assign content to a page:** Use the `pages` property to assign the content item to a page. If you don't, or if you assign the content to a page that doesn't exist, the content will be created but won't be displayed in the Game Portal. To create a page or view a list of existing pages, see [Create and Manage a Game Portal Page](/../../guides/game-portal/create-and-manage-a-game-portal-page). * **Content types**: * `article`: Articles with a title, subtitle, and body text. * `news`: News content with a title, subtitle, and body text. * **Content states**: * `visible`: Content is publicly visible in the Game Portal. * `hidden`: Content exists but is not displayed. * `scheduled`: Content will become visible at the specified `publishDate`. * **Visibility**: * `public`: Content is visible for all players. * `private`: Content is only visible for segmented players (players who are logged into the Game Portal). * **Translations**: Before adding translations, you must first [add the locale in the Publisher Dashboard](/../../guides/translations/add-and-manage-languages). # Update Content Source: https://docs.appcharge.com/api-reference/game-portal/content/update-content openapi-portal-content.json PUT /v1/portal-content/{contentId} Updates a content item. ```bash Update Content theme={"system"} curl -X PUT \ 'https://api.appcharge.com/v1/portal-content/507f1f77bcf86cd799439011' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "title": "New Game: Jelly Soda", "state": "visible", "labels": ["tutorial", "beginner", "featured"] }' ``` ```json Update Content theme={"system"} { "id": "507f1f77bcf86cd799439011", "title": "New Game: Jelly Soda", "subTitle": "Everything you need to know", "bodyText": "This is the main content body with detailed information...", "headerImage": "https://cdn.example.com/images/header.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["tutorial", "beginner", "featured"], "state": "visible", "contentType": "article", "slug": "welcome-to-our-game", "visibility": "public", "tag": "spring2025", "createdAt": "2025-10-15T10:30:00.000Z", "updatedAt": "2025-10-20T14:45:00.000Z", "translations": [ { "isoCode": "fr-FR", "title": "Bienvenue dans notre jeu", "subTitle": "Tout ce que vous devez savoir", "bodyText": "Ceci est le contenu principal de l'article en français...", "headerImage": "https://cdn.example.com/images/header-fr.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["tutoriel", "débutant"] } ], "pages": [ { "id": "6850249eb5bd5c59b9bab7e2", "pageName": "FAQs" }, { "id": "692eb70d0293e07ab4895518", "pageName": "Events" } ] } ``` ```json 400 theme={"system"} { "message": "BAD_REQUEST", "requestUrl": "/v1/portal-content/{contentId}", "body": "Invalid request body or validation error." } ``` ```json 401 theme={"system"} { "message": "UNAUTHORIZED", "requestUrl": "/v1/portal-content/{contentId}", "body": "Invalid or missing publisher token." } ``` ```json 404 theme={"system"} { "message": "NOT_FOUND", "requestUrl": "/v1/portal-content/{contentId}", "body": "Content not found." } ``` ```json 409 theme={"system"} { "message": "CONFLICT", "requestUrl": "/v1/portal-content/{contentId}", "body": "Slug already exists." } ``` ```json 500 theme={"system"} { "message": "INTERNAL_SERVER_ERROR", "requestUrl": "/v1/portal-content/{contentId}", "body": "Server error." } ``` # Upsert Content Translation Source: https://docs.appcharge.com/api-reference/game-portal/content/upsert-content-translation openapi-portal-content.json PUT /v1/portal-content/{contentId}/translations/{isoCode} Creates or updates a translation for a content item in a specific locale. This operation doesn't modify translations in other locales or other content fields. > **Note:** You must first [add the locale in the Publisher Dashboard](/../../guides/translations/add-and-manage-languages) before adding its translation. ```bash Upsert Content Translation theme={"system"} curl -X PUT \ 'https://api.appcharge.com/v1/portal-content/507f1f77bcf86cd799439011/translations/fr-FR' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "title": "Bienvenue dans notre jeu", "subTitle": "Tout ce que vous devez savoir", "bodyText": "Ceci est le contenu principal de l'\''article en français...", "headerImage": "https://cdn.example.com/images/header-fr.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["tutoriel", "débutant"] }' ``` ```json Upsert Content Translation theme={"system"} { "id": "507f1f77bcf86cd799439011", "title": "Welcome to Our Game", "subTitle": "Everything you need to know", "bodyText": "This is the main content body with detailed information...", "headerImage": "https://cdn.example.com/images/header.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["tutorial", "beginner"], "state": "visible", "contentType": "article", "slug": "welcome-to-our-game", "visibility": "public", "tag": "spring2025", "createdAt": "2025-10-15T10:30:00.000Z", "updatedAt": "2025-10-20T14:45:00.000Z", "translations": [ { "isoCode": "fr-FR", "title": "Bienvenue dans notre jeu", "subTitle": "Tout ce que vous devez savoir", "bodyText": "Ceci est le contenu principal de l'article en français...", "headerImage": "https://cdn.example.com/images/header-fr.jpg", "thumbnailImage": "https://media.appcharge.com/media/25cb4861ec8924a6b69a0f59/book-shelf1920.jpg", "labels": ["tutoriel", "débutant"] } ], "pages": [ { "id": "6850249eb5bd5c59b9bab7e2", "pageName": "FAQs" } ] } ``` ```json 400 theme={"system"} { "message": "BAD_REQUEST", "requestUrl": "/v1/portal-content/{contentId}/translations/{isoCode}", "body": "Invalid request body or validation error." } ``` ```json 401 theme={"system"} { "message": "UNAUTHORIZED", "requestUrl": "/v1/portal-content/{contentId}/translations/{isoCode}", "body": "Invalid or missing publisher token." } ``` ```json 404 theme={"system"} { "message": "NOT_FOUND", "requestUrl": "/v1/portal-content/{contentId}/translations/{isoCode}", "body": "Content not found." } ``` ```json 409 theme={"system"} { "message": "CONFLICT", "requestUrl": "/v1/portal-content/{contentId}/translations/{isoCode}", "body": "Slug already exists." } ``` ```json 413 theme={"system"} { "message": "PAYLOAD_TOO_LARGE", "requestUrl": "/v1/portal-content/{contentId}/translations/{isoCode}", "body": "Request payload is too large." } ``` ```json 500 theme={"system"} { "message": "INTERNAL_SERVER_ERROR", "requestUrl": "/v1/portal-content/{contentId}/translations/{isoCode}", "body": "Server error." } ``` # API Reference Source: https://docs.appcharge.com/api-reference/introduction Welcome to the Appcharge API Reference documentation. Here, you'll find everything you need to integrate and utilize Appcharge’s suite of tools effectively. ## Overview Our API Reference is your go-to resource for understanding how to implement Appcharge products into your system. It includes detailed documentation for our **APIs**, **SDKs**, and **Webhooks**, all organized by the key products we offer: * **Checkout:** Streamline your payment processes. * **Web Store:** Create and manage your in-game stores. * **In-Game Checkout:** Provide seamless purchasing experiences within your games. ## More Information For a deeper dive into using our APIs and SDKs, head over to our [Guides section](/../../guides/introduction), where you’ll find step-by-step instructions, best practices, and practical examples to help you get started quickly. Whether you're integrating Checkout, setting up your Web Store, or enhancing in-game purchasing, our documentation will guide you through every step. # Create Asset Source: https://docs.appcharge.com/api-reference/media/assets-library/create-asset openapi-assets-api.json POST /components/v1/asset Creates an asset in the Assets Library. # Delete Asset Source: https://docs.appcharge.com/api-reference/media/assets-library/delete-asset openapi-assets-api.json DELETE /components/v1/asset/{name} Deletes an asset in the Assets Library. # Get All Assets Source: https://docs.appcharge.com/api-reference/media/assets-library/get-all-assets openapi-assets-api.json GET /components/v1/asset Retrieves a list of all assets in the Assets Library. ```json Response theme={"system"} [ { "id": "507f1f77bcf86cd799439011", "name": "gold_coins_icon", "type": "product", "imageUrl": "https://example.com/assets/gold_coins_icon.png", "contentType": "image/png", "externalImageUrl": "https://example.com/assets/gold_coins_icon.png" }, { "id": "507f1f77bcf86cd799439012", "name": "summer_sale_badge", "type": "badge", "imageUrl": "https://media.appcharge.com/media/691d8c97d-4b55c292b2cg6", "contentType": "image/jpeg" } ] ``` # Get Asset Source: https://docs.appcharge.com/api-reference/media/assets-library/get-asset openapi-assets-api.json GET /components/v1/asset/{name} Retrieves a specific asset in the Assets Library. # Introduction Source: https://docs.appcharge.com/api-reference/media/assets-library/introduction The Assets API allows you to create and manage visual assets such as backgrounds, logos, favicons, and offer headers in the Assets Library. You can add assets by uploading local files or providing external image URLs. Learn more about the [Assets Library](/../../guides/publisher-dashboard/add-an-asset). With the Assets API, you can: * [Create a new asset](./create-asset). * [Retrieve](./get-asset) a specific asset. * [Retrieve a list of all assets](./get-all-assets). * [Update an existing asset](./update-asset). * [Delete an asset](./delete-asset). ## Before you begin Review the following before you begin: * If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. * We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. # Update Asset Source: https://docs.appcharge.com/api-reference/media/assets-library/update-asset openapi-assets-api.json PUT /components/v1/asset/{name} Updates an asset in the Assets Library. # About the Sandbox Account Source: https://docs.appcharge.com/api-reference/sandbox-account/about-the-sandbox-account ## Overview The Sandbox Demo Account facilitates a thorough evaluation of the Appcharge platform. Through this account: * You will access a Sandbox environment linked to Demo Facebook, Apple, and Google accounts. * You can simulate transactions, explore functionalities, and navigate seamlessly within the platform. * Appcharge internally records and processes orders, ensuring a realistic evaluation experience. * The same account smoothly transitions into initial integration with sandbox environments, simplifying the integration process. ## Understanding Sandbox in Appcharge The Sandbox environment in Appcharge is designed to seamlessly integrate with the publisher's corresponding sandbox environment. Sandbox mirrors the functionality of the Production environment, although with operations conducted on distinct accounts. Transactions within the Sandbox environment are facilitated with virtual currency. ### Configuring Appcharge's Sandbox Environment To initiate the setup of the Sandbox environment as outlined in our documentation, navigate to the relevant API endpoint. Switch the Base URL to`https://api-sandbox.appcharge.com`from the drop-down menu. For instance, in the provided API endpoint below, selecting the option highlighted in red alters the environment to Sandbox: # Sandbox Payment Methods Source: https://docs.appcharge.com/api-reference/sandbox-account/payment-methods ## Credit cards to use for testing To simulate a successful payment, use test cards from the following list. The billing country for each test card is set to the United States. | BRAND | NUMBER | CVC | DATE | | - | - | - | - | | Visa | 4242424242424242 | Any 3 digits | Any future date | | Visa (debit) | 4000056655665556 | Any 3 digits | Any future date | | Mastercard | 5555555555554444 | Any 3 digits | Any future date | | Mastercard (2-series) | 2223003122003222 | Any 3 digits | Any future date | | Mastercard (debit) | 5200828282828210 | Any 3 digits | Any future date | | Mastercard (prepaid) | 5105105105105100 | Any 3 digits | Any future date | | American Express | 378282246310005 | Any 4 digits | Any future date | | American Express | 371449635398431 | Any 4 digits | Any future date | | Discover | 6011111111111117 | Any 3 digits | Any future date | | Discover | 6011000990139424 | Any 3 digits | Any future date | | Discover (debit) | 6011981111111113 | Any 3 digits | Any future date | | Diners Club | 3056930009020004 | Any 3 digits | Any future date | | Diners Club (14-digit card) | 36227206271667 | Any 3 digits | Any future date | | BCcard and DinaCard | 6555900000604105 | Any 3 digits | Any future date | | JCB | 3566002020360505 | Any 3 digits | Any future date | | UnionPay | 6200000000000005 | Any 3 digits | Any future date | | UnionPay (debit) | 6200000000000047 | Any 3 digits | Any future date | | UnionPay (19-digit card) | 6205500000000000004 | Any 3 digits | Any future date | # Supported Environments and Limitations Source: https://docs.appcharge.com/api-reference/supported-environments-and-limitations Appcharge is designed to work reliably across a wide range of modern browsers, devices, and operating systems. This article lists the environments we support, along with minimum screen requirements and known limitations to ensure optimal performance. ## Supported browsers Appcharge supports the following browsers: | Browser | Browser version | | - | - | | Chrome | Version 57 and above | | Safari | Version 13 and above | | Firefox | Version 70 and above | | Edge | Version 70 and above | ## Operating systems Appcharge supports the following operating systems: | OS | OS version | | - | - | | iOS | Version 14 and above | | Android | Android (Quince Tart) 10 and above | > **Note:** Appcharge may work on older versions of the browsers and operating systems listed above, but full compatibility is not guaranteed. ## Minimum Screen Size Appcharge requires a minimum screen width of 375 pixels. Devices with smaller screen sizes aren’t supported, and players may encounter layout or functionality issues when using them. ## Dark Mode Appcharge does not currently support dark mode. ## Browser Extensions Appcharge does not support issues or bugs caused by third-party browser extensions, including but not limited to: * Google Translate * Zoom * Ad blockers * Accessibility overlays # Get Translations Source: https://docs.appcharge.com/api-reference/translations/get-translations openapi-translations.json GET /v1/translations Retrieves a list of all translatable fields and their translations. Use the `locale` parameter to return translations for a specific locale. If a field doesn't have a translation for the requested locale, the value defaults to English, `en`. If no locale is specified, all translations are returned, including the default English values. ```bash Get Translations theme={"system"} curl -X GET \ 'https://api.appcharge.com/v1/translations' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ ``` ```bash Get Spanish Translations theme={"system"} curl -X GET \ 'https://api.appcharge.com/v1/translations?locale=es-ES' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ ``` ```json Get Translations theme={"system"} { "dynamicTranslations": [ { "type": "product", "externalId": "SKU-12345", "field": "display_name", "locale": "es-ES", "value": "Espada legendaria" }, { "type": "product", "externalId": "SKU-12345", "field": "display_name", "locale": "en", "value": "Legendary Sword" }, { "type": "product", "externalId": "SKU-12345", "field": "display_name", "locale": "pl", "value": "Legendarny Miecz" }, { "type": "offer_design", "externalId": "OD-987", "field": "title", "locale": "es-ES", "value": "Oferta de Verano" }, { "type": "offer_design", "externalId": "OD-987", "field": "title", "locale": "en", "value": "Summer Offer" }, { "type": "offer_design", "externalId": "OD-987", "field": "title", "locale": "pl", "value": "Letnia Oferta" } ], "staticTranslations": [ { "key": "checkout.pay_button", "locale": "es-ES", "value": "Pagar ahora" }, { "key": "checkout.pay_button", "locale": "en", "value": "Pay Now" }, { "key": "checkout.pay_button", "locale": "pl", "value": "Zapłać teraz" }, { "key": "ui.loading", "locale": "es-ES", "value": "Cargando…" }, { "key": "ui.loading", "locale": "en", "value": "Loading…" }, { "key": "ui.loading", "locale": "pl", "value": "Ładowanie…" } ] } ``` ```json Get Spanish Translations theme={"system"} { "dynamicTranslations": [ { "type": "product", "externalId": "SKU-12345", "field": "display_name", "locale": "es-ES", "value": "Espada legendaria" }, { "type": "offer_design", "externalId": "OD-987", "field": "title", "locale": "es-ES", "value": "Oferta de Verano" } ], "staticTranslations": [ { "key": "checkout.pay_button", "locale": "es-ES", "value": "Pagar ahora" }, { "key": "ui.loading", "locale": "es-ES", "value": "Cargando…" } ] } ``` # Introduction Source: https://docs.appcharge.com/api-reference/translations/introduction The Translations API service lets you manage translations in the web store, checkout, and game portal, allowing players to view content in their preferred language. Learn more about the [Translation feature](/../../guides/translations/about-translations). With the Translations API service, you can: * [Add translations](./set-translations) or update existing ones as needed. * [Retrieve a list of all translatable fields](./get-translations), and their translations if available. ## Workflow for using the Translations API service This API service is intended to be used in a specific sequence as part of a defined flow: 1. [Add a new language](/../../guides/translations/add-and-manage-languages) in the Publisher Dashboard. Each time a new langugage is added, a new object is added to the API for each field. 2. Call the [Get Translations API](./get-translations) to get a list of all translatable fields, including both `staticTranslations` and `dynamicTranslations` strings. 3. Translate the content for the available languages. 4. Call the [Set Translations API](./set-translations) with the translated fields. 5. Activate the language in the Publisher Dashboard: * Go to the **Localization** tab. * Scroll to **Manage Languages**. * Turn on the toggle for each language you want to make available to customers. To keep translations current, repeat steps 2- 4 regularly. ## Before you begin Review the following before you begin: * There are 2 types of content you can translate: * `staticTranslations`: Fixed interface elements such as button labels and headers. * `dynamicTranslations`: Content-specific values you define, such as product prefixes. * The original content is in English, `en`, which serves as the default language when no translation is provided for a field. * You can only add translation content for locales that already have a language set up. * If you're using the Game Portal, you can only use this API to translate Game Portal pages, including the web store page. To translate Game Portal content, see [Translate Game Portal Content](/../../guides/translations/translate-game-portal-content). # Set Translations Source: https://docs.appcharge.com/api-reference/translations/set-translations openapi-translations.json POST /v1/translations Sets translation content for translatable fields. Use this API to add new translations or update existing ones as needed. The request payload has a maximum size of 100 KB. ```bash Set Translations theme={"system"} curl -X POST \ 'https://api.appcharge.com/v1/translations' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "staticTranslations": [ { "key": "ui.loading", "locale": "es-ES", "value": "Cargando…" } ], "dynamicTranslations": [ { "type": "product", "externalId": "SKU-12345", "field": "display_name", "locale": "es-ES", "value": "Espada legendaria" } ] }' ``` ```json Set Translations theme={"system"} { "dynamicTranslations": [ { "type": "product", "externalId": "SKU-12345", "field": "display_name", "locale": "es-ES", "value": "Espada legendaria" }, { "type": "product", "externalId": "SKU-12345", "field": "display_name", "locale": "en-US", "value": "Legendary Sword" }, { "type": "product", "externalId": "SKU-12345", "field": "display_name", "locale": "pl", "value": "Legendarny Miecz" }, { "type": "offer_design", "externalId": "OD-987", "field": "title", "locale": "es-ES", "value": "Oferta de Verano" }, { "type": "offer_design", "externalId": "OD-987", "field": "title", "locale": "en-US", "value": "Summer Offer" }, { "type": "offer_design", "externalId": "OD-987", "field": "title", "locale": "pl", "value": "Letnia Oferta" } ], "staticTranslations": [ { "key": "checkout.pay_button", "locale": "es-ES", "value": "Pagar ahora" }, { "key": "checkout.pay_button", "locale": "en-US", "value": "Pay Now" }, { "key": "checkout.pay_button", "locale": "pl", "value": "Zapłać teraz" }, { "key": "ui.loading", "locale": "es-ES", "value": "Cargando…" }, { "key": "ui.loading", "locale": "en-US", "value": "Loading…" }, { "key": "ui.loading", "locale": "pl", "value": "Ładowanie…" } ] } ``` # API Versioning Policy Source: https://docs.appcharge.com/api-reference/versioning-policy As we continue to expand and enhance our APIs, we recognize the importance of stability and transparency for your integrations. Our API versioning policy ensures that every change is carefully evaluated and clearly communicated, keeping you informed at all times. To help you understand how changes may impact your integration, we categorize updates as breaking changes or non-breaking changes. ## Breaking Changes When a change qualifies as a breaking change, we introduce a new API version and provide a deprecation date, giving you time to transition to the new API version smoothly. These changes will be documented in the [Release Notes](./whats-new/release-notes) and [Deprecation Notices](./whats-new/deprecation-notices). ## Non-Breaking Changes When a change qualifies as a non-breaking change, you don’t need to do anything. Your integrations will continue to function as normal while maintaining backward compatibility. These changes will be documented in the Release Notes to keep you informed of new features and improvements. The table below outlines what constitutes a breaking change versus a non-breaking change: | Change Type | Breaking Change? | | - | - | | Removing or renaming a property in the request or response. | Yes | | Changing a property's type. | Yes | | Changing an API's endpoint URL. | Yes | | Altering response behavior for the same request. | Yes | | Changing the paging mechanism. | Yes | | Adding a new property to the request or response. | No | | Adding a member to an enumeration. | No | | Updating an error code. | No | | Changing the order of properties in the request or response. | No | # Versioning Strategy Our versioning strategy ensures smooth transitions and backward compatibility by clearly defining how updates are managed. ## APIs New API versions are included in the endpoint URL using the following format: `https://api.example.com/v{version_number}/{service}/{param_value}` For example, version 2 of the Create Checkout Session API: `https://api.example.com/v2/create-checkout-session/1000` ## Personalization API The Personalization API response includes a version field, enabling integrations to adapt dynamically without modifying request URLs. For example, version 2 of the Personalization API will look like: ``` { "version": 2, "status": "valid", "profileFrameId": "123456", ... } ``` # Deprecations We provide a 6-month deprecation notice before retiring an API, giving you sufficient time to adopt the new version. During this period, the existing API version will continue to function as normal. Afterward, it will no longer be supported or accessible. Towards the end of the API lifecycle, our development and customer success teams will notify you to assist with a smooth transition. # Communication & Updates * See the [Release Notes](./whats-new/release-notes) for a list of all the latest updates. * See the [Deprecation Notices](./whats-new/deprecation-notices), detailing APIs scheduled for deprecation and their deprecation dates. # Create Badge Source: https://docs.appcharge.com/api-reference/webstore/offer-components/badges/create-badge openapi-badges-api.json POST /components/v1/badge Creates a badge. ```bash Create Emblem Badge with Asset ID theme={"system"} curl -X POST \ 'https://api.appcharge.com/components/v1/badge' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "name": "New Item", "publisherBadgeId": "new_item", "type": "emblem", "badgeImageId": "507f1f77bcf86cd799439011" }' ``` ```bash Create Emblem Badge with Image URL theme={"system"} curl -X POST \ 'https://api.appcharge.com/components/v1/badge' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "name": "Limited Offer", "publisherBadgeId": "limited_offer", "type": "emblem", "badgeImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5" }' ``` ```bash Emblem Badge with Asset ID and Image URL theme={"system"} curl -X POST \ 'https://api.appcharge.com/components/v1/badge' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "name": "New Item", "publisherBadgeId": "new_item", "type": "emblem", "badgeImageId": "507f1f77bcf86cd799439011", "badgeImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5" }' ``` ```json Emblem Badge with Asset ID theme={"system"} { "id": "507f1f77bcf86cd799439020", "name": "New Item", "publisherBadgeId": "new_item", "type": "emblem", "badgeImageId": "507f1f77bcf86cd799439011", "badgeImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5" } ``` ```json Emblem Badge with Image URL theme={"system"} { "id": "507f1f77bcf86cd799439021", "name": "Limited Offer", "publisherBadgeId": "limited_offer", "type": "emblem", "badgeImageId": "507f1f77bcf86cd799439022", "badgeImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5" } ``` ```json Emblem Badge with Asset ID and Image URL theme={"system"} { "id": "507f1f77bcf86cd799439020", "name": "New Item", "publisherBadgeId": "new_item", "type": "emblem", "badgeImageId": "507f1f77bcf86cd799439011", "badgeImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5" } ``` # Delete Badge Source: https://docs.appcharge.com/api-reference/webstore/offer-components/badges/delete-badge openapi-badges-api.json DELETE /components/v1/badge/{externalId} Deletes a badge. ```bash Delete Badge theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/components/v1/badge/new_item' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Badge theme={"system"} { "id": "507f1f77bcf86cd799439020", "name": "New Item", "publisherBadgeId": "new_item", "type": "emblem", "badgeImageId": "507f1f77bcf86cd799439011", "badgeImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5" } ``` # Get All Badges Source: https://docs.appcharge.com/api-reference/webstore/offer-components/badges/get-all-badges openapi-badges-api.json GET /components/v1/badge Retrieves a list of all badges. ```bash Get All Badges theme={"system"} curl -X GET \ 'https://api.appcharge.com/components/v1/badge' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' ``` ```json Get All Badges theme={"system"} [ { "id": "507f1f77bcf86cd799439011", "name": "New Item", "publisherBadgeId": "new_item", "type": "emblem", "badgeImageId": "507f1f77bcf86cd799439011", "badgeImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5" }, { "id": "507f1f77bcf86cd799439013", "name": "Limited Offer", "publisherBadgeId": "limited_offer", "type": "emblem", "badgeImageUrl": "https://images.pexels.com/photos/limited-offer.png" }, { "id": "507f1f77bcf86cd799439012", "name": "New Year Celebration", "publisherBadgeId": "new_year_celebration", "type": "ribbon", "badgeImageUrl": "https://images.pexels.com/photos/new-years.png", "text": "New Year Sale", "backgroundColor": { "colorOne": "#00c6ff", "colorTwo": "#0072ff", "gradientDirection": "to right" }, "textColor": { "colorOne": "#ffffff" } } ] ``` # Get Badge Source: https://docs.appcharge.com/api-reference/webstore/offer-components/badges/get-badge openapi-badges-api.json GET /components/v1/badge/{externalId} Retrieves a specific badge. ```bash Get Badge theme={"system"} curl -X GET \ 'https://api.appcharge.com/components/v1/badge/new_item' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' ``` ```json Get Badge theme={"system"} { "id": "507f1f77bcf86cd799439020", "name": "New Item", "publisherBadgeId": "new_item", "type": "emblem", "badgeImageId": "507f1f77bcf86cd799439011", "badgeImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5" } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offer-components/badges/introduction The Badges API allows you to create visual badges to highlight offers. You can choose between a ribbon and an emblem to draw attention to limited-time deals, best-value options, or exclusive items. Learn more about [badges](/../../guides/webstore/design/add-a-badge). With the Badges API, you can: * [Create a badge](./create-badge). * [Retrieve](./get-badge) a specific badge. * [Retrieve a list of all badges](./get-all-badges). * [Update a badge](./update-badge). * [Delete a badge](./delete-badge). # Update Badge Source: https://docs.appcharge.com/api-reference/webstore/offer-components/badges/update-badge openapi-badges-api.json PUT /components/v1/badge/{externalId} Updates a badge. ```bash Update Emblem Badge with Asset ID theme={"system"} curl -X PUT \ 'https://api.appcharge.com/components/v1/badge/new_item' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "name": "New Item", "publisherBadgeId": "new_item", "type": "emblem", "badgeImageId": "507f1f77bcf86cd799439011" }' ``` ```bash Update Emblem Badge with Image URL theme={"system"} curl -X PUT \ 'https://api.appcharge.com/components/v1/badge/limited_offer' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "name": "Limited Offer", "publisherBadgeId": "limited_offer", "type": "emblem", "badgeImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5" }' ``` ```json Update Emblem Badge with Asset ID theme={"system"} { "id": "507f1f77bcf86cd799439020", "name": "New Item", "publisherBadgeId": "new_item", "type": "emblem", "badgeImageId": "507f1f77bcf86cd799439011", "badgeImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5" } ``` ```json Update Emblem Badge with Image URL theme={"system"} { "id": "507f1f77bcf86cd799439021", "name": "Limited Offer", "publisherBadgeId": "limited_offer", "type": "emblem", "badgeImageId": "507f1f77bcf86cd799439022", "badgeImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5" } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offer-components/introduction The Offer Components API is a suite of APIs that allows you to create and manage the building blocks of your [web store’s offers](/../../guides/webstore/offers/about-offers), including products, layout designs, and badges. Once you have created these components, you can reference them in the [Offers API](/../api-reference/webstore/offers-v2/introduction) when building an offer. These components are reusable, so you can use them across multiple offers. The Offer Components API includes the following: * [Offer Designs API](./offer-designs/introduction): Design the layout of your bundles, special offers, popups, and rolling offers. * [Products API](./products/introduction): Configure products for your offers, such as virtual or time-based items. * [Badges API](./badges/introduction): Create visual badges in the form of ribbons or emblems to highlight offers. # Create Bundle Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/bundles/create-bundle-design openapi-bundle-design.json POST /components/v1/offer-design Creates a bundle design. ```bash Create Bundle Design theme={"system"} curl -X POST \ 'https://api.appcharge.com/components/v1/offer-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "Bundle", "name": "Starter Bundle Design", "externalId": "starter-bundle-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "backgroundColor": { "colorOne": "#E7CF88", "colorTwo": "#FDFCF9", "gradientDirection": "to right" }, "buttonSuffixImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/bundle-button-suffix.png", "buttonSuffixAnimation": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/bundle-button-suffix-animation.json" }' ``` ```json Create Bundle Design theme={"system"} { "id": "68b3e3473e2ea6249862bddf", "offerUiType": "Bundle", "name": "Starter Bundle Design", "externalId": "starter-bundle-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "backgroundColor": { "colorOne": "#E7CF88", "colorTwo": "#FDFCF9", "gradientDirection": "to right" }, "buttonSuffixImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/bundle-button-suffix.png", "buttonSuffixAnimation": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/bundle-button-suffix-animation.json" } ``` # Delete Bundle Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/bundles/delete-bundle-design openapi-bundle-design.json DELETE /components/v1/offer-design/{externalId} Deletes a bundle design. **Note:** You can't delete an offer design while it's in use by an offer. ```bash Delete Bundle Design theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/components/v1/offer-design/starter-bundle-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Bundle Design theme={"system"} { "id": "68b3e3473e2ea6249862bddf", "offerUiType": "Bundle", "name": "Starter Bundle Design", "externalId": "starter-bundle-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "backgroundColor": { "colorOne": "#E7CF88", "colorTwo": "#FDFCF9", "gradientDirection": "to right" }, "buttonSuffixImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/bundle-button-suffix.png", "buttonSuffixAnimation": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/bundle-button-suffix-animation.json" } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/bundles/introduction The Bundle Designs API allows you to create and manage designs for bundle offers. With this API, you can: * [Create a bundle design](./create-bundle-design). * [Update a bundle design](./update-bundle-design). * [Delete a bundle design](./delete-bundle-design). # Update Bundle Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/bundles/update-bundle-design openapi-bundle-design.json PUT /components/v1/offer-design/{externalId} Updates a bundle design. ```bash Update Bundle Design theme={"system"} curl -X PUT \ 'https://api.appcharge.com/components/v1/offer-design/starter-bundle-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "Bundle", "name": "Starter Bundle Design Updated", "externalId": "starter-bundle-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background-v2.png", "backgroundColor": { "colorOne": "#E7CF88", "colorTwo": "#FDFCF9", "gradientDirection": "to right" }, "buttonSuffixImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/bundle-button-suffix-v2.png", "buttonSuffixAnimation": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/bundle-button-suffix-animation-v2.json" }' ``` ```json Update Bundle Design theme={"system"} { "id": "68b3e3473e2ea6249862bddf", "offerUiType": "Bundle", "name": "Starter Bundle Design Updated", "externalId": "starter-bundle-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background-v2.png", "backgroundColor": { "colorOne": "#E7CF88", "colorTwo": "#FDFCF9", "gradientDirection": "to right" }, "buttonSuffixImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/bundle-button-suffix-v2.png", "buttonSuffixAnimation": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/bundle-button-suffix-animation-v2.json" } ``` # Create Daily Bonus Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/daily-bonuses/create-daily-bonus-design openapi-daily-bonus-design.json POST /components/v1/offer-design Creates a daily bonus design. ```bash Create Daily Bonus Design theme={"system"} curl -X POST \ 'https://api.appcharge.com/components/v1/offer-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "PopUp", "offerUiSubType": "DailyBonus", "name": "Daily Bonus Design", "externalId": "daily-bonus-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "title": { "text": "Your daily bonus!", "fontColor": "#FFFFFF", "fontSize": 20, "fontWeight": "normal" } }' ``` ```json Create Daily Bonus Design theme={"system"} { "id": "68cbf09967ba5ab776c2745e", "offerUiType": "PopUp", "offerUiSubType": "DailyBonus", "name": "Daily Bonus Design", "externalId": "daily-bonus-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "title": { "text": "Your daily bonus!", "fontColor": "#FFFFFF", "fontSize": 20, "fontWeight": "normal" } } ``` # Delete Daily Bonus Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/daily-bonuses/delete-daily-bonus-design openapi-daily-bonus-design.json DELETE /components/v1/offer-design/{externalId} Deletes a daily bonus design. **Note:** You can't delete an offer design while it's in use by an offer. ```bash Delete Daily Bonus Design theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/components/v1/offer-design/daily-bonus-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Daily Bonus Design theme={"system"} { "id": "68cbf09967ba5ab776c2745e", "offerUiType": "PopUp", "offerUiSubType": "DailyBonus", "name": "Daily Bonus Design", "externalId": "daily-bonus-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "title": { "text": "Your daily bonus!", "fontColor": "#FFFFFF", "fontSize": 20, "fontWeight": "normal" } } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/daily-bonuses/introduction The Daily Bonus Designs API allows you to create and manage designs for daily bonus offers. With this API, you can: * [Create a daily bonus design](./create-daily-bonus-design). * [Update a daily bonus design](./update-daily-bonus-design). * [Delete a daily bonus design](./delete-daily-bonus-design). # Update Daily Bonus Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/daily-bonuses/update-daily-bonus-design openapi-daily-bonus-design.json PUT /components/v1/offer-design/{externalId} Updates a daily bonus design. ```bash Update Daily Bonus Design theme={"system"} curl -X PUT \ 'https://api.appcharge.com/components/v1/offer-design/daily-bonus-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "PopUp", "offerUiSubType": "DailyBonus", "name": "Daily Bonus Design Updated", "externalId": "daily-bonus-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background-v2.png", "title": { "text": "Your daily bonus!", "fontColor": "#FFFFFF", "fontSize": 20, "fontWeight": "normal" } }' ``` ```json Update Daily Bonus Design theme={"system"} { "id": "68cbf09967ba5ab776c2745e", "offerUiType": "PopUp", "offerUiSubType": "DailyBonus", "name": "Daily Bonus Design Updated", "externalId": "daily-bonus-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background-v2.png", "title": { "text": "Your daily bonus!", "fontColor": "#FFFFFF", "fontSize": 20, "fontWeight": "normal" } } ``` # Get All Offer Designs Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/get-all-offer-designs openapi-offer-designs-api.json GET /components/v1/offer-design Retrieves a list of all offer designs. ```bash Get All Offer Designs theme={"system"} curl -X GET \ 'https://api.appcharge.com/components/v1/offer-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' ``` ```json Get All Offer Designs theme={"system"} [ { "id": "68b3e3473e2ea6249862bddf", "offerUiType": "Bundle", "name": "Starter Bundle Design", "externalId": "starter-bundle-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "backgroundColor": { "colorOne": "#E7CF88", "colorTwo": "#FDFCF9", "gradientDirection": "to right" }, "buttonSuffixImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/bundle-button-suffix.png", "buttonSuffixAnimation": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/bundle-button-suffix-animation.json" }, { "id": "68b3f37f3a2852af1a154fae", "offerUiType": "SpecialOffer", "name": "Summer Special Design", "externalId": "summer-special-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "title": { "text": "Limited Time Offer", "fontColor": { "colorOne": "#ffffff" }, "fontSize": 20, "fontWeight": "bold" }, "buttonSuffixImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/special-offer-button-suffix.png", "buttonSuffixAnimation": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/special-offer-button-suffix-animation.json" }, { "id": "68cbf09967ba5ab776c2745e", "offerUiType": "PopUp", "offerUiSubType": "DailyBonus", "name": "Daily Bonus Design", "externalId": "daily-bonus-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "title": { "text": "Your daily bonus!", "fontColor": "#FFFFFF", "fontSize": 20, "fontWeight": "normal" } }, { "id": "68d2b9cf7a8b4d2f1b8e0a31", "offerUiType": "PopUp", "offerUiSubType": "RewardCalendar", "name": "Weekly Reward Calendar", "externalId": "reward-calendar-design-1", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/reward-calendar-background.png", "rewardCalendar": { "collectibleBadgeImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/collectible-badge.png", "lockedBadgeImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/locked-badge.png", "backgroundColor": "#101225", "collectIconImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/collect-icon.png", "lockedIconImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/locked-icon.png", "dayFontColor": "#FFFFFF", "subRewardBackgroundImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/sub-reward-background.png", "mainRewardBackgroundImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/main-reward-background.png", "headerImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/header.png" } }, { "id": "6a09aa1018b751228b09faed", "offerUiType": "PopUp", "offerUiSubType": "PostPurchase", "name": "Post Purchase Popup Design", "externalId": "post-purchase-popup-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "title": { "text": "Post purchase offer", "fontColor": "#FFFFFF", "fontSize": 20, "fontWeight": "medium" } }, { "id": "694a7c8e87f78fb36a931763", "offerUiType": "RollingOffer", "name": "Rolling Offer Design", "externalId": "rolling-offer-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "backgroundColor": "#272727", "backgroundOpacity": 80, "headerImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/header.png", "arrowColor": "#ffffff", "borderColor": { "colorOne": "#ffffff", "colorTwo": "#ffffff", "direction": "to right" }, "borderWidth": 2, "subRollingOffer": { "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/sub-background.png", "collectText": "FREE" } }, { "id": "6909e7684f11e8957afd5d53", "offerUiType": "ProgressBar", "name": "Classic Progress Bar Design", "externalId": "progress-bar-design-classic", "backgroundImageUrl": "https://media.appcharge.com/defaults/background.png", "backgroundColor": { "colorOne": "#1a1a1a", "colorTwo": "#1a1a1a", "gradientDirection": "to right" }, "backgroundOpacity": 100, "frameRadius": 8, "headerImageUrl": "https://example.com/header.png", "title": { "text": "Classic Progress Bar", "fontColor": "#FFD700", "fontSize": 10, "fontWeight": "bold" }, "subtitle": { "text": "Collect rewards along the way", "fontColor": "#FFD700", "fontSize": 8, "fontWeight": "medium" }, "progressBar": { "barFillColor": { "colorOne": "#FFD700", "colorTwo": "#FFA500", "gradientDirection": "to right" }, "borderColor": { "colorOne": "#1a1a1a", "colorTwo": "#3a3a3a", "gradientDirection": "to right" }, "borderWidth": 3, "barRadius": 4, "backgroundColor": { "colorOne": "#1a1a1a", "colorTwo": "#111111", "gradientDirection": "to bottom" }, "textColor": "#FFD700", "accumulatedItem": { "imageUrl": "https://example.com/item.png", "ribbonImageUrl": "https://example.com/ribbon.png" }, "type": "classic", "milestones": null } } ] ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/introduction The Offer Designs API allows you to create and manage offer designs. Each design defines the visual layout of the offer, including backgrounds, titles, and styling options. This API supports all offers except Checkout Link Offers, as they don't have a UI design. Learn more about [offer designs](/../../guides/webstore/design/design-an-offer). After you create an offer design, use it when creating the actual offer with the [Offers V2 API](../../offers-v2/introduction). The Offer Designs API includes the following: * [Special Offer Designs API](./special-offers/introduction): Create and update designs for special offers. * [Bundle Designs API](./bundles/introduction): Create and update designs for bundle offers. * [Daily Bonus Designs API](./daily-bonuses/introduction): Create and update designs for daily bonus offers. * [Reward Calendar Designs API](./reward-calendars/introduction): Create and update designs for reward calendar offers. * [Triggered Popup Designs API](./triggered-popups/introduction): Create and update designs for triggered popup offers. * [Rolling Offer Designs API](./rolling-offers/introduction): Create and update designs for rolling offers. * [Progress Bar Designs API](./progress-bars/introduction): Create, update, and delete designs for progress bar offers. With this API, you can also: * [Retrieve all offer designs](./get-all-offer-designs). # Create Progress Bar Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/progress-bars/create-progress-bar-design openapi-progress-bar-design.json POST /components/v1/offer-design Creates a progress bar design. When you create a progress bar design, `progressBar.type` defaults to `classic`. To create a milestones design, set `progressBar.type` to `milestones` and include the `milestones` object. ```bash Create Classic Progress Bar Design theme={"system"} curl -X POST \ 'https://api.appcharge.com/components/v1/offer-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "ProgressBar", "name": "Classic Progress Bar Design", "externalId": "progress-bar-design-classic", "backgroundImageUrl": "https://media.appcharge.com/defaults/background.png", "backgroundColor": { "colorOne": "#1a1a1a", "colorTwo": "#1a1a1a", "gradientDirection": "to right" }, "backgroundOpacity": 100, "frameRadius": 8, "headerImageUrl": "https://example.com/header.png", "title": { "text": "Classic Progress Bar", "fontColor": "#FFD700", "fontSize": 10, "fontWeight": "bold" }, "subtitle": { "text": "Collect rewards along the way", "fontColor": "#FFD700", "fontSize": 8, "fontWeight": "medium" }, "progressBar": { "barFillColor": { "colorOne": "#FFD700", "colorTwo": "#FFA500", "gradientDirection": "to right" }, "borderColor": { "colorOne": "#1a1a1a", "colorTwo": "#3a3a3a", "gradientDirection": "to right" }, "borderWidth": 3, "barRadius": 4, "backgroundColor": { "colorOne": "#1a1a1a", "colorTwo": "#111111", "gradientDirection": "to bottom" }, "textColor": "#FFD700", "accumulatedItem": { "imageUrl": "https://example.com/item.png", "ribbonImageUrl": "https://example.com/ribbon.png" }, "type": "classic" } }' ``` ```bash Create Milestone Progress Bar Design theme={"system"} curl -X POST \ 'https://api.appcharge.com/components/v1/offer-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "ProgressBar", "name": "Milestone Progress Bar Design", "externalId": "progress-bar-design-milestones", "backgroundImageUrl": "https://media.appcharge.com/defaults/background.png", "backgroundColor": { "colorOne": "#1a1a1a", "colorTwo": "#1a1a1a", "gradientDirection": "to right" }, "backgroundOpacity": 100, "frameRadius": 8, "headerImageUrl": "https://example.com/header.png", "title": { "text": "Reach Every Milestone", "fontColor": "#FFD700", "fontSize": 10, "fontWeight": "bold" }, "subtitle": { "text": "Collect rewards along the way", "fontColor": "#FFD700", "fontSize": 8, "fontWeight": "medium" }, "progressBar": { "barFillColor": { "colorOne": "#FFD700", "colorTwo": "#FFA500", "gradientDirection": "to right" }, "borderColor": { "colorOne": "#1a1a1a", "colorTwo": "#3a3a3a", "gradientDirection": "to right" }, "borderWidth": 3, "barRadius": 4, "backgroundColor": { "colorOne": "#1a1a1a", "colorTwo": "#111111", "gradientDirection": "to bottom" }, "textColor": "#FFD700", "accumulatedItem": { "imageUrl": "https://example.com/item.png", "ribbonImageUrl": "https://example.com/ribbon.png" }, "type": "milestones", "milestones": { "milestoneCompletedIconUrl": "https://example.com/checkmark.png", "tooltipBackgroundColor": "#1f9eec" } } }' ``` ```json Create Classic Progress Bar Design theme={"system"} { "id": "6909e7684f11e8957afd5d53", "offerUiType": "ProgressBar", "name": "Classic Progress Bar Design", "externalId": "progress-bar-design-classic", "backgroundImageUrl": "https://media.appcharge.com/defaults/background.png", "backgroundColor": { "colorOne": "#1a1a1a", "colorTwo": "#1a1a1a", "gradientDirection": "to right" }, "backgroundOpacity": 100, "frameRadius": 8, "headerImageUrl": "https://example.com/header.png", "title": { "text": "Classic Progress Bar", "fontColor": "#FFD700", "fontSize": 10, "fontWeight": "bold" }, "subtitle": { "text": "Collect rewards along the way", "fontColor": "#FFD700", "fontSize": 8, "fontWeight": "medium" }, "progressBar": { "barFillColor": { "colorOne": "#FFD700", "colorTwo": "#FFA500", "gradientDirection": "to right" }, "borderColor": { "colorOne": "#1a1a1a", "colorTwo": "#3a3a3a", "gradientDirection": "to right" }, "borderWidth": 3, "barRadius": 4, "backgroundColor": { "colorOne": "#1a1a1a", "colorTwo": "#111111", "gradientDirection": "to bottom" }, "textColor": "#FFD700", "accumulatedItem": { "imageUrl": "https://example.com/item.png", "ribbonImageUrl": "https://example.com/ribbon.png" }, "type": "classic", "milestones": null } } ``` ```json Create Milestone Progress Bar Design theme={"system"} { "id": "6909e7684f11e8957afd5d54", "offerUiType": "ProgressBar", "name": "Milestone Progress Bar Design", "externalId": "progress-bar-design-milestones", "backgroundImageUrl": "https://media.appcharge.com/defaults/background.png", "backgroundColor": { "colorOne": "#1a1a1a", "colorTwo": "#1a1a1a", "gradientDirection": "to right" }, "backgroundOpacity": 100, "frameRadius": 8, "headerImageUrl": "https://example.com/header.png", "title": { "text": "Reach Every Milestone", "fontColor": "#FFD700", "fontSize": 10, "fontWeight": "bold" }, "subtitle": { "text": "Collect rewards along the way", "fontColor": "#FFD700", "fontSize": 8, "fontWeight": "medium" }, "progressBar": { "barFillColor": { "colorOne": "#FFD700", "colorTwo": "#FFA500", "gradientDirection": "to right" }, "borderColor": { "colorOne": "#1a1a1a", "colorTwo": "#3a3a3a", "gradientDirection": "to right" }, "borderWidth": 3, "barRadius": 4, "backgroundColor": { "colorOne": "#1a1a1a", "colorTwo": "#111111", "gradientDirection": "to bottom" }, "textColor": "#FFD700", "accumulatedItem": { "imageUrl": "https://example.com/item.png", "ribbonImageUrl": "https://example.com/ribbon.png" }, "type": "milestones", "milestones": { "milestoneCompletedIconUrl": "https://example.com/checkmark.png", "tooltipBackgroundColor": "#1f9eec" } } } ``` # Delete Progress Bar Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/progress-bars/delete-progress-bar-design openapi-progress-bar-design.json DELETE /components/v1/offer-design/{externalId} Deletes a progress bar design. ```bash Delete Classic Progress Bar Design theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/components/v1/offer-design/progress-bar-design-classic' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' ``` ```bash Delete Milestone Progress Bar Design theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/components/v1/offer-design/progress-bar-design-milestones' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Classic Progress Bar Design theme={"system"} { "id": "6909e7684f11e8957afd5d53", "offerUiType": "ProgressBar", "name": "Classic Progress Bar Design", "externalId": "progress-bar-design-classic", "backgroundImageUrl": "https://media.appcharge.com/defaults/background.png", "backgroundColor": { "colorOne": "#1a1a1a", "colorTwo": "#1a1a1a", "gradientDirection": "to right" }, "backgroundOpacity": 100, "frameRadius": 8, "headerImageUrl": "https://example.com/header.png", "title": { "text": "Classic Progress Bar", "fontColor": "#FFD700", "fontSize": 10, "fontWeight": "bold" }, "subtitle": { "text": "Collect rewards along the way", "fontColor": "#FFD700", "fontSize": 8, "fontWeight": "medium" }, "progressBar": { "barFillColor": { "colorOne": "#FFD700", "colorTwo": "#FFA500", "gradientDirection": "to right" }, "borderColor": { "colorOne": "#1a1a1a", "colorTwo": "#3a3a3a", "gradientDirection": "to right" }, "borderWidth": 3, "barRadius": 4, "backgroundColor": { "colorOne": "#1a1a1a", "colorTwo": "#111111", "gradientDirection": "to bottom" }, "textColor": "#FFD700", "accumulatedItem": { "imageUrl": "https://example.com/item.png", "ribbonImageUrl": "https://example.com/ribbon.png" }, "type": "classic", "milestones": null } } ``` ```json Delete Milestone Progress Bar Design theme={"system"} { "id": "6909e7684f11e8957afd5d54", "offerUiType": "ProgressBar", "name": "Milestone Progress Bar Design", "externalId": "progress-bar-design-milestones", "backgroundImageUrl": "https://media.appcharge.com/defaults/background.png", "backgroundColor": { "colorOne": "#1a1a1a", "colorTwo": "#1a1a1a", "gradientDirection": "to right" }, "backgroundOpacity": 100, "frameRadius": 8, "headerImageUrl": "https://example.com/header.png", "title": { "text": "Reach Every Milestone", "fontColor": "#FFD700", "fontSize": 10, "fontWeight": "bold" }, "subtitle": { "text": "Collect rewards along the way", "fontColor": "#FFD700", "fontSize": 8, "fontWeight": "medium" }, "progressBar": { "barFillColor": { "colorOne": "#FFD700", "colorTwo": "#FFA500", "gradientDirection": "to right" }, "borderColor": { "colorOne": "#1a1a1a", "colorTwo": "#3a3a3a", "gradientDirection": "to right" }, "borderWidth": 3, "barRadius": 4, "backgroundColor": { "colorOne": "#1a1a1a", "colorTwo": "#111111", "gradientDirection": "to bottom" }, "textColor": "#FFD700", "accumulatedItem": { "imageUrl": "https://example.com/item.png", "ribbonImageUrl": "https://example.com/ribbon.png" }, "type": "milestones", "milestones": { "milestoneCompletedIconUrl": "https://example.com/checkmark.png", "tooltipBackgroundColor": "#1f9eec" } } } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/progress-bars/introduction The Progress Bar Designs API allows you to create, update, and delete designs for progress bar offers. There are 2 types of progress bars: * **Classic:** Only one mission is displayed on the bar at a given time, and the bar resets when the next mission begins. * **Milestones:** All missions are displayed simultaneously along the bar. Players can see every reward ahead of them, including the final grand reward at the last mission. With this API, you can: * [Create a progress bar design](./create-progress-bar-design). * [Update a progress bar design](./update-progress-bar-design). * [Delete a progress bar design](./delete-progress-bar-design). # Update Progress Bar Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/progress-bars/update-progress-bar-design openapi-progress-bar-design.json PUT /components/v1/offer-design/{externalId} Updates a progress bar design. When you update a progress bar design, `progressBar.type` defaults to `classic`. To keep a milestones design, set `progressBar.type` to `milestones` and include the `milestones` object. ```bash Update Classic Progress Bar Design theme={"system"} curl -X PUT \ 'https://api.appcharge.com/components/v1/offer-design/progress-bar-design-classic' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "ProgressBar", "name": "Classic Progress Bar Design Updated", "externalId": "progress-bar-design-classic", "backgroundImageUrl": "https://media.appcharge.com/defaults/background.png", "backgroundColor": { "colorOne": "#222222", "colorTwo": "#444444", "gradientDirection": "to bottom" }, "backgroundOpacity": 90, "frameRadius": 12, "headerImageUrl": "https://example.com/header-new.png", "title": { "text": "Updated Classic Bar", "fontColor": "#FF0000", "fontSize": 12, "fontWeight": "bold" }, "subtitle": { "text": "New rewards at every step", "fontColor": "#FF0000", "fontSize": 9, "fontWeight": "medium" }, "progressBar": { "barFillColor": { "colorOne": "#00FF00", "colorTwo": "#007700", "gradientDirection": "to right" }, "backgroundColor": { "colorOne": "#333333", "colorTwo": "#555555", "gradientDirection": "to right" }, "borderColor": { "colorOne": "#FF0000", "colorTwo": "#880000", "gradientDirection": "to bottom" }, "borderWidth": 4, "barRadius": 8, "accumulatedItem": { "imageUrl": "https://example.com/item-new.png", "ribbonImageUrl": "https://example.com/ribbon-new.png" }, "textColor": "#FF0000", "type": "classic" } }' ``` ```bash Update Milestone Progress Bar Design theme={"system"} curl -X PUT \ 'https://api.appcharge.com/components/v1/offer-design/progress-bar-design-milestones' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "ProgressBar", "name": "Milestone Progress Bar Design Updated", "externalId": "progress-bar-design-milestones", "backgroundImageUrl": "https://media.appcharge.com/defaults/background.png", "backgroundColor": { "colorOne": "#222222", "colorTwo": "#444444", "gradientDirection": "to bottom" }, "backgroundOpacity": 90, "frameRadius": 12, "headerImageUrl": "https://example.com/header-new.png", "title": { "text": "Updated Milestone Bar", "fontColor": "#FF0000", "fontSize": 12, "fontWeight": "bold" }, "subtitle": { "text": "New rewards at every step", "fontColor": "#FF0000", "fontSize": 9, "fontWeight": "medium" }, "progressBar": { "barFillColor": { "colorOne": "#00FF00", "colorTwo": "#007700", "gradientDirection": "to right" }, "backgroundColor": { "colorOne": "#333333", "colorTwo": "#555555", "gradientDirection": "to right" }, "borderColor": { "colorOne": "#FF0000", "colorTwo": "#880000", "gradientDirection": "to bottom" }, "borderWidth": 4, "barRadius": 8, "accumulatedItem": { "imageUrl": "https://example.com/item-new.png", "ribbonImageUrl": "https://example.com/ribbon-new.png" }, "textColor": "#FF0000", "type": "milestones", "milestones": { "milestoneCompletedIconUrl": "https://example.com/checkmark-new.png", "tooltipBackgroundColor": "#1f9eec" } } }' ``` ```json Update Classic Progress Bar Design theme={"system"} { "id": "6a2536c0b0fbdcd303bd861b", "offerUiType": "ProgressBar", "name": "Classic Progress Bar Design Updated", "externalId": "progress-bar-design-classic", "backgroundImageUrl": "https://media.appcharge.com/defaults/background.png", "backgroundColor": { "colorOne": "#222222", "colorTwo": "#444444", "gradientDirection": "to bottom" }, "backgroundOpacity": 90, "frameRadius": 12, "headerImageUrl": "https://example.com/header-new.png", "title": { "text": "Updated Classic Bar", "fontColor": "#FF0000", "fontSize": 12, "fontWeight": "bold" }, "subtitle": { "text": "New rewards at every step", "fontColor": "#FF0000", "fontSize": 9, "fontWeight": "medium" }, "progressBar": { "barFillColor": { "colorOne": "#00FF00", "colorTwo": "#007700", "gradientDirection": "to right" }, "backgroundColor": { "colorOne": "#333333", "colorTwo": "#555555", "gradientDirection": "to right" }, "borderColor": { "colorOne": "#FF0000", "colorTwo": "#880000", "gradientDirection": "to bottom" }, "borderWidth": 4, "barRadius": 8, "accumulatedItem": { "imageUrl": "https://example.com/item-new.png", "ribbonImageUrl": "https://example.com/ribbon-new.png" }, "textColor": "#FF0000", "type": "classic", "milestones": null } } ``` ```json Update Milestone Progress Bar Design theme={"system"} { "id": "6a2536c0b0fbdcd303bd861c", "offerUiType": "ProgressBar", "name": "Milestone Progress Bar Design Updated", "externalId": "progress-bar-design-milestones", "backgroundImageUrl": "https://media.appcharge.com/defaults/background.png", "backgroundColor": { "colorOne": "#222222", "colorTwo": "#444444", "gradientDirection": "to bottom" }, "backgroundOpacity": 90, "frameRadius": 12, "headerImageUrl": "https://example.com/header-new.png", "title": { "text": "Updated Milestone Bar", "fontColor": "#FF0000", "fontSize": 12, "fontWeight": "bold" }, "subtitle": { "text": "New rewards at every step", "fontColor": "#FF0000", "fontSize": 9, "fontWeight": "medium" }, "progressBar": { "barFillColor": { "colorOne": "#00FF00", "colorTwo": "#007700", "gradientDirection": "to right" }, "backgroundColor": { "colorOne": "#333333", "colorTwo": "#555555", "gradientDirection": "to right" }, "borderColor": { "colorOne": "#FF0000", "colorTwo": "#880000", "gradientDirection": "to bottom" }, "borderWidth": 4, "barRadius": 8, "accumulatedItem": { "imageUrl": "https://example.com/item-new.png", "ribbonImageUrl": "https://example.com/ribbon-new.png" }, "textColor": "#FF0000", "type": "milestones", "milestones": { "milestoneCompletedIconUrl": "https://example.com/checkmark-new.png", "tooltipBackgroundColor": "#1f9eec" } } } ``` # Create Reward Calendar Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/reward-calendars/create-reward-calendar-design openapi-reward-calendar-design.json POST /components/v1/offer-design Creates a reward calendar design. ```bash Create Reward Calendar Design theme={"system"} curl -X POST \ 'https://api.appcharge.com/components/v1/offer-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "PopUp", "offerUiSubType": "RewardCalendar", "name": "Weekly Reward Calendar 1", "externalId": "reward-calendar-design-1", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/reward-calendar-background.png", "rewardCalendar": { "collectibleBadgeImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/collectible-badge.png", "lockedBadgeImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/locked-badge.png", "backgroundColor": "#101225", "collectIconImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/collect-icon.png", "lockedIconImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/locked-icon.png", "dayFontColor": "#FFFFFF", "subRewardBackgroundImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/sub-reward-background.png", "mainRewardBackgroundImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/main-reward-background.png", "headerImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/header.png" } }' ``` ```json Create Reward Calendar Design theme={"system"} { "id": "68d2b9cf7a8b4d2f1b8e0a31", "offerUiType": "PopUp", "offerUiSubType": "RewardCalendar", "name": "Weekly Reward Calendar 1", "externalId": "reward-calendar-design-1", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/reward-calendar-background.png", "rewardCalendar": { "collectibleBadgeImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/collectible-badge.png", "lockedBadgeImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/locked-badge.png", "backgroundColor": "#101225", "collectIconImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/collect-icon.png", "lockedIconImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/locked-icon.png", "dayFontColor": "#FFFFFF", "subRewardBackgroundImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/sub-reward-background.png", "mainRewardBackgroundImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/main-reward-background.png", "headerImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/header.png" } } ``` # Delete Reward Calendar Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/reward-calendars/delete-reward-calendar-design openapi-reward-calendar-design.json DELETE /components/v1/offer-design/{externalId} Deletes a reward calendar design. **Note:** You can't delete an offer design while it's in use by an offer. ```bash Delete Reward Calendar Design theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/components/v1/offer-design/reward-calendar-design-1' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Reward Calendar Design theme={"system"} { "id": "68d2b9cf7a8b4d2f1b8e0a31", "offerUiType": "PopUp", "offerUiSubType": "RewardCalendar", "name": "Weekly Reward Calendar", "externalId": "reward-calendar-design-1", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/reward-calendar-background.png", "rewardCalendar": { "collectibleBadgeImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/collectible-badge.png", "lockedBadgeImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/locked-badge.png", "backgroundColor": "#101225", "collectIconImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/collect-icon.png", "lockedIconImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/locked-icon.png", "dayFontColor": "#FFFFFF", "subRewardBackgroundImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/sub-reward-background.png", "mainRewardBackgroundImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/main-reward-background.png", "headerImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/header.png" } } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/reward-calendars/introduction The Reward Calendar Designs API allows you to create and manage designs for reward calendar offers. Reward calendars are 7-day calendars that display one reward per day. Days 1-6 are sub rewards displayed as regular calendar days, while Day 7 is the main reward displayed as a larger, wider featured tile. With this API, you can: * [Create a reward calendar design](./create-reward-calendar-design). * [Update a reward calendar design](./update-reward-calendar-design). * [Delete a reward calendar design](./delete-reward-calendar-design). ## Terminology * **Collect icon:** The icon shown on the tile representing the current day in the calendar after a player collects a reward. * **Locked icon:** The icon shown on reward tiles representing upcoming days in the calendar that aren't yet available to collect. * **Collectible badge:** The persistent badge players click to open the calendar popup and collect the current day's reward. * **Locked badge:** The persistent badge players click to open the calendar popup, preview upcoming rewards, and see when the next reward becomes available. # Update Reward Calendar Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/reward-calendars/update-reward-calendar-design openapi-reward-calendar-design.json PUT /components/v1/offer-design/{externalId} Updates a reward calendar design. ```bash Update Reward Calendar Design theme={"system"} curl -X PUT \ 'https://api.appcharge.com/components/v1/offer-design/reward-calendar-design-1' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "PopUp", "offerUiSubType": "RewardCalendar", "name": "Updated Reward Calendar Design", "externalId": "reward-calendar-design-1", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/reward-calendar-background-v2.png", "rewardCalendar": { "collectibleBadgeImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/collectible-badge-v2.png", "lockedBadgeImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/locked-badge-v2.png", "backgroundColor": "#111832", "collectIconImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/collect-icon-v2.png", "lockedIconImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/locked-icon-v2.png", "dayFontColor": "#FFFFFF", "headerImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/header.png" } }' ``` ```json Update Reward Calendar Design theme={"system"} { "id": "68d2b9cf7a8b4d2f1b8e0a31", "offerUiType": "PopUp", "offerUiSubType": "RewardCalendar", "name": "Updated Reward Calendar Design", "externalId": "reward-calendar-design-1", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/reward-calendar-background-v2.png", "rewardCalendar": { "collectibleBadgeImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/collectible-badge-v2.png", "lockedBadgeImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/locked-badge-v2.png", "backgroundColor": "#111832", "collectIconImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/collect-icon-v2.png", "lockedIconImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/locked-icon-v2.png", "dayFontColor": "#FFFFFF", "headerImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/header.png", } } ``` # Create Rolling Offer Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/rolling-offers/create-rolling-offer-design openapi-rolling-offer-design.json POST /components/v1/offer-design Creates a rolling offer design. ```bash Create Rolling Offer Design theme={"system"} curl -X POST \ 'https://api.appcharge.com/components/v1/offer-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "RollingOffer", "name": "Rolling Offer Design", "externalId": "rolling-offer-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "backgroundColor": "#272727", "backgroundOpacity": 80, "headerImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/header.png", "arrowColor": "#ffffff", "borderColor": { "colorOne": "#ffffff", "colorTwo": "#ffffff", "gradientDirection": "to right" }, "borderWidth": 2, "subRollingOffer": { "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "collectText": "FREE" } }' ``` ```json Create Rolling Offer Design theme={"system"} { "id": "694a7c8e87f78fb36a931763", "offerUiType": "RollingOffer", "name": "Rolling Offer Design", "externalId": "rolling-offer-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "backgroundColor": "#272727", "backgroundOpacity": 80, "headerImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/header.png", "arrowColor": "#ffffff", "borderColor": { "colorOne": "#ffffff", "colorTwo": "#ffffff", "direction": "to right" }, "borderWidth": 2, "subRollingOffer": { "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "collectText": "FREE" } } ``` # Delete Rolling Offer Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/rolling-offers/delete-rolling-offer-design openapi-rolling-offer-design.json DELETE /components/v1/offer-design/{externalId} Deletes a rolling offer design. **Note:** You can't delete an offer design while it's in use by an offer. ```bash Delete Rolling Offer Design theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/components/v1/offer-design/rolling-offer-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Rolling Offer Design theme={"system"} { "id": "694a7c8e87f78fb36a931763", "offerUiType": "RollingOffer", "name": "Rolling Offer Design", "externalId": "rolling-offer-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "backgroundColor": "#272727", "backgroundOpacity": 80, "headerImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/header.png", "arrowColor": "#ffffff", "borderColor": { "colorOne": "#ffffff", "colorTwo": "#ffffff", "direction": "to right" }, "borderWidth": 2, "subRollingOffer": { "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "collectText": "FREE" } } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/rolling-offers/introduction The Rolling Offer Designs API allows you to create and manage designs for rolling offers. With this API, you can: * [Create a rolling offer design](./create-rolling-offer-design). * [Update a rolling offer design](./update-rolling-offer-design). * [Delete a rolling offer design](./delete-rolling-offer-design). # Update Rolling Offer Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/rolling-offers/update-rolling-offer-design openapi-rolling-offer-design.json PUT /components/v1/offer-design/{externalId} Updates a rolling offer design. ```bash Update Rolling Offer Design theme={"system"} curl -X PUT \ 'https://api.appcharge.com/components/v1/offer-design/rolling-offer-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "RollingOffer", "name": "Rolling Offer Design Updated", "externalId": "rolling-offer-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background-v2.png", "backgroundColor": "#272727", "backgroundOpacity": 80, "headerImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/header.png", "arrowColor": "#ffffff", "borderColor": { "colorOne": "#ffffff", "colorTwo": "#ffffff", "gradientDirection": "to right" }, "borderWidth": 2, "subRollingOffer": { "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "collectText": "FREE" } }' ``` ```json Update Rolling Offer Design theme={"system"} { "id": "694a7c8e87f78fb36a931763", "offerUiType": "RollingOffer", "name": "Rolling Offer Design Updated", "externalId": "rolling-offer-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background-v2.png", "backgroundColor": "#272727", "backgroundOpacity": 80, "headerImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/header.png", "arrowColor": "#ffffff", "borderColor": { "colorOne": "#ffffff", "colorTwo": "#ffffff", "direction": "to right" }, "borderWidth": 2, "subRollingOffer": { "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "collectText": "FREE" } } ``` # Create Special Offer Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/special-offers/create-special-offer-design openapi-special-offer-design.json POST /components/v1/offer-design Creates a special offer design. ```bash Create Special Offer Design theme={"system"} curl -X POST \ 'https://api.appcharge.com/components/v1/offer-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "SpecialOffer", "name": "Summer Special Design", "externalId": "summer-special-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "title": { "text": "Limited Time Offer", "fontColor": "#ffffff", "fontSize": 20, "fontWeight": "bold" }, "buttonSuffixImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/button-suffix.png", "buttonSuffixAnimation": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/button-suffix-animation.json" }' ``` ```json Create Special Offer Design theme={"system"} { "id": "68b3f37f3a2852af1a154fae", "offerUiType": "SpecialOffer", "name": "Summer Special Design", "externalId": "summer-special-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "title": { "text": "Limited Time Offer", "fontColor": { "colorOne": "#ffffff" }, "fontSize": 20, "fontWeight": "bold" }, "buttonSuffixImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/button-suffix.png", "buttonSuffixAnimation": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/button-suffix-animation.json" } ``` # Delete Special Offer Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/special-offers/delete-special-offer-design openapi-special-offer-design.json DELETE /components/v1/offer-design/{externalId} Deletes a special offer design. **Note:** You can't delete an offer design while it's in use by an offer. ```bash Delete Special Offer Design theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/components/v1/offer-design/summer-special-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Special Offer Design theme={"system"} { "id": "68b3f37f3a2852af1a154fae", "offerUiType": "SpecialOffer", "name": "Summer Special Design", "externalId": "summer-special-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "title": { "text": "Limited Time Offer", "fontColor": { "colorOne": "#ffffff" }, "fontSize": 20, "fontWeight": "bold" }, "buttonSuffixImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/button-suffix.png", "buttonSuffixAnimation": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/button-suffix-animation.json" } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/special-offers/introduction The Special Offer Designs API allows you to create and manage designs for special offers. With this API, you can: * [Create a special offer design](./create-special-offer-design). * [Update a special offer design](./update-special-offer-design). * [Delete a special offer design](./delete-special-offer-design). # Update Special Offer Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/special-offers/update-special-offer-design openapi-special-offer-design.json PUT /components/v1/offer-design/{externalId} Updates a special offer design. ```bash Update Special Offer Design theme={"system"} curl -X PUT \ 'https://api.appcharge.com/components/v1/offer-design/summer-special-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "SpecialOffer", "name": "Summer Special Design Updated", "externalId": "summer-special-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background-v2.png", "title": { "text": "Limited Time Offer", "fontColor": "#ffffff", "fontSize": 20, "fontWeight": "bold" }, "buttonSuffixImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/button-suffix-v2.png", "buttonSuffixAnimation": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/button-suffix-animation-v2.json" }' ``` ```json Update Special Offer Design theme={"system"} { "id": "68b3f37f3a2852af1a154fae", "offerUiType": "SpecialOffer", "name": "Summer Special Design Updated", "externalId": "summer-special-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background-v2.png", "title": { "text": "Limited Time Offer", "fontColor": { "colorOne": "#ffffff" }, "fontSize": 20, "fontWeight": "bold" }, "buttonSuffixImage": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/button-suffix-v2.png", "buttonSuffixAnimation": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/button-suffix-animation-v2.json" } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/triggered-popups/introduction The Triggered Popup Designs API is a suite of APIs that allow you to create, update, and delete designs for triggered popup offers. The Triggered Popup Designs API includes the following: * [Post Purchase Popup Designs API](./post-purchase-popups/introduction): Create, update, and delete designs for popup offers triggered after a player completes a purchase. # Create Post Purchase Popup Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/triggered-popups/post-purchase-popups/create-post-purchase-popup-design openapi-post-purchase-popup-design.json POST /components/v1/offer-design Creates a post purchase popup design. ```bash Create Post Purchase Popup Design theme={"system"} curl -X POST \ 'https://api.appcharge.com/components/v1/offer-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "PopUp", "offerUiSubType": "PostPurchase", "name": "Post Purchase Popup Design", "externalId": "post-purchase-popup-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "title": { "text": "Post purchase offer", "fontColor": "#FFFFFF", "fontSize": 20, "fontWeight": "medium" } }' ``` ```json Create Post Purchase Popup Design theme={"system"} { "id": "6a09aa1018b751228b09faed", "offerUiType": "PopUp", "offerUiSubType": "PostPurchase", "name": "Post Purchase Popup Design", "externalId": "post-purchase-popup-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "title": { "text": "Post purchase offer", "fontColor": "#FFFFFF", "fontSize": 20, "fontWeight": "medium" } } ``` # Delete Post Purchase Popup Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/triggered-popups/post-purchase-popups/delete-post-purchase-popup-design openapi-post-purchase-popup-design.json DELETE /components/v1/offer-design/{externalId} Deletes a post purchase popup design. **Note:** You can't delete an offer design while it's in use by an offer. ```bash Delete Post Purchase Popup Design theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/components/v1/offer-design/post-purchase-popup-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Post Purchase Popup Design theme={"system"} { "id": "6a09aa1018b751228b09faed", "offerUiType": "PopUp", "offerUiSubType": "PostPurchase", "name": "Post Purchase Popup Design", "externalId": "post-purchase-popup-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background.png", "title": { "text": "Post purchase offer", "fontColor": "#FFFFFF", "fontSize": 20, "fontWeight": "medium" } } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/triggered-popups/post-purchase-popups/introduction The Post Purchase Popup Designs API allows you to create and manage designs for popup offers triggered after a player completes a purchase. With this API, you can: * [Create a post purchase popup design](./create-post-purchase-popup-design). * [Update a post purchase popup design](./update-post-purchase-popup-design). * [Delete a post purchase popup design](./delete-post-purchase-popup-design). # Update Post Purchase Popup Design Source: https://docs.appcharge.com/api-reference/webstore/offer-components/offer-designs/triggered-popups/post-purchase-popups/update-post-purchase-popup-design openapi-post-purchase-popup-design.json PUT /components/v1/offer-design/{externalId} Updates a post purchase popup design. ```bash Update Post Purchase Popup Design theme={"system"} curl -X PUT \ 'https://api.appcharge.com/components/v1/offer-design/post-purchase-popup-design' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "offerUiType": "PopUp", "offerUiSubType": "PostPurchase", "name": "Post Purchase Popup Design Updated", "externalId": "post-purchase-popup-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background-v2.png", "title": { "text": "Post purchase offer", "fontColor": "#FFFFFF", "fontSize": 20, "fontWeight": "medium" } }' ``` ```json Update Post Purchase Popup Design theme={"system"} { "id": "6a09aa1018b751228b09faed", "offerUiType": "PopUp", "offerUiSubType": "PostPurchase", "name": "Post Purchase Popup Design Updated", "externalId": "post-purchase-popup-design", "backgroundImageUrl": "https://media.appcharge.com/media/65cb7861ec8924a6b69a0f59/background-v2.png", "title": { "text": "Post purchase offer", "fontColor": "#FFFFFF", "fontSize": 20, "fontWeight": "medium" } } ``` # Create Product Source: https://docs.appcharge.com/api-reference/webstore/offer-components/products/create-product openapi-products-api.json POST /components/v1/product Creates a product. ```bash Create Product with Asset ID theme={"system"} curl -X POST \ 'https://api.appcharge.com/components/v1/product' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "name": "Gold Coins Pack", "displayName": "Gold Coins", "publisherProductId": "gold_coins_100", "type": "Quantity", "description": "A pack of 100 gold coins.", "prefix": "Get", "suffix": "coins", "textFontColorHex": "#f5c518", "productImageId": "507f1f77bcf86cd799439011" }' ``` ```bash Create Product with Image URL theme={"system"} curl -X POST \ 'https://api.appcharge.com/components/v1/product' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "name": "Gold Coins Pack", "displayName": "Gold Coins", "publisherProductId": "gold_coins_100", "type": "Quantity", "description": "A pack of 100 gold coins.", "prefix": "Get", "suffix": "coins", "textFontColorHex": "#f5c518", "productImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5" }' ``` ```json Create Product with Asset ID theme={"system"} { "id": "507f1f77bcf86cd799439015", "name": "Gold Coins Pack", "displayName": "Gold Coins", "publisherProductId": "gold_coins_100", "type": "Quantity", "description": "A pack of 100 gold coins.", "prefix": "Get", "suffix": "coins", "textFontColorHex": "#f5c518", "productImageId": "507f1f77bcf86cd799439011", "productImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5", "productPrefixImageUrl": "https://media.appcharge.com/product-prefix1.png" } ``` ```json Create Product with Image URL theme={"system"} { "id": "507f1f77bcf86cd799439015", "name": "Gold Coins Pack", "displayName": "Gold Coins", "publisherProductId": "gold_coins_100", "type": "Quantity", "description": "A pack of 100 gold coins.", "prefix": "Get", "suffix": "coins", "textFontColorHex": "#f5c518", "productImageId": "507f1f77bcf86cd799439023", "productImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5", "productPrefixImageUrl": "https://media.appcharge.com/product-prefix1.png" } ``` # Delete Product Source: https://docs.appcharge.com/api-reference/webstore/offer-components/products/delete-product openapi-products-api.json DELETE /components/v1/product/{externalId} Deletes a product. ```bash Delete Product theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/components/v1/product/gold_coins_100' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Product theme={"system"} { "id": "507f1f77bcf86cd799439015", "name": "Gold Coins Pack", "displayName": "Gold Coins", "publisherProductId": "gold_coins_100", "type": "Quantity", "description": "A pack of 100 gold coins.", "prefix": "Get", "suffix": "coins", "textFontColorHex": "#f5c518", "productImageId": "507f1f77bcf86cd799439011", "productImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5", "productPrefixImageUrl": "https://media.appcharge.com/product-prefix1.png" } ``` # Get All Products Source: https://docs.appcharge.com/api-reference/webstore/offer-components/products/get-all-products openapi-products-api.json GET /components/v1/product Retrieves a list of all products. ```bash Get All Products theme={"system"} curl -X GET \ 'https://api.appcharge.com/components/v1/product' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' ``` ```json Get All Products theme={"system"} [ { "id": "507f1f77bcf86cd799439015", "name": "Gold Coins Pack", "displayName": "Gold Coins", "publisherProductId": "gold_coins_100", "type": "Quantity", "description": "A pack of 100 gold coins.", "prefix": "Get", "suffix": "coins", "textFontColorHex": "#f5c518", "productImageId": "507f1f77bcf86cd799439011", "productImageUrl": "https://media.appcharge.com/product1.png", "productPrefixImageUrl": "https://media.appcharge.com/product-prefix1.png" }, { "id": "507f1f77bcf86cd799439016", "name": "Premium Product", "displayName": "Premium Product", "publisherProductId": "premium_product", "type": "Time", "description": "premium product access.", "prefix": "Get", "suffix": "days", "textFontColorHex": "#d4af37", "productImageUrl": "https://images.pexels.com/images/product2.png", "productPrefixImageUrl": "https://media.appcharge.com/product-prefix2.png", "productImageExternalUrl": "https://images.pexels.com/images/product2.png" } ] ``` # Get Product Source: https://docs.appcharge.com/api-reference/webstore/offer-components/products/get-product openapi-products-api.json GET /components/v1/product/{externalId} Retrieves the details of a specific product. ```bash Get Product theme={"system"} curl -X GET \ 'https://api.appcharge.com/components/v1/product/gold_coins_100' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' ``` ```json Get Product theme={"system"} { "id": "507f1f77bcf86cd799439015", "name": "Gold Coins Pack", "displayName": "Gold Coins", "publisherProductId": "gold_coins_100", "type": "Quantity", "description": "A pack of 100 gold coins.", "prefix": "Get", "suffix": "coins", "textFontColorHex": "#f5c518", "productImageId": "507f1f77bcf86cd799439011", "productImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5", "productPrefixImageUrl": "https://media.appcharge.com/product-prefix1.png" } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offer-components/products/introduction The Products API allows you to define virtual items for purchase in your web store. Products can be quantity-based or time-based. You can set names, images, and display properties to control how each one appears in an offer. Learn more about [products](/../../guides/webstore/design/add-a-product). With the Products API, you can: * [Create a product](./create-product). * [Retrieve](./get-product) a specific product. * [Retrieve a list of all products](./get-all-products). * [Update a product](./update-product). * [Delete a product](./delete-product). # Update Product Source: https://docs.appcharge.com/api-reference/webstore/offer-components/products/update-product openapi-products-api.json PUT /components/v1/product/{externalId} Updates a product. ```bash Update Product with Asset ID theme={"system"} curl -X PUT \ 'https://api.appcharge.com/components/v1/product/gold_coins_100' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "name": "Premium Gold Coins Pack", "displayName": "Premium Gold Coins", "publisherProductId": "gold_coins_100", "type": "Quantity", "textFontColorHex": "#d4af37", "productImageId": "507f1f77bcf86cd799439011" }' ``` ```bash Update Product with Image URL theme={"system"} curl -X PUT \ 'https://api.appcharge.com/components/v1/product/gold_coins_100' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ --data '{ "name": "Premium Gold Coins Pack", "displayName": "Premium Gold Coins", "publisherProductId": "gold_coins_100", "type": "Quantity", "textFontColorHex": "#d4af37", "productImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5" }' ``` ```json Update Product with Asset ID theme={"system"} { "id": "507f1f77bcf86cd799439015", "name": "Premium Gold Coins Pack", "displayName": "Premium Gold Coins", "publisherProductId": "gold_coins_100", "type": "Quantity", "description": "A pack of 100 gold coins.", "prefix": "Get", "suffix": "coins", "textFontColorHex": "#d4af37", "productImageId": "507f1f77bcf86cd799439011", "productImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5", "productPrefixImageUrl": "https://media.appcharge.com/product-prefix1.png" } ``` ```json Update Product with Image URL theme={"system"} { "id": "507f1f77bcf86cd799439015", "name": "Premium Gold Coins Pack", "displayName": "Premium Gold Coins", "publisherProductId": "gold_coins_100", "type": "Quantity", "description": "A pack of 100 gold coins.", "prefix": "Get", "suffix": "coins", "textFontColorHex": "#d4af37", "productImageId": "507f1f77bcf86cd799439023", "productImageUrl": "https://media.appcharge.com/media/69133d595af23405d8e843a5", "productPrefixImageUrl": "https://media.appcharge.com/product-prefix1.png" } ``` # Create Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v1/create-offer POST /offering/offer # Delete Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v1/delete-offer DELETE /offering/offer/{publisherOfferId} # Get Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v1/get-offer POST /offering/offer/get-offers # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offers-v1/introduction The Offers API provides a way to manage special promotions, bundles, and bonuses through a standardized system. *Note: You can read more about the [Offers API](/../../guides/webstore/offers/about-offers) in the Guides section.* Here's a simple overview of what you can do with this API: ## Key Capabilities: 1. **Create New Offers:** * You can create new offers, specifying details like the offer name, description, type (e.g., bundle, special offer), and timing intervals. * Offers can be visually customized with UI elements such as background images and titles. 2. **Update Existing Offers:** * Existing offers can be updated to change their details or to reflect new marketing strategies. * Adjustments can be made to the offer's type, description, availability, and associated UI elements. 3. **Dynamic User Interface Integration:** * The API supports dynamic UI elements, making it easy to update the look and feel of offers without hardcoding these elements into your app. * Elements such as whether the offer is active, cooldown periods between uses, and player segmentation for targeted offers are managed dynamically. 4. **Player Segmentation:** * Offers can be targeted to specific player segments, like new users or high spenders, ensuring that promotions are relevant to the right audience. 5. **Product Sequences and Availability:** * For rolling offers or promotions featuring multiple products, you can specify the sequence of products and their availability. * This helps in managing complex offers that involve multiple steps or stages. 6. **Metadata and Security:** * Each request and response includes important metadata, like publisher tokens and offer IDs, to ensure secure and accurate data handling. ## Practical Use Cases: * **Promotions:** Create time-limited special offers that appear as promotional tiles or in a gallery format within your app. * **Bundles:** Offer product bundles that provide added value to the players, such as buy-one-get-one-free deals. * **Targeted Marketing:** Use player segmentation to tailor offers to specific groups, increasing the relevance and attractiveness of your promotions. # Create Daily Bonus Popup Source: https://docs.appcharge.com/api-reference/webstore/offers-v1/popups/create-daily-bonus openapi-daily-bonus_v1.json POST /offering/offer/popup # Create Post Purchase Popup Source: https://docs.appcharge.com/api-reference/webstore/offers-v1/popups/create-post-purchase-popup openapi-post-purchase-popup_v1.json POST /offering/offer/popup # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offers-v1/popups/introduction The Popup API enables you to create and manage various types of in-app popups, including daily bonuses and post-purchase engagements. This tool is essential for enhancing user interactions and increasing overall app monetization. *Note: You can read more about [Daily Bonuses](/../../guides/webstore/offers/popups/create-a-daily-bonus) and [Post-Purchase Popups](/../../guides/webstore/offers/popups/create-a-post-purchase-popup) in the Guides section.* ### Types of Popups * **Daily Bonuses:** Create and manage popups that reward users for daily engagement. * **Post-Purchase Popups:** Set up popups that appear after a user completes a purchase, which can be used for additional promotions or information. ### How to Use Popups For detailed instructions on creating and managing each type of popup, please refer to our guides: * [Daily Bonus Documentation](/../../guides/webstore/offers/popups/create-a-daily-bonus) * [Post-Purchase Documentation](/../../guides/webstore/offers/popups/create-a-post-purchase-popup) # Update Popup Source: https://docs.appcharge.com/api-reference/webstore/offers-v1/popups/update-popups openapi-update-popups_v1.json PUT /offering/offer/popup/{offerSKU} # Create Rolling Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v1/rolling-offers/create-rolling-offer POST /offering/rolling-offer # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offers-v1/rolling-offers/introduction The Rolling Offer API enables you to create and update rolling offers in your web store. A rolling offer is a dynamic promotional tool that allows players to progressively unlock offers, encouraging repeat interactions and increasing revenue. > **Note:** You can learn more about [Rolling Offers](/../../guides/webstore/offers/rolling-offers/about-rolling-offers) in the guides section. ### With this API, you can: * **Create New Rolling Offers:** Define offers with multiple sequential sub-offers, each containing specific products, pricing, and availability. * **Update Existing Rolling Offers:** Modify attributes of current rolling offers, such as adjusting product sequences, pricing, and scheduling. # Update Rolling Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v1/rolling-offers/update-rolling-offer PUT /offering/rolling-offer/{rollingOfferSKU} # Update Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v1/update-offer PUT /offering/offer/{offerSKU} # Create Bundle Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/bundles/create-bundle openapi-bundle.json POST /v2/offer Creates a bundle. ```bash Create Bundle theme={"system"} curl -X POST \ 'https://api.appcharge.com/v2/offer' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "publisherOfferId": "bundle-offer-1", "name": "My Bundle", "type": "Bundle", "active": true, "segments": [ "New User" ], "publisherTabId": "tab-1", "productsSequence": [ { "index": 1, "products": [ { "priority": "Sub", "publisherProductId": "123", "quantity": "500", } ] "priceInUsdCents": 980, "progressBarPoints": [ { "barId": "69525aae0cbfad2a5507cd54", "points": 10 } ], } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "displayName": "My Bundle", "description": "This is my bundle description.", "offerUiId": "ac77ff889b", "offerExternalUiId": "ac22377ff889cc", "badges": [ { "publisherBadgeId": "22ac77ff889b" } ] }' ``` ```json Create Bundle theme={"system"} { "publisherId": "35nb7861ec9924a6b69a0fe59", "offerId": "226cff96123a8717", "publisherOfferId": "bundle-offer-1", "name": "My Bundle", "displayName": "My Bundle", "description": "This is my bundle description.", "type": "Bundle", "active": true, "segments": [ "New User" ], "publisherTabId": "tab-1", "offerUi": { "offerUiId": "27e7fb3663e1bfbbf340ffff", "active": true, "offerUiType": "Bundle", "name": "BundOff273", "description": "description", "backgroundImage": "https://media.appcharge.com/media/65cb7182__4dc30c81-e4aa-40e8-9033-84cb05721bd0", "borderColor": { "colorOne": "#ffffff", "colorTwo": "", "direction": "" }, "borderWidth": 2, "externalId": "BundOff273" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "123", "name": "Coins", "textFontColorHex": "#FFFFFF", "type": "Quantity", "prefix": "", "suffix": "", "priority": "Sub", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/45cb7861ec8924a6b69a0f59/download.jpeg" }, { "type": "productPrefix", "url": "" } ], "createdAt": "2024-02-14T10:08:17.061Z", "updatedAt": "2024-09-27T13:41:55.775Z", "displayName": "coins", "productId": "65cc91114cf653a9cc2dce2c" }, "publisherProductId": "123", "quantity": 500, "priority": "Main" } ], "priceInUsdCents": 980, "progressBarPoints": [ { "barId": "69525aae0cbfad2a5507cd54", "points": 10 } ], "badges": [], "id": "68b4092c7a895e559a3ac8d9" } ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ``` # Delete Bundle Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/bundles/delete-bundle openapi-bundle.json DELETE /v2/offer/{publisherOfferId} Deletes a bundle. ```bash Delete Bundle theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/v2/offer/bundle-offer-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Bundle theme={"system"} { "publisherId": "35nb7861ec9924a6b69a0fe59", "offerId": "226cff96123a8717", "publisherOfferId": "bundle-offer-1", "name": "My Bundle", "displayName": "My Bundle", "description": "This is my bundle description.", "type": "Bundle", "active": true, "segments": [ "New User" ], "publisherTabId": "tab-1", "offerUi": { "offerUiId": "27e7fb3663e1bfbbf340ffff", "active": true, "offerUiType": "Bundle", "name": "BundOff273", "description": "description", "backgroundImage": "https://media.appcharge.com/media/65cb7182__4dc30c81-e4aa-40e8-9033-84cb05721bd0", "borderColor": { "colorOne": "#ffffff", "colorTwo": "", "direction": "" }, "borderWidth": 2, "externalId": "BundOff273" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "123", "name": "Coins", "textFontColorHex": "#FFFFFF", "type": "Quantity", "prefix": "", "suffix": "", "priority": "Sub", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/45cb7861ec8924a6b69a0f59/download.jpeg" }, { "type": "productPrefix", "url": "" } ], "createdAt": "2024-02-14T10:08:17.061Z", "updatedAt": "2024-09-27T13:41:55.775Z", "displayName": "coins", "productId": "65cc91114cf653a9cc2dce2c" }, "publisherProductId": "123", "quantity": 500, "priority": "Main" } ], "priceInUsdCents": 980, "progressBarPoints": [ { "barId": "69525aae0cbfad2a5507cd54", "points": 10 } ], "badges": [], "id": "68b4092c7a895e559a3ac8d9" } ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ``` # Get Bundle Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/bundles/get-bundle openapi-bundle.json GET /v2/offer Retrieves one or more bundles. ```bash Get Bundle theme={"system"} curl -X GET \ 'https://api.appcharge.com/v2/offer?publisherOfferIds=bundle-offer-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Get Bundle theme={"system"} { "totalCount": 1, "offers": [ { "publisherId": "35nb7861ec9924a6b69a0fe59", "offerId": "226cff96123a8717", "publisherOfferId": "bundle-offer-1", "name": "My Bundle", "displayName": "My Bundle", "description": "This is my bundle description.", "type": "Bundle", "active": true, "segments": [ "New User" ], "publisherTabId": "tab-1", "offerUi": { "offerUiId": "27e7fb3663e1bfbbf340ffff", "active": true, "offerUiType": "Bundle", "name": "BundOff273", "description": "description", "backgroundImage": "https://media.appcharge.com/media/65cb7182__4dc30c81-e4aa-40e8-9033-84cb05721bd0", "borderColor": { "colorOne": "#ffffff", "colorTwo": "", "direction": "" }, "borderWidth": 2, "externalId": "BundOff273" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "123", "name": "Coins", "textFontColorHex": "#FFFFFF", "type": "Quantity", "prefix": "", "suffix": "", "priority": "Sub", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/45cb7861ec8924a6b69a0f59/download.jpeg" }, { "type": "productPrefix", "url": "" } ], "createdAt": "2024-02-14T10:08:17.061Z", "updatedAt": "2024-09-27T13:41:55.775Z", "displayName": "coins", "productId": "65cc91114cf653a9cc2dce2c" }, "publisherProductId": "123", "quantity": 500, "priority": "Main" } ], "priceInUsdCents": 980, "progressBarPoints": [ { "barId": "69525aae0cbfad2a5507cd54", "points": 10 } ], "badges": [], "id": "68b4092c7a895e559a3ac8d9" } ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ] } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/bundles/introduction The Bundles API allows you to create and manage product bundles in your web store. Bundles are offers that include multiple products sold at a discounted price or with additional value. Note that bundles can't be scheduled in advance, and remain active until they are set as inactive. With the Bundles API, you can: * [Create a new bundle](./create-bundle). * [Update an existing bundle](./update-bundle). * [Retrieve one or more bundles](./get-bundle). * [Retrieve all bundles](../get-offers). * [Delete a bundle](./delete-bundle). # Update Bundle Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/bundles/update-bundle PUT /v2/offer/${publisherOfferId} Updates a bundle. ```bash Update Bundle theme={"system"} curl -X PUT \ 'https://api.appcharge.com/v2/offer/bundle-offer-1' \ -H 'x-publisher-token: ' \ -H 'Content-Type: application/json' \ -d '{ "name": "My New Bundle Name", "type": "Bundle", "active": true, "segments": [ "New User" ], "productsSequence": [ { "index": 1, "products": [ { "priority": "Sub", "publisherProductId": "123", "quantity": "500", } ] "priceInUsdCents": 980 } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "displayName": "My Bundle", "description": "This is my bundle description.", "offerUiId": "ac77ff889b", "offerExternalUiId": "ac22377ff889cc", "badges": [ { "publisherBadgeId": "22ac77ff889b" } ] }' ``` ```json Update Bundle theme={"system"} { "publisherId": "35nb7861ec9924a6b69a0fe59", "offerId": "226cff96123a8717", "publisherOfferId": "bundle-offer-1", "name": "My New Bundle Name", "displayName": "My Bundle", "description": "This is my bundle description.", "type": "Bundle", "active": true, "segments": [ "New User" ], "publisherTabId": "tab-1", "offerUi": { "offerUiId": "27e7fb3663e1bfbbf340ffff", "active": true, "offerUiType": "Bundle", "name": "BundOff273", "description": "description", "backgroundImage": "https://media.appcharge.com/media/65cb7182__4dc30c81-e4aa-40e8-9033-84cb05721bd0", "borderColor": { "colorOne": "#ffffff", "colorTwo": "", "direction": "" }, "borderWidth": 2, "externalId": "BundOff273" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "123", "name": "Coins", "textFontColorHex": "#FFFFFF", "type": "Quantity", "prefix": "", "suffix": "", "priority": "Sub", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/45cb7861ec8924a6b69a0f59/download.jpeg" }, { "type": "productPrefix", "url": "" } ], "createdAt": "2024-02-14T10:08:17.061Z", "updatedAt": "2024-09-27T13:41:55.775Z", "displayName": "coins", "productId": "65cc91114cf653a9cc2dce2c" }, "publisherProductId": "123", "quantity": 500, "priority": "Main" } ], "priceInUsdCents": 980, "badges": [], "id": "68b4092c7a895e559a3ac8d9" } ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-06-11T20:00:33.528Z" } ``` # Create Checkout Link Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/checkout-link-offers/create-checkout-link-offer openapi-checkout-links.json POST /v2/offer Creates a checkout link offer. ```bash Create Checkout Link Offer Request theme={"system"} curl -X POST \ 'https://api.appcharge.com/v2/offer' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "publisherOfferId": "checkout-link-1", "name": "My Checkout Link Offer", "displayName": "My Checkout Link Offer", "type": "CheckoutLink", "active": true, "productsSequence": [ { "index": 1, "playerAvailability": 12, "products": [ { "priority": "Sub", "publisherProductId": "6cb43621ccf1", "quantity": "100", } ], "priceInUsdCents": 1000 } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "description": "This is my checkout link offer description.", "offerUiId": "9ac77ff889b", "offerExternalUiId": "9ac22377ff889cc", "segments": [ "New User" ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ] }' ``` ```json Create Checkout Link Offer Response theme={"system"} { "offerId": "867f5b309118", "publisherId": "35nb7861ec9924a6b69a0fe59", "publisherOfferId": "checkout-link-1", "name": "My Checkout Link Offer", "displayName": "My Checkout Link Offer", "type": "CheckoutLink", "active": true, "segments": [ "New User" ], "productsSequence": [ { "index": 1, "playerAvailability": 12, "products": [ { "priority": "Sub", "publisherProductId": "6cb43621ccf1", "quantity": "100", } ], "priceInUsdCents": 1000, "playerClickedTtl": 300 } ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "description": "This is my checkout link offer description.", "deeplinkUrl": "https://best-game.appcharge.com/login/campaign/YL2bAHqnuSMBhXIwMJbEM", "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ``` # Delete Checkout Link Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/checkout-link-offers/delete-checkout-link-offer openapi-checkout-links.json DELETE /v2/offer/{publisherOfferId} Deletes a checkout link offer. ```bash Delete Checkout Link Offer theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/v2/offer/checkout-link-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Checkout Link Offer theme={"system"} { "offerId": "867f5b309118", "publisherId": "35nb7861ec9924a6b69a0fe59", "publisherOfferId": "checkout-link-1", "name": "My Checkout Link Offer", "displayName": "My Checkout Link Offer", "type": "CheckoutLink", "active": true, "segments": [ "New User" ], "productsSequence": [ { "index": 1, "playerAvailability": 12, "products": [ { "priority": "Sub", "publisherProductId": "6cb43621ccf1", "quantity": "100" } ], "priceInUsdCents": 1000, "playerClickedTtl": 300 } ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "description": "This is my checkout link offer description.", "deeplinkUrl": "https://best-game.appcharge.com/login/campaign/YL2bAHqnuSMBhXIwMJbEM", "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ``` # Get Checkout Link Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/checkout-link-offers/get-checkout-link-offer openapi-checkout-links.json GET /v2/offer Retrieves one or more checkout link offers. ```bash Get Checkout Link Offer theme={"system"} curl -X GET \ 'https://api.appcharge.com/v2/offer?publisherOfferIds=checkout-link-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Get Checkout Link Offer theme={"system"} { "totalCount": 1, "offers": [ { "offerId": "867f5b309118", "publisherId": "35nb7861ec9924a6b69a0fe59", "publisherOfferId": "checkout-link-1", "name": "My Checkout Link Offer", "displayName": "My Checkout Link Offer", "type": "CheckoutLink", "active": true, "segments": [ "New User" ], "productsSequence": [ { "index": 1, "playerAvailability": 12, "products": [ { "priority": "Sub", "publisherProductId": "6cb43621ccf1", "quantity": "100" } ], "priceInUsdCents": 1000, "playerClickedTtl": 300 } ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "description": "This is my checkout link offer description.", "deeplinkUrl": "https://best-game.appcharge.com/login/campaign/YL2bAHqnuSMBhXIwMJbEM", "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ] } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/checkout-link-offers/introduction The Checkout Link Offers API allows you to create and manage checkout link offers that can be shared with players through a deeplink. Distribute the link across any platform, such as social media, direct messages (DMs), or email. When a player clicks the deeplink, they’re taken directly to the checkout, with the offer details already preloaded. You can use the [Personalization API](../../personalization/introduction) to customize the product amount, pricing, and availability, allowing for deeper segmentation strategies. You can schedule offers in advance, control their availability, and set how often each player can purchase them. With the Checkout Link Offers API, you can: * [Create a new checkout link offer](./create-checkout-link-offer). * [Update an existing checkout link offer](./update-checkout-link-offer). * [Retrieve one or more checkout link offers](./get-checkout-link-offer). * [Retrieve all checkout link offers](../get-offers). * [Delete a checkout link offer](./delete-checkout-link-offer). * [Listen for events](../../../events/v2/webstore/offer/offers_loaded) when checkout link offers are loaded and displayed in the web store. Learn more about [Checkout Link Offers](/../../guides/webstore/offers/checkout-link-offers/about-checkout-link-offers). ## Before you begin It's important to note the following points before starting to code: * If you're using the [Personalization API](../../../webstore/personalization/introduction) to send offers to players, make sure to include the checkout link offer in the API payload. Although this offer doesn't appear in the web store, it is still valid and must be explicitly sent to the player through the API. * Before sending the `deeplinkUrl` value to players, you can append UTM attributes to the URL with query params as follows: ```js theme={"system"} https://best-game.appcharge.com/login/campaign/YL2bAHqnu?utmSource=Facebook&utmCampaign=VipCampaign ``` * If you're using the legacy JWT authentication method: * You must [sign the deeplink with a JWT](/../../guides/webstore/offers/checkout-link-offers/use-jwt-method) before distributing it. * You can [listen for events when the Approval Request is displayed and closed](../../../events/v2/webstore/offer/approval_request_displayed). # Update Checkout Link Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/checkout-link-offers/update-checkout-link-offer openapi-checkout-links.json PUT /v2/offer/${publisherOfferId} Updates a checkout link offer. ```bash Update Checkout Link Offer theme={"system"} curl -X PUT \ 'https://api.appcharge.com/v2/offer/checkout-link-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "name": "My Checkout Link Offer", "displayName": "My Checkout Link Offer", "type": "CheckoutLink", "active": true, "productsSequence": [ { "index": 1, "playerAvailability": 12, "products": [ { "priority": "Sub", "publisherProductId": "6cb43621ccf1", "quantity": "100", } ], "priceInUsdCents": 1000 } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "description": "This is my checkout link offer description.", "offerUiId": "9ac77ff889b", "offerExternalUiId": "9ac22377ff889cc", "segments": [ "New User" ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ] }' ``` ```json Update Checkout Link Offer theme={"system"} { "offerId": "867f5b309118", "publisherId": "35nb7861ec9924a6b69a0fe59", "publisherOfferId": "checkout-link-1", "name": "My New Checkout Link Offer Name", "displayName": "My Checkout Link Offer", "type": "CheckoutLink", "active": true, "segments": [ "New User" ], "productsSequence": [ { "index": 1, "playerAvailability": 12, "products": [ { "priority": "Sub", "publisherProductId": "6cb43621ccf1", "quantity": "100", } ], "priceInUsdCents": 1000, "playerClickedTtl": 300 } ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "description": "This is my checkout link offer description.", "deeplinkUrl": "https://best-game.appcharge.com/login/campaign/YL2bAHqnuSMBhXIwMJbEM", "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-06-06T10:00:44.528Z" } ``` # Create Daily Bonus Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/daily-bonuses/create-daily-bonus openapi-daily-bonus.json POST /v2/offer Creates a daily bonus. ```bash Create Daily Bonus theme={"system"} curl -X POST \ 'https://api.appcharge.com/v2/offer' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "publisherOfferId": "daily-bonus-1", "name": "My Daily Bonus", "type": "PopUp", "subType": "DailyBonus", "active": true, "productsSequence": [ { "index": 1, "products": [ { "priority": "Main", "publisherProductId": "TreasureChest", "quantity": 10 } ], "priceInUsdCents": 2000 } ] "productSale": { "type": "percentage", "sale": 10 }, "priceDiscount": { "type": "percentage", "discount": 10 }, "displayName": "My Daily Bonus", "description": "This is my daily bonus description.", "offerUiId": "68b41c4aa1c5b1a284737e9b", "offerExternalUiId": "58b41c4aa1c5b1a284737e9b", "segments": [ "New User" ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ] }' ``` ```json Create Daily Bonus theme={"system"} { "offerId": "223b4cc89711ac", "publisherOfferId": "daily-bonus-1", "name": "My Daily Bonus", "type": "PopUp", "subType": "DailyBonus", "displayName": "My Daily Bonus", "description": "This is my daily bonus description.", "type": "string", "active": true, "segments": [ "New User" ], "offerUi": { "offerUiId": "68b41c4aa1c5b1a284737e9b", "active": true, "offerUiType": "PopUp", "offerUiSubType": "DailyBonus", "name": "popup", "description": "description", "backgroundImage": "https://media.appcharge.com/media/75cb7861ec8924a63338-5790-47c8-a6a0-23cb43db5883", "buttonSuffixImage": "", "buttonSuffixAnimation": "", "specialOffer": { "templateType": "Single", "presentOfferEndTimer": false, "title": "jrwtnip", "fontSize": 620, "fontWeight": "normal", "fontColor": { "colorOne": "#ffffff" }, "subTitle": { "text": "", "fontSize": 16, "fontWeight": "normal", "fontColor": { "colorOne": "#ffffff" } }, "backgroundColor": { "colorOne": "#CACBD4" } }, "borderColor": { "colorOne": "#e70d0d", "colorTwo": "", "direction": "" }, "borderWidth": 10, "externalId": "popup" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "TreasureChest", "name": "Treasure Chest", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/35nb7861ec9924a6b69a0fe59/2208472.png" }, { "type": "productPrefix", "url": "" } ], "displayName": "Treasure Chest" } } ] } ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ], "productSale": { "type": "percentage", "sale": 10 }, "priceDiscount": { "type": "percentage", "discount": 10 }, "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ``` # Delete Daily Bonus Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/daily-bonuses/delete-daily-bonus openapi-daily-bonus.json DELETE /v2/offer/{publisherOfferId} Deletes a daily bonus. ```bash Delete Daily Bonus theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/v2/offer/daily-bonus-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Daily Bonus theme={"system"} { "offerId": "223b4cc89711ac", "publisherOfferId": "daily-bonus-1", "name": "My Daily Bonus", "type": "PopUp", "subType": "DailyBonus", "displayName": "My Daily Bonus", "description": "This is my daily bonus description.", "type": "string", "active": true, "segments": [ "New User" ], "offerUi": { "offerUiId": "68b41c4aa1c5b1a284737e9b", "active": true, "offerUiType": "PopUp", "offerUiSubType": "DailyBonus", "name": "popup", "description": "description", "backgroundImage": "https://media.appcharge.com/media/75cb7861ec8924a63338-5790-47c8-a6a0-23cb43db5883", "buttonSuffixImage": "", "buttonSuffixAnimation": "", "specialOffer": { "templateType": "Single", "presentOfferEndTimer": false, "title": "jrwtnip", "fontSize": 620, "fontWeight": "normal", "fontColor": { "colorOne": "#ffffff" }, "subTitle": { "text": "", "fontSize": 16, "fontWeight": "normal", "fontColor": { "colorOne": "#ffffff" } }, "backgroundColor": { "colorOne": "#CACBD4" } }, "borderColor": { "colorOne": "#e70d0d", "colorTwo": "", "direction": "" }, "borderWidth": 10, "externalId": "popup" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "TreasureChest", "name": "Treasure Chest", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/35nb7861ec9924a6b69a0fe59/2208472.png" }, { "type": "productPrefix", "url": "" } ], "displayName": "Treasure Chest" } } ] } ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ], "productSale": { "type": "percentage", "sale": 10 }, "priceDiscount": { "type": "percentage", "discount": 10 }, "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ``` # Get Daily Bonus Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/daily-bonuses/get-daily-bonus openapi-daily-bonus.json GET /v2/offer Retrieves one or more daily bonuses. ```bash Get Daily Bonus theme={"system"} curl -X GET \ 'https://api.appcharge.com/v2/offer?publisherOfferIds=daily-bonus-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Get Daily Bonus theme={"system"} { "totalCount": 1, "offers": [ { "offerId": "223b4cc89711ac", "publisherOfferId": "daily-bonus-1", "name": "My Daily Bonus", "type": "PopUp", "subType": "DailyBonus", "displayName": "My Daily Bonus", "description": "This is my daily bonus description.", "type": "string", "active": true, "segments": [ "New User" ], "offerUi": { "offerUiId": "68b41c4aa1c5b1a284737e9b", "active": true, "offerUiType": "PopUp", "offerUiSubType": "DailyBonus", "name": "popup", "description": "description", "backgroundImage": "https://media.appcharge.com/media/75cb7861ec8924a63338-5790-47c8-a6a0-23cb43db5883", "buttonSuffixImage": "", "buttonSuffixAnimation": "", "specialOffer": { "templateType": "Single", "presentOfferEndTimer": false, "title": "jrwtnip", "fontSize": 620, "fontWeight": "normal", "fontColor": { "colorOne": "#ffffff" }, "subTitle": { "text": "", "fontSize": 16, "fontWeight": "normal", "fontColor": { "colorOne": "#ffffff" } }, "backgroundColor": { "colorOne": "#CACBD4" } }, "borderColor": { "colorOne": "#e70d0d", "colorTwo": "", "direction": "" }, "borderWidth": 10, "externalId": "popup" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "TreasureChest", "name": "Treasure Chest", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/35nb7861ec9924a6b69a0fe59/2208472.png" }, { "type": "productPrefix", "url": "" } ], "displayName": "Treasure Chest" } } ] } ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ], "productSale": { "type": "percentage", "sale": 10 }, "priceDiscount": { "type": "percentage", "discount": 10 }, "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ] } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/daily-bonuses/introduction The Daily Bonuses API allows you to create and manage daily bonuses in your web store. These rewards appear as popup modals when players open the web store, encouraging them to return regularly. With the Daily Bonuses API, you can: * [Create a new daily bonus](./create-daily-bonus). * [Update an existing daily bonus](./update-daily-bonus). * [Retrieve one or more daily bonuses](./get-daily-bonus). * [Retrieve all daily bonuses](../get-offers). * [Delete a daily bonus](./delete-daily-bonus). # Update Daily Bonus Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/daily-bonuses/update-daily-bonus openapi-daily-bonus.json PUT /v2/offer/${publisherOfferId} Updates a daily bonus. ```bash Update Daily Bonus theme={"system"} curl -X PUT \ 'https://api.appcharge.com/v2/offer/daily-bonus-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "name": "My New Daily Bonus Name", "type": "PopUp", "subType": "DailyBonus", "active": true, "productsSequence": [ { "index": 1, "products": [ { "priority": "Main", "publisherProductId": "TreasureChest", "quantity": 10 } ], "priceInUsdCents": 2000 } ] "productSale": { "type": "percentage", "sale": 10 }, "priceDiscount": { "type": "percentage", "discount": 10 }, "displayName": "My Daily Bonus", "description": "This is my daily bonus description.", "offerUiId": "68b41c4aa1c5b1a284737e9b", "offerExternalUiId": "58b41c4aa1c5b1a284737e9b", "segments": [ "New User" ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ] }' ``` ```json Update Daily Bonus theme={"system"} { "offerId": "223b4cc89711ac", "publisherOfferId": "daily-bonus-1", "name": "My New Daily Bonus Name", "type": "PopUp", "subType": "DailyBonus", "displayName": "My Daily Bonus", "description": "This is my daily bonus description.", "type": "string", "active": true, "segments": [ "New User" ], "offerUi": { "offerUiId": "68b41c4aa1c5b1a284737e9b", "active": true, "offerUiType": "PopUp", "offerUiSubType": "DailyBonus", "name": "popup", "description": "description", "backgroundImage": "https://media.appcharge.com/media/75cb7861ec8924a63338-5790-47c8-a6a0-23cb43db5883", "buttonSuffixImage": "", "buttonSuffixAnimation": "", "specialOffer": { "templateType": "Single", "presentOfferEndTimer": false, "title": "jrwtnip", "fontSize": 620, "fontWeight": "normal", "fontColor": { "colorOne": "#ffffff" }, "subTitle": { "text": "", "fontSize": 16, "fontWeight": "normal", "fontColor": { "colorOne": "#ffffff" } }, "backgroundColor": { "colorOne": "#CACBD4" } }, "borderColor": { "colorOne": "#e70d0d", "colorTwo": "", "direction": "" }, "borderWidth": 10, "externalId": "popup" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "TreasureChest", "name": "Treasure Chest", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/35nb7861ec9924a6b69a0fe59/2208472.png" }, { "type": "productPrefix", "url": "" } ], "displayName": "Treasure Chest" } } ] } ], "badges": [ { "publisherBadgeId": "22ac77ff889b" } ], "productSale": { "type": "percentage", "sale": 10 }, "priceDiscount": { "type": "percentage", "discount": 10 }, "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-06-06T10:00:44.528Z" } ``` # Get All Offers Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/get-offers openapi-offers-all.json GET /v2/offer Retrieves a list of offers based on the specified query parameters. ```bash Get All Offers theme={"system"} curl -X GET \ 'https://api.appcharge.com/v2/offer?publisherOfferIds=post-purchase-1,rolling-offer-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Get All Offers theme={"system"} { "totalCount": 2, "offers": [ { "publisherId": "35nb7861ec9924a6b69a0fe59", "publisherOfferId": "post-purchase-1", "name": "Purchase Reward Offer", "displayName": "Purchase Reward Offer", "description": "Post purchase offer for VIP players.", "type": "PopUp", "subType": "PostPurchase", "active": true, "segments": [], "offerUi": { "offerUiId": "68b41c5aa1c5b1a284737e9b", "active": true, "offerUiType": "PopUp", "name": "popup", "description": "description", "backgroundImage": "https://media.appcharge.com/media/35nb7861ec9924a6b69a0fe59/2755379465856__fa883338-5790-47c8-a6a0-23cb43db58844", "externalId": "popup" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "TreasureChest", "name": "Treasure Chest", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/35nb7861ec9924a6b69a0fe59/2208472.png" }, { "type": "productPrefix", "url": "" } ], "displayName": "Treasure Chest" } } ] } ], "priority": 1, "showAfter": "purchase", "triggers": [ { "type": "event", "eventName": "purchase", "every": 1, "rules": [] } ], "createdAt": "2025-09-01T14:16:09.499Z", "updatedAt": "2025-09-01T14:16:09.499Z", "offerId": "68b5aaa9b73fceb9ffc26f9b" }, { "publisherId": "35nb7861ec9924a6b69a0fe59", "offerId": "726cff96123a8717", "publisherOfferId": "rolling-offer-1", "name": "My Rolling Offer", "type": "RollingOffer", "active": true, "displayName": "My Rolling Offer", "description": "This is my rolling offer description.", "segments": [ "New User" ], "offerUi": null, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "613", "name": "Sword", "textFontColorHex": "#f60404", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/25cb7861ec8924a6b69a0f59/408472.png" }, { "type": "productPrefix", "url": "" } ], "createdAt": "2024-03-01T10:14:34.142Z", "updatedAt": "2025-02-05T13:20:50.759Z", "displayName": "Sword", "productId": "25e1aa8a7ef37e0d94b16fdf" } ], "priceInUsdCents": 5000 }, { "index": 2, "products": [ { "product": { "publisherProductId": "614", "name": "Boost", "textFontColorHex": "#bfc6e8", "type": "Quantity", "prefix": "+", "suffix": "🎉", "priority": "Sub", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/25cb7861ec8924a6b69a0f59/1730204644395__99c7d8e4-4658-49db-ac4f-501ab93fee9a" }, { "type": "productPrefix", "url": "" } ], "displayName": "Boost", "createdAt": "2024-10-29T12:24:23.083Z", "updatedAt": "2025-01-16T09:38:15.446Z", "productId": "6720d3f7aaca102ce5fb0ce2" } } ], "priceInUsdCents": 3000 } ], "priority": 1, "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-06-22T12:05:00.000Z", "endTime": "2025-06-22T12:10:00.000Z", "notes": "", "id": "68078610fb23b166fb160469" } ] }, "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ] } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/introduction The Offers V2 API allows you to create and manage digital product offers in your web store. This suite of APIs provides a variety of offer types, including exclusive bundles, rolling offers, and time sensitive promotions. You can tailor these offers to support various monetization strategies and maximize player engagement. Learn more about the [Offers](/../../guides/webstore/offers/about-offers) feature. The Offers V2 API includes the following: * [Bundles API](./bundles/introduction): Set up bundles that offer discounts on multiple products. * [Special Offers API](./special-offers/introduction): Schedule and manage time limited special offers for promotions. * [Rolling Offers API](./rolling-offers/introduction): Create rolling offers that unlock new deals dynamically. * [Progress Bars API](./progress-bars/introduction): Create progress bars that encourage players to purchase additional offers. * [Daily Bonuses API](./daily-bonuses/introduction): Design daily bonus popups to keep players returning. * [Reward Calendars API](./reward-calendars/introduction): Create reward calendars that encourage players to return for consecutive daily rewards. * [Triggered Popups API](./triggered-popups/introduction): Present targeted popup offers based on player actions or web store refreshes. * [Post Purchase Popups API](./triggered-popups/post-purchase-popups/introduction): Promote additional sales through post purchase popups. * [Store Refresh Popups API](./triggered-popups/store-refresh-popups/introduction): Present offers when the web store refreshes. * [Checkout Link Offers API](./checkout-link-offers/introduction): Send an offer via a deeplink to players through a broadcast distributor. With this API, you can also: * [Retrieve all offers](./get-offers) to monitor and optimize performance. * [Listen for events](../../events/v2/webstore/offer/offers_loaded) when offers are loaded and displayed in the web store. ## Before you begin It’s important to note the following point before starting to code: * Before using this API to create an offer, create the offer design using the [Offer Designs API](../offer-components/offer-designs/introduction). Checkout Link Offers don't require an offer design. # Create Progress Bar Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/progress-bars/create-progress-bar openapi-progress-bar.json POST /v2/offer Creates a Progress Bar offer. ```bash Create Classic Progress Bar theme={"system"} curl -X POST \ 'https://api.appcharge.com/v2/offer' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "publisherOfferId": "progressBar-single-1", "name": "My Classic Progress Bar", "type": "ProgressBar", "active": true, "offerExternalUiId": "progress-bar-design-single", "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "priority": "Main", "quantity": 300 } ], "priceInUsdCents": 0, "barSize": 10 }, { "index": 2, "products": [ { "publisherProductId": "coins", "priority": "Main", "quantity": 500 } ], "priceInUsdCents": 0, "barSize": 20 } ], "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-11-01T12:05:00.000Z", "endTime": "2025-11-22T12:10:00.000Z", "notes": "Holiday promotion period." } ] }, "displayName": "My Classic Progress Bar", "description": "A progress bar with sequential missions.", "segments": [ "New User", "VIP Player" ] }' ``` ```bash Create Milestone Progress Bar theme={"system"} curl -X POST \ 'https://api.appcharge.com/v2/offer' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "publisherOfferId": "progressBar-milestones-1", "name": "My Milestone Progress Bar", "type": "ProgressBar", "active": true, "offerExternalUiId": "progress-bar-design-milestones", "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "priority": "Main", "quantity": 300 }, { "publisherProductId": "gems", "priority": "Sub", "quantity": 50 } ], "priceInUsdCents": 0, "barSize": 10 }, { "index": 2, "products": [ { "publisherProductId": "coins", "priority": "Main", "quantity": 500 }, { "publisherProductId": "gems", "priority": "Sub", "quantity": 100 } ], "priceInUsdCents": 0, "barSize": 20 }, { "index": 3, "products": [ { "publisherProductId": "coins", "priority": "Main", "quantity": 1000 }, { "publisherProductId": "gems", "priority": "Sub", "quantity": 250 }, { "publisherProductId": "energy", "priority": "Sub", "quantity": 100 } ], "priceInUsdCents": 0, "barSize": 30 } ], "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-11-01T12:05:00.000Z", "endTime": "2025-11-22T12:10:00.000Z", "notes": "Holiday promotion period." } ] }, "displayName": "My Milestone Progress Bar", "description": "A progress bar with all milestones visible at once.", "segments": [ "New User", "VIP Player" ] }' ``` ```json Create Classic Progress Bar theme={"system"} { "offerId": "67890abcdef1234567890123", "active": true, "description": "A progress bar with sequential missions.", "displayName": "My Classic Progress Bar", "name": "My Classic Progress Bar", "type": "ProgressBar", "offerUi": { "id": "67890abcdef1234567890124", "offerUiType": "ProgressBar", "name": "Classic Progress Bar Design", "description": "Progress Bar UI design template", "backgroundImageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/background-image.png", "title": { "text": "Mission impossible!", "fontColor": "#FFD700", "fontSize": 10, "fontWeight": "bold" }, "subtitle": { "text": "To infinity and beyond!", "fontColor": "#FFD700", "fontSize": 8, "fontWeight": "normal" }, "progressBar": { "barFillColor": { "colorOne": "#FFD450", "colorTwo": "#EDB923", "gradientDirection": "to bottom" }, "barRadius": 12, "accumulatedItem": { "imageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/item.jpeg", "ribbonImageUrl": "https://plus.unsplash.com/premium_photo-1681400545953-0ba00cfa7926?q=80&w=880&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" }, "backgroundOpacity": 80, "frameRadius": 12 }, "borderColor": { "colorOne": "#DBBD9C", "colorTwo": "#DBBD9C", "gradientDirection": "to right" }, "backgroundColor": { "colorOne": "#DABA98", "colorTwo": "#FDFCF9", "gradientDirection": "to right" }, "borderWidth": 3, "externalId": "progress-bar-design-single" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "coins", "name": "coins", "textFontColorHex": "#cb1010", "type": "Quantity", "prefix": "+", "suffix": "", "priority": "Main", "images": [ { "type": "product", "url": "https://media-dev.appcharge.com/media/63e53f149e43bf44513e15c3/asset.png" } ], "createdAt": "2024-01-15T10:30:00.000Z", "updatedAt": "2024-11-20T14:22:00.000Z", "displayName": "Coins", "description": "In-game currency used for purchases.", "productId": "67890abcdef1234567890125" }, "publisherProductId": "coins", "quantity": 300, "priority": "Main", "quantityDisplay": "+ 300" } ], "priceInUsdCents": 0, "barSize": 10, "id": "67890abcdef1234567890126" }, { "index": 2, "products": [ { "product": { "publisherProductId": "coins", "name": "coins", "textFontColorHex": "#cb1010", "type": "Quantity", "prefix": "+", "suffix": "", "priority": "Main", "images": [ { "type": "product", "url": "https://media-dev.appcharge.com/media/63e53f149e43bf44513e15c3/asset.png" } ], "createdAt": "2024-01-15T10:30:00.000Z", "updatedAt": "2024-11-20T14:22:00.000Z", "displayName": "Coins", "description": "In-game currency used for purchases.", "productId": "67890abcdef1234567890125" }, "publisherProductId": "coins", "quantity": 500, "priority": "Main", "quantityDisplay": "+ 500" } ], "priceInUsdCents": 0, "barSize": 20, "id": "67890abcdef1234567890127" } ], "publisherId": "6555b69c02ee8eca00465694", "publisherOfferId": "progressBar-single-1", "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-11-01T12:05:00.000Z", "endTime": "2025-11-22T12:10:00.000Z", "notes": "Holiday promotion period.", "id": "67890abcdef1234567890128" } ] }, "segments": [ "New User", "VIP Player" ], "createdAt": "2024-11-15T09:30:00.000Z", "updatedAt": "2024-11-15T09:30:00.000Z" } ``` ```json Create Milestone Progress Bar theme={"system"} { "offerId": "67890abcdef1234567890200", "active": true, "description": "A progress bar with all milestones visible at once.", "displayName": "My Milestone Progress Bar", "name": "My Milestone Progress Bar", "type": "ProgressBar", "offerUi": { "id": "67890abcdef1234567890201", "offerUiType": "ProgressBar", "name": "Milestone Progress Bar Design", "description": "Milestone Progress Bar UI design template", "backgroundImageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/background-image.png", "title": { "text": "Reach Every Milestone", "fontColor": "#FFD700", "fontSize": 10, "fontWeight": "bold" }, "subtitle": { "text": "Collect rewards along the way", "fontColor": "#FFD700", "fontSize": 8, "fontWeight": "normal" }, "progressBar": { "barFillColor": { "colorOne": "#FFD450", "colorTwo": "#EDB923", "gradientDirection": "to bottom" }, "barRadius": 12, "accumulatedItem": { "imageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/item.jpeg", "ribbonImageUrl": "https://plus.unsplash.com/premium_photo-1681400545953-0ba00cfa7926?q=80&w=880&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" }, "headerImageUrl": "https://plus.unsplash.com/premium_photo-1785080652560-f334e6ea704c?q=80&w=687&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "backgroundColor": { "colorOne": "#dde9f4", "colorTwo": "#f66578", "gradientDirection": "to bottom" }, "textColor": "#FFD700", "backgroundOpacity": 80, "frameRadius": 12, "type": "milestones", "milestones": { "milestoneCompletedIconUrl": "https://plus.unsplash.com/premium_photo-1681400545953-0ba00cfa7926?q=80&w=880&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "tooltipBackgroundColor": "#1f9eec" } }, "borderColor": { "colorOne": "#DBBD9C", "colorTwo": "#DBBD9C", "gradientDirection": "to right" }, "backgroundColor": { "colorOne": "#DABA98", "colorTwo": "#FDFCF9", "gradientDirection": "to right" }, "borderWidth": 3, "externalId": "progress-bar-design-milestones" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "quantity": 300, "priority": "Main", "quantityDisplay": "+ 300" }, { "publisherProductId": "gems", "quantity": 50, "priority": "Sub", "quantityDisplay": "+ 50" } ], "priceInUsdCents": 0, "barSize": 10, "id": "67890abcdef1234567890202" }, { "index": 2, "products": [ { "publisherProductId": "coins", "quantity": 500, "priority": "Main", "quantityDisplay": "+ 500" }, { "publisherProductId": "gems", "quantity": 100, "priority": "Sub", "quantityDisplay": "+ 100" } ], "priceInUsdCents": 0, "barSize": 20, "id": "67890abcdef1234567890203" }, { "index": 3, "products": [ { "publisherProductId": "coins", "quantity": 1000, "priority": "Main", "quantityDisplay": "+ 1000" }, { "publisherProductId": "gems", "quantity": 250, "priority": "Sub", "quantityDisplay": "+ 250" }, { "publisherProductId": "energy", "quantity": 100, "priority": "Sub", "quantityDisplay": "+ 100" } ], "priceInUsdCents": 0, "barSize": 30, "id": "67890abcdef1234567890204" } ], "publisherId": "6555b69c02ee8eca00465694", "publisherOfferId": "progressBar-milestones-1", "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-11-01T12:05:00.000Z", "endTime": "2025-11-22T12:10:00.000Z", "notes": "Holiday promotion period.", "id": "67890abcdef1234567890205" } ] }, "segments": [ "New User", "VIP Player" ], "createdAt": "2024-11-15T09:30:00.000Z", "updatedAt": "2024-11-15T09:30:00.000Z" } ``` # Delete Progress Bar Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/progress-bars/delete-progress-bar openapi-progress-bar.json DELETE /v2/offer/{publisherOfferId} Deletes a Progress Bar offer. ```bash Delete Classic Progress Bar theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/v2/offer/progressBar-single-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```bash Delete Milestone Progress Bar theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/v2/offer/progressBar-milestones-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Classic Progress Bar theme={"system"} { "offerId": "67890abcdef1234567890123", "active": true, "description": "A progress bar with sequential missions.", "displayName": "My Classic Progress Bar", "name": "My Classic Progress Bar", "type": "ProgressBar", "offerUi": { "id": "67890abcdef1234567890124", "offerUiType": "ProgressBar", "name": "Classic Progress Bar Design", "description": "Progress Bar UI design template", "backgroundImageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/background-image.png", "title": { "text": "Mission impossible!", "fontColor": "#FFD700", "fontSize": 10, "fontWeight": "bold" }, "subtitle": { "text": "To infinity and beyond!", "fontColor": "#FFD700", "fontSize": 8, "fontWeight": "normal" }, "progressBar": { "barFillColor": { "colorOne": "#FFD450", "colorTwo": "#EDB923", "gradientDirection": "to bottom" }, "barRadius": 12, "accumulatedItem": { "imageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/item.jpeg", "ribbonImageUrl": "https://plus.unsplash.com/premium_photo-1681400545953-0ba00cfa7926?q=80&w=880&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" }, "backgroundOpacity": 80, "frameRadius": 12 }, "borderColor": { "colorOne": "#DBBD9C", "colorTwo": "#DBBD9C", "gradientDirection": "to right" }, "backgroundColor": { "colorOne": "#DABA98", "colorTwo": "#FDFCF9", "gradientDirection": "to right" }, "borderWidth": 3, "externalId": "progress-bar-design-single" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "quantity": 300, "priority": "Main", "quantityDisplay": "+ 300" } ], "priceInUsdCents": 0, "barSize": 10, "id": "67890abcdef1234567890126" }, { "index": 2, "products": [ { "publisherProductId": "coins", "quantity": 500, "priority": "Main", "quantityDisplay": "+ 500" } ], "priceInUsdCents": 0, "barSize": 20, "id": "67890abcdef1234567890127" } ], "publisherId": "6555b69c02ee8eca00465694", "publisherOfferId": "progressBar-single-1", "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-11-01T12:05:00.000Z", "endTime": "2025-11-22T12:10:00.000Z", "notes": "Holiday promotion period.", "id": "67890abcdef1234567890128" } ] }, "segments": [ "New User", "VIP Player" ], "createdAt": "2024-11-15T09:30:00.000Z", "updatedAt": "2024-11-15T09:30:00.000Z" } ``` ```json Delete Milestone Progress Bar theme={"system"} { "offerId": "67890abcdef1234567890200", "active": true, "description": "A progress bar with all milestones visible at once.", "displayName": "My Milestone Progress Bar", "name": "My Milestone Progress Bar", "type": "ProgressBar", "offerUi": { "id": "67890abcdef1234567890201", "offerUiType": "ProgressBar", "name": "Milestone Progress Bar Design", "description": "Milestone Progress Bar UI design template", "backgroundImageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/background-image.png", "title": { "text": "Reach Every Milestone", "fontColor": "#FFD700", "fontSize": 10, "fontWeight": "bold" }, "subtitle": { "text": "Collect rewards along the way", "fontColor": "#FFD700", "fontSize": 8, "fontWeight": "normal" }, "progressBar": { "barFillColor": { "colorOne": "#FFD450", "colorTwo": "#EDB923", "gradientDirection": "to bottom" }, "barRadius": 12, "accumulatedItem": { "imageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/item.jpeg", "ribbonImageUrl": "https://plus.unsplash.com/premium_photo-1681400545953-0ba00cfa7926?q=80&w=880&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" }, "headerImageUrl": "https://plus.unsplash.com/premium_photo-1785080652560-f334e6ea704c?q=80&w=687&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "backgroundColor": { "colorOne": "#dde9f4", "colorTwo": "#f66578", "gradientDirection": "to bottom" }, "textColor": "#FFD700", "backgroundOpacity": 80, "frameRadius": 12, "type": "milestones", "milestones": { "milestoneCompletedIconUrl": "https://plus.unsplash.com/premium_photo-1681400545953-0ba00cfa7926?q=80&w=880&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "tooltipBackgroundColor": "#1f9eec" } }, "borderColor": { "colorOne": "#DBBD9C", "colorTwo": "#DBBD9C", "gradientDirection": "to right" }, "backgroundColor": { "colorOne": "#DABA98", "colorTwo": "#FDFCF9", "gradientDirection": "to right" }, "borderWidth": 3, "externalId": "progress-bar-design-milestones" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "quantity": 300, "priority": "Main", "quantityDisplay": "+ 300" }, { "publisherProductId": "gems", "quantity": 50, "priority": "Sub", "quantityDisplay": "+ 50" } ], "priceInUsdCents": 0, "barSize": 10, "id": "67890abcdef1234567890202" }, { "index": 2, "products": [ { "publisherProductId": "coins", "quantity": 500, "priority": "Main", "quantityDisplay": "+ 500" }, { "publisherProductId": "gems", "quantity": 100, "priority": "Sub", "quantityDisplay": "+ 100" } ], "priceInUsdCents": 0, "barSize": 20, "id": "67890abcdef1234567890203" }, { "index": 3, "products": [ { "publisherProductId": "coins", "quantity": 1000, "priority": "Main", "quantityDisplay": "+ 1000" }, { "publisherProductId": "gems", "quantity": 250, "priority": "Sub", "quantityDisplay": "+ 250" }, { "publisherProductId": "energy", "quantity": 100, "priority": "Sub", "quantityDisplay": "+ 100" } ], "priceInUsdCents": 0, "barSize": 30, "id": "67890abcdef1234567890204" } ], "publisherId": "6555b69c02ee8eca00465694", "publisherOfferId": "progressBar-milestones-1", "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-11-01T12:05:00.000Z", "endTime": "2025-11-22T12:10:00.000Z", "notes": "Holiday promotion period.", "id": "67890abcdef1234567890205" } ] }, "segments": [ "New User", "VIP Player" ], "createdAt": "2024-11-15T09:30:00.000Z", "updatedAt": "2024-11-15T09:30:00.000Z" } ``` # Get Progress Bar Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/progress-bars/get-progress-bar openapi-progress-bar.json GET /v2/offer Retrieves one or more Progress Bar offers. ```bash Get Classic Progress Bar theme={"system"} curl -X GET \ 'https://api.appcharge.com/v2/offer?publisherOfferIds=progressBar-single-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```bash Get Milestone Progress Bar theme={"system"} curl -X GET \ 'https://api.appcharge.com/v2/offer?publisherOfferIds=progressBar-milestones-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Get Classic Progress Bar theme={"system"} { "totalCount": 1, "offers": [ { "offerId": "67890abcdef1234567890123", "active": true, "description": "A progress bar with sequential missions.", "displayName": "My Classic Progress Bar", "name": "My Classic Progress Bar", "type": "ProgressBar", "offerUi": { "id": "67890abcdef1234567890124", "offerUiType": "ProgressBar", "name": "Classic Progress Bar Design", "description": "Progress Bar UI design template", "backgroundImageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/background-image.png", "title": { "text": "Mission impossible!", "fontColor": "#FFD700", "fontSize": 10, "fontWeight": "bold" }, "subtitle": { "text": "To infinity and beyond!", "fontColor": "#FFD700", "fontSize": 8, "fontWeight": "normal" }, "progressBar": { "barFillColor": { "colorOne": "#FFD450", "colorTwo": "#EDB923", "gradientDirection": "to bottom" }, "barRadius": 12, "accumulatedItem": { "imageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/item.jpeg", "ribbonImageUrl": "https://plus.unsplash.com/premium_photo-1681400545953-0ba00cfa7926?q=80&w=880&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" }, "backgroundOpacity": 80, "frameRadius": 12 }, "borderColor": { "colorOne": "#DBBD9C", "colorTwo": "#DBBD9C", "gradientDirection": "to right" }, "backgroundColor": { "colorOne": "#DABA98", "colorTwo": "#FDFCF9", "gradientDirection": "to right" }, "borderWidth": 3, "externalId": "progress-bar-design-single" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "quantity": 300, "priority": "Main", "quantityDisplay": "+ 300" } ], "priceInUsdCents": 0, "barSize": 10, "id": "67890abcdef1234567890126" }, { "index": 2, "products": [ { "publisherProductId": "coins", "quantity": 500, "priority": "Main", "quantityDisplay": "+ 500" } ], "priceInUsdCents": 0, "barSize": 20, "id": "67890abcdef1234567890127" } ], "publisherId": "6555b69c02ee8eca00465694", "publisherOfferId": "progressBar-single-1", "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-11-01T12:05:00.000Z", "endTime": "2025-11-22T12:10:00.000Z", "notes": "Holiday promotion period.", "id": "67890abcdef1234567890128" } ] }, "segments": [ "New User", "VIP Player" ], "createdAt": "2024-11-15T09:30:00.000Z", "updatedAt": "2024-11-15T09:30:00.000Z" } ] } ``` ```json Get Milestone Progress Bar theme={"system"} { "totalCount": 1, "offers": [ { "offerId": "67890abcdef1234567890200", "active": true, "description": "A progress bar with all milestones visible at once.", "displayName": "My Milestone Progress Bar", "name": "My Milestone Progress Bar", "type": "ProgressBar", "offerUi": { "id": "67890abcdef1234567890201", "offerUiType": "ProgressBar", "name": "Milestone Progress Bar Design", "description": "Milestone Progress Bar UI design template", "backgroundImageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/background-image.png", "title": { "text": "Reach Every Milestone", "fontColor": "#FFD700", "fontSize": 10, "fontWeight": "bold" }, "subtitle": { "text": "Collect rewards along the way", "fontColor": "#FFD700", "fontSize": 8, "fontWeight": "normal" }, "progressBar": { "barFillColor": { "colorOne": "#FFD450", "colorTwo": "#EDB923", "gradientDirection": "to bottom" }, "barRadius": 12, "accumulatedItem": { "imageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/item.jpeg", "ribbonImageUrl": "https://plus.unsplash.com/premium_photo-1681400545953-0ba00cfa7926?q=80&w=880&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" }, "headerImageUrl": "https://plus.unsplash.com/premium_photo-1785080652560-f334e6ea704c?q=80&w=687&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "backgroundColor": { "colorOne": "#dde9f4", "colorTwo": "#f66578", "gradientDirection": "to bottom" }, "textColor": "#FFD700", "backgroundOpacity": 80, "frameRadius": 12, "type": "milestones", "milestones": { "milestoneCompletedIconUrl": "https://plus.unsplash.com/premium_photo-1681400545953-0ba00cfa7926?q=80&w=880&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "tooltipBackgroundColor": "#1f9eec" } }, "borderColor": { "colorOne": "#DBBD9C", "colorTwo": "#DBBD9C", "gradientDirection": "to right" }, "backgroundColor": { "colorOne": "#DABA98", "colorTwo": "#FDFCF9", "gradientDirection": "to right" }, "borderWidth": 3, "externalId": "progress-bar-design-milestones" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "quantity": 300, "priority": "Main", "quantityDisplay": "+ 300" }, { "publisherProductId": "gems", "quantity": 50, "priority": "Sub", "quantityDisplay": "+ 50" } ], "priceInUsdCents": 0, "barSize": 10, "id": "67890abcdef1234567890202" }, { "index": 2, "products": [ { "publisherProductId": "coins", "quantity": 500, "priority": "Main", "quantityDisplay": "+ 500" }, { "publisherProductId": "gems", "quantity": 100, "priority": "Sub", "quantityDisplay": "+ 100" } ], "priceInUsdCents": 0, "barSize": 20, "id": "67890abcdef1234567890203" }, { "index": 3, "products": [ { "publisherProductId": "coins", "quantity": 1000, "priority": "Main", "quantityDisplay": "+ 1000" }, { "publisherProductId": "gems", "quantity": 250, "priority": "Sub", "quantityDisplay": "+ 250" }, { "publisherProductId": "energy", "quantity": 100, "priority": "Sub", "quantityDisplay": "+ 100" } ], "priceInUsdCents": 0, "barSize": 30, "id": "67890abcdef1234567890204" } ], "publisherId": "6555b69c02ee8eca00465694", "publisherOfferId": "progressBar-milestones-1", "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-11-01T12:05:00.000Z", "endTime": "2025-11-22T12:10:00.000Z", "notes": "Holiday promotion period.", "id": "67890abcdef1234567890205" } ] }, "segments": [ "New User", "VIP Player" ], "createdAt": "2024-11-15T09:30:00.000Z", "updatedAt": "2024-11-15T09:30:00.000Z" } ] } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/progress-bars/introduction The Progress Bars API lets you create and manage progress bar offers in the web store. Progress Bars are promotional offers that encourage players to make additional purchases by earning points toward configured targets. Each target has a reward and a target size. You set target size using the `productsSequence.barSize` property, which is the number of accumulated items (points) required to complete the target. Players earn points by purchasing eligible offers or collecting free rewards. When a target's point requirement is met, the player receives the reward and a free order is created. After all targets are completed, the Progress Bar is removed from the web store. There are 2 types of progress bars: * **Classic:** Only one mission is displayed on the bar at a time, and the bar resets when the next mission begins. * **Milestones:** All milestones are displayed at once along the bar. Learn more about [Progress Bar offers](/../../guides/webstore/offers/progress-bars/about-progress-bars). With the Progress Bars API, you can: * [Create a new progress bar](./create-progress-bar). * [Update an existing progress bar](./update-progress-bar). * [Retrieve one or more progress bars](./get-progress-bar). * [Retrieve all progress bars](../get-offers). * [Delete a progress bar](./delete-progress-bar). You can also listen for events when a mission is [started](/api-reference/events/v2/webstore/offer/progress_bar_mission_started), [completed](/api-reference/events/v2/webstore/offer/progress_bar_mission_completed), and [points are granted](/api-reference/events/v2/webstore/offer/progress_bar_points_granted). ## Before you begin Review the following before you begin: * Updating the `productsSequence.barSize` property may affect player progress. Before making changes, review [updating required points](/../../guides/webstore/offers/progress-bars/about-progress-bars#update-required-points). * Setting the `active` property to `false` marks the Progress Bar as inactive and removes it from the web store. If the Progress Bar is later reactivated, players will see the Progress Bar along with their existing progress in the web store. * You can schedule a Progress Bar using the `schedule` property. When the scheduled period ends, the Progress Bar is removed from the web store but remains `active` unless it is explicitly set to `"active": false` or deactivated in the Publisher Dashboard. # Update Progress Bar Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/progress-bars/update-progress-bar openapi-progress-bar.json PUT /v2/offer/${publisherOfferId} Updates a Progress Bar offer. ```bash Update Classic Progress Bar theme={"system"} curl -X PUT \ 'https://api.appcharge.com/v2/offer/progressBar-single-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "name": "My Classic Progress Bar Updated", "type": "ProgressBar", "active": false }' ``` ```bash Update Milestone Progress Bar theme={"system"} curl -X PUT \ 'https://api.appcharge.com/v2/offer/progressBar-milestones-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "name": "My Milestone Progress Bar Updated", "type": "ProgressBar", "active": true, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "priority": "Main", "quantity": 400 }, { "publisherProductId": "gems", "priority": "Sub", "quantity": 75 } ], "priceInUsdCents": 0, "barSize": 15 }, { "index": 2, "products": [ { "publisherProductId": "coins", "priority": "Main", "quantity": 600 }, { "publisherProductId": "gems", "priority": "Sub", "quantity": 150 } ], "priceInUsdCents": 0, "barSize": 25 }, { "index": 3, "products": [ { "publisherProductId": "coins", "priority": "Main", "quantity": 1200 }, { "publisherProductId": "gems", "priority": "Sub", "quantity": 300 }, { "publisherProductId": "energy", "priority": "Sub", "quantity": 150 } ], "priceInUsdCents": 0, "barSize": 35 } ] }' ``` ```json Update Classic Progress Bar theme={"system"} { "offerId": "67890abcdef1234567890123", "active": false, "description": "A progress bar with sequential missions.", "displayName": "My Classic Progress Bar", "name": "My Classic Progress Bar Updated", "type": "ProgressBar", "offerUi": { "id": "67890abcdef1234567890124", "offerUiType": "ProgressBar", "name": "Classic Progress Bar Design", "description": "Progress Bar UI design template", "backgroundImageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/background-image.png", "title": { "text": "Mission impossible!", "fontColor": "#FFD700", "fontSize": 10, "fontWeight": "bold" }, "subtitle": { "text": "To infinity and beyond!", "fontColor": "#FFD700", "fontSize": 8, "fontWeight": "normal" }, "progressBar": { "barFillColor": { "colorOne": "#FFD450", "colorTwo": "#EDB923", "gradientDirection": "to bottom" }, "barRadius": 12, "accumulatedItem": { "imageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/item.jpeg", "ribbonImageUrl": "https://plus.unsplash.com/premium_photo-1681400545953-0ba00cfa7926?q=80&w=880&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" }, "backgroundOpacity": 80, "frameRadius": 12 }, "borderColor": { "colorOne": "#DBBD9C", "colorTwo": "#DBBD9C", "gradientDirection": "to right" }, "backgroundColor": { "colorOne": "#DABA98", "colorTwo": "#FDFCF9", "gradientDirection": "to right" }, "borderWidth": 3, "externalId": "progress-bar-design-single" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "quantity": 400, "priority": "Main", "quantityDisplay": "+ 400" } ], "priceInUsdCents": 0, "barSize": 15, "id": "67890abcdef1234567890126" }, { "index": 2, "products": [ { "publisherProductId": "coins", "quantity": 600, "priority": "Main", "quantityDisplay": "+ 600" } ], "priceInUsdCents": 0, "barSize": 25, "id": "67890abcdef1234567890127" } ], "publisherId": "6555b69c02ee8eca00465694", "publisherOfferId": "progressBar-single-1", "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-12-01T12:05:00.000Z", "endTime": "2025-12-22T12:10:00.000Z", "notes": "Updated holiday promotion period.", "id": "67890abcdef1234567890128" } ] }, "segments": [ "New User", "VIP Player" ], "createdAt": "2024-11-15T09:30:00.000Z", "updatedAt": "2024-12-01T10:15:00.000Z" } ``` ```json Update Milestone Progress Bar theme={"system"} { "offerId": "67890abcdef1234567890200", "active": true, "description": "A progress bar with all milestones visible at once.", "displayName": "My Milestone Progress Bar", "name": "My Milestone Progress Bar Updated", "type": "ProgressBar", "offerUi": { "id": "67890abcdef1234567890201", "offerUiType": "ProgressBar", "name": "Milestone Progress Bar Design", "description": "Milestone Progress Bar UI design template", "backgroundImageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/background-image.png", "title": { "text": "Reach Every Milestone", "fontColor": "#FFD700", "fontSize": 10, "fontWeight": "bold" }, "subtitle": { "text": "Collect rewards along the way", "fontColor": "#FFD700", "fontSize": 8, "fontWeight": "normal" }, "progressBar": { "barFillColor": { "colorOne": "#FFD450", "colorTwo": "#EDB923", "gradientDirection": "to bottom" }, "barRadius": 12, "accumulatedItem": { "imageUrl": "https://media-dev.appcharge.com/media/6555b69c02ee8eca00465694/item.jpeg", "ribbonImageUrl": "https://plus.unsplash.com/premium_photo-1681400545953-0ba00cfa7926?q=80&w=880&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" }, "headerImageUrl": "https://plus.unsplash.com/premium_photo-1785080652560-f334e6ea704c?q=80&w=687&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "backgroundColor": { "colorOne": "#dde9f4", "colorTwo": "#f66578", "gradientDirection": "to bottom" }, "textColor": "#FFD700", "backgroundOpacity": 80, "frameRadius": 12, "type": "milestones", "milestones": { "milestoneCompletedIconUrl": "https://plus.unsplash.com/premium_photo-1681400545953-0ba00cfa7926?q=80&w=880&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "tooltipBackgroundColor": "#1f9eec" } }, "borderColor": { "colorOne": "#DBBD9C", "colorTwo": "#DBBD9C", "gradientDirection": "to right" }, "backgroundColor": { "colorOne": "#DABA98", "colorTwo": "#FDFCF9", "gradientDirection": "to right" }, "borderWidth": 3, "externalId": "progress-bar-design-milestones" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "quantity": 400, "priority": "Main", "quantityDisplay": "+ 400" }, { "publisherProductId": "gems", "quantity": 75, "priority": "Sub", "quantityDisplay": "+ 75" } ], "priceInUsdCents": 0, "barSize": 15, "id": "67890abcdef1234567890202" }, { "index": 2, "products": [ { "publisherProductId": "coins", "quantity": 600, "priority": "Main", "quantityDisplay": "+ 600" }, { "publisherProductId": "gems", "quantity": 150, "priority": "Sub", "quantityDisplay": "+ 150" } ], "priceInUsdCents": 0, "barSize": 25, "id": "67890abcdef1234567890203" }, { "index": 3, "products": [ { "publisherProductId": "coins", "quantity": 1200, "priority": "Main", "quantityDisplay": "+ 1200" }, { "publisherProductId": "gems", "quantity": 300, "priority": "Sub", "quantityDisplay": "+ 300" }, { "publisherProductId": "energy", "quantity": 150, "priority": "Sub", "quantityDisplay": "+ 150" } ], "priceInUsdCents": 0, "barSize": 35, "id": "67890abcdef1234567890204" } ], "publisherId": "6555b69c02ee8eca00465694", "publisherOfferId": "progressBar-milestones-1", "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-12-01T12:05:00.000Z", "endTime": "2025-12-22T12:10:00.000Z", "notes": "Updated holiday promotion period.", "id": "67890abcdef1234567890205" } ] }, "segments": [ "New User", "VIP Player" ], "createdAt": "2024-11-15T09:30:00.000Z", "updatedAt": "2024-12-01T10:15:00.000Z" } ``` # Create Reward Calendar Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/reward-calendars/create-reward-calendar openapi-reward-calendar.json POST /v2/offer Creates a Reward Calendar offer. ```bash Create Reward Calendar theme={"system"} curl -X POST \ 'https://api.appcharge.com/v2/offer' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ -d '{ "publisherOfferId": "reward-calendar-1", "name": "Weekly Reward Calendar", "type": "PopUp", "subType": "RewardCalendar", "active": true, "priority": 1, "offerExternalUiId": "reward-calendar-design-1", "startOver": false, "rewardCalendar": { "resetBehavior": "ToCalendarStart", "popupTrigger": "ShowAutomatically", "rewardCollectionBehavior": "ForcePlayerToCollect" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "quantity": 100, "priority": "Sub" } ], "priceInUsdCents": 0 }, { "index": 2, "products": [ { "publisherProductId": "coins", "quantity": 150, "priority": "Sub" } ], "priceInUsdCents": 0 }, { "index": 3, "products": [ { "publisherProductId": "coins", "quantity": 200, "priority": "Sub" } ], "priceInUsdCents": 0 }, { "index": 4, "products": [ { "publisherProductId": "coins", "quantity": 250, "priority": "Sub" } ], "priceInUsdCents": 0 }, { "index": 5, "products": [ { "publisherProductId": "coins", "quantity": 300, "priority": "Sub" } ], "priceInUsdCents": 0 }, { "index": 6, "products": [ { "publisherProductId": "coins", "quantity": 350, "priority": "Sub" } ], "priceInUsdCents": 0 }, { "index": 7, "products": [ { "publisherProductId": "chest", "quantity": 1, "priority": "Main" } ], "priceInUsdCents": 0 } ], "segments": [ "New User" ] }' ``` ```json Create Reward Calendar theme={"system"} { "publisherId": "69133d595af23405d88843a5", "publisherOfferId": "reward-calendar-1", "name": "Weekly Reward Calendar", "displayName": "Weekly Reward Calendar", "type": "PopUp", "subType": "RewardCalendar", "active": true, "segments": [ "New User" ], "offerUi": { "offerUiId": "6a1828e5e75e5598d942e257", "active": true, "offerUiType": "PopUp", "offerUiSubType": "RewardCalendar", "name": "Weekly Reward Calendar Design", "description": "description", "backgroundImage": "", "rewardCalendar": { "collectibleBadgeImage": "https://media.appcharge.com/defaults/reward-calendar/reward_badge.png", "lockedBadgeImage": "https://media.appcharge.com/defaults/reward-calendar/reward_badge_locked.png", "dayFontColor": "#764cd4", "subRewardBackgroundImage": "https://media-staging.appcharge.com/media/69133d595af23405d88843a5/1779967290083__9f0c1502-10e0-4b75-a670-3748c2ebbdf1", "mainRewardBackgroundImage": "", "backgroundColor": "#97daf4", "headerImage": "https://media-staging.appcharge.com/media/69133d595af23405d88843a5/1779966861904__a16963b5-db9b-45de-b5c5-cdcc7dcf79f3", "collectIconImage": "https://media.appcharge.com/defaults/reward-calendar/default_collected_icon.png", "lockedIconImage": "https://media.appcharge.com/defaults/reward-calendar/default_lock_icon.png" }, "externalId": "reward-calendar-design-1" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "coins", "name": "Coins", "description": "Coins reward.", "textFontColorHex": "#FFFFFF", "type": "Quantity", "prefix": "", "suffix": "", "images": [ { "type": "product", "url": "https://media-staging.appcharge.com/media/69133d595af23405d88843a5/1770287158114__a4266bfc-297f-47c9-b5e5-16d7fdb987ea" }, { "type": "productPrefix", "url": "" } ], "displayName": "Coins", "createdAt": "2026-02-05T10:26:12.307Z", "updatedAt": "2026-02-05T10:26:12.307Z", "productId": "698470440b0547d86762f85e" }, "publisherProductId": "coins", "quantity": 100, "priority": "Sub" } ], "priceInUsdCents": 0, "badges": [] }, { "index": 2, "products": [ { "product": { "publisherProductId": "coins", "name": "Coins", "description": "Coins reward.", "textFontColorHex": "#FFFFFF", "type": "Quantity", "prefix": "", "suffix": "", "images": [ { "type": "product", "url": "https://media-staging.appcharge.com/media/69133d595af23405d88843a5/1762940780865__0f4b7e05-6051-46c8-9160-d155e9ca2c3b" }, { "type": "productPrefix", "url": "" } ], "displayName": "Coins", "createdAt": "2025-11-12T09:46:28.925Z", "updatedAt": "2025-11-12T09:46:28.925Z", "productId": "69145774cceb99de11dfe64a" }, "publisherProductId": "coins", "quantity": 150, "priority": "Sub" } ], "priceInUsdCents": 0, "badges": [] }, { "index": 3, "products": [ { "product": { "publisherProductId": "coins", "name": "Coins", "description": "Coins reward.", "textFontColorHex": "#FFFFFF", "type": "Quantity", "prefix": "", "suffix": "", "images": [ { "type": "product", "url": "https://media-staging.appcharge.com/media/69133d595af23405d88843a5/1762940945510__6d0b0fbd-1833-4f01-b230-421a5f4bdba9" }, { "type": "productPrefix", "url": "" } ], "displayName": "Coins", "createdAt": "2025-11-12T09:49:10.063Z", "updatedAt": "2025-11-12T09:49:10.063Z", "productId": "69145816cceb99de11dfe692" }, "publisherProductId": "coins", "quantity": 200, "priority": "Sub" } ], "priceInUsdCents": 0, "badges": [] }, { "index": 4, "products": [ { "product": { "publisherProductId": "coins", "name": "Coins", "description": "Coins reward.", "textFontColorHex": "#FFFFFF", "type": "Quantity", "prefix": "", "suffix": "", "images": [ { "type": "product", "url": "https://media-staging.appcharge.com/media/69133d595af23405d88843a5/1763013669345__fda4f44a-19e6-4a9a-b71a-9e55903dfece" }, { "type": "productPrefix", "url": "https://media-staging.appcharge.com/media/69133d595af23405d88843a5/1763013758566__745ba5f4-582f-401f-b9fe-08cd218bf778" } ], "createdAt": "2025-11-11T13:42:51.928Z", "updatedAt": "2025-11-13T06:02:42.481Z", "displayName": "Coins", "productId": "69133d5bcceb99de11df0200" }, "publisherProductId": "coins", "quantity": 250, "priority": "Sub" } ], "priceInUsdCents": 0, "badges": [] }, { "index": 5, "products": [ { "product": { "publisherProductId": "coins", "name": "Coins", "description": "Coins reward.", "textFontColorHex": "#FFFFFF", "type": "Quantity", "prefix": "", "suffix": "", "images": [ { "type": "product", "url": "https://media-staging.appcharge.com/media/69133d595af23405d88843a5/1770287224409__a406068e-4153-4f75-93b9-ea884d6fac82" }, { "type": "productPrefix", "url": "" } ], "displayName": "Coins", "createdAt": "2026-02-05T10:27:18.553Z", "updatedAt": "2026-02-05T10:27:18.553Z", "productId": "6984708615abbcb66f201dbe" }, "publisherProductId": "coins", "quantity": 300, "priority": "Sub" } ], "priceInUsdCents": 0, "badges": [] }, { "index": 6, "products": [ { "product": { "publisherProductId": "coins", "name": "Coins", "description": "Coins reward.", "textFontColorHex": "#FFFFFF", "type": "Quantity", "prefix": "", "suffix": "", "images": [ { "type": "product", "url": "https://media-staging.appcharge.com/media/69133d595af23405d88843a5/1770287198121__4f7c17dc-7a12-4554-89b2-dd90c51e8114" }, { "type": "productPrefix", "url": "" } ], "displayName": "Coins", "createdAt": "2026-02-05T10:26:41.716Z", "updatedAt": "2026-02-05T10:26:41.716Z", "productId": "6984706115abbcb66f201dae" }, "publisherProductId": "coins", "quantity": 350, "priority": "Sub" } ], "priceInUsdCents": 0, "badges": [] }, { "index": 7, "products": [ { "product": { "publisherProductId": "chest", "name": "Chest", "description": "Chest reward.", "textFontColorHex": "#FFFFFF", "type": "Quantity", "prefix": "", "suffix": "", "images": [ { "type": "product", "url": "https://media-staging.appcharge.com/media/69133d595af23405d88843a5/1770287158114__a4266bfc-297f-47c9-b5e5-16d7fdb987ea" }, { "type": "productPrefix", "url": "" } ], "displayName": "Chest", "createdAt": "2026-02-05T10:26:12.307Z", "updatedAt": "2026-02-05T10:26:12.307Z", "productId": "698470440b0547d86762f85e" }, "publisherProductId": "chest", "quantity": 1, "priority": "Main" } ], "priceInUsdCents": 0, "badges": [] } ], "priority": 1, "startOver": false, "rewardCalendar": { "resetBehavior": "ToCalendarStart", "popupTrigger": "ShowAutomatically", "rewardCollectionBehavior": "ForcePlayerToCollect" }, "badges": [], "createdAt": "2026-06-11T05:09:03.575Z", "updatedAt": "2026-06-11T05:09:03.575Z", "offerId": "6a2a42ef85ce5ccba45444f3" } ``` # Delete Reward Calendar Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/reward-calendars/delete-reward-calendar openapi-reward-calendar.json DELETE /v2/offer/{publisherOfferId} Deletes a Reward Calendar offer. ```bash Delete Reward Calendar theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/v2/offer/reward-calendar-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Reward Calendar theme={"system"} { "offerId": "69fb22e6dd352b799c65e97f", "publisherOfferId": "reward-calendar-1", "name": "Weekly Reward Calendar 1", "type": "PopUp", "subType": "RewardCalendar", "active": true, "priority": 1, "startOver": true, "rewardCalendar": { "resetBehavior": "ToCalendarStart", "popupTrigger": "ShowAutomatically", "rewardCollectionBehavior": "ForcePlayerToCollect" }, "offerUi": { "offerUiId": "69fb22e6dd352b799c65e97e", "active": true, "offerUiType": "PopUp", "offerUiSubType": "RewardCalendar", "name": "Weekly Reward Calendar Design", "externalId": "reward-calendar-design-1" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "quantity": 100, "priority": "Sub" } ], "priceInUsdCents": 0 }, { "index": 7, "products": [ { "publisherProductId": "chest", "quantity": 1, "priority": "Main" } ], "priceInUsdCents": 0 } ], "segments": [ "New User" ], "createdAt": "2026-06-08T10:00:44.528Z", "updatedAt": "2026-06-08T10:00:44.528Z" } ``` # Get Reward Calendar Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/reward-calendars/get-reward-calendar openapi-reward-calendar.json GET /v2/offer Retrieves one or more Reward Calendar offers. ```bash Get Reward Calendar theme={"system"} curl -X GET \ 'https://api.appcharge.com/v2/offer?publisherOfferIds=reward-calendar-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Get Reward Calendar theme={"system"} { "totalCount": 1, "offers": [ { "offerId": "69fb22e6dd352b799c65e97f", "publisherOfferId": "reward-calendar-1", "name": "Weekly Reward Calendar", "type": "PopUp", "subType": "RewardCalendar", "active": true, "priority": 1, "startOver": false, "rewardCalendar": { "resetBehavior": "ToCalendarStart", "popupTrigger": "ShowAutomatically", "rewardCollectionBehavior": "ForcePlayerToCollect" }, "offerUi": { "offerUiId": "69fb22e6dd352b799c65e97e", "active": true, "offerUiType": "PopUp", "offerUiSubType": "RewardCalendar", "name": "Weekly Reward Calendar Design", "externalId": "reward-calendar-design-1" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "quantity": 100, "priority": "Sub" } ], "priceInUsdCents": 0 }, { "index": 2, "products": [ { "publisherProductId": "gems", "quantity": 10, "priority": "Sub" } ], "priceInUsdCents": 0 }, { "index": 3, "products": [ { "publisherProductId": "energy", "quantity": 5, "priority": "Sub" } ], "priceInUsdCents": 0 }, { "index": 4, "products": [ { "publisherProductId": "coins", "quantity": 250, "priority": "Sub" } ], "priceInUsdCents": 0 }, { "index": 5, "products": [ { "publisherProductId": "booster", "quantity": 1, "priority": "Sub" } ], "priceInUsdCents": 0 }, { "index": 6, "products": [ { "publisherProductId": "gems", "quantity": 25, "priority": "Sub" } ], "priceInUsdCents": 0 }, { "index": 7, "products": [ { "publisherProductId": "chest", "quantity": 1, "priority": "Main" } ], "priceInUsdCents": 0 } ], "segments": [ "New User" ], "createdAt": "2026-06-08T10:00:44.528Z", "updatedAt": "2026-06-08T10:00:44.528Z" } ] } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/reward-calendars/introduction The Reward Calendars API service allows you to create and manage reward calendar offers in your web store. Reward calendars are 7-day calendar popup offers that show players the upcoming rewards of the week, and let them collect the current day's reward. Learn more about [Reward Calendar offers](/../../guides/webstore/offers/reward-calendars/about-reward-calendars). With the Reward Calendars API service, you can: * [Create a new reward calendar offer](./create-reward-calendar). * [Update an existing reward calendar offer](./update-reward-calendar). * [Retrieve one or more reward calendar offers](./get-reward-calendar). * [Retrieve all reward calendar offers](../get-offers). * [Delete a reward calendar offer](./delete-reward-calendar). ## Before you begin It’s important to note the following points before starting to code: * The `productsSequence` array must include seven objects representing the reward tiles for each configured week. You can configure one to 10 weeks, so the sequence must be a multiple of 7 and a maximum of 70 items. The main reward is every seventh index, such as 7, 14, and 21. All other indexes are sub rewards. * If you set `rewardCollectionBehavior` to `ForcePlayerToCollect`, players must collect the available reward when the popup opens. Because collection can't be deferred, the collectible badge isn't shown. ## Terminology These terms define how the Reward Calendar behaves for players: * **Reset behavior:** Determines how player progress resets after a missed day, either to Week 1, Day 1, or to Day 1 of the current week. * **Popup trigger:** Determines whether the popup opens automatically when a reward becomes available, or only after the player clicks the badge. * **Reward collection behavior:** Determines whether players must collect the reward immediately, or can close the popup and collect later that day. * **Start over:** Determines whether the calendar restarts after players complete all configured weeks. # Update Reward Calendar Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/reward-calendars/update-reward-calendar openapi-reward-calendar.json PUT /v2/offer/${publisherOfferId} Updates a Reward Calendar offer. ```bash Update Reward Calendar theme={"system"} curl -X PUT \ 'https://api.appcharge.com/v2/offer/reward-calendar-1' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'x-publisher-token: ' \ -d '{ "name": "Updated Weekly Reward Calendar", "type": "PopUp", "subType": "RewardCalendar", "active": true, "startOver": false, "rewardCalendar": { "resetBehavior": "ToCurrentWeekStart", "popupTrigger": "ShowOnBadgeClick", "rewardCollectionBehavior": "PlayerCanSkipCollection" } }' ``` ```json Update Reward Calendar theme={"system"} { "offerId": "69fb22e6dd352b799c65e97f", "publisherOfferId": "reward-calendar-1", "name": "Updated Weekly Reward Calendar", "type": "PopUp", "subType": "RewardCalendar", "active": true, "priority": 1, "startOver": false, "rewardCalendar": { "resetBehavior": "ToCurrentWeekStart", "popupTrigger": "ShowOnBadgeClick", "rewardCollectionBehavior": "PlayerCanSkipCollection" }, "offerUi": { "offerUiId": "69fb22e6dd352b799c65e97e", "active": true, "offerUiType": "PopUp", "offerUiSubType": "RewardCalendar", "name": "Weekly Reward Calendar Design", "externalId": "reward-calendar-design-1" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "quantity": 100, "priority": "Sub" } ], "priceInUsdCents": 0 }, { "index": 7, "products": [ { "publisherProductId": "chest", "quantity": 1, "priority": "Main" } ], "priceInUsdCents": 0 } ], "segments": [ "New User" ], "createdAt": "2026-06-08T10:00:44.528Z", "updatedAt": "2026-06-08T10:15:44.528Z" } ``` # Create Rolling Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/rolling-offers/create-rolling-offer openapi-rolling-offer.json POST /v2/offer Creates a rolling offer. ```bash Create Rolling Offer theme={"system"} curl -X POST \ 'https://api.appcharge.com/v2/offer' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "publisherOfferId": "rolling-offer-1", "name": "My Rolling Offer", "type": "RollingOffer", "active": true, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "613", "name": "Sword", "textFontColorHex": "#f60404", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/25cb7861ec8924a6b69a0f59/408472.png" }, { "type": "productPrefix", "url": "" } ], "createdAt": "2024-03-01T10:14:34.142Z", "updatedAt": "2025-02-05T13:20:50.759Z", "displayName": "Sword", "productId": "25e1aa8a7ef37e0d94b16fdf" } ], "priceInUsdCents": 5000 }, { "index": 2, "products": [ { "product": { "publisherProductId": "614", "name": "Boost", "textFontColorHex": "#bfc6e8", "type": "Quantity", "prefix": "+", "suffix": "🎉", "priority": "Sub", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/25cb7861ec8924a6b69a0f59/1730204644395__99c7d8e4-4658-49db-ac4f-501ab93fee9a" }, { "type": "productPrefix", "url": "" } ], "displayName": "Boost", "createdAt": "2024-10-29T12:24:23.083Z", "updatedAt": "2025-01-16T09:38:15.446Z", "productId": "6720d3f7aaca102ce5fb0ce2" } } ], "priceInUsdCents": 3000 } ], "priority": 1, "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-06-22T12:05:00.000Z", "endTime": "2025-06-22T12:10:00.000Z", "notes": "", "id": "68078610fb23b166fb160469" } ] }, "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "displayName": "My Rolling Offer", "description": "This is my rolling offer description.", "segments": [ "New User" ], "publisherTabId": "tab-1" }' ``` ```json Create Rolling Offer theme={"system"} { "publisherId": "35nb7861ec9924a6b69a0fe59", "offerId": "726cff96123a8717", "publisherOfferId": "rolling-offer-1", "name": "My Rolling Offer", "type": "RollingOffer", "active": true, "active": true, "displayName": "My Rolling Offer", "description": "This is my rolling offer description.", "segments": [ "New User" ], "publisherTabId": "tab-1", "offerUi": null, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "613", "name": "Sword", "textFontColorHex": "#f60404", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/25cb7861ec8924a6b69a0f59/408472.png" }, { "type": "productPrefix", "url": "" } ], "createdAt": "2024-03-01T10:14:34.142Z", "updatedAt": "2025-02-05T13:20:50.759Z", "displayName": "Sword", "productId": "25e1aa8a7ef37e0d94b16fdf" } ], "priceInUsdCents": 5000 }, { "index": 2, "products": [ { "product": { "publisherProductId": "614", "name": "Boost", "textFontColorHex": "#bfc6e8", "type": "Quantity", "prefix": "+", "suffix": "🎉", "priority": "Sub", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/25cb7861ec8924a6b69a0f59/1730204644395__99c7d8e4-4658-49db-ac4f-501ab93fee9a" }, { "type": "productPrefix", "url": "" } ], "displayName": "Boost", "createdAt": "2024-10-29T12:24:23.083Z", "updatedAt": "2025-01-16T09:38:15.446Z", "productId": "6720d3f7aaca102ce5fb0ce2" } } ], "priceInUsdCents": 3000 } ], "priority": 1, "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-06-22T12:05:00.000Z", "endTime": "2025-06-22T12:10:00.000Z", "notes": "", "id": "68078610fb23b166fb160469" } ] }, "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ``` # Delete Rolling Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/rolling-offers/delete-rolling-offer openapi-rolling-offer.json DELETE /v2/offer/{publisherOfferId} Deletes a rolling offer. ```bash Delete Rolling Offer theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/v2/offer/rolling-offer-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Rolling Offer theme={"system"} { "publisherId": "35nb7861ec9924a6b69a0fe59", "offerId": "726cff96123a8717", "publisherOfferId": "rolling-offer-1", "name": "My Rolling Offer", "type": "RollingOffer", "active": true, "active": true, "displayName": "My Rolling Offer", "description": "This is my rolling offer description.", "segments": [ "New User" ], "publisherTabId": "tab-1", "offerUi": null, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "613", "name": "Sword", "textFontColorHex": "#f60404", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/25cb7861ec8924a6b69a0f59/408472.png" }, { "type": "productPrefix", "url": "" } ], "createdAt": "2024-03-01T10:14:34.142Z", "updatedAt": "2025-02-05T13:20:50.759Z", "displayName": "Sword", "productId": "25e1aa8a7ef37e0d94b16fdf" } ], "priceInUsdCents": 5000 }, { "index": 2, "products": [ { "product": { "publisherProductId": "614", "name": "Boost", "textFontColorHex": "#bfc6e8", "type": "Quantity", "prefix": "+", "suffix": "🎉", "priority": "Sub", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/25cb7861ec8924a6b69a0f59/1730204644395__99c7d8e4-4658-49db-ac4f-501ab93fee9a" }, { "type": "productPrefix", "url": "" } ], "displayName": "Boost", "createdAt": "2024-10-29T12:24:23.083Z", "updatedAt": "2025-01-16T09:38:15.446Z", "productId": "6720d3f7aaca102ce5fb0ce2" } } ], "priceInUsdCents": 3000 } ], "priority": 1, "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-06-22T12:05:00.000Z", "endTime": "2025-06-22T12:10:00.000Z", "notes": "", "id": "68078610fb23b166fb160469" } ] }, "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ``` # Get Rolling Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/rolling-offers/get-rolling-offer openapi-rolling-offer.json GET /v2/offer Retrieves one or more rolling offers. ```bash Get Rolling Offer theme={"system"} curl -X GET \ 'https://api.appcharge.com/v2/offer?publisherOfferIds=rolling-offer-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Get Rolling Offer theme={"system"} { "totalCount": 1, "offers": [ { "publisherId": "35nb7861ec9924a6b69a0fe59", "offerId": "726cff96123a8717", "publisherOfferId": "rolling-offer-1", "name": "My Rolling Offer", "type": "RollingOffer", "active": true, "active": true, "displayName": "My Rolling Offer", "description": "This is my rolling offer description.", "segments": [ "New User" ], "publisherTabId": "tab-1", "offerUi": null, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "613", "name": "Sword", "textFontColorHex": "#f60404", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/25cb7861ec8924a6b69a0f59/408472.png" }, { "type": "productPrefix", "url": "" } ], "createdAt": "2024-03-01T10:14:34.142Z", "updatedAt": "2025-02-05T13:20:50.759Z", "displayName": "Sword", "productId": "25e1aa8a7ef37e0d94b16fdf" } ], "priceInUsdCents": 5000 }, { "index": 2, "products": [ { "product": { "publisherProductId": "614", "name": "Boost", "textFontColorHex": "#bfc6e8", "type": "Quantity", "prefix": "+", "suffix": "🎉", "priority": "Sub", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/25cb7861ec8924a6b69a0f59/1730204644395__99c7d8e4-4658-49db-ac4f-501ab93fee9a" }, { "type": "productPrefix", "url": "" } ], "displayName": "Boost", "createdAt": "2024-10-29T12:24:23.083Z", "updatedAt": "2025-01-16T09:38:15.446Z", "productId": "6720d3f7aaca102ce5fb0ce2" } } ], "priceInUsdCents": 3000 } ], "priority": 1, "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-06-22T12:05:00.000Z", "endTime": "2025-06-22T12:10:00.000Z", "notes": "", "id": "68078610fb23b166fb160469" } ] }, "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ] } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/rolling-offers/introduction The Rolling Offers API allows you to create and manage rolling offers. These offers unlock new sub-offers as players progress. Each offer reveals the next, motivating repeat interactions before the promotion resets. These time-sensitive offers are scheduled, with a countdown timer showing how long the current offer is active. If players don't unlock all the offers before time runs out, the sequence resets. With the Rolling Offers API, you can: * [Create a new rolling offer](./create-rolling-offer). * [Update an existing rolling offer](./update-rolling-offer). * [Retrieve one or more rolling offers](./get-rolling-offer). * [Retrieve all rolling offers](../get-offers). * [Delete a rolling offer](./delete-rolling-offer). # Update Rolling Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/rolling-offers/update-rolling-offer openapi-rolling-offer.json PUT /v2/offer/${publisherOfferId} Updates a rolling offer. ```bash Update Rolling Offer theme={"system"} curl -X PUT \ 'https://api.appcharge.com/v2/offer/rolling-offer-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "name": "My New Rolling Offer Name", "type": "RollingOffer", "active": true, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "613", "name": "Sword", "textFontColorHex": "#f60404", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/25cb7861ec8924a6b69a0f59/408472.png" }, { "type": "productPrefix", "url": "" } ], "createdAt": "2024-03-01T10:14:34.142Z", "updatedAt": "2025-02-05T13:20:50.759Z", "displayName": "Sword", "productId": "25e1aa8a7ef37e0d94b16fdf" } ], "priceInUsdCents": 5000 }, { "index": 2, "products": [ { "product": { "publisherProductId": "614", "name": "Boost", "textFontColorHex": "#bfc6e8", "type": "Quantity", "prefix": "+", "suffix": "🎉", "priority": "Sub", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/25cb7861ec8924a6b69a0f59/1730204644395__99c7d8e4-4658-49db-ac4f-501ab93fee9a" }, { "type": "productPrefix", "url": "" } ], "displayName": "Boost", "createdAt": "2024-10-29T12:24:23.083Z", "updatedAt": "2025-01-16T09:38:15.446Z", "productId": "6720d3f7aaca102ce5fb0ce2" } } ], "priceInUsdCents": 3000 } ], "priority": 1, "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-06-22T12:05:00.000Z", "endTime": "2025-06-22T12:10:00.000Z", "notes": "", "id": "68078610fb23b166fb160469" } ] }, "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "displayName": "My Rolling Offer", "description": "This is my rolling offer description.", "segments": [ "New User" ] }' ``` ```json Update Rolling Offer theme={"system"} { "publisherId": "35nb7861ec9924a6b69a0fe59", "offerId": "726cff96123a8717", "publisherOfferId": "rolling-offer-1", "name": "My New Rolling Offer Name", "type": "RollingOffer", "active": true, "active": true, "displayName": "My Rolling Offer", "description": "This is my rolling offer description.", "segments": [ "New User" ], "publisherTabId": "tab-1", "offerUi": null, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "613", "name": "Sword", "textFontColorHex": "#f60404", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/25cb7861ec8924a6b69a0f59/408472.png" }, { "type": "productPrefix", "url": "" } ], "createdAt": "2024-03-01T10:14:34.142Z", "updatedAt": "2025-02-05T13:20:50.759Z", "displayName": "Sword", "productId": "25e1aa8a7ef37e0d94b16fdf" } ], "priceInUsdCents": 5000 }, { "index": 2, "products": [ { "product": { "publisherProductId": "614", "name": "Boost", "textFontColorHex": "#bfc6e8", "type": "Quantity", "prefix": "+", "suffix": "🎉", "priority": "Sub", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/25cb7861ec8924a6b69a0f59/1730204644395__99c7d8e4-4658-49db-ac4f-501ab93fee9a" }, { "type": "productPrefix", "url": "" } ], "displayName": "Boost", "createdAt": "2024-10-29T12:24:23.083Z", "updatedAt": "2025-01-16T09:38:15.446Z", "productId": "6720d3f7aaca102ce5fb0ce2" } } ], "priceInUsdCents": 3000 } ], "priority": 1, "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2025-06-22T12:05:00.000Z", "endTime": "2025-06-22T12:10:00.000Z", "notes": "", "id": "68078610fb23b166fb160469" } ] }, "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-06-06T10:00:44.528Z" } ``` # Create Special Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/special-offers/create-special-offer openapi-special-offers.json POST /v2/offer Creates a special offer. ```bash Create Special Offer theme={"system"} curl -X POST \ 'https://api.appcharge.com/v2/offer' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "publisherOfferId": "special-offer-1", "name": "My Special Offer", "type": "SpecialOffer", "active": true, "segments": [ "New User" ], "publisherTabId": "tab-1", "productsSequence": [ { "index": 1, "playerAvailability": 12, "hidePlayerAvailability": true, "products": [ { "priority": "Sub", "publisherProductId": "6cb43621ccf1", "quantity": "100", } ] "priceInUsdCents": 1000 } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "displayName": "My Special Offer", "description": "This is my special offer description.", "offerUiId": "2bc77ff889b", "offerExternalUiId": "2bc22377ff889cc", "badges": [ { "publisherBadgeId": "12ac77ff889b" } ] }' ``` ```json Create Special Offer theme={"system"} { "publisherId": "35nb7861ec9924a6b69a0fe59", "offerId": "226cff96123a8717", "publisherOfferId": "special-offer-1", "displayName": "My Special Offer", "description": "This is my special offer description.", "name": "My Special Offer", "type": "SpecialOffer", "active": true, "segments": [ "New User" ], "publisherTabId": "tab-1", "offerUi": { "offerUiId": "2bc77ff889b", "active": true, "offerUiType": "SpecialOffer", "name": "specialOffer1", "description": "description", "backgroundImage": "https://media.appcharge.com/media/65cb7182__4dc30c81-e4aa-40e8-9033-84cb05721bd0", "borderColor": { "colorOne": "#ffffff", "colorTwo": "", "direction": "" }, "borderWidth": 2, "externalId": "specialOffer1" }, "productsSequence": [ { "index": 1, "playerAvailability": 12, "hidePlayerAvailability": true, "products": [ { "product": { "publisherProductId": "6cb43621ccf1", "name": "Coins", "textFontColorHex": "#FFFFFF", "type": "Quantity", "prefix": "", "suffix": "", "priority": "Sub", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/45cb7861ec8924a6b69a0f59/download.jpeg" }, { "type": "productPrefix", "url": "" } ], "createdAt": "2024-02-14T10:08:17.061Z", "updatedAt": "2024-09-27T13:41:55.775Z", "displayName": "coins", "productId": "75cc91114cf653a9cc2dce2c" }, "publisherProductId": "6cb43621ccf1", "quantity": 1000, "priority": "Main" } ], "priceInUsdCents": 980, "badges": [], "id": "68b4092c7a895e559a3ac8d9" } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "offerExternalUiId": "2bc22377ff889cc", "badges": [ { "publisherBadgeId": "12ac77ff889b" } ], "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ``` # Delete Special Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/special-offers/delete-special-offer openapi-special-offers.json DELETE /v2/offer/{publisherOfferId} Deletes a special offer. ```bash Delete Special Offer theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/v2/offer/special-offer-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Special Offer theme={"system"} { "publisherId": "35nb7861ec9924a6b69a0fe59", "offerId": "226cff96123a8717", "publisherOfferId": "special-offer-1", "displayName": "My Special Offer", "description": "This is my special offer description.", "name": "My Special Offer", "type": "SpecialOffer", "active": true, "segments": [ "New User" ], "publisherTabId": "tab-1", "offerUi": { "offerUiId": "2bc77ff889b", "active": true, "offerUiType": "SpecialOffer", "name": "specialOffer1", "description": "description", "backgroundImage": "https://media.appcharge.com/media/65cb7182__4dc30c81-e4aa-40e8-9033-84cb05721bd0", "borderColor": { "colorOne": "#ffffff", "colorTwo": "", "direction": "" }, "borderWidth": 2, "externalId": "specialOffer1" }, "productsSequence": [ { "index": 1, "playerAvailability": 12, "products": [ { "product": { "publisherProductId": "6cb43621ccf1", "name": "Coins", "textFontColorHex": "#FFFFFF", "type": "Quantity", "prefix": "", "suffix": "", "priority": "Sub", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/45cb7861ec8924a6b69a0f59/download.jpeg" }, { "type": "productPrefix", "url": "" } ], "createdAt": "2024-02-14T10:08:17.061Z", "updatedAt": "2024-09-27T13:41:55.775Z", "displayName": "coins", "productId": "75cc91114cf653a9cc2dce2c" }, "publisherProductId": "6cb43621ccf1", "quantity": 1000, "priority": "Main" } ], "priceInUsdCents": 980, "badges": [], "id": "68b4092c7a895e559a3ac8d9" } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "offerExternalUiId": "2bc22377ff889cc", "badges": [ { "publisherBadgeId": "12ac77ff889b" } ], "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ``` # Get Special Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/special-offers/get-special-offer openapi-special-offers.json GET /v2/offer Retrieves one or more special offers. ```bash Get Special Offer theme={"system"} curl -X GET \ 'https://api.appcharge.com/v2/offer?publisherOfferIds=special-offer-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Get Special Offer theme={"system"} { "totalCount": 1, "offers": [ { "publisherId": "35nb7861ec9924a6b69a0fe59", "offerId": "226cff96123a8717", "publisherOfferId": "special-offer-1", "displayName": "My Special Offer", "description": "This is my special offer description.", "name": "My Special Offer", "type": "SpecialOffer", "active": true, "segments": [ "New User" ], "publisherTabId": "tab-1", "offerUi": { "offerUiId": "2bc77ff889b", "active": true, "offerUiType": "SpecialOffer", "name": "specialOffer1", "description": "description", "backgroundImage": "https://media.appcharge.com/media/65cb7182__4dc30c81-e4aa-40e8-9033-84cb05721bd0", "borderColor": { "colorOne": "#ffffff", "colorTwo": "", "direction": "" }, "borderWidth": 2, "externalId": "specialOffer1" }, "productsSequence": [ { "index": 1, "playerAvailability": 12, "products": [ { "product": { "publisherProductId": "6cb43621ccf1", "name": "Coins", "textFontColorHex": "#FFFFFF", "type": "Quantity", "prefix": "", "suffix": "", "priority": "Sub", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/45cb7861ec8924a6b69a0f59/download.jpeg" }, { "type": "productPrefix", "url": "" } ], "createdAt": "2024-02-14T10:08:17.061Z", "updatedAt": "2024-09-27T13:41:55.775Z", "displayName": "coins", "productId": "75cc91114cf653a9cc2dce2c" }, "publisherProductId": "6cb43621ccf1", "quantity": 1000, "priority": "Main" } ], "priceInUsdCents": 980, "badges": [], "id": "68b4092c7a895e559a3ac8d9" } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "offerExternalUiId": "2bc22377ff889cc", "badges": [ { "publisherBadgeId": "12ac77ff889b" } ], "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-04-06T10:00:44.528Z" } ] } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/special-offers/introduction The Special Offers API allows you to create and manage special product offers in your web store. Special offers feature one or more products that can be scheduled to appear at specific times. These offers typically appear in a rotating gallery at the top of the web store, and are often used to highlight time-limited deals. With the Special Offers API, you can: * [Create a special offer](./create-special-offer). * [Update an existing special offer](./update-special-offer). * [Retrieve one or more special offers](./get-special-offer). * [Retrieve all special offers](../get-offers). * [Delete a special offer](./delete-special-offer). # Update Special Offer Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/special-offers/update-special-offer openapi-special-offers.json PUT /v2/offer/${publisherOfferId} Updates a special offer. ```bash Update Special Offer theme={"system"} curl -X POST \ 'https://api.appcharge.com/v2/offer/special-offer-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "name": "My New Special Offer Name", "type": "SpecialOffer", "active": true, "segments": [ "New User" ], "productsSequence": [ { "index": 1, "playerAvailability": 12, "hidePlayerAvailability": true, "products": [ { "priority": "Sub", "publisherProductId": "6cb43621ccf1", "quantity": "100", } ] "priceInUsdCents": 1000 } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "displayName": "My Special Offer", "description": "This is my special offer description.", "offerUiId": "2bc77ff889b", "offerExternalUiId": "2bc22377ff889cc", "badges": [ { "publisherBadgeId": "12ac77ff889b" } ] }' ``` ```json Update Special Offer theme={"system"} { "publisherId": "35nb7861ec9924a6b69a0fe59", "offerId": "226cff96123a8717", "publisherOfferId": "special-offer-1", "displayName": "My Special Offer", "description": "This is my special offer description.", "name": "My New Special Offer Name", "type": "SpecialOffer", "active": true, "segments": [ "New User" ], "publisherTabId": "tab-1", "offerUi": { "offerUiId": "2bc77ff889b", "active": true, "offerUiType": "SpecialOffer", "name": "specialOffer1", "description": "description", "backgroundImage": "https://media.appcharge.com/media/65cb7182__4dc30c81-e4aa-40e8-9033-84cb05721bd0", "borderColor": { "colorOne": "#ffffff", "colorTwo": "", "direction": "" }, "borderWidth": 2, "externalId": "specialOffer1" }, "productsSequence": [ { "index": 1, "playerAvailability": 12, "hidePlayerAvailability": true, "products": [ { "product": { "publisherProductId": "6cb43621ccf1", "name": "Coins", "textFontColorHex": "#FFFFFF", "type": "Quantity", "prefix": "", "suffix": "", "priority": "Sub", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/45cb7861ec8924a6b69a0f59/download.jpeg" }, { "type": "productPrefix", "url": "" } ], "createdAt": "2024-02-14T10:08:17.061Z", "updatedAt": "2024-09-27T13:41:55.775Z", "displayName": "coins", "productId": "75cc91114cf653a9cc2dce2c" }, "publisherProductId": "6cb43621ccf1", "quantity": 1000, "priority": "Main" } ], "priceInUsdCents": 980, "badges": [], "id": "68b4092c7a895e559a3ac8d9" } ], "productSale": { "type": "percentage", "sale": 100 }, "priceDiscount": { "type": "percentage", "discount": 20 }, "offerExternalUiId": "2bc22377ff889cc", "badges": [ { "publisherBadgeId": "12ac77ff889b" } ], "createdAt": "2025-04-06T10:00:44.528Z", "updatedAt": "2025-06-06T10:00:44.528Z" } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/triggered-popups/introduction The Triggered Popups API is a suite of APIs that allow you to create and manage Triggered Popup offers in your web store. These offers are triggered when specific actions occur in the web store, such as when a player completes a purchase or refreshes the store. Learn more about the [Triggered Popups](/../../guides/webstore/offers/triggered-popups/about-triggered-popups) feature. The Triggered Popups API includes the following: * [Post Purchase Popups API](./post-purchase-popups/introduction): Create and manage popup offers triggered when a player makes a purchase. * [Store Refresh Popups API](./store-refresh-popups/introduction): Create and manage popup offers triggered when a player refreshes the web store. # Create Post Purchase Popup Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/triggered-popups/post-purchase-popups/create-post-purchase-popup openapi-post-purchase.json POST /v2/offer Creates a post purchase offer. ```bash Create Post Purchase Popup theme={"system"} curl -X POST \ 'https://api.appcharge.com/v2/offer' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ --data '{ "publisherOfferId": "post-purchase-1", "name": "Purchase Reward Offer", "displayName": "Purchase Reward Offer", "description": "Post purchase offer for VIP players.", "type": "PopUp", "subType": "PostPurchase", "active": true, "priority": 1, "offerExternalUiId": "popup", "segments": [], "productsSequence": [ { "index": 1, "products": [ { "priority":"Main", "publisherProductId": "TreasureChest", "quantity": 10 } ], "priceInUsdCents": 2000 } ] }' ``` ```json Create Post Purchase Popup theme={"system"} { "publisherId": "35nb7861ec9924a6b69a0fe59", "publisherOfferId": "post-purchase-1", "name": "Purchase Reward Offer", "displayName": "Purchase Reward Offer", "description": "Post purchase offer for VIP players.", "type": "PopUp", "subType": "PostPurchase", "active": true, "segments": [], "offerUi": { "offerUiId": "68b41c5aa1c5b1a284737e9b", "active": true, "offerUiType": "PopUp", "name": "popup", "description": "description", "backgroundImage": "https://media.appcharge.com/media/35nb7861ec9924a6b69a0fe59/2755379465856__fa883338-5790-47c8-a6a0-23cb43db58844", "externalId": "popup" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "TreasureChest", "name": "Treasure Chest", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/35nb7861ec9924a6b69a0fe59/2208472.png" }, { "type": "productPrefix", "url": "" } ], "displayName": "Treasure Chest" } } ] } ], "priority": 1, "showAfter": "purchase", "triggers": [ { "type": "event", "eventName": "purchase", "every": 1, "rules": [] } ], "createdAt": "2025-09-01T14:16:09.499Z", "updatedAt": "2025-09-01T14:16:09.499Z", "offerId": "68b5aaa9b73fceb9ffc26f9b" } ``` # Delete Post Purchase Popup Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/triggered-popups/post-purchase-popups/delete-post-purchase-popup openapi-post-purchase.json DELETE /v2/offer/{publisherOfferId} Deletes a post purchase popup. ```bash Delete Post Purchase Popup theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/v2/offer/post-purchase-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Post Purchase Popup theme={"system"} { "publisherId": "35nb7861ec9924a6b69a0fe59", "publisherOfferId": "post-purchase-1", "name": "Purchase Reward Offer", "displayName": "Purchase Reward Offer", "description": "Post purchase offer for VIP players.", "type": "PopUp", "subType": "PostPurchase", "active": true, "segments": [], "offerUi": { "offerUiId": "68b41c5aa1c5b1a284737e9b", "active": true, "offerUiType": "PopUp", "name": "popup", "description": "description", "backgroundImage": "https://media.appcharge.com/media/35nb7861ec9924a6b69a0fe59/2755379465856__fa883338-5790-47c8-a6a0-23cb43db58844", "externalId": "popup" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "TreasureChest", "name": "Treasure Chest", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/35nb7861ec9924a6b69a0fe59/2208472.png" }, { "type": "productPrefix", "url": "" } ], "displayName": "Treasure Chest" } } ] } ], "priority": 1, "showAfter": "purchase", "triggers": [ { "type": "event", "eventName": "purchase", "every": 1, "rules": [] } ], "createdAt": "2025-09-01T14:16:09.499Z", "updatedAt": "2025-09-01T14:16:09.499Z", "offerId": "68b5aaa9b73fceb9ffc26f9b" } ``` # Get Post Purchase Popup Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/triggered-popups/post-purchase-popups/get-post-purchase-popup openapi-post-purchase.json GET /v2/offer Retrieves one or more post purchase popups. ```bash Get Post Purchase Popup theme={"system"} curl -X GET \ 'https://api.appcharge.com/v2/offer?publisherOfferIds=post-purchase-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Get Post Purchase Popup theme={"system"} { "totalCount": 1, "offers": [ { "publisherId": "35nb7861ec9924a6b69a0fe59", "publisherOfferId": "post-purchase-1", "name": "Purchase Reward Offer", "displayName": "Purchase Reward Offer", "description": "Post purchase offer for VIP players.", "type": "PopUp", "subType": "PostPurchase", "active": true, "segments": [], "offerUi": { "offerUiId": "68b41c5aa1c5b1a284737e9b", "active": true, "offerUiType": "PopUp", "name": "popup", "description": "description", "backgroundImage": "https://media.appcharge.com/media/35nb7861ec9924a6b69a0fe59/2755379465856__fa883338-5790-47c8-a6a0-23cb43db58844", "externalId": "popup" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "TreasureChest", "name": "Treasure Chest", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/35nb7861ec9924a6b69a0fe59/2208472.png" }, { "type": "productPrefix", "url": "" } ], "displayName": "Treasure Chest" } } ] } ], "priority": 1, "showAfter": "purchase", "triggers": [ { "type": "event", "eventName": "purchase", "every": 1, "rules": [] } ], "createdAt": "2025-09-01T14:16:09.499Z", "updatedAt": "2025-09-01T14:16:09.499Z", "offerId": "68b5aaa9b73fceb9ffc26f9b" } ] } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/triggered-popups/post-purchase-popups/introduction The Post Purchase Popups API allows you to create and manage popups that are triggered after a player completes a purchase in your web store. Use Post Purchase popups to offer a paid product or free reward after checkout. With the Post Purchase Popups API, you can: * [Create a new post purchase popup](./create-post-purchase-popup). * [Update an existing post purchase popup](./update-post-purchase-popup). * [Retrieve one or more post purchase popups](./get-post-purchase-popup). * [Retrieve all post purchase popups](../../get-offers). * [Delete a post purchase popup](./delete-post-purchase-popup). # Update Post Purchase Popup Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/triggered-popups/post-purchase-popups/update-post-purchase-popup openapi-post-purchase.json PUT /v2/offer/${publisherOfferId} Updates a post purchase offer. ```bash Update Post Purchase Popup theme={"system"} curl -X PUT \ 'https://api.appcharge.com/v2/offer/post-purchase-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "name": "New Post Purchase Name", "displayName": "Purchase Reward Offer", "description": "The post purchase offer for VIP players.", "type": "PopUp", "subType": "PostPurchase", "active": true, "priority": 1, "offerExternalUiId": "popup", "segments": [], "productsSequence": [ { "index": 1, "products": [ { "priority": "Main", "publisherProductId": "ManeProduct", "quantity": 104 } ], "priceInUsdCents": 2000 } ] }' ``` ```json Update Post Purchase Popup theme={"system"} { "publisherId": "35nb7861ec9924a6b69a0fe59", "publisherOfferId": "post-purchase-1", "name": "New Post Purchase Name", "displayName": "Purchase Reward Offer", "description": "Post purchase offer for VIP players.", "type": "PopUp", "subType": "PostPurchase", "active": true, "segments": [], "offerUi": { "offerUiId": "68b41c5aa1c5b1a284737e9b", "active": true, "offerUiType": "PopUp", "name": "popup", "description": "description", "backgroundImage": "https://media.appcharge.com/media/35nb7861ec9924a6b69a0fe59/2755379465856__fa883338-5790-47c8-a6a0-23cb43db58844", "externalId": "popup" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "TreasureChest", "name": "Treasure Chest", "type": "Quantity", "prefix": "$", "suffix": "M", "priority": "Main", "images": [ { "type": "product", "url": "https://media.appcharge.com/media/35nb7861ec9924a6b69a0fe59/2208472.png" }, { "type": "productPrefix", "url": "" } ], "displayName": "Treasure Chest" } } ] } ], "priority": 1, "showAfter": "purchase", "triggers": [ { "type": "event", "eventName": "purchase", "every": 1, "rules": [] } ], "createdAt": "2025-09-01T14:16:09.499Z", "updatedAt": "2025-09-01T14:16:09.499Z", "offerId": "68b5aaa9b73fceb9ffc26f9b" } ``` # Create Store Refresh Popup Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/triggered-popups/store-refresh-popups/create-store-refresh-popup openapi-store-refresh.json POST /v2/offer Creates a Store Refresh popup offer. Triggered when a player refreshes the web store. ```bash Create Store Refresh Popup theme={"system"} curl -X POST \ 'https://api.appcharge.com/v2/offer' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ --data '{ "type": "PopUp", "subType": "StoreRefresh", "active": true, "publisherOfferId": "store-refresh-offer-1", "name": "Store Refresh Offer 1", "displayName": "Limited time deal", "description": "Shown periodically when the store refreshes.", "segments": [], "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "green_diamond", "quantity": 1, "priority": "Main" }, { "publisherProductId": "pink_diamond", "quantity": 2, "priority": "Main" } ], "priceInUsdCents": 0, "playerAvailability": 10, "hidePlayerAvailability": true } ], "priority": 5, "offerExternalUiId": "Real_Store_Refresh", "displayRule": { "frequency": 3, "cooldownInMinutes": 1 }, "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2026-05-02T00:00:00.000Z", "endTime": "2026-05-04T23:59:59.000Z", "notes": "Initial weekend rollout" }, { "startTime": "2026-05-10T00:00:00.000Z", "endTime": "2026-05-12T23:59:59.000Z" } ] }, "productSale": { "sale": 30, "type": "percentage" }, "priceDiscount": { "discount": 25, "type": "percentage" }, "badges": [ { "publisherBadgeId": "best_value" } ] }' ``` ```json Create Store Refresh Popup theme={"system"} { "publisherId": "35nb7861ec9924a6b69a0fe59", "publisherOfferId": "store-refresh-offer", "name": "Store Refresh Offer", "displayName": "Limited time deal", "description": "Shown periodically when the store refreshes", "type": "PopUp", "subType": "StoreRefresh", "active": true, "segments": [], "offerUi": { "offerUiId": "68b41c5aa1c5b1a284737e9b", "active": true, "offerUiType": "PopUp", "name": "Real_Store_Refresh", "description": "description", "externalId": "Real_Store_Refresh" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "green_diamond", "name": "Green Diamond", "type": "Quantity", "priority": "Main", "displayName": "Green Diamond" } }, { "product": { "publisherProductId": "pink_diamond", "name": "Pink Diamond", "type": "Quantity", "priority": "Main", "displayName": "Pink Diamond" } } ], "priceInUsdCents": 0, "playerAvailability": 10, "hidePlayerAvailability": true } ], "priority": 5, "displayRule": { "frequency": 3, "cooldownInMinutes": 1 }, "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2026-05-02T00:00:00.000Z", "endTime": "2026-05-04T23:59:59.000Z", "notes": "Initial weekend rollout" }, { "startTime": "2026-05-10T00:00:00.000Z", "endTime": "2026-05-12T23:59:59.000Z" } ] }, "productSale": { "sale": 30, "type": "percentage" }, "priceDiscount": { "discount": 25, "type": "percentage" }, "badges": [ { "publisherBadgeId": "best_value" } ], "createdAt": "2026-05-01T14:16:09.499Z", "updatedAt": "2026-05-01T14:16:09.499Z", "offerId": "68b5aaa9b73fceb9ffc26f9b" } ``` # Delete Store Refresh Popup Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/triggered-popups/store-refresh-popups/delete-store-refresh-popup openapi-store-refresh.json DELETE /v2/offer/{publisherOfferId} Deletes a store refresh popup. ```bash Delete Store Refresh Popup theme={"system"} curl -X DELETE \ 'https://api.appcharge.com/v2/offer/store-refresh-offer-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Delete Store Refresh Popup theme={"system"} { "publisherId": "35nb7861ec9924a6b69a0fe59", "publisherOfferId": "store-refresh-offer", "name": "Store Refresh Offer", "displayName": "Limited time deal", "description": "Shown periodically when the store refreshes", "type": "PopUp", "subType": "StoreRefresh", "active": true, "segments": [], "offerUi": { "offerUiId": "68b41c5aa1c5b1a284737e9b", "active": true, "offerUiType": "PopUp", "name": "Real_Store_Refresh", "description": "description", "externalId": "Real_Store_Refresh" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "green_diamond", "name": "Green Diamond", "type": "Quantity", "priority": "Main", "displayName": "Green Diamond" } }, { "product": { "publisherProductId": "pink_diamond", "name": "Pink Diamond", "type": "Quantity", "priority": "Main", "displayName": "Pink Diamond" } } ], "priceInUsdCents": 0, "playerAvailability": 10 } ], "priority": 5, "displayRule": { "frequency": 3, "cooldownInMinutes": 1 }, "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2026-05-02T00:00:00.000Z", "endTime": "2026-05-04T23:59:59.000Z", "notes": "Initial weekend rollout" }, { "startTime": "2026-05-10T00:00:00.000Z", "endTime": "2026-05-12T23:59:59.000Z" } ] }, "productSale": { "sale": 30, "type": "percentage" }, "priceDiscount": { "discount": 25, "type": "percentage" }, "badges": [ { "publisherBadgeId": "best_value" } ], "createdAt": "2026-05-01T14:16:09.499Z", "updatedAt": "2026-05-01T14:16:09.499Z", "offerId": "68b5aaa9b73fceb9ffc26f9b" } ``` # Get Store Refresh Popup Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/triggered-popups/store-refresh-popups/get-store-refresh-popup openapi-store-refresh.json GET /v2/offer Retrieves one or more store refresh popups. ```bash Get Store Refresh Popup theme={"system"} curl -X GET \ 'https://api.appcharge.com/v2/offer?publisherOfferIds=store-refresh-offer-1' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Get Store Refresh Popup theme={"system"} { "totalCount": 1, "offers": [ { "publisherId": "35nb7861ec9924a6b69a0fe59", "publisherOfferId": "store-refresh-offer", "name": "Store Refresh Offer", "displayName": "Limited time deal", "description": "Shown periodically when the store refreshes", "type": "PopUp", "subType": "StoreRefresh", "active": true, "segments": [], "offerUi": { "offerUiId": "68b41c5aa1c5b1a284737e9b", "active": true, "offerUiType": "PopUp", "name": "Real_Store_Refresh", "description": "description", "externalId": "Real_Store_Refresh" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "green_diamond", "name": "Green Diamond", "type": "Quantity", "priority": "Main", "displayName": "Green Diamond" } }, { "product": { "publisherProductId": "pink_diamond", "name": "Pink Diamond", "type": "Quantity", "priority": "Main", "displayName": "Pink Diamond" } } ], "priceInUsdCents": 0, "playerAvailability": 10 } ], "priority": 5, "displayRule": { "frequency": 3, "cooldownInMinutes": 1 }, "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2026-05-02T00:00:00.000Z", "endTime": "2026-05-04T23:59:59.000Z", "notes": "Initial weekend rollout" }, { "startTime": "2026-05-10T00:00:00.000Z", "endTime": "2026-05-12T23:59:59.000Z" } ] }, "productSale": { "sale": 30, "type": "percentage" }, "priceDiscount": { "discount": 25, "type": "percentage" }, "badges": [ { "publisherBadgeId": "best_value" } ], "createdAt": "2026-05-01T14:16:09.499Z", "updatedAt": "2026-05-01T14:16:09.499Z", "offerId": "68b5aaa9b73fceb9ffc26f9b" } ] } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/triggered-popups/store-refresh-popups/introduction The Store Refresh Popups API allows you to create and manage popups that are triggered when the web store refreshes. A store refresh can happen after player login, when the browser is refreshed, or when the store is explicitly reloaded. With the Store Refresh Popups API, you can: * [Create a new store refresh popup](./create-store-refresh-popup). * [Update an existing store refresh popup](./update-store-refresh-popup). * [Retrieve one or more store refresh popups](./get-store-refresh-popup). * [Retrieve all store refresh popups](../../get-offers). * [Delete a store refresh popup](./delete-store-refresh-popup). # Update Store Refresh Popup Source: https://docs.appcharge.com/api-reference/webstore/offers-v2/triggered-popups/store-refresh-popups/update-store-refresh-popup openapi-store-refresh.json PUT /v2/offer/${publisherOfferId} Updates a Store Refresh popup offer. ```bash Update Store Refresh Popup theme={"system"} curl -X PUT \ 'https://api.appcharge.com/v2/offer/store-refresh-offer' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "type": "PopUp", "subType": "StoreRefresh", "active": true, "name": "Updated Store Refresh Offer", "displayName": "Updated limited time deal", "description": "Shown periodically when the store refreshes", "segments": [], "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "green_diamond", "quantity": 1, "priority": "Main" }, { "publisherProductId": "pink_diamond", "quantity": 2, "priority": "Main" } ], "priceInUsdCents": 0, "playerAvailability": 10, "hidePlayerAvailability": true } ], "priority": 5, "offerExternalUiId": "Real_Store_Refresh", "displayRule": { "frequency": 3, "cooldownInMinutes": 1 }, "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2026-05-02T00:00:00.000Z", "endTime": "2026-05-04T23:59:59.000Z", "notes": "Initial weekend rollout" }, { "startTime": "2026-05-10T00:00:00.000Z", "endTime": "2026-05-12T23:59:59.000Z" } ] }, "productSale": { "sale": 30, "type": "percentage" }, "priceDiscount": { "discount": 25, "type": "percentage" }, "badges": [ { "publisherBadgeId": "best_value" } ] }' ``` ```json Update Store Refresh Popup theme={"system"} { "publisherId": "35nb7861ec9924a6b69a0fe59", "publisherOfferId": "store-refresh-offer", "name": "Updated Store Refresh Offer", "displayName": "Updated limited time deal", "description": "Shown periodically when the store refreshes", "type": "PopUp", "subType": "StoreRefresh", "active": true, "segments": [], "offerUi": { "offerUiId": "68b41c5aa1c5b1a284737e9b", "active": true, "offerUiType": "PopUp", "name": "Real_Store_Refresh", "description": "description", "externalId": "Real_Store_Refresh" }, "productsSequence": [ { "index": 1, "products": [ { "product": { "publisherProductId": "green_diamond", "name": "Green Diamond", "type": "Quantity", "priority": "Main", "displayName": "Green Diamond" } }, { "product": { "publisherProductId": "pink_diamond", "name": "Pink Diamond", "type": "Quantity", "priority": "Main", "displayName": "Pink Diamond" } } ], "priceInUsdCents": 0, "playerAvailability": 10, "hidePlayerAvailability": true } ], "priority": 5, "displayRule": { "frequency": 3, "cooldownInMinutes": 1 }, "schedule": { "permanent": false, "timeFrames": [ { "startTime": "2026-05-02T00:00:00.000Z", "endTime": "2026-05-04T23:59:59.000Z", "notes": "Initial weekend rollout" }, { "startTime": "2026-05-10T00:00:00.000Z", "endTime": "2026-05-12T23:59:59.000Z" } ] }, "productSale": { "sale": 30, "type": "percentage" }, "priceDiscount": { "discount": 25, "type": "percentage" }, "badges": [ { "publisherBadgeId": "best_value" } ], "createdAt": "2026-05-01T14:16:09.499Z", "updatedAt": "2026-05-02T14:16:09.499Z", "offerId": "68b5aaa9b73fceb9ffc26f9b" } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/personalization/introduction The Web Store Personalization API service allows you to deliver personalized content in the web store for each player. Appcharge automatically triggers the [Personalize Web Store Callback](./personalize-webstore-callback) during specific events in the web store. When this callback is invoked, your server receives a request for the player's most current data, including their latest in-game activity such as level, balance, and segment, as well as all available offers for that player. Appcharge uses the data you return to update the player’s web store with the latest relevant offers and visual elements, such as profile images and promotional banners. Each player sees content that reflects their current status and behavior. If you want to refresh player data outside of the automatic events, you can invoke the callback on demand. Learn more about the [Personalization](/../../guides/webstore/personalization/about-personalization) feature. With the Web Store Personalization API service, you can: * Get notified when to [personalize a player's web store](./personalize-webstore-callback). * Trigger [web store personalization for all players](./trigger-webstore-personalization). * Trigger [web store personalization for specific players by ID](./trigger-webstore-personalization-by-player-id). ## Override properties Several properties in the [Personalize Web Store Callback](./personalize-webstore-callback) response include `Override` in their name. These properties replace values configured in the Publisher Dashboard with personalized values for the web store. When you pass an override property, the web store renders that value instead of the saved default. If you omit an override property, the web store falls back to the saved default. ## Before you begin Review the following before you begin: * You must [configure personalization](/../../guides/webstore/personalization/configure-personalization) for your web store in the Publisher Dashboard. * If you're implementing a [Progress Bar](/../../guides/webstore/offers/progress-bars/about-progress-bars), you need to: 1. Pass the offer as usual in the `offers` array: ```json theme={"system"} { "publisherOfferId": "progress_bar_1", "productsSequence": [ { // Mission or Milestone 1 "index": 1, "products": [ { "publisherProductId": "coins", "quantity": "500" } ] }, { // Mission or Milestone 2 "index": 2, "products": [ { "publisherProductId": "coins", "quantity": "700" } ] } ] } ``` 2. Add the `progressBarPoints` property to the offers you want to contribute to towards the Progress Bar. ```json theme={"system"} { "publisherOfferId": "bundle_offer_1", "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "quantity": "200" } ], "progressBarPoints": [ { "publisherBarId": "progress_bar_1", "points": 200 } ] } ] } ``` # Personalize Web Store Callback Source: https://docs.appcharge.com/api-reference/webstore/personalization/personalize-webstore-callback openapi-personalize-webstore-callback.json POST /{YOUR_PERSONALIZE_WEBSTORE_ENDPOINT} > **Note:** This is a callback API. Appcharge calls this endpoint on your server when specific events occur. Notifies your system to personalize the web store for a player. Appcharge calls this endpoint when: - A player logs in to your web store. - A player completes a purchase. - Every 5 minutes after the player’s last sync. Your server responds with the most current player data and all available offers for the player. Appcharge then updates the web store for the player accordingly. ```bash Personalize Web Store theme={"system"} curl -X POST \ 'https://{YOUR_PERSONALIZE_WEBSTORE_ENDPOINT}' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -H 'signature: ' \ -d '{ "playerId": "vip2247691" }' ``` ```json Personalize Web Store theme={"system"} { "version": 2, "logo": "game_logo_main", "status": "valid", "sessionMetadata": { "abTestGroup": "variant_A", "locale": "en-US", "campaignId": "summer_2025" }, "profileFrameId": "diamond_frame", "playerLevelName": "Diamond Tier", "bannerExternalId": "welcome_banner_01", "playerLevel": { "assetId": "level_diamond", "text": "15% OFF", "endsIn": 1735689600000 }, "playerLevelBanners": [ { "assetId": "seasonal_banner", "designId": "banner_design_01", "text": [ { "id": "title", "content": "Summer Sale" }, { "id": "subtitle", "content": "Up to 50% off" } ], "endsIn": 1735689600000 } ], "offersOrder": "priceLowToHigh", "sectionsOrder": [ "featured", "daily_deals", "bundles" ], "segments": [ "vip_players", "high_spenders", "active_users" ], "focus": { "publisherBundleId": "mega_bundle" }, "attributes": { "player_tier": "diamond", "monetization_persona": "whale", "last_purchase_days": 3 }, "storeTheme": { "bgImageMobile": "mobile_bg_2", "bgImageDesktop": "desktop_bg_2", "logo": "store_logo_2", "profileFrameImage": "profile_frame_2", "bannerImage": "banner_2", "playerLevelImage": "player_level_2" }, "balances": [ { "publisherProductId": "gold_coins", "quantity": 15420 }, { "publisherProductId": "gems", "quantity": 850 }, { "publisherProductId": "energy", "quantity": 95 } ], "offers": [ { "publisherOfferId": "starter_pack_01", "offerDesignOverride": { "titleText": "Starter Pack", "offerDesignSubtitleTextOverride": "Perfect for new players" }, "offerDescriptionOverride": "Everything you need to get started! A great value bundle with essential resources.", "priceDiscount": { "priceBeforeDiscount": 999, "discount": 25, "type": "percentage" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "gold_coins", "quantity": 5000, "priority": "Main", "assetId": "gold_chest", "traits": [ { "assetId": "rarity_common", "text": "Rarity: Common" }, { "assetId": "bonus_starter", "text": "Starter Bonus: +50%" } ] }, { "publisherProductId": "gems", "quantity": 100, "priority": "Sub" }, { "publisherProductId": "energy", "quantity": 50, "priority": "Sub" } ] } ] }, { "publisherOfferId": "progress_bar_1", "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "coins", "quantity": "500" } ] }, { "index": 2, "products": [ { "publisherProductId": "coins", "quantity": "700" } ] }, { "index": 3, "products": [ { "publisherProductId": "coins", "quantity": "800" } ] } ] }, { "publisherOfferId": "weekend_special", "offerDesignOverride": { "titleText": "Weekend Special", "offerDesignSubtitleTextOverride": "Limited time weekend deal" }, "offerDescriptionOverride": "Don't miss out on this exclusive weekend offer with premium rewards!", "priceDiscount": { "priceBeforeDiscount": 4999, "discount": 40, "type": "percentage" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "gems", "quantity": 1200, "priority": "Main", "traits": [ { "assetId": "rarity_rare", "text": "Rarity: Rare" }, { "assetId": "bonus_weekend", "text": "Weekend Bonus: +100%" }, { "assetId": "time_limited", "text": "Time Limited" } ] }, { "publisherProductId": "gold_coins", "quantity": 25000, "priority": "Sub" }, { "publisherProductId": "energy", "quantity": 200, "priority": "Sub" } ], "progressBarPoints": [ { "publisherBarId": "progress_bar_1", "points": 200 } ] } ] }, { "publisherOfferId": "mega_bundle", "offerDesignOverride": { "titleText": "Mega Saver", "offerDesignSubtitleTextOverride": "Best value for your money" }, "offerDescriptionOverride": "Our most popular bundle! Get the best value with this mega pack of resources.", "priceDiscount": { "priceBeforeDiscount": 9999, "discount": 50, "type": "percentage" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "gold_coins", "quantity": 100000, "priority": "Main", "traits": [ { "assetId": "rarity_epic", "text": "Rarity: Epic" }, { "assetId": "bonus_mega", "text": "Mega Bonus: +200%" }, { "assetId": "best_value", "text": "Best Value" } ] }, { "publisherProductId": "gems", "quantity": 5000, "priority": "Sub" }, { "publisherProductId": "energy", "quantity": 500, "priority": "Sub" } ], "progressBarPoints": [ { "publisherBarId": "progress_bar_1", "points": 200 } ] } ] }, { "publisherOfferId": "daily_deal_gems", "offerDescriptionOverride": "Today's special: Premium gems at a discount!", "priceDiscount": { "priceBeforeDiscount": 1999, "discount": 30, "type": "percentage" }, "offerDesignOverride": { "titleText": "Daily Gem Deal", "offerDesignSubtitleTextOverride": "Refreshes daily" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "gems", "quantity": 500, "priority": "Main", "traits": [ { "assetId": "daily_special", "text": "Daily Special" } ] }, { "publisherProductId": "gold_coins", "quantity": 10000, "priority": "Sub" }, { "publisherProductId": "energy", "quantity": 75, "priority": "Sub" } ] } ] }, { "publisherOfferId": "energy_boost", "offerDescriptionOverride": "Need more energy? This pack will keep you going!", "priceDiscount": { "priceBeforeDiscount": 499, "discount": 20, "type": "percentage" }, "offerDesignOverride": { "titleText": "Energy Boost", "offerDesignSubtitleTextOverride": "Energy pack" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "energy", "quantity": 150, "priority": "Main", "traits": [ { "assetId": "instant_boost", "text": "Instant Boost" } ] }, { "publisherProductId": "gold_coins", "quantity": 2500, "priority": "Sub" } ] } ] }, { "publisherOfferId": "vip_exclusive", "offerDescriptionOverride": "Exclusive VIP bundle with premium rewards!", "priceDiscount": { "priceBeforeDiscount": 19999, "discount": 35, "type": "percentage" }, "offerDesignOverride": { "titleText": "VIP Exclusive", "offerDesignSubtitleTextOverride": "VIP members only" }, "productsSequence": [ { "index": 1, "products": [ { "publisherProductId": "gems", "quantity": 15000, "priority": "Main", "traits": [ { "assetId": "rarity_legendary", "text": "Rarity: Legendary" }, { "assetId": "vip_exclusive", "text": "VIP Exclusive" } ] }, { "publisherProductId": "gold_coins", "quantity": 250000, "priority": "Sub" }, { "publisherProductId": "energy", "quantity": 1000, "priority": "Sub" } ] } ] } ] } ``` # Trigger Web Store Personalization Source: https://docs.appcharge.com/api-reference/webstore/personalization/trigger-webstore-personalization openapi-trigger-webstore-personalization.json POST /refresh-active-players Triggers the [Personalize Web Store Callback](./personalize-webstore-callback) for all players. When refreshing data for all active players, Appcharge identifies everyone currently browsing the web store, and updates their store view in real time. ```bash Trigger Personalization for All Players theme={"system"} curl -X POST \ 'https://api.appcharge.com/store/v1/personalization/refresh-active-players' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' ``` ```json Trigger Personalization for All Players theme={"system"} { "message": "Event triggered for publisher 6422d554acc1a482bac4698e7" } ``` # Trigger Web Store Personalization By Player ID Source: https://docs.appcharge.com/api-reference/webstore/personalization/trigger-webstore-personalization-by-player-id openapi-trigger-webstore-personalization-by-player-id.json POST /refresh-specific-active-players Triggers the [Personalize Web Store Callback](./personalize-webstore-callback) by player ID. ```bash Trigger Personalization for Specific Players theme={"system"} curl -X POST \ 'https://api.appcharge.com/store/v1/personalization/refresh-specific-active-players' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -d '{ "playerIds": ["player123", "player456", "player789"] }' ``` ```json Trigger Personalization for Specific Players theme={"system"} { "message": "Event triggered for publisher 6422d554acc1a482bac4698e7" } ``` ```json 400 theme={"system"} { "message": "Schema Validation Error", "requestUrl": "/store/v1/personalization/refresh-specific-active-players", "body": "Property playerIds has failed the following validations: each value in playerIds must be a string, playerIds must contain at least 1 elements, playerIds must be an array." } ``` # Authenticate Player Callback Source: https://docs.appcharge.com/api-reference/webstore/player-authentication/authenticate-player-callback openapi-authenticate-player-callback.json POST /{YOUR_AUTHENTICATE_PLAYER_ENDPOINT} > **Note:** This is a callback API. Appcharge calls this endpoint on your server when specific events occur. Notifies your system to authenticate a player in your web store. Appcharge calls this endpoint when a player attempts to log in to your web store using one of the configured login methods. Your server identifies the player and responds with either the player data or an authentication error. If the response indicates a successful authentication, the player is logged in to the web store. ```bash Authenticate Game Redirect Login theme={"system"} curl -X POST \ 'https://{YOUR_AUTHENTICATE_PLAYER_ENDPOINT}' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -H 'signature: ' \ -d '{ "authMethod": "otp", "date": "2025-10-21T14:17:27.329Z", "appId": "NA", "playerLocation": { "countryCode2": "US", "state": "FL" }, "otp": { "playerCode": "974018", "accessToken": "9ac888fa33412197b" }, "os": "ios", "sessionId": "2e55b3fc-31ef-6dd7-8161-8aeb376b3a23" }' ``` ```bash Authenticate SSO Login theme={"system"} curl -X POST \ 'https://{YOUR_AUTHENTICATE_PLAYER_ENDPOINT}' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -H 'signature: ' \ -d '{ "authMethod": "google", "token": "sdfddtt7", "date": "2024-07-21T14:17:27.329Z", "appId": "611392880818819", "playerLocation": { "countryCode2": "US", "state": "NY" }, "os": "android", "utmSource": "Instagram", "utmCampaign": "spring_sale.", "sessionId": "2e55b3fc-31ef-6dd7-8161-8aeb376b3a23" }' ``` ```json Authenticate Game Redirect Login theme={"system"} { "status": "valid", "playerProfileImage": "", "publisherPlayerId": "986222719", "playerName": "Mary Littlelamb", "playerOverrideCountry": "CA", "sessionMetadata": { "abTest": "group1", "locale": "en-CA" } } ``` ```json Authenticate SSO Login theme={"system"} { "status": "valid", "playerProfileImage": "https://scontent-iad4-1.xx.fbcdn.net/v/t6.30597-1/84628273_176159830277856_972693363922829312_n.jpg?stp=c379.0.1290.1290a_cp0_dst-jpg_s50x50_tt6&ccb=1-7", "publisherPlayerId": "vip2247691", "playerName": "Jim Cardashian", "sessionMetadata": { "abTest": "group1", "locale": "en-US" } } ``` ```json Login Failed theme={"system"} { "status": "Invalid", "publisherErrorMessageType": "plainText", "publisherErrorMessage": "Lost internet connection.", "publisherErrorMessageTitle": "Whoops! Login Failed." } ``` # Initiate Game Auth Callback Source: https://docs.appcharge.com/api-reference/webstore/player-authentication/initiate-game-auth-callback openapi-initiate-game-auth-callback.json POST /{YOUR_INITIATE_GAME_AUTH_ENDPOINT} > **Warning:** This API endpoint is only relevant for the Game Redirect Login method. > **Note:** This is a callback API. Appcharge calls this endpoint on your server when specific events occur. Notifies your system to initiate an authentication session in your game. Appcharge calls this endpoint when a player attempts to log in via [Game Redirect Login](/../../guides/webstore/player-authentication/game-redirect-login/about-game-redirect-login). Your server responds with either the data needed to redirect the player to your game for authentication, or an error. ```bash Initiate Game Auth - Mobile theme={"system"} curl -X POST \ 'https://{YOUR_INITIATE_GAME_AUTH_ENDPOINT}' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -H 'signature: ' \ -d '{ "device": "MOBILE", "date": "2023-11-07T05:31:56Z" }' ``` ```bash Initiate Game Auth - Desktop theme={"system"} curl -X POST \ 'https://{YOUR_INITIATE_GAME_AUTH_ENDPOINT}' \ -H 'Content-Type: application/json' \ -H 'x-publisher-token: ' \ -H 'signature: ' \ -d '{ "device": "DESKTOP", "date": "2023-11-07T05:31:56Z" }' ``` ```json Initiate Game Auth - Mobile theme={"system"} { "deepLink": "https://my-awesome-game/2298/bv45d674?key=549bc5151667f6216629efe46vf7bacd2812d82298", "accessToken": "9ac8883227afa33412197b", "desktopAutoRedirect": false } ``` ```json Initiate Game Auth - Desktop theme={"system"} { "deepLink": "https://my-awesome-game/auth?key=549bc5151667f6216629efe46vf7bacd2812d82298", "accessToken": "9ac8883227afa33412197b", "desktopAutoRedirect": true } ``` ```json 400 theme={"system"} { "error": "Invalid signature" } ``` ```json 401 theme={"system"} { "error": "Unauthorized" } ``` ```json 403 theme={"system"} { "error": "Parameters not correct" } ``` # Introduction Source: https://docs.appcharge.com/api-reference/webstore/player-authentication/introduction The Player Authentication API service allows you to verify a player’s identity in your web store using the authentication methods you configure, such as SSO Login, Pre-Authenticated Login, and Game Redirect Login. When a player attempts to log in, Appcharge triggers the [Authenticate Player Callback](./authenticate-player-callback) on your server with the login details. This callback prompts your server to validate the player's credentials and respond with either the player data or an authentication error. After your server returns the player data, Appcharge logs the player into the web store. If a player uses Game Redirect Login, Appcharge first calls the [Initiate Game Auth Callback](./initiate-game-auth-callback) on your server to start an authentication session in your game. Once that session completes, Appcharge calls the Authenticate Player Callback to verify the player’s credentials.\ For the full step-by-step flow, see [About Game Redirect Login](/../../guides/webstore/player-authentication/game-redirect-login/about-game-redirect-login). Learn more about the [Player Authentication feature](/../../guides/webstore/player-authentication/about-player-authentication). With the Player Authentication API service, you can: * Get notified when to [authenticate players](./authenticate-player-callback). * Get notified when to [initiate an authentication session in your game](./initiate-game-auth-callback). ## Before you begin Review the following before you begin: * Make sure you've completed the [Player Authentication setup](/../../guides/webstore/player-authentication/set-up-player-authentication) in the Publisher Dashboard. * **Authenticate Player Callback:** * The `token` field varies by login method: * **SSO Login:** Token returned by the SSO provider. * **Player ID Login:** Player ID entered by the player. * For both **Pre-Authenticated Login** and **Game Redirect Login**, Appcharge sends `authMethod: "otp"` and includes an `otp` object: * **Pre-Authenticated Login:** Appcharge extracts the player code and access token from your game’s deeplink and forwards them to your Authenticate Player Callback. * **Game Redirect Login:** Appcharge first calls the Initiate Game Auth Callback on your server to start the flow. Your game responds with the player code and token through the return URL, and Appcharge forwards them to your Authenticate Player Callback. To enable Game Redirect Login, follow [Set up Game Redirect Login](/../../guides/webstore/player-authentication/game-redirect-login/set-up-game-redirect-login). # Deprecation Notices Source: https://docs.appcharge.com/api-reference/whats-new/deprecation-notices This article lists APIs and Events in the API Reference that will be deprecated. Each deprecation includes a specified date, after which it'll be removed from the documentation and will no longer be supported or accessible. To ensure continued functionality, update your integrations before the deprecation date. For deprecated properties, as well as details on new API versions, Events, and relevant migration instructions, refer to the [Release Notes](./release-notes). *** ## Invalid Property Error Event The [Invalid Property Error event](../events/v2/webstore/invalid_property) will be deprecated and replaced by the [Personalization Response Error event](../events/v2/webstore/personalization_response_error). ## Events V1 Events V1 will be deprecated and replaced by Events V2. ## Offers V1 The following APIs will be deprecated and replaced by the Offers V2 API: * **Offers API** → replaced by Offers V2 API * **Popups API** → replaced by Offers V2 API * **Rolling Offer API** → replaced by Offers V2 API # Release Notes Source: https://docs.appcharge.com/api-reference/whats-new/release-notes The release notes provide the latest updates to our API Reference documentation. It contains comprehensive information on all API modifications, including new features and version updates. Each release note details specific changes and any required actions for developers. By regularly reviewing this page, you can stay informed about the latest improvements to our platform and ensure you have the most current information to optimize your integration with Appcharge. *** ## Events V2 Events V2 now includes a `landingUrl` property containing the URL the player used to enter the web store for the current session. You can use this value to attribute transactions to the originating link. The property appears at the root of the [Web Store Displayed](../events/v2/webstore/login/webstore_store_displayed) event and under `storeMetadata` in the [Order Completed](../events/v2/order/order_completed) event. It's omitted when no landing URL is available. ## Products API and Badges API The [Create Product](../webstore/offer-components/products/create-product), [Update Product](../webstore/offer-components/products/update-product), [Create Badge](../webstore/offer-components/badges/create-badge), and [Update Badge](../webstore/offer-components/badges/update-badge) endpoints now support optional `productImageId` and `badgeImageId` properties. ## Grant Award Callback The `playerEmail`, `createdByIp`, and `zipCode` properties in the [Grant Award Callback](../checkout/awards/grant-award-callback) are now deprecated. They will continue to be included in callback payloads for backward compatibility until **November 27, 2026**, but we recommend removing any logic that reads or stores these values as soon as possible. After this date, these properties will be removed from the payload and won't be supported or accessible. ## Personalize Web Store Callback We added a new optional `offers.productsSequence.products.assetId` property to the [Personalize Web Store Callback](../webstore/personalization/personalize-webstore-callback). Pass an Asset ID (external ID) from the Asset Library to override a product's display asset in the web store. If omitted or unrecognized, the store falls back to the product's saved default asset in the Publisher Dashboard. ## Progress Bar Designs API The new [Progress Bar Designs API](../webstore/offer-components/offer-designs/progress-bars/introduction) allows you to create, update, and delete designs for progress bar offers. Progress bar designs support two types: * **Classic:** One mission is displayed on the bar at a time, and the bar resets when the next mission begins. * **Milestones:** All milestones are displayed at once along the bar. The Progress Bar Designs API includes the following endpoints: * [Create Progress Bar Design](../webstore/offer-components/offer-designs/progress-bars/create-progress-bar-design): Creates a new progress bar design. * [Update Progress Bar Design](../webstore/offer-components/offer-designs/progress-bars/update-progress-bar-design): Updates an existing progress bar design. * [Delete Progress Bar Design](../webstore/offer-components/offer-designs/progress-bars/delete-progress-bar-design): Deletes a progress bar design. The [Get Offer Designs API](../webstore/offer-components/offer-designs/get-all-offer-designs) response now includes `ProgressBar` offer designs. ## Milestone Progress Bars API The [Progress Bars API](../webstore/offers-v2/progress-bars/introduction) has been updated to support a new **Milestones** progress bar type. The existing Progress Bar is now called **Classic** in the API and documentation. Updates include: * Progress bar design responses now return a `progressBar.type` property with values `classic` or `milestones`, plus a `milestones` object for milestone-specific design settings such as `milestoneCompletedIconUrl` and `tooltipBackgroundColor`. * Create, update, get, and delete Progress Bar endpoint examples now include Classic and Milestones request and response samples. Learn more about [Progress Bars](/../../guides/webstore/offers/progress-bars/about-progress-bars). ## Get Transactions API We've added the new `device` object to the [Get Transactions API](../checkout/finance-and-analytics/get-transactions). The `device` object includes details about the customer's device, such as `osType`, `osVersion`, `browserType`, and `browserVersion`. ## Events V2 We've added the new `device` object to order events in [Events v2](../events/v2/order/order_created). The `device` object includes details about the player's device, operating system, and browser, such as `platform`, `deviceModel`, `osType`, `osVersion`, `browserType`, and `browserVersion`. ## Reward Calendars API The new [Reward Calendars API](../webstore/offers-v2/reward-calendars/introduction) allows you to create and manage Reward Calendar offers in your web store. Reward Calendars are 7-day calendar popup offers that show players a week's worth of upcoming rewards and let them collect the current day's reward. The Reward Calendars API includes the endpoints: * [Create Reward Calendar](../webstore/offers-v2/reward-calendars/create-reward-calendar): Creates a new Reward Calendar offer. * [Update Reward Calendar](../webstore/offers-v2/reward-calendars/update-reward-calendar): Updates an existing Reward Calendar offer. * [Get Reward Calendar](../webstore/offers-v2/reward-calendars/get-reward-calendar): Retrieves one or more Reward Calendar offers. * [Delete Reward Calendar](../webstore/offers-v2/reward-calendars/delete-reward-calendar): Deletes a Reward Calendar offer. We've also added the new [Reward Calendar Designs API](../webstore/offer-components/offer-designs/reward-calendars/introduction), which includes the endpoints: * [Create Reward Calendar Design](../webstore/offer-components/offer-designs/reward-calendars/create-reward-calendar-design): Creates a new Reward Calendar design. * [Update Reward Calendar Design](../webstore/offer-components/offer-designs/reward-calendars/update-reward-calendar-design): Updates an existing Reward Calendar design. * [Delete Reward Calendar Design](../webstore/offer-components/offer-designs/reward-calendars/delete-reward-calendar-design): Deletes a Reward Calendar design. Learn more about the [Reward Calendars](/../../guides/webstore/offers/reward-calendars/about-reward-calendars) feature. ## Offers V2 API We've added the new `hidePlayerAvailability` property to objects in the `productsSequence` array in the [Special Offers API](../webstore/offers-v2/special-offers/introduction) and [Store Refresh Popups API](../webstore/offers-v2/triggered-popups/store-refresh-popups/introduction). Use it with `hidePlayerAvailability` to control whether player availability text is shown in the web store. If `hidePlayerAvailability: false` and `playerAvailability: 5`, the web store displays `Available 5/5`. When a player collects or purchases the offer, the displayed availability decreases, for example to `Available 4/5`. ## Price Localization API We've added the new [Get Price Points for a Country](../checkout/price-localization/get-price-points-for-a-country) endpoint to the Price Localization API. Use this endpoint to retrieve localized prices for a list of USD price points in a specific country. We've also added a new [Price Localization Errors](../checkout/price-localization/error-messages) page that lists possible error messages for the Price Localization API service. ## Initiate Game Auth Callback We've added the new optional `desktopAutoRedirect` property to the [Initiate Game Auth Callback](../webstore/player-authentication/initiate-game-auth-callback) response. Set it to `true` to redirect players logging into the web store on desktop directly to the deepLink URL. When the property is `false` or omitted, these players see a QR code of the deeplink and must scan it with their phone to open the game. ## Daily Bonuses and Triggered Popups APIs The Offers V2 **Popups** section previously included the Daily Bonuses API and Post Purchase Popups API. It has been restructured as follows: * The **[Daily Bonuses API](../webstore/offers-v2/daily-bonuses/introduction)** is now a standalone API in the Offers V2 API service. * The **Popups** API section is now called **Triggered Popups**. Post Purchase Popups API endpoints continue to be available under this API service. * We've added the new [Store Refresh Popups API](../webstore/offers-v2/triggered-popups/store-refresh-popups/introduction), which includes the following endpoints: * [Create Store Refresh Popup](../webstore/offers-v2/triggered-popups/store-refresh-popups/create-store-refresh-popup). * [Update Store Refresh Popup](../webstore/offers-v2/triggered-popups/store-refresh-popups/update-store-refresh-popup). Learn more about the [Daily Bonuses](/../../guides/webstore/offers/daily-bonuses/about-daily-bonuses) and [Triggered Popups](/../../guides/webstore/offers/triggered-popups/about-triggered-popups) features. ## Create Checkout Session API We've added the new `identitySignals` object to the `customer` object in the [Create Checkout Session API](../checkout/checkout-session/create-checkout-session) request. The `identitySignals` object contains the `firstSeenAt` property, which lets you pass the date and time when a player was first observed on your monetization platform to improve risk decisions and reduce false declines. ## Game Portal Content API We've added two new endpoints to the [Game Portal Content API](../game-portal/content/introduction): * [Upsert Content Translation](../game-portal/content/upsert-content-translation): Creates or updates a translation for a content item in a specific locale. * [Get Content Translations](../game-portal/content/get-content-translations): Retrieves all existing translations for a content item. ## Portal Block Clicked Event We've added a new Game Portal event, [Portal Block Clicked](../events/v2/portal/ui/portal_block_clicked), which is triggered when a Game Portal block is clicked. ## Progress Bar Events We've added three new web store events to support the Progress Bar feature: * [Progress Bar Points Granted](../events/v2/webstore/offer/progress_bar_points_granted): Triggered when a player is granted Progress Bar points. * [Progress Bar Mission Started](../events/v2/webstore/offer/progress_bar_mission_started): Triggered when a new Progress Bar mission starts and is revealed to the player. * [Progress Bar Mission Completed](../events/v2/webstore/offer/progress_bar_mission_completed): Triggered when a Progress Bar mission is completed. We've also added a new `progressBars` property to the [Offers Loaded](../events/v2/webstore/offer/offers_loaded) and [Offers Displayed](../events/v2/webstore/offer/offers_displayed) events. This property returns a list of Progress Bars associated with the event and includes the following fields: * `progressBarExternalId`: Progress Bar external ID. * `missionIndex`: Current mission index. * `points`: Number of points the player has earned so far in the current mission. * `pointsTarget`: Total number of points required to complete the current mission. * `products`: List of products in the Progress Bar, each with a `productExternalId` and `productQuantity`. ## Authenticate Player Callback We added the new `publisherErrorMessageTitle` property to the [Authenticate Player Callback](../webstore/player-authentication/authenticate-player-callback) response. This property defines the error message title displayed to players when a login attempt fails. ## Coupons API You can now create and manage coupons and promo codes using the new [Coupons API](../checkout/coupons/introduction). This API lets you create discount campaigns and distribute unique promo codes that players can redeem at checkout. The Coupons API includes the following endpoints: * [Create Coupon](../checkout/coupons/create-coupon). * [Get Coupon by Name](../checkout/coupons/get-coupon-by-name). * [Update Coupon](../checkout/coupons/update-coupon). * [Bulk Create Promo Codes](../checkout/coupons/bulk-create-promo-codes). * [Get Promo Code](../checkout/coupons/get-promo-code). * [List Promo Codes](../checkout/coupons/list-promo-codes). * [Bulk Set Promo Codes Activation](../checkout/coupons/bulk-set-promo-codes-activation). Learn more about the [Coupons](/../../guides/checkout/coupons/about-coupons) feature. ## Price Localization API You can now manage localized pricing using the new [Price Localization API](../checkout/price-localization/introduction). This API lets you define price points in USD and automatically generate localized prices for supported currencies. Localized prices are calculated using current exchange rates and applicable tax and rounding rules, and can be overridden for specific countries when needed. The Price Localization API includes the following endpoints: * [Create Price Point](../checkout/price-localization/create-price-point). * [Get Price Point](../checkout/price-localization/get-price-point). * [Get All Price Points](../checkout/price-localization/get-all-price-points). * [Update Price Point](../checkout/price-localization/update-price-point). * [Delete Price Point](../checkout/price-localization/delete-price-point). Learn more about the [Price Points](/../../guides/checkout/price-localization/set-up-price-points) feature. ## Create Checkout Session API The `url` property in the [Create Checkout Session API](../checkout/checkout-session/create-checkout-session) is now deprecated. It will continue to be supported for backward compatibility until **August 23, 2026**, but we recommend migrating to the new `parsedUrl` property as soon as possible. After this date, this property will be removed from the documentation and will no longer be supported or accessible. ## Offer Popup Closed Event We've added a new web store event, [Offer Popup Closed](../events/v2/webstore/offer/offer_popup_closed), which is triggered when a player closes a popup offer in the web store. ## Get Transactions API The new [Get Transactions API](../checkout/finance-and-analytics/get-transactions) allows you to retrieve transaction data for a given time period. ## Content API Service We've added a new `tag` property to the following [Content APIs](../game-portal/content/introduction): * [Create Content](../game-portal/content/create-content) * [Get Content](../game-portal/content/get-content) * [Get Content By ID](../game-portal/content/get-content-by-id) * [Update Content](../game-portal/content/update-content) This property lets you add an internal tag to each content item to better organize your content. Tags are for internal use only and are not visible to players. ## Offer Components API and Assets API We’ve added new GET endpoints that allow you to retrieve a complete list of each entity type, including offer designs, products, badges, and assets. **Offer Components API:** * [Get All Offer Designs](../webstore/offer-components/offer-designs/get-all-offer-designs) * [Get All Products](../webstore/offer-components/products/get-all-products) * [Get All Badges](../webstore/offer-components/badges/get-all-badges) **Assets API:** * [Get All Assets](../media/assets-library/get-all-assets) ## Offers V2 API Service We added a new `progressBarPoints` object to the `productsSequence` property in following Offers V2 APIs: * [Bundles API](../webstore/offers-v2/bundles/introduction) * [Special Offers API](../webstore/offers-v2/special-offers/introduction) * [Rolling Offers API](../webstore/offers-v2/rolling-offers/introduction) This object assigns point values to offers that contribute toward a progress bar. It includes the following properties: * `publisherBarId`: ID of the Progress Bar this offer contributes to. * `points`: Number of points awarded when this offer is purchased or claimed. In addition, you can override these values by sending the same object in the [Personalize Web Store Callback](..//webstore/personalization/personalize-webstore-callback). ## Progress Bar API Service The new [Progress Bar API service](../webstore/offers-v2/progress-bars/introduction) allows you to create and manage Progress Bar offers in your web store. Progress Bars are offers that encourage players to purchase additional offers. The Progress Bars API includes the endpoints: * [Create Progress Bar](../webstore/offers-v2/progress-bars/create-progress-bar): Creates a new Progress Bar offer. * [Update Progress Bar](../webstore/offers-v2/progress-bars/update-progress-bar): Updates an existing Progress Bar offer. * [Get Progress Bar](../webstore/offers-v2/progress-bars/get-progress-bar): Retrieves one or more Progress Bar offers. * [Delete Progress Bar](../webstore/offers-v2/progress-bars/delete-progress-bar): Deletes a Progress Bar offer. Learn more about the [Progress Bar feature](/../../guides/webstore/offers/progress-bars/about-progress-bars). ## Create Checkout Session API We added a new `parsedUrl` property to the [Create Checkout Session API](../checkout/checkout-session/create-checkout-session) response. This property will now be used in upcoming SDK updates. In a later release, `parsedUrl` will replace the existing `url` property. We'll notify you in advance when migration is required. ## Web Store Events We added a new `offers.tab` property to the [Offers Loaded](../events/v2/webstore/offer/offers_loaded) and [Offers Displayed](../events/v2/webstore/offer/offers_displayed) events. This property represents the tab in which the offer is in. ## Content API Service The new [Content API service](../game-portal/content/introduction) allows you to create and manage content items in your Game Portal. The Content API includes the endpoints: * [Create Content](../game-portal/content/create-content): Creates a new content item. * [Get Content](../game-portal/content/get-content): Retrieves a list of all content items. * [Get Content By ID](../game-portal/content/get-content-by-id): Retrieves a specific content item by its ID. * [Update Content](../game-portal/content/update-content): Updates a content item. * [Delete Content](../game-portal/content/delete-content): Deletes a content item. ## Personalize Web Store Callback We added a new `storeTheme` object to the [Personalize Web Store Callback](..//webstore/personalization/personalize-webstore-callback), allowing you to override the background images configured in the Publisher Dashboard for both mobile and desktop versions of your web store and game portal. The object includes the following properties: * `bgImageMobile`: Name of the asset to use as the background image on mobile devices. * `bgImageDesktop`: Name of the asset to use as background image on desktop devices. ## Personalize Web Store Callback We added a new `offers.productsSequence.progressBarPoints` object to the [Personalize Web Store Callback](..//webstore/personalization/personalize-webstore-callback) for implementing the new [Progress Bar offer](/../../guides/webstore/offers/progress-bars/about-progress-bars). This object assigns point values to offers that contribute toward a progress bar. The object includes the following properties: * `publisherBarId`: ID of the Progress Bar this offer contributes to. * `points`: Number of points awarded when this offer is purchased or claimed. ## Trigger Web Store Personalization By Player ID We've added a new API, [Trigger Web Store Personalization By Player ID](../webstore/personalization/trigger-webstore-personalization-by-player-id), that allows you to trigger Web Store Personalization on-demand for individual players. This gives you finer control by letting you refresh personalization for a single player instead of triggering a refresh for all active players. ## Web Store Personalization We’ve updated our terminology to make it more consistent and easier to use: The Personalization API is now called [Personalize Web Store Callback](..//webstore/personalization/personalize-webstore-callback). Learn more about the [Web Store Personalization feature](/../../guides/webstore/personalization/about-personalization). ## Unity Payment Links SDK We've released a new [Payment Links SDK for Unity](/../../sdks/payment-links/unity/setup) that provides a unified cross-platform solution for both iOS and Android. This replaces the previous platform-specific Unity implementations. **What's changed:** Previously, the Payment Links SDK was organized by platform with separate Unity implementations: * iOS (Native and Unity) * Android (Native and Unity) Now, the SDK structure is streamlined: * iOS (Native) * Android (Native) * Unity (Cross-platform for iOS and Android) ## Personalization Response Error Event We've added a new [Personalization Response Error event](../events/v2/webstore/personalization_response_error), which replaces the deprecated [Invalid Property Error event](../events/v2/webstore/invalid_property). The deprecated event will continue to be supported for backward compatibility, but we recommend migrating to the new event. ## Create Checkout Session API We added a new `countryCode2` property to the [Create Checkout Session API](../checkout/checkout-session/create-checkout-session) request. Use this to specify the player's two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. If not provided, Appcharge determines the customer's country from the player's IP address. ## Create Checkout Session API We added a new `receiptMetadata` object to the [Create Checkout Session API](../checkout/checkout-session/create-checkout-session) request. Use this object to specify the language of customer receipts. If the property isn't included, the receipt defaults to English, `en`. The object includes the following property: * `locale`: The locale code. Both ISO-639 language code and ISO-3166 country code formats are supported. ## Player Authentication We’ve updated our terminology for clarity: * The Authenticate Player API is now called [Authenticate Player Callback](../webstore/player-authentication/authenticate-player-callback) * The Initiate Game Auth API is now called [Initiate Game Auth Callback](../webstore/player-authentication/initiate-game-auth-callback) ## Translations The new [Translations API service](./../translations/introduction) lets you manage translations in the web store, checkout, and game portal, allowing players to view content in their preferred language. The Translations API service includes the following endpoints: * [Get Translations](./../translations/get-translations): Retrieves a list of all translatable fields and their translations. * [Set Translations](./../translations/set-translations): Sets translation content for translatable fields. Learn more about the [Translations feature](/../../guides/translations/about-translations). ## Awards We’ve updated our terminology to make it more consistent and easier to use: Grant Award Callback is now called [Grant Award Callback](../checkout/awards/grant-award-callback). For more details, see the [Awards API service](../checkout/awards/introduction). Learn more about the [Awards feature](/../../guides/checkout/awards/about-awards). ## Offers API We added a new `publisherTabId` property, which allows you to assign offers to tabs in your web store. This property is available in the following APIs: * [Bundles](../webstore/offers-v2/bundles/introduction) * [Special Offers](../webstore/offers-v2/special-offers/introduction) * [Rolling Offers](../webstore/offers-v2/rolling-offers/introduction) * [Get All Offers](../webstore/offers-v2/get-offers). Learn more about [tabs feature](/../../guides/webstore/design/add-a-tab). ## Player Authentication We’ve updated the Player Authentication terminology to make it more consistent and easier to use: * Player Authentication Webhook is now called [Authenticate Player API](../webstore/player-authentication/authenticate-player-api). * OTP Authentication Webhook and Pre-Authenticated Login Webhook have been consolidated into the [Authenticate Player API](../webstore/player-authentication/authenticate-player-api). See the [introduction](../webstore/player-authentication/introduction) for details. * Password-less Authentication (OTP) is now called [Game Redirect Login](../../guides/webstore/player-authentication/game-redirect-login/about-game-redirect-login). Its webhook, previously OTP Deeplink Webhook is now the [Initiate Game Auth API](../webstore/player-authentication/game-redirect-login/initiate-game-auth). ## Personalization API We added a new `logo` property to the [Personalization API](./../webstore/personalization/personalization-api). This property is the asset ID of a logo uploaded via the Assets Library. Use it to display a custom logo in your web store. ## Grant Award Callback The [Grant Award Callback](../checkout/orders/player-order-reporting-webhook) now includes the `taxRate` property, allowing you to track the percentage of tax paid by the player. ## Offer Components API The new [Offer Components API](../webstore/offer-components/introduction) is a suite of APIs that allows you to create and manage the individual elements that make up your web store’s offers, including products, layout designs, and badges. The Offer Components API includes the following: * [Offer Designs API](../webstore/offer-components/offer-designs/introduction): Design the layout of your bundles, special offers, popups, and rolling offers. * [Products API](../webstore/offer-components/products/introduction): Configure products for your offers, such as virtual or time-based items. * [Badges API](../webstore/offer-components/badges/introduction): Create visual badges in the form of ribbons or emblems to highlight offers. ## Assets API The new [Assets API](../media/assets-library/introduction) allows you to create and manage visual assets such as backgrounds, logos, favicons, and offer headers in the Assets Library. ## Player Authentication Webhook We added a new `playerLocation` object to the [Player Authentication Webhook](../webstore/player-authentication/player-authentication-webhook) request. This object provides information about the player's location, and includes the following properties: * `countryCode`: Two-letter country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. * `state`: Two-letter state code. This addition makes it easier to apply location-based logic during player authentication. ## Events V2 [Events V2](./../events/v2/introduction) introduces a more structured and consistent format for webhook events, making it easier to parse and integrate. Review the updated schema and validation process in the new documentation. ## Initiate Refund API The new [Initiate Refund API](../checkout/orders/initiate-refund) allows you to initiate a full refund for a specified order. Upon successful processing, the full amount is reimbursed to the player, and the order status is updated accordingly. ## Personalization API We added 2 new properties to the [Personalization API](./../webstore/personalization/personalization-api): * `offers.offerDescriptionOverride`: Replaces the current offer description in the store UI with a custom description. * `offers.productsSequence.products.traits`: Defines a list of visual or descriptive features associated with the product, such as bonuses or variants. Each trait includes a `text` field describing the feature and an `assetId` referencing the associated asset from your Asset Library. ## Personalization and Create Checkout Session APIs We added a new `attributes` property to both the [Personalization API](./../webstore/personalization/personalization-api) and the [Create Checkout Session API](../checkout/checkout-session/create-checkout-session). This object allows you to define custom key-value pairs to tag players for A/B testing, segmentation, or other use cases. These tags can then be used to filter players in the Publisher Dashboard. ## iOS Payment Links SDK for Unity The iOS Payment Links SDK is now available for [Unity iOS](/../../sdks/ios-payment-links/ios-mobile-checkout-sdk/unity/setup). The SDK makes it easy to add the [iOS Payment Links](/../../guides/ios-payment-links/about-ios-payment-links) feature to your app. Instead of relying on traditional in-app purchases, players can buy items like coin packs, character skins, or bundles through a fast, mobile-optimized checkout page. ## Personalization API We added a new `offers.productsSequence.products.endsIn` property to the [Personalization API](./../webstore/personalization/personalization-api). This property indicates how much time remains before an offer expires, using an [epoch](https://www.epoch101.com/) timestamp in milliseconds. ## Cancel Checkout Session API The new [Cancel Checkout Session API](../checkout/checkout-session/cancel-checkout-session) allows you to cancel an open checkout session at any time, such as when multiple checkout tabs are open. ## iOS Payment Links SDK The new [iOS Payment Links SDK](/../../sdks/payment-links/ios/introduction) allows you to easily integrate a mobile checkout experience directly into your iOS game. Instead of relying on traditional in-app purchases, players can buy items like coin packs, character skins, or bundles through a fast, mobile-optimized checkout page. ## Store Interaction Events We added the `sessionId` property to [Store Interaction Events](../events/store-interaction), allowing you to identify the player session associated with each event. ## Pre-Authenticated Login Webhook The Seamless Login Webhook has been renamed to the [Pre-Authenticated Login Webhook](./../webstore/player-authentication/preauthenticated-login/preauthenticated-login-webhook). ## Grant Award Callback We added a new `paymentPriceInDollar` property to [Grant Award Callback](../checkout/orders/player-order-reporting-webhook). This property represents the base price of the offer in USD cents. Note that this is not the same as `originalPriceInDollar`, which is also the base price in USD cents—but if you're using Appcharge's Web Store and `pricePointMetadata` is provided, then `pricePointMetadata` overrides `originalPriceInDollar`. ## Create Checkout Session API We added a new `quantityDisplay` property to `items` object in the [Create Checkout Session API](../checkout/checkout-session/create-checkout-session). This property overrides the `quantity` value displayed in the checkout. ## Auto-Update SDK The new [Auto-Update SDK](/../../sdks/appdirect/auto-update-sdk/introduction) enables you to seamlessly update your app without requiring players to manually download and install a new version. This allows you to quickly roll out critical updates, new content, or bug fixes. It ensures a smoother player experience and helps maintain version consistency. The Auto-Update SDK is available for [Android](/../../sdks/appdirect/auto-update-sdk/android/setup) and [Unity](/../../sdks/appdirect/auto-update-sdk/unity/setup). ## Appcharge Payment Links The new [Appcharge Payment Links](/../../guides/ios-payment-links/about-ios-payment-links) feature allows players to make secure purchases in your iOS game. Players can buy digital content such as bundles, coin packs, or skins through a secure and branded page outside your app, giving you more control over the purchase experience and a seamless checkout flow. See a [sample Unity app flow](/../../guides/ios-payment-links/sample-unity-app-flow) that guides you through the recommended process for integrating Appcharge Payment Links into an iOS game. ## Personalization Trigger API The new [Personalization Trigger API](./../webstore/personalization/personalization-trigger-api) enables you to invoke the [Personalization API](./../webstore/personalization/personalization-api) on demand, giving you more control over when player data is refreshed. This gives you the flexibility to respond to time sensitive moments, like when a player runs out of resources and needs a personalized refill offer. It also helps with operational fixes, such as correcting an invalid offer to avoid unnecessary costs. Learn more about the [Personalization feature](/../../guides/webstore/personalization/about-personalization). ## Checkout Link Offers API The Offers V2 API now includes a new Checkout Link Offers API, which allows you to generate deeplinks that direct players to the checkout page, pre-configured with a unique offer. This feature is useful for sending exclusive, personalized offers outside the web store, such as through a social media broadcast distributor. With the new [Checkout Link Offers API](./../webstore/offers-v2/checkout-link-offers/introduction) you can: * [Create a checkout link offer.](./../webstore/offers-v2/checkout-link-offers/create-checkout-link-offer) * [Update a checkout link offer.](./../webstore/offers-v2/checkout-link-offers/update-checkout-link-offer) Learn more in the [Checkout Link Offers](/../../guides/webstore/offers/checkout-link-offers/about-checkout-link-offers) guide. ## Personalization API The Player Info Sync Webhook has been renamed to the [Personalization API](./../webstore/personalization/personalization-api). ## UTM Parameters We added new `utmSource`, `utmMedium`, and `utmCampaign` properties to the [Player Authentication Webhook](./../webstore/player-authentication/player-authentication-webhook). These same properties are now also included as a `utms` object within the `storeMetadata` field of the [Grant Award Callback](./../checkout/orders/player-order-reporting-webhook). This allows you to track the origin of your players, the channels they came through, and the campaigns that brought them in. ## Player Info Sync Webhook The `dynamicOfferUi` object is deprecated. See the new structure below: **For Rolling Offers:** * `dynamicOfferUi.badges` → `offers.productsSequence.badges` * `dynamicOfferUi.offerDesignId` → `offerDesignSyncOverride.offerDesignId` * `dynamicOfferUi.salePercentage` → `offers.productsSequence.productSale.sale` * `dynamicOfferUi.salePercentageDisplayType` → `offers.productsSequence.productSale.type` **For all other offer types:** * `dynamicOfferUi.badges` → `offers.badges` * `dynamicOfferUi.offerDesignId` → `offerDesignOverride.offerDesignId` * `dynamicOfferUi.salePercentage` → `offers.productSale.sale` * `dynamicOfferUi.salePercentageDisplayType` → `offers.productSale.type` > **Note:** These properties do not apply to Checkout Link Offers because there is no support for configuring badges, sale percentages, or offer designs for them. ## Player Info Sync Webhook We added a new `playerLevelBanners` object to the [Player Info Sync Webhook](./../webstore/personalization/personalization-api), allowing you to dynamically display specific banners to players based on their game level. ## VueJS 3 SDK We released a new [VueJS 3 SDK](/../../sdks/checkout/frontend-sdk/vuejs3-sdk) that supports the latest Vue.js version, Vue 3. See the documentation for more details. ## Offers V2 API A new version of the Offers API is now available. [Offers V2 API](./../webstore/offers-v2/introduction) enables you to create and manage offers more effectively, helping to enhance player engagement and improve customer retention. It supports various offer types, including bundles, special offers, daily bonuses, and post-purchase deals. With the Offers V2 API, you can: * Create and update a bundle. * Create and update a special offer. * Create and update a rolling offer. * Create and update a daily bonus. * Create and update a post-purchase popup. * Get and delete offers. **Key changes from Offers API → Offers V2 API** * A new `productSale` object includes the `amountBeforeSale` property. * The `dynamicOfferUi` property is deprecated. Sending this in the payload will result in failure: * `dynamicOfferUi.badges` → moved to root as `badges` * `dynamicOfferUi.salePercentage` → moved to `productSale.salePercentage` * `dynamicOfferUi.salePercentageType` → moved to `productSale.salePercentageType` * The `intervals` property is deprecated. Use the `schedule` property instead. * The `coolDownInHours` property is deprecated. * The `publisherSectionId` property is now only relevant for the [Bundles API](./../webstore/offers-v2/bundles/introduction). ## Rolling Offers API The Offers API contains a new [Rolling Offers API](./../webstore/offers-v1/rolling-offers/introduction) that allows players to unlock deals in succession. As each offer is claimed, the next one is revealed, keeping players engaged and eager to continue. The rolling offer feature boosts player interaction and maximizes revenue potential. With the new Rolling Offer API you can: * Create a rolling offer. * Update a rolling offer. Learn more about the [Rolling Offer feature](/../../guides/webstore/offers/rolling-offers/about-rolling-offers). ## Offers API We added a new `schedule` property in the [Create an Offer](./../webstore/offers-v1/create-offer) and [Update an Offer](./../webstore/offers-v1/update-offer) APIs, allowing you to specify the time intervals when promotions are available to players. # Welcome to the Appcharge Changelog Source: https://docs.appcharge.com/changelog The changelog provides a detailed log of all updates and improvements across our platform. Stay informed on the latest changes to our products, ensuring you have the most up-to-date information to optimize your integration with Appcharge. ## Receipt and Refund Email Time Zones Purchase and refund receipt emails now show the date and time in the player's local time zone instead of UTC, with a time zone label. If the player's time zone couldn't be captured, the email falls back to UTC. Orders placed before this change aren't backfilled. When you translate receipts, the email uses the player's web store language, or the locale you pass in `receiptMetadata` if you don't have a web store. If that locale can't be rendered, the email falls back to English. Learn more about [receipts](/guides/checkout/receipts/about-receipts). ## Portal Background Images You can now upload separate background images for desktop and mobile in the [Game Portal](/../../guides/game-portal/design-your-game-portal#design-your-game-portal-theme) from **Builder > Portal Theme > General Settings** in the Publisher Dashboard. If you don't upload an image, the portal uses the provided **General Background Color**. ## User Management We’ve added a dedicated **User Management** section to the Publisher Dashboard, giving Administrators a company-level view of users across the projects they manage. Administrators can invite up to 20 users at once, add existing users to projects, update roles by project, remove access, resend pending invitations, and search or filter users. See our updated guide on [Managing User Roles and Permissions](/guides/publisher-dashboard/manage-user-roles-and-permissions) to learn more. ## Bouncy Overscroll Behavior You can now enable or disable the native overscroll bounce effect on iOS from [General Store Settings](/../../guides/webstore/settings/configure-general-store-settings). On Android, the same setting reloads the page when players overscroll. ## Milestone Progress Bars We've added a new **Milestones** Progress Bar type. The Progress Bar you already use is now called **Classic**. With Milestones, all targets display at once along a single bar, so players can see every reward ahead of them, including the grand reward at the final milestone. The [Progress Bar guides](/guides/webstore/offers/progress-bars/about-progress-bars) have been updated to document both Classic and Milestones behavior, rollover points, and how [target configuration updates](/guides/webstore/offers/progress-bars/about-progress-bars#update-target-configuration) affect in-progress players when you add or remove targets or change required points. Learn how to [design, create, and manage a Progress Bar](/guides/webstore/offers/progress-bars/create-and-manage-a-progress-bar). ## Daily Reset Timezone You can now set the timezone for the daily offer reset in the Publisher Dashboard. Offers such as [Daily Bonuses](/guides/webstore/offers/daily-bonuses/about-daily-bonuses) and [Reward Calendars](/guides/webstore/offers/reward-calendars/about-reward-calendars) reset at 00:00 in the selected timezone. The default is UTC+00:00, and a new timezone takes effect at the next reset. Learn how to [configure the daily reset timezone](/guides/webstore/settings/configure-general-store-settings#daily-reset-timezone). ## Group Blocks We've added the [Group Blocks feature](/guides/webstore/design/template-studio/template-editor/customize-your-web-store-layout-using-blocks#group-blocks) which allows you to combine multiple eligible Blocks into one visual group so their badges appear side by side in the web store. ## Reward Calendar Offers We've added the [Reward Calendar](/../../guides/webstore/offers/reward-calendars/about-reward-calendars), a 7-day calendar popup offer that shows players a week's worth of upcoming rewards and lets them collect the current day's reward. You can configure up to 10 weeks of rewards and customize the calendar design, including badges, and reward tiles. Learn how to [create and manage a Reward Calendar](/../../guides/webstore/offers/reward-calendars/create-and-manage-a-reward-calendar). ## Progress Bar Mission Configuration Updates We've changed how live updates to [Progress Bar mission configuration](/../../guides/webstore/offers/progress-bars/about-progress-bars#update-mission-configuration) affect players. Appcharge no longer recalculates or redistributes player progress when you update required points or the total number of missions. For active missions, the point requirement is locked as soon as the player sees the mission. If you later update the point requirement for that same mission, the player continues using the original requirement they saw. Only missions the player hasn’t yet reached use the updated configuration. If you reduce the total number of missions so that there are fewer missions than the player's current position, the player continues their current mission as the final mission in the Progress Bar. Players don't receive rewards for missions that were removed. ## Payment Links SDK Updates We've released new versions of the Payment Links SDK. See each platform's changelog for the full release notes: * [Unity v2.5.0](/../../sdks/payment-links/unity/changelog) * [iOS v1.8.0](/../../sdks/payment-links/ios/changelog) * [Android v1.6.0](/../../sdks/payment-links/android/changelog) ## Appcharge MCP Server We've introduced the [Appcharge Model Context Protocol (MCP) server](/../../guides/appcharge-ai/appcharge-mcp) for MCP-compatible AI clients such as Cursor and Claude. Use it to interact with Appcharge data and documentation without leaving your AI client. ## Game Redirect Login Desktop Behavior Publishers using [Game Redirect Login](/../../guides/webstore/player-authentication/game-redirect-login/about-game-redirect-login) can now optionally redirect players logging into the web store on desktop directly to the game deeplink, instead of displaying a QR code for them to scan with their phone to open the game. ## Daily Bonuses and Triggered Popups The **Popups** offer category previously included Daily Bonuses and Post Purchase Popups. It has been restructured as follows: * **[Daily Bonuses](/../../guides/webstore/offers/daily-bonuses/about-daily-bonuses)** are now a standalone category in the Publisher Dashboard. * The **Popups** category is now called **Triggered Popups**. Post Purchase Popup offers continue to be available under this category. * We've added [Store Refresh Popups](/../../guides/webstore/offers/triggered-popups/about-triggered-popups#store-refresh-popups), a new Triggered Popup offer type that appears when the web store refreshes, such as after player login, browser refresh, or an explicit store reload. Learn how to [create a Daily Bonus](/../../guides/webstore/offers/daily-bonuses/create-a-daily-bonus) or [create a Triggered Popup](/../../guides/webstore/offers/triggered-popups/create-a-triggered-popup) in the Publisher Dashboard. ## External Image URL Handling External image URLs are now saved and used as-is across the Assets Library, Offer Components, and the Personalize Web Store Callback. Appcharge no longer downloads, copies, uploads, or hosts images provided by URL. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. When possible, we recommend uploading image files instead of using external URLs. Appcharge hosts uploaded files on its CDN. ## Supported PayPal Currencies We've added a new [Supported PayPal Currencies](/../../merchant-of-record/finance/supported-paypal-currencies) reference page listing all currencies for which PayPal is available as a payment option in the Appcharge checkout. ## New Game Portal Event We've added a new [Portal Block Clicked event](/../../api-reference/events/v2/portal/ui/portal_block_clicked) to the [Events Center](/../../guides/events/about-the-events-center), which is triggered when a Game Portal block is clicked. Use this event to track player interactions with blocks in your Game Portal. ## New Template Studio Section in Publisher Dashboard We’ve introduced the [Template Studio](/../../guides/webstore/design/template-studio/about-the-template-studio), a new workspace in the Publisher Dashboard for designing and managing your web store layout using templates. **Key capabilities include:** * Create and manage multiple web store templates. * Customize store layouts and styling, including showing, hiding, and reordering sections. * Apply global branding settings such as fonts, colors, and images. * Preview your store before going live, including personalization scenarios. * Activate a template to update your live web store. #### Migration to the Template Studio Storefront configuration is moving from the **Builder** section to **Template Studio**. **What will be managed in the Template Studio:** * Brand Kit settings (logo, colors, fonts, backgrounds) * External Buttons settings (Add To Home Screen and Back To Game buttons) * Storefront layout configuration **What will still be managed in the Builder:** * General store settings * Checkout page configuration * Completed page configuration * Login page configuration #### Learn more * [Tour the Template Editor](/../../guides/webstore/design/template-studio/template-editor/tour-the-template-editor). * [Customize Your Web Store Layout Using Blocks](/../../guides/webstore/design/template-studio/template-editor/customize-your-web-store-layout-using-blocks). * [Set Up Your Brand Kit](/../../guides/webstore/design/template-studio/template-editor/set-up-your-brand-kit). * [Preview the Web Store with Personalization Data](/../../guides/webstore/design/template-studio/template-editor/preview-the-webstore-with-personalization-data). ## New Progress Bar Events We've added three new web store events to the [Events Center](/../../guides/events/about-the-events-center) to support the Progress Bar feature: * [Progress Bar Points Granted](/../../api-reference/events/v2/webstore/offer/progress_bar_points_granted): Triggered when a player is granted Progress Bar points. * [Progress Bar Mission Started](/../../api-reference/events/v2/webstore/offer/progress_bar_mission_started): Triggered when a new Progress Bar mission starts and is revealed to the player. * [Progress Bar Mission Completed](/../../api-reference/events/v2/webstore/offer/progress_bar_mission_completed): Triggered when a Progress Bar mission is completed. ## New Developer Settings Tab in Publisher Dashboard We've added a new [Developer Settings tab](/../../guides/publisher-dashboard/configure-developer-settings) to the Publisher Dashboard, bringing all technical configuration required to connect your systems with Appcharge into one place. From this tab, you can manage your project identity, credentials, callbacks, and webhooks. You can also test callbacks and webhooks directly from the dashboard before going live. Testing sends a simulated Appcharge request or event to your endpoint so you can verify delivery and response handling. The **Developer Settings** tab is located in the **Settings** page of the sidebar menu and replaces the **Company** and **Integration** tabs that were previously available there. Any existing configuration previously set in the **Company** and **Integration** tabs has been automatically carried over to the new **Developer Settings** tab. ## New Web Store Event We've added a new [Offer Popup Closed event](/../../api-reference/events/v2/webstore/offer/offer_popup_closed), which is triggered when a player closes a popup offer in the web store. Use this event to track player engagement with popup offers. ## Internal Tag for Game Portal Content You can now add an internal tag to each [Game Portal Content item](/../../guides/game-portal/create-and-manage-game-portal-content) to better organize your content. Tags are for internal use only and aren’t visible to players. ## Frontend SDK Documentation Updates We've reorganized the Frontend SDK documentation to improve consistency and ease of use: * **Unified platform documentation**: All supported platforms (React, Angular, Vue 2, Vue 3, and JavaScript) are now consolidated into single articles with platform-specific code examples shown in tabs, making it easier to find and compare implementation details across platforms. * **Updated platform version requirements**: Documentation has been updated to reflect the latest supported platform versions for each SDK. * **Dedicated articles**: Checkout translations and Price Points management instructions have been moved to dedicated articles for better organization. To learn more, see the [Frontend SDK documentation](/../../sdks/checkout/frontend-sdk/introduction). ## Expanded Currency Support We’ve expanded our list of [supported currencies](/../../merchant-of-record/finance/supported-currencies), allowing you to offer players more options for paying in their preferred local currency. ## Add to Home Screen and Back to Game Button Updates You now have greater control over the positioning of your [Add to Home Screen](../../guides/webstore/design/implement-the-add-to-home-screen-button) and [Back to Game](../../guides/webstore/design/configure-the-back-to-game-button) buttons, as follows: * You can adjust the vertical placement of the Add to Home Screen button. * You can choose whether the Back to Game button appears on the left or right side of the screen, allowing better alignment with your UI layout. ## Refund Guide We’ve created an article on how to [Initiate a Refund](../../guides/checkout/initiate-a-refund). ## Payment Links SDK Updates We've updated the [Payment Links SDK](/../../sdks/payment-links/introduction) to improve consistency across platforms, simplify integration, and enhance overall developer experience. **What's changed:** * Expanded SDK distribution through standard package managers: * iOS now supports CocoaPods. * Android is available via Maven Central. * Unity supports the Unity Package Manager (UPM). * Enhanced stability, validation, and configuration across supported platforms. For platform-specific details and versioned changes, see the individual SDK changelogs. ## QR Code Sharing for Checkout Link Offers You can now share [Checkout Link offers](/../../guides/webstore/offers/checkout-link-offers/about-checkout-link-offers) with players using a QR code. After creating a Checkout Link offer, you can download the QR code and share it with players digitally or physically by printing it out, making it easier to distribute offers across different platforms and in print materials. ## Game Portal Blocks You can now build and edit Game Portal Page layouts using [Blocks](/../../guides/game-portal/create-and-manage-game-portal-blocks) in the Publisher Dashboard. Blocks let you assemble a page with elements like images, videos, content previews, and custom HTML, giving you full control over the page’s appearance and where content is placed, and allowing you to tailor layouts for different goals such as announcements, content pages, minimalist experiences, or live events. You can reuse Blocks across multiple pages, helping you update pages faster and easier. ## Replacement of Bulgarian Lev (BGN) with Euro (EUR) We’ve updated our list of [supported countries](/../../guides/checkout/price-localization/supported-countries) to replace Bulgarian Lev (BGN) with Euro (EUR). This ensures publishers and players in Bulgaria can seamlessly process payments using the Euro. Our [supported currencies](/../../merchant-of-record/finance/supported-currencies) list has also been updated accordingly, as BGN is no longer supported. ## Sub Pages in the Game Portal You can now add Sub Pages in the Game Portal, nested under a parent Page to organize content into a clear, hierarchical structure. To learn more, see [Create and Manage a Game Portal Page](/../../guides/game-portal/create-and-manage-a-game-portal-page). ## Web Only Products You can now display any product in a [Special Offer](/../../guides/webstore/offers/special-offers/create-and-manage-a-special-offer) or [Bundle](/../..//guides/webstore/offers/bundles/create-and-manage-a-bundle) as Web Only, allowing you to highlight items that are available exclusively in your Web Store. ## Button Suffix Badge The new Button Suffix Badge allows you to add an image or JSON animation directly to your call-to-action button to create a more dynamic visual cue in your promotions. Available for [Special Offers](/../../guides/webstore/offers/special-offers/create-and-manage-a-special-offer) and [Bundles](/../..//guides/webstore/offers/bundles/create-and-manage-a-bundle). ## Support for Armenian Dram (AMD) We’ve expanded our list of [supported currencies](/../../merchant-of-record/finance/supported-currencies) to include Armenian Dram (AMD). This update allows publishers operating in Armenia, or players who prefer to pay in AMD, to seamlessly process payments in their local currency. ## Appcharge Compliant with Texas SB 2420 In compliance with Texas SB 2420 (effective January 1, 2026), Utah SB 142 (effective May 7, 2026), and Louisiana HB 570 (effective July 1, 2026), we've added new compliance requirements for age verification and parental consent for minors (under 18). Appcharge enables compliance by blocking prohibited users before any data is collected. Each game publisher is responsible for verifying player age during account creation and linking any minor's account to a verified parent or guardian account. For more information, review the [Texas SB 2420 Compliance Policy](/../../merchant-of-record/policies/texas-law-compliance-policy). ## Design Game Portal Menu You can now customize the style and placement of your [Game Portal menu](/../../guides/game-portal/design-your-game-portal), helping you deliver a more intuitive experience for your players. ## Custom Arrow Images for Rolling Offers When designing a [Rolling Offer](/../../guides/webstore/offers/rolling-offers/create-and-manage-a-rolling-offer), you can now upload a custom image to replace the default arrows between sub offers. This gives you more control over your branding and visuals, helping you create a cohesive and polished flow across your offers. ## Progress Bar Offers The new [Progress Bar offer](/../../guides/webstore/offers/progress-bars/about-progress-bars) encourages players to purchase additional offers. A progress bar displays in your web store, representing a mission and acting as a visual indicator of how far players advance towards completing it. Each mission has a defined number of points needed to earn a reward. Players earn points by purchasing offers or collecting free rewards, and the bar fills to show their advancement. When complete, they receive their reward, the bar resets, and they automatically advance to the next mission if available. Learn how to [create and manage a Progress Bar](/../../guides/webstore/offers/progress-bars/create-and-manage-a-progress-bar). ## Web Store Personalization for Specific Players You can now trigger web store personalization on-demand for specific players using the new [Trigger Web Store Personalization By Player ID](api-reference/webstore/personalization/trigger-webstore-personalization-by-player-id). This gives you finer control by allowing you to refresh personalization for specific players rather than all active players. ## Web Store Personalization We’ve updated our terminology to make it more consistent and easier to use: * The Personalization feature is now called [Web Store Personalization](/../../guides/webstore/personalization/about-personalization). * The Personalization API is now called [Personalize Web Store Callback](api-reference/webstore/personalization/personalize-webstore-callback). ## Unity Payment Links SDK We've released a new [Payment Links SDK for Unity](/../../sdks/payment-links/unity/setup) that provides a unified cross-platform solution for both iOS and Android. This replaces the previous platform-specific Unity implementations. **What's changed:** Previously, the Payment Links SDK was organized by platform with separate Unity implementations: * iOS (Native and Unity) * Android (Native and Unity) Now, the SDK structure is streamlined: * iOS (Native) * Android (Native) * Unity (Cross-platform for iOS and Android) ## Appcharge Compliant with SOC 1 Appcharge maintains SOC 1 Type 2 certification, demonstrating that our controls over financial processes have been tested and validated over an extended period. As a Merchant of Record and payment processor, this certification ensures financial accuracy, transaction integrity, and reliable reporting for our merchants. For more information, review the [SOC 1 Compliance documentation](/../../merchant-of-record/policies/soc-1-compliance-at-appcharge). ## Personalization Response Error Event We've added a new [Personalization Response Error event](/../../api-reference/events/v2/webstore/personalization_response_error), which replaces the deprecated [Invalid Property Error event](/../../api-reference/events/v2/webstore/invalid_property). The deprecated event will continue to be supported for backward compatibility, but we recommend migrating to the new event. ## Translations We’ve updated our terminology to make it more consistent and easier to use, and we've also improved the documentation: Language Localization is now called [Translations](/../../guides/translations/about-translations). ## Add to Home Screen Button for Game Portal You can now enable the [Add to Home Screen Button in the Game Portal](/../../guides/game-portal/design-your-game-portal#configure-your-game-portal-settings). When enabled, players will see a button that lets them add the Game Portal directly to their mobile device’s home screen, creating an app-like shortcut for quick access. ## Parking Domains You can now create [Parking Domains](/../../guides/game-portal/parking-domains/about-parking-domains) that let you direct players from your game to your web store in compliance with Apple and Google guidelines. Parking Domains help you reach a wider player audience and increase traffic through seamless, pre-authenticated redirection. ## Awards We’ve updated our terminology to make it more consistent and easier to use: Player Order Reporting is now called [Awards](/../../guides/checkout/awards/about-awards). ## Tabs in the Web Store You can now organize and display different offers in your web store using [tabs](/../../guides/webstore/design/add-a-tab). You can assign an offer to a single tab or to all tabs. When players click a tab, they'll see the offers assigned to it. ## Checkout Link Offers [Checkout Link Offers](/../../guides/webstore/offers/checkout-link-offers/about-checkout-link-offers) now use [Game Redirect Login](../../guides/webstore/player-authentication/game-redirect-login/about-game-redirect-login) for authentication, replacing the legacy [JWT method](../../guides/webstore/offers/checkout-link-offers/use-jwt-method). We will continue to support JWT, but recommend migrating to Game Redirect Login. ## Player Authentication We’ve updated our [Player Authentication](/../../guides/webstore/player-authentication/about-player-authentication) docs to make them clearer and easier to use: * Password-less Authentication (OTP) is now called [**Game Redirect Login**](../../guides/webstore/player-authentication/game-redirect-login/about-game-redirect-login). * We’ve also reorganized the documentation to improve readability and navigation. ## A/B Testing You can now [implement A/B Testing](/../../guides/measurement-tools/implement-ab-testing) in both the web store and checkout to compare product features, creative assets, pricing strategies, or promotional campaigns. After setting up your test, [track performance](/../../guides/publisher-dashboard/view-analytics) in the Publisher Dashboard to see which experience drives the best results based on player behavior. ## Currency Localization In the Publisher Dashboard, admins can now manage how prices are displayed across regions by selecting which currencies convert from USD. This helps improve clarity for players in countries with unstable or fluctuating currencies. Learn more about [currency localization](/../../guides/checkout/price-localization/set-up-price-points#price-points-settings). ## New Events Version The new [Events V2](/../../api-reference/events/v2/introduction) includes a standardized and consistent structure for webhook events, making them easier to integrate. ## iOS Payment Links SDK for Unity The iOS Payment Links SDK is now available for [Unity iOS](/../../sdks/ios-payment-links/ios-mobile-checkout-sdk/unity/setup). The SDK makes it easy to add the [iOS Payment Links](/../../guides/ios-payment-links/about-ios-payment-links) feature to your app. Instead of relying on traditional in-app purchases, players can buy items like coin packs, character skins, or bundles through a fast, mobile-optimized checkout page. ## Integration with AppsFlyer We now have an integration with [AppsFlyer](https://www.appsflyer.com/), a leading Mobile Measurement Partner (MMP). This code-free integration lets you track and attribute player activity across your game and Appcharge web store, giving you a complete view of the player journey. See our [AppsFlyer Integration guide](/../../guides/integrations/appsflyer) to get started. ## Add a Loader Animation You can now add a custom [loader animation](/../../guides/webstore/design/add-a-loader-animation) to your web store. The animation appears whenever content is loading, such as during checkout, payment processing, or when a player opens an offer. Instead of the default spinner, you can upload a branded [Lottie](https://lottiefiles.com/) file that matches your game’s design, helping maintain a consistent and trusted experience. ## Cancel a Checkout Session It is now possible to cancel an open checkout session at any time with the new [Cancel Checkout Session API](/../../api-reference/checkout/checkout-session/cancel-checkout-session). For example, when multiple checkout tabs are open. ## iOS Payment Links SDK The new [iOS Payment Links SDK](/../../sdks/payment-links/ios/introduction) makes it easy to add the [iOS Payment Links](/../../guides/ios-payment-links/about-ios-payment-links) feature to your app. Instead of relying on traditional in-app purchases, players can buy items like coin packs, character skins, or bundles through a fast, mobile-optimized checkout page. ## Game Portal The new [Game Portal](/../../guides/game-portal/about-the-game-portal) feature lets you create a single hub where players can explore your game’s content beyond the app. It combines news, updates, and your web store in one place, so players stay informed and make purchases without being redirected. The Game Portal uses your existing web store configuration, with no additional integration required. ## Custom Distribution for Checkout Link Offers You can now distribute [Checkout Link Offers](/../../guides/webstore/offers/checkout-link-offers/about-checkout-link-offers) using your own custom distribution method. To support this, our documentation provides clear guidance to help you implement this approach within your system, giving you full control over how offers are delivered and activated by your players. ## Expanded Price Localization Coverage Appcharge now supports price localization in the following countries: * Albania * Andorra * Armenia * Bangladesh * Costa Rica * Ecuador * Georgia * Guernsey * Iceland * Jordan * Lebanon * Lesotho * Macau * Maldives * Martinique * Nauru * North Macedonia * Panama * Ukraine View the full list of [supported countries](/../../guides/checkout/price-localization/supported-countries). ## Add Allowed Players to Coupons You can now restrict coupon usage to specific players by uploading a CSV file with eligible player IDs in the Publisher Dashboard. This feature gives you more control over coupon distribution and allows you to tailor campaigns to specific segments—such as VIPs, returning players, or special event participants. Learn more about [coupons](/../../guides/checkout/coupons/about-coupons). ## AppDirect The new [AppDirect](/../../guides/appdirect/about-appdirect) feature allows you to easily deploy your app directly to players' devices without going through an app store. Players install the app by following simple on-screen instructions. The platform supports automatic updates, ensuring they always use the latest version without needing to download or install anything manually. This feature delivers value for both you and your players. ## Appcharge Payment Links You can now offer players a simple and secure way to make purchases in your iOS game using [Appcharge Payment Links](/../../guides/ios-payment-links/about-ios-payment-links). Players can buy digital content such as bundles, coin packs, or skins through a secure and branded page outside your app, giving you more control over the purchase experience and a seamless checkout flow. ## Live Store Sync With the [Personalization feature](/../../guides/webstore/personalization/about-personalization), you now have greater control over when player data is refreshed and offers are updated. You can manually refresh data to push updated offers directly to the player's device in real time. This gives you the flexibility to respond to time sensitive moments, like when a player runs out of resources and needs a personalized refill offer. It also helps with operational fixes, such as correcting an invalid offer to avoid unnecessary costs. ## View Blocked Players You can now view [blocked players](/../../guides/publisher-dashboard/view-blocked-players) in the Publisher Dashboard. This new feature gives you better visibility into blocked player data, including current status and a full history of suspensions, so you can manage enforcement more effectively. ## Exchange Rate Gap Threshold You can now define [custom exchange rate thresholds](/../../guides/checkout/price-localization/set-up-price-points#exchange-rate-gap-threshold) when setting your price points in the Publisher Dashboard. This feature helps you better manage currency fluctuations. Configure minimum and maximum percentage limits, and apply them to specific price ranges as needed. ## Checkout Link Offers The new [Checkout Link Offers](/../../guides/webstore/offers/checkout-link-offers/about-checkout-link-offers) feature lets you create exclusive, personalized offers that can be sent directly to players through a social media broadcast distributor. Each offer includes a deep link that brings players directly to the checkout page, where the offer is preloaded and ready for purchase. ## Personalization Player Info Sync is now called [Personalization](/../../guides/webstore/personalization/about-personalization), and the Player Info Sync Webhook has been renamed to the [Personalization API](/../../api-reference/webstore/personalization/personalization-api). ## Player Level Banners The new [Player Level Banners](/../../guides/webstore/design/add-a-banner#player-level-banners) feature allows you to dynamically display specific banners to players based on their game level. ## VueJS 3 SDK We released a new [VueJS 3 SDK](/../../sdks/fe-checkout/vuejs3-sdk) that supports the latest Vue.js version, Vue 3. See the documentation for more details. ## Rolling Offers The new [Rolling Offers](/../../guides/webstore/offers/rolling-offers/about-rolling-offers) feature allows players to unlock deals in succession. As each offer is claimed, the next one is revealed, keeping players engaged and eager to continue. The rolling offer feature boosts player interaction and maximizes revenue potential. Learn how to [create and manage rolling offers](/../../guides/webstore/offers/rolling-offers/create-and-manage-a-rolling-offer). ## Support for UTM Tracking We now have new UTM-related properties in login events, offering insights into traffic sources, marketing channels, and specific campaigns. For more information, view the [Login Events documentation](/../../api-reference/events/login/login_land). ## Events Center We are rolling out a new Events Center, unifying all event tracking under one section in the API reference. These events provide structured data for key system interactions—such as player logins, store navigation, and checkout actions—allowing you to track, monitor, and analyze more effectively. This new approach is self-serve, enabling direct configuration in the Publisher Dashboard. For more information, view the [Events documentation](/../../guides/events/about-the-events-center). ## Checkout Coupons We now support an advanced Coupons feature that allows you to create, manage, and configure coupons for promotional campaigns. We group multiple promo codes under a single coupon, providing discounts to players while streamlining redemption processes and offering better performance insights for you. For more information, view the [Coupons documentation](/../../guides/checkout/coupons/about-coupons). ## Appcharge Alignment with California Law (AB 2426) In compliance with California law (AB 2426), we added new legal text to checkout for players in California: “An in-game purchase grants a license to Virtual Items. For full terms and conditions of the license, please see the EULA.” This update is part of the new transparency requirements regarding "digital goods" as outlined by the California Business and Professions Code Section 17500.6, which mandates that consumers are informed that they are purchasing a license to virtual items, not full ownership. This change went into effect on January 1, 2025. For more information, review [California Bill AB 2426](https://leginfo.legislature.ca.gov/faces/billNavClient.xhtml?bill_id=202320240AB2426). ## 2025 VAT Rate Updates We updated the VAT rates in the following countries for 2025 to reflect the latest tax changes. These adjustments affect price points and apply to all relevant transactions: * Israel: The VAT rate has increased from 17% to 18% as part of the country's fiscal policy update. * Slovakia: The VAT rate has increased from 20% to 23% following recent tax reform measures. * Indonesia: The VAT rate has increased from 11% to 12% in alignment with ongoing tax modernization efforts. These changes went into effect on January 1, 2025. You should review their price points to ensure pricing and tax configurations are aligned with these updates. ## Pay with Venmo Venmo is now available as a payment method for U.S. players. This popular APM offers a fast, convenient, and familiar way to pay. ## Scheduled Special Promotions We now enable you to define intervals during which promotions are available. You can set up campaigns in advance, specifying intervals for future availability. Additionally, the availability of offers can be reset based on the defined intervals. For more information, view the [Scheduled Offers documentation](/../../guides/webstore/offers/special-offers/schedule-an-offer). ## Web Store and Checkout Localization We now allow you to localize the web store and checkout by defining new languages directly from the dashboard. You can localize static store text, builder inputs, and display names for offers and products. For more information, view the [Localization documentation](/../../guides/publisher-dashboard/add-translations). ## New Unity SDK Version The Unity SDK is updated to version 3.0.0, featuring fullscreen checkout, improved callbacks, simplified setup, enhanced error handling, and new support for price points and actions via orderId. For more details on Unity SDK 3.0.0, refer to the [Unity SDK Change Log](/../../sdks/appdirect/mobile-checkout-sdk/unity/changelog). ## New Checkout SDKs Checkout SDKs have been updated to support multiple stores per domain. For more details on these updates, including token changes, refer to the [Frontend SDKs Change Log](/../../sdks/checkout/frontend-sdk/frontend-sdk-changelog). ## Checkout Builder We now have a versatile checkout builder in the dashboard, providing expanded options for uploading assets and configuring themes. A preview feature allows users to review configurations easily. The builder is currently accessible to the super admin role, with potential availability for other publisher roles pending future product decisions. The dashboard also enables you to manage offer visibility by toggling offers as active or inactive. These changes can be seen in the Publisher Dashboard by going to the **Builder > Checkout Page**. ## Offers Loaded Store Interaction Event We now have a comprehensive list of all offers available to a player during that session, even if not all offers are displayed simultaneously. The Offers Loaded event triggers once when the store is first opened. This event ensures you have visibility into every offer a player could encounter. For more information, view the [Offers Loaded Events Webhook](/../../api-reference/events/store-interaction/offers_loaded). ## Complex Tooltips with Design and Images We now support the creation of complex tooltips that include images. Tooltip content is managed via Player Info Sync. These changes can be seen in the [Player Info Sync webhook](/../../api-reference/webstore/personalization/personalization-api). ## Optimized Offer Processing in Player Info Sync We now process valid offers in Player Info Sync even if an invalid offer payload is detected. A new event notification is triggered whenever an error occurs due to an incorrectly formatted offer, assisting with identifying and resolving integration issues. For more information, view the [Integration Error Events Webhook](/../../api-reference/events/error/invalid_property_error). ## New Checkout SDKs We released a new version of the Android Mobile SDK, aligning more closely with Google’s in-app purchase flow. This update simplifies the integration process and enhances the user experience. A dedicated changelog has been created to track these and future updates. For more information, view the [Android Mobile SDK Change Log](/../../sdks/appdirect/mobile-checkout-sdk/android/changelog). ## OTP in Webview Landing Page We now offer expanded support for webviews within its web store, improving user experience across platforms. This ensures players receive the most suitable solution for their device and situation, optimizing in-app purchase processes and marketing efforts within webviews. ## Changelog Launch While this changelog begins in September 2024, we’ve been building and evolving our platform since 2022. We created the changelog to share announcements, product updates, and new features as they’re released. It’s part of our ongoing effort to keep you informed and make it easier to track what’s new, what’s improved, and what’s coming next. # Model Context Protocol (MCP) Source: https://docs.appcharge.com/guides/appcharge-ai/appcharge-mcp The Appcharge Model Context Protocol (MCP) server connects MCP-compatible AI clients to Appcharge data and operations. Use it to manage Publisher Dashboard setup, look up your projects, and search Appcharge documentation without leaving your AI client. The server supports SSE transport and works with MCP-compatible clients such as Cursor, Claude, and Claude Code. It's currently available in **sandbox**, and will soon be available in the **production** environment. The MCP server doesn't expose secrets, tokens, player-level data, payment data, internal logs, or unrelated publisher configuration. ## Before you begin Make sure you have: * An MCP-compatible AI client that supports remote MCP servers over SSE. * Access to your Publisher Dashboard sandbox account. Appcharge uses OAuth to authenticate the MCP server. ## Connect to the MCP server The process for connecting to the MCP server is subject to change. AI clients may update how they configure or connect to MCP servers, so the steps below may vary depending on your client version and settings. Follow the instructions for your AI client to add and authenticate the Appcharge MCP server. Once connected, your client can call the MCP tools available for your Publisher Dashboard account.
To connect the MCP server to Cursor: 1. In Cursor, open **Cursor Settings**. 2. In the sidebar menu, go to **Tools & MCPs**, and then click **New MCP Server**. A JSON file opens with a list of your existing MCP servers. 3. Add and save the Appcharge MCP server configuration to the file: ```json theme={"system"} { "mcpServers": { "appcharge-sandbox": { "url": "https://api-sandbox.appcharge.com/mcp", "timeout": 10000 } } } ``` 4. Now that it's installed, you need to log in to the Publisher Dashboard to authorize the Appcharge MCP. To do this, go back to **Cursor Settings** and click the **Connect** button next to the Appcharge MCP. 5. The browser opens. If you're not already logged in to the Publisher Dashboard sandbox environment, you'll be directed to log in. Once authenticated, the browser will prompt you to open Cursor. Click **Open Cursor**. 6. In **Cursor Settings**, you should now see that you're logged in and connected to the Appcharge MCP. To connect the MCP server to Claude Code: 1. Make sure you have the [Claude Code CLI](https://code.claude.com/docs/en/setup#install-claude-code) installed. 2. In your terminal, run the following command to add the Appcharge MCP server: ```bash theme={"system"} claude mcp add --transport http appcharge-sandbox https://api-sandbox.appcharge.com/mcp ``` 3. Now that it's installed, you need to authorize the Appcharge MCP. To do this, open Claude Code in the same folder where you ran the CLI command. Then, in the chat panel, ask it to **Connect to the Appcharge MCP server**, or **Authenticate with Appcharge**. 4. Claude Code will respond with a generated URL. Click the URL to open it in the browser. If you're not already logged in to the Publisher Dashboard sandbox environment, you'll be directed to log in. Once logged in, you'll see a success screen in the browser. 5. In Claude Code, you should now see that you're logged in and connected to the Appcharge MCP. To connect the MCP server to Claude Desktop: 1. Log in to your Publisher Dashboard sandbox account. 2. Open Claude Desktop, and in the top navigation bar, go to **Claude > Settings**. 3. In the sidebar, go to **Developer**, and click **Edit Config**. Your file system opens with the Claude config file selected. 4. Drag the Claude Desktop config file into an AI coding assistant, then paste the following prompt: ```plaintext theme={"system"} Read how to add an MCP server to Claude Desktop, then add the Appcharge MCP sandbox server to this config file. ``` Claude Desktop requires MCP servers to be added in a specific format, so using an AI coding assistant helps make sure the configuration is added correctly. 5. Restart Claude Desktop. 6. Claude should recognize the new MCP server. Confirm that it appears as connected. To connect the MCP server to other MCP-compatible clients: 1. In your MCP-compatible client, add and save the Appcharge MCP server configuration. For more information on how to connect an MCP server, refer to your specific client documentation. ```json theme={"system"} { "appcharge-sandbox": { "url": "https://api-sandbox.appcharge.com/mcp", "timeout": 10000 } } ``` 2. Authenticate the MCP server by logging in to your Publisher Dashboard sandbox environment. Your client may provide a **Connect** button or prompt you to open an authorization URL in the browser, similar to the Cursor and Claude Code flows. 3. In your client, you should now see that you're logged in and connected to the Appcharge MCP.
## MCP tools The Appcharge MCP server exposes the following tools. ### Project tools Use this tool to look up your Publisher Dashboard projects in the environment you connected to. | Tool name | Description | Use case | | - | - | - | | `list_projects` | Lists your Publisher Dashboard projects in the configured environment, including project ID, name, and type. | Find your project ID when configuring integrations or switching context between projects. | ### Documentation tools Use these tools to interact with the [Appcharge documentation](/guides/introduction). | Tool name | Description | Use case | | - | - | - | | `list_docs` | Lists all available documentation pages. | Discover available documentation pages without leaving your AI client. | | `get_doc` | Fetches the full content of a specific article. | Read full documentation content for a specific topic or API reference page. | | `search_docs` | Searches documentation by keyword. | Find documentation pages related to a keyword or integration topic. | ### Appcharge integration tools Instead of configuring your [developer settings](/guides/publisher-dashboard/configure-developer-settings) manually in the Publisher Dashboard, use these tools to manage callback and webhook URLs in the environment you connected to. | Tool name | Description | Use case | | - | - | - | | `get_webhooks_urls` | Retrieves your current callback and webhook URL configuration from the Publisher Dashboard. | Check which integration URLs are configured, missing, or ready for onboarding validation. | | `update_webhooks_urls` | Updates your callback and webhook URL configuration in the Publisher Dashboard. Omitted fields are left unchanged, and fields set to `null` are cleared. | Configure or update your integration URLs. | | `test_webhooks_urls` | Validates your callback and webhook URL configuration in the Publisher Dashboard and reports any issues. | Check whether your integration URLs are reachable and correctly configured before onboarding. | ## Example prompts After you connect the MCP server, try prompts such as: ```plaintext theme={"system"} Check which of my callback URLs are missing for my account ``` ```plaintext theme={"system"} List the IDs for all my web store projects ``` ```plaintext theme={"system"} Explain player authentication ``` ```plaintext theme={"system"} Validate my Grant Awards callback URL and tell me what to fix ``` # About the Checkout Source: https://docs.appcharge.com/guides/checkout/about-the-checkout Appcharge's Checkout Solution offers a streamlined approach to enhance your store's checkout experience. The integration process involves embedding Appcharge's checkout SDK into your store, enabling a smooth and optimized checkout flow. This documentation provides the resources and guidance necessary for a successful integration, allowing you to maximize the potential of Appcharge's Checkout Solution effortlessly. ## Two Checkout Variations 1. **Appcharge Web Store Checkout:** This variation connects directly to the Appcharge-provided web store, offering a seamless solution for managing in-app purchases and transactions. It handles all elements of the purchase flow from storefront to payment. * For more details on integrating the Appcharge Web Store Checkout solution, see the [Web Store High-Level flow](../webstore/webstore-high-level-flow). 2. **External Store Integration:** This option allows Appcharge's Checkout to integrate with your own external store, providing flexibility while maintaining the enhanced checkout flow powered by Appcharge's infrastructure. The checkout process is initiated on your existing store platform, and Appcharge handles the payment and session management. * For more details on integrating the External Checkout solution, see the [Checkout High-Level flow](./checkout-high-level-flow). # Add Apple Pay Source: https://docs.appcharge.com/guides/checkout/add-apple-pay Enabling Apple Pay on your Appcharge checkout requires you to register every domain that Apple Pay will be loaded on, including test environments. ## Why Apple Pay domain registration is required Apple requires all merchants to [register & verify](https://developer.apple.com/documentation/applepaywebmerchantregistrationapi/preparing_merchant_domains_for_verification) each domain that Apple Pay will be used in. Access to the Apple Pay API will be granted after a successful domain verification. Appcharge will register & verify your domain(s) for you with Apple during your onboarding process. Alternatively, you can register your domains directly with Apple by yourself. Follow the below guides to proceed with domain registration. ## Have Appcharge register your domain(s) for you Follow these steps to register your domains with Appcharge 1. Provide Appcharge with a list of every domain/subdomain that your checkout will be loaded in, including test environments. Please specify which domain(s) will be used for production. 2. Appcharge will register your domains with Apple and send back a certification file 3. Upload the certification file to all relevant domain(s) as per the following: **your-domain.com/.well-known/apple-developer-merchantid-domain-association** 4. Notify Appcharge once the certification file was uploaded. Appcharge will verify your certifications 5. Once verification is complete, make an Apple Pay test transaction in your test environment to ensure correct integration # About Awards Source: https://docs.appcharge.com/guides/checkout/awards/about-awards Awards are how customers get the items or bonuses they purchase or earn with Appcharge. When a customer places an order, whether free or paid, Appcharge processes the transaction, verifies the payment if required, and sends you a notification to grant the award or purchased item. The notification makes sure the customer gets the right award at the right time. It includes key order details such as the order ID, products, tax, and payment method. With this information, your system can accurately track transactions, manage purchases, and keep data synchronized across platforms. Appcharge also notifies you about free orders so you can update the customer balance and grant the award in the same way you would for a purchased order. This ensures clear visibility and a smooth customer experience. To receive award notifications, see [Set Up Award Notifications](./set-up-award-notifications). # Set Up Award Notifications Source: https://docs.appcharge.com/guides/checkout/awards/set-up-award-notifications This article explains how to set up award notifications for your app. To receive award notifications: 1. Create and expose an API endpoint on your server that follows the [Grant Award Callback](/../../api-reference/checkout/awards/grant-award-callback) structure. Appcharge will call this endpoint when customer payment is finalized, or when a free order is collected. 2. Register the endpoint in the Publisher Dashboard: * In **Settings**, go to the **Integration** tab. * In the **Grant Award Callback** field, enter your server's endpoint URL. Appcharge will now send award notifications with order details directly to your system. # High-Level Flow Source: https://docs.appcharge.com/guides/checkout/checkout-high-level-flow This guide outlines the key stages of integrating Appcharge Checkout with an external store, providing flexibility while leveraging Appcharge’s infrastructure for payments and the merchant of record. If you are using the full Appcharge solution with both the Web Store and Checkout, please refer to the [Web Store High-Level Flow](../webstore/webstore-high-level-flow). *** # Initial Setup Requirements ### 1. Set Up Price Localization Decide how to handle price localization to provide players with region-specific pricing. Appcharge offers two main models for this, but we recommend using Price Points for flexibility and a consistent player experience. * [Support Price Points Localization](/../../sdks/checkout/frontend-sdk/set-up-price-points) * [Price Localization Models](./price-localization/choose-a-price-localization-model) * [Price Points Dashboard Setup](./price-localization/set-up-price-points) ### 2. Enable Apple Pay In order to support Apple Pay, enable it during the checkout flow for faster transactions. * [Enabling Apple Pay guide](./add-apple-pay) ### 3. Set Up Checkout Language Localization (Optional) Appcharge supports the localization of checkout screens, allowing publishers to provide a customized, language-specific experience for players based on their region. * [Checkout Language Localization guide](/../../guides/translations/about-translations) *** # Frontend Integration Before initiating the runtime flow, integrate the necessary frontend components for managing the checkout process. Appcharge supports integration with various frontend frameworks, giving you flexibility in managing the checkout. * [Frontend SDKs](/../../sdks/checkout/frontend-sdk/introduction) * [Frontend Integration Overview](/../../sdks/checkout/frontend-sdk/about-frontend-integration) * [Player Payment Real Time SDK Events](/../../sdks/checkout/frontend-sdk/player-payment-real-time-sdk-events) *** # Steps To Go Live ### 1. Pull Price Points For external stores, retrieve the price points before starting the checkout process to ensure region-specific pricing is managed correctly. * [Support Price Points Localization](/../../sdks/checkout/frontend-sdk/set-up-price-points) ### 2. Create a Checkout Session The checkout process begins by creating a session via the Create a Checkout Session API. This session tracks the player’s activity throughout the transaction. * [Create Checkout Session API](/../../api-reference/checkout/checkout-session/create-checkout-session) * [Checkout Configuration guide](./configure-the-checkout) ### 3. Pull Orders via Grant Award Callback The Grant Award Callback sends transaction details in real-time to the publisher, ensuring order confirmations are received. * [Grant Award Callback](/../../api-reference/checkout/orders/player-order-reporting-webhook) * [Player Order Reporting guide](./orders/about-player-order-reporting) *** # Performance Analytics Analyze web store and checkout performance through APIs, webhooks, and the dashboard. ### Receive Events Directly from Appcharge Notifications via webhooks for player activities in the web store and checkout. **Pull Player Authentication Events:**
Monitor login activities. * Guide: [Player Authentication Events](../events/about-the-events-center) * API Reference: [Player Authentication Events](../../api-reference/events/login/login_land) **Pull Impression Events:**
Monitor page impressions. * API Reference: [Login Impression Events](../../api-reference/events/login/login_land) **Pull Player Order Events:**
Monitor player actions in the Checkout. * Guide: [Player Order Events](../events/about-the-events-center) * API Reference: [Player Order Events](../../api-reference/events/order/order_created) ### Connect to the Orders Reporting APIs **Extract Financial Reports With Financial Reporting API:**
The Financial Reporting API allows publishers to access a summary of all transactions and monitor sales performance. * API Reference: [Financial Reporting API](../../api-reference/checkout/finance-and-analytics/financial-reporting-api) **Extract Analytics With Analytics Reporting API:**
Use the Orders Analytics API to gather insights into transaction performance, including metrics such as conversion rates and average order values, to optimize monetization strategies. * API Reference: [Analytics Reporting API](../../api-reference/checkout/finance-and-analytics/analytics-reporting-api) ### View Analytics in the Dashboard **Access Dashboard Analytics:**
The Analytics Page in the dashboard provides metrics on user behavior and revenue. * Guide: [Dashboard Analytics](../publisher-dashboard/view-analytics) # About Coupons Source: https://docs.appcharge.com/guides/checkout/coupons/about-coupons Coupons allow you to provide discounts on one or more offers as part of a promotional campaign. Players redeem these discounts using a promo code that you configure. You can assign multiple promo codes to the same coupon, making it easier to track performance across different channels or user groups. For example, you might create unique codes for individual players, influencers, or marketing partners, depending on your distribution strategy, to compare effectiveness and optimize future campaigns. You can also limit coupon access to specific players. This helps you control distribution and tailor campaigns to targeted segments, such as returning players, VIPs, or participants in special events. ## How it works When creating a coupon, you define key details such as the discount amount, eligibility rules, and expiration date. Each coupon requires at least one promo code, with a unique name and redemption limit. To restrict coupon access to specific players, upload a CSV file containing a list of eligible player IDs. Only players on this list can redeem the associated promo codes. Once the coupon is set up, you can distribute promo codes to players through your chosen channels. When a player enters a promo code during checkout, the system checks eligibility based on the player ID, offer, and region. If valid, the discount is applied instantly. After a successful transaction, players receive a confirmation email with a receipt showing the applied discount and final amount. You can then monitor promo code effectiveness by tracking redemption rates in the Publisher Dashboard. ### Usage guidelines When a player uses a coupon: * Only one promo code can be used per purchase. * Players must spend at least \$1 for the coupon to apply. If they do not, the promo code will be rejected and an error message will appear. * Once redeemed through a successful payment, a promo code cannot be reversed, even if the payment is refunded or disputed. ## Key features * **Redemption limits:** Control how many times a promo code can be used overall to manage costs. * **Expiration dates:** Encourage timely usage by setting clear end dates for each coupon. * **New player incentive:** Use the **First Purchase Only** option to incentivize first-time buyers. ## Best practices * **Use simple promo codes:** Short, easy-to-remember promo codes (6–12 characters) reduce entry errors. * **Test coupons before launch:** Always test coupon and promo code behavior in a staging environment before publishing. Learn how to [create and manage coupons](./create-and-manage-a-coupon). # Create and Manage a Coupon Source: https://docs.appcharge.com/guides/checkout/coupons/create-and-manage-a-coupon This article explains how to create and manage coupons using the Publisher Dashboard. You can also create and manage coupons and promo codes via the [Coupons API](/../../api-reference/checkout/coupons/introduction). ## Create a new coupon To create a coupon: 1. Go to the **Coupons** tab and click **Add New Coupon**. 2. In the **General Settings**, enter a name, define the discount percentage, and set an expiration date. 3. In the **Offers Settings**, select the offers the coupon will apply to. 4. Fill out the **Player Settings** section as needed. 5. In **Allowed Players**, configure player restrictions: * Click **EXPORT CSV** in the **Allowed Players** section. * Fill out the `PlayerID` column of the downloaded file. * Upload the completed file using **IMPORT CSV**. > **Important:** Player IDs must be added correctly in the designated column. If a player ID is misplaced, the system won't recognize it, and the player won't be able to redeem the coupon. 6. Add a promo code name and redemption limit in the **Promo Codes** Section. > **Notes:** > > * At least one promo code must be added. > * Promo codes cannot be edited after creation, only deactivated. > * Promo codes will display a **Pending Save** status until the coupon configuration is saved. ## Activate or deactivate a promo code To activate or deactivate a promo code: 1. Go to the **Coupons** tab. 2. Click the ellipsis next to the coupon and select **Edit**. 3. In the **Promo Codes** section, click the ellipsis next to the promo code. 4. Select **Activate** or **Deactivate**. ## Edit a coupon 1. Go to the **Coupons** tab. 2. Click the ellipsis next to the coupon you want to edit, and select **Edit**. 3. Modify the coupon as necessary. > \*\* Note:\*\* To update the list of allowed players, upload a new file using the **IMPORT CSV** button. 4. Click **Save** to apply the changes. ## Deactivate or activate a coupon 1. Go to the **Coupons** tab. 2. Click the ellipsis next to the coupon. 3. Select **Activate** or **Deactivate**. # Design Your Checkout Source: https://docs.appcharge.com/guides/checkout/design-your-checkout This article explains how to design and customize both the Checkout Page and the Completed Page. The Checkout Page is the purchase flow itself, where players review the offer details, select a payment method, and complete the transaction. You can customize key UI elements such as headers, buttons, and branding assets to match your game's aesthetic. The Completed Page is the purchase confirmation screen displayed after a successful checkout. It can also be customized to reinforce branding and provide a consistent post-purchase experience. This article includes steps for adding images. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. ## Customize the Checkout Page To customize your Checkout Page: 1. In the **Publisher Dashboard**, go to **Studio > Builder** and click the **Checkout Page** tab. 2. Complete the following fields: * **Logo:** Select or upload a logo image to display at the top of the Checkout Page. * **Game Name:** Enter the name of your game. * **Font Color:** Select a text color. * **Background Image:** Select or upload a background image. * **Background Image (Mobile):** Select or upload a background image optimized for mobile devices. * **Legal Text:** Use the fields below to add your own legal text in the Checkout footer. The Appcharge legal text is displayed before your legal text, and can't be changed. * **General Footer Legal Text:** Enter your default legal text for the Checkout footer. Appcharge shows this when no localized text matches the player's location. If you don't configure either field, only Appcharge legal text is displayed. Use the rich text editor to format the text and add links. * **Localized Legal Text:** Add country- or state-specific legal text that completely replaces the general text for players in that location. Players see only one publisher footer text block. Use this for region-specific legal disclosures (for example, tax or refund language for the UK) or to provide a translated version of your general text: 1. Select a **Country**. 2. Enter the legal text in the rich text editor. 3. Click **Add**. 4. Repeat steps 1 through 3 for each additional country. 3. Click **Preview (Web and Mobile)** to review your changes, and then click **Save**. ## Customize the Completed Page To customize your Completed Page: 1. In the **Publisher Dashboard**, go to **Studio > Builder** and click the **Completed Page** tab. 2. Complete the following sections: * **General** * **Custom X Icon:** Upload or select the close icon displayed in the top-right corner of the Completed Page. * **Background Opacity:** Enter the background opacity percentage. * **Purchase Completed Modal** * **Header Text:** Enter the text displayed at the top of the Completed Page, such as **Purchase Completed!**. * **Font Color:** Use the drop-down menu to select **Solid** to apply a single color, or **Linear** to apply a gradient. * **Font Size (px):** Enter the font size in pixels. * **Font Weight:** Use the drop-down menu to select a font weight, **Regular**, **Medium**, or **Bold**. * **Additional Text** * **Body Text:** Enter additional text to display on the page, such as **Open the game to see your new items**. * **Font Color:** Use the drop-down menu to select a text color. * **Font Size (px):** Enter the font size in pixels. * **Font Weight:** Use the drop-down menu to select a font weight, **Regular**, **Medium**, or **Bold**. * **Products Quantity** * **Font Color:** Use the drop-down menu to select a text color for the quantity numbers shown next to products on the Completed Page. * **Font Size (px):** Enter the font size in pixels. * **Font Weight:** Use the drop-down menu to select a font weight, **Regular**, **Medium**, or **Bold**. * **Back to Game Button** * **Button Text:** Enter the text that appears on the button, such as **Back to game**. * **Button Image:** Upload a custom button image. If no image is uploaded, the button displays the text you entered. * **Android:** Enter the redirect URL or deep link for Android devices. * **Apple (iOS):** Enter the redirect URL or deep link for Apple devices. * **Web:** Enter the redirect URL for web browsers. 3. Click **Save** to apply your changes. You should see the updated Completed Page the next time a player completes a checkout. # Initiate a Refund Source: https://docs.appcharge.com/guides/checkout/initiate-a-refund This article explains how refunds work in Appcharge and how to initiate a full refund for an order using the Publisher Dashboard. You can also process full refunds using the [Initiate Refund API](../../api-reference/checkout/refunds/initiate-refund). To process a partial refund, contact your account manager. Once processed, all refunds are final and irreversible. ## How it works When you initiate a refund, Appcharge begins to process the request and updates the order status to **Refund Pending**. A refund receipt is automatically emailed to the player. Once Appcharge completes refund processing, the order status is updated to **Refunded**. It may still take several business days to credit the refunded amount to the player’s account, depending on their bank and payment provider. ### Eligibility Refunds can only be initiated in the Publisher Dashboard for orders with the following statuses: * **Succeeded** * **Charge Failed** To refund orders with other statuses, contact your account manager. ### Refund availability window The time period in which you can initiate a refund depends on the payment method or card scheme used for the original transaction. Most payment methods allow refunds within approximately 90–180 days from the transaction date, but check with your card scheme for the exact refund availability window. ## Refund an order To initiate a full refund: 1. In the Publisher Dashboard, go to **Dashboard > Orders**. The **Orders** page displays a list of your orders. 2. Select the relevant order to open the order details page. 3. In the top-right of the order details page, click **Refund**. A confirmation window opens. For order statuses other than **Succeeded** or **Charge Failed**, the **Refund** button is not displayed in the order details view. 4. In the confirmation window, click **Refund** again to confirm. Once confirmed, the refund is processed and cannot be reversed. The order details page displays the updated order status of **Refund Pending** or **Refunded**. If the refund fails, contact your account manager for assistance. # About Price Localization for External Stores Source: https://docs.appcharge.com/guides/checkout/price-localization/about-price-localization-for-external-webstores This page provides an overview of the technical flows for integrating price localization in an external web store using Appcharge. ***Note:** You can read more about the two currently localization models that Appcharge offers in the [Currency Localization Models documentation](./choose-a-price-localization-model).* ## Price Points Localization in External Store * Set up price points in USD in the Publisher Dashboard (see [Price Points Dashboard Setup Guide](./set-up-price-points)), or create and manage them using the [Price Points API](/../../api-reference/checkout/price-localization/introduction). * On your backend, retrieve localized prices using the Price Points API, for example with [Get Price Points for a Country](/../../api-reference/checkout/price-localization/get-price-points-for-a-country). * Display the localized prices, formatted with the local currency and tax inclusive, on the store screen. * When an offer is selected, call the [Create Checkout Session API](/../../api-reference/checkout/checkout-session/create-checkout-session) from your backend with the relevant localized price in the `priceDetails` property. *** ## Currency Conversion in External Store * Present prices in USD in the store phase. * When an offer is selected, call the [Create Checkout Session API](/../../api-reference/checkout/checkout-session/create-checkout-session) from your backend using the relevant price in USD. * The checkout process will automatically convert the USD amount to the player’s local currency. Simple conversion model tax implications
Note that the tax will be cut out of the total price in 'tax inclusive' countries (which means that you will receive the USD amount minus the tax amount), and no rounding rules will be applied on localized prices.
For more detailed technical documentation on how to integrate these localization models, see the [Price Points API documentation](/../../api-reference/checkout/price-localization/introduction). # Choose a Price Localization Model Source: https://docs.appcharge.com/guides/checkout/price-localization/choose-a-price-localization-model Appcharge supports two currency localization models based on your pricing needs, allowing players to see prices in their local currency across regions. # 1. Localization via Price Points This model is based on predefined price points in USD, updated to local currencies across regions. It ensures consistent revenue for publishers globally, showing stable, localized prices in the player’s currency without reliance on fluctuating exchange rates, reduces friction between prices shown in the store and checkout, and supports seamless integration with existing app store practices, allowing publishers to export price points from Google and Apple platforms directly into Appcharge. ## How it Works 1. **Price Point Configuration:** * Publisher defines each base price point in USD within the Appcharge Dashboard. * View [Price Point Dashboard Setup documentation](./set-up-price-points) for step-by-step guidance. * Once price points are configured, Appcharge automatically calculates and updates prices across 200+ currencies, applies appropriate taxes, and rounds prices intuitively where applicable. 2. **Store Presents Localized Prices:** * When the player browses the store, the prices are shown in their local currency, pre-set with applicable tax inclusions and price adjustments. 3. **Checkout Opens with Localized Prices:** * Upon checkout, players see the same localized prices they saw in the store, ensuring consistency. ### Rounding Rules Appcharge applies rounding rules to make prices more appealing and consistent. When prices are converted to local currencies, decimal currencies (such as USD and EUR) are rounded to endings like .00 or .99, while zero-decimal currencies (such as JPY, KRW, and VND) are rounded to natural denominations. Either way, players see attractive, familiar pricing. ***Note:** For more details on rounding rules, including exceptions and configuration options, see the [Price Point Dashboard Setup documentation](./set-up-price-points).* ## Benefits of Using Price Points **For Publishers:** * **Localized Currency Display:** Players see prices in their local currency, offering a familiar and trustworthy experience. * **Consistent Revenue:** Publishers achieve uniform net earnings per sale, streamlining financial reporting by eliminating variable currency exchange impacts. * **Local Buying Power Adjustments:** Publishers can adjust pricing to match the economic conditions, value perception, and demand across different regions, supporting both promotional and economic flexibility. **For Players:** * **Stable Prices:** By setting price points, players experience stable prices unaffected by exchange rate fluctuations. * **Enhanced Customer Experience:** Attractive, rounded prices build trust and improve player experience. * **Fair, Transparent Pricing:** Ensures fair pricing, including taxes where applicable, across all regions. *** # 2. Localization via Simple Currency Conversion This model is straightforward, with prices shown in USD until checkout, where they convert to the local currency. Limited benefits make this model ideal only for specific cases. ***Note:** To use this model, please contact the Appcharge team directly.* # How it Works 1. **Store Presents Prices in USD:** * Prices display in USD during store browsing. 2. **Local Currency Conversion at Checkout:** * When the player initiates the checkout process, Appcharge converts the USD price to the local currency based on their location. * Unlike the Price Points model, this approach does not use pre-configured price points or apply rounding rules. 3. **Tax Handling for 'Tax Inclusive' Countries:** * Appcharge converts the USD price to the player’s currency only during checkout, without price rounding or stability guarantees. Simple conversion model tax implications
Note that the tax will be cut out of the total price in 'tax inclusive' countries (which means that you will receive the USD amount minus the tax amount), and no rounding rules will be applied on localized prices.
## Benefits of Simple Currency Conversion * **Localized Pricing**: Players see prices in their local currency. * **Automatic Currency Conversion:** Appcharge keeps up with real-time currency conversions, ensuring players see updated pricing at checkout based on current exchange rates. *** For users integrating with an external web store, refer to [Display Localized Prices in External Store](./about-price-localization-for-external-webstores) for the technical flow to display localized prices. # Set Up Price Points Source: https://docs.appcharge.com/guides/checkout/price-localization/set-up-price-points # Overview Appcharge allows users to manage pricing points by adding them manually or uploading them in bulk using a CSV file. With support for over 80 currencies, you can update price points to reflect changes in taxes or currency rates. It’s recommended to review and update prices quarterly to keep them consistent. For more details, see the [Supported Countries for Price Points document](./supported-countries). # Add Price Points Manually 1. Navigate to the Appcharge dashboard. 2. Go to the 'Pricing' section. 3. Click on “Create New Pricing” at the top right of the dashboard. 4. Enter a new Price Point in USD.
***Note:** The price point cannot be lower than \$0.8.* 5. Adjust the prices for the specific countries where you want to apply the new price point. Ensure the prices align with your desired currency and tax settings for each country. 6. Click 'Save' at the top right corner to save the new Price Point. # Manually Edit Existing Price Points 1. Navigate to the Appcharge dashboard. 2. Go to the 'Pricing' section. 3. Click the three dots to the right of the price point you wish to edit. 4. Select "Edit." 5. Find the relevant country whose price you want to edit. 6. Under the price column, click the pencil symbol for that country. 7. Add the new price. 8. Click 'Save' at the top right of the page. 9. The status will change to 'Manually Updated' for the country you edited. # Add Price Points via CSV 1. Navigate to the Appcharge dashboard. 2. Go to the 'Pricing' section. 3. Click 'Export' to download a pre-formatted CSV template. This template will contain all current price point data already updated in Appcharge. If no price points exist, the template will be empty. 4. Once the CSV template is opened, fill it with the desired price points, ensuring all conditions are met (see the conditions and format rules below). 5. Upload the completed CSV file by clicking the ‘Import’ button. ### CSV Format Rules * Each **column** should represent a supported country. Countries must be listed using their Alpha-3 codes (not currency abbreviations). For example, the code for the United States is USA. * The **first column** should always contain the USD price for the price points you're configuring. * Each **row** should represent a different USD price point that you want to convert to various supported currencies. The price points in USD will be converted to their corresponding values in the local currencies for the selected countries. * For each country (column), list the converted price in its local currency. If you choose to leave a country out, the conversion for that country will be left blank. * ***Note:** If the country is not supported for price points or if the price point is not configured for a specific country, the price will default to USD.* Here’s an example of how the filled-out CSV should look: | USD price point | USA | FRA | BRA | AUS | CAN | JPN | QAT | | - | - | - | - | - | - | - | - | | 1.99 | 1.99 | 1.99 | 3.99 | 3.90 | 2.99 | 219 | 7.25 | | 5.99 | 5.99 | 5.99 | 10.99 | 8.90 | 7.99 | 796 | 29.99 | | 9.99 | 9.99 | 9.99 | 14.99 | 13.90 | 12.99 | 1107 | 45.00 | | 15.99 | 15.99 | 15.99 | 23.99 | 19.90 | 16.49 | 1711 | 61.00 | ### CSV Conditions When uploading a CSV file, please note the following conditions: * You can select any country supported by Appcharge for price point conversions and provide the appropriate currency values for each USD price point. To view the full list of supported countries for price point conversions, refer to this [documentation](./supported-countries). * The CSV should use the country's Alpha-3 code, not currency abbreviations. A reference link to the correct Alpha-3 codes is provided [here](https://www.iban.com/country-codes). * The base price values must be between 0.8 and 5000 (USD). View our [Supported Currencies](/../../merchant-of-record/finance/supported-currencies) documentation to see the minimum and maximum charge amount for every currency. * For zero-decimal currencies only, if a decimal is included in the CSV, it will be ignored, and only the integer part will be used. ### CSV Error Handling 1. **Unsupported or Non-Existent Country Codes:** * If the country isn’t supported or if a wrong (non-existent) country code is used, the entire CSV will not be uploaded, and an error will be displayed. 2. **USD Requirement** * The first column must list all of the price points in USD. * The title of the first column must explicitly be “USD price point.” * If these requirements are not met, the file will not be uploaded, and an error will be displayed. 3. **Non-Numeric Values** * All rows (excluding the header row) must contain numeric values for price points. * If any of the cells (beyond the header row) contain non-numeric data, the CSV will not be uploaded, and an error will be displayed. 4. **Out of Range Values** * If any price value is outside the supported range for its currency, an error will be returned. * The error will include the incorrect input value and the supported range for that specific currency. * Because the range for each currency can differ, please refer to our [Supported Currencies](/../../merchant-of-record/finance/supported-currencies) documentation for the minimum and maximum values. * If any price point is invalid, the entire file will not be uploaded. # Price points settings This section covers price configuration options available in the **Pricing > Settings** tab, including tax settings, rounding rules, currency exchange rate updates, and price guards. ### Currency localization The currency localization feature enables Publisher Dashboard admins to control how prices are displayed across different regions. To account for areas with high currency fluctuation, admins can select which currencies to localize from USD. If a currency is unchecked, prices for all countries using that currency will be displayed in USD instead of the local currency. For example, unchecking ARS will display prices in USD for players in Argentina. Prices are automatically calculated based on the set price point and, if the **Display Tax-Inclusive Prices** toggle is enabled, the applicable tax will also be included in the displayed price. #### Select currencies to display To select the currencies to display: 1. In the Publisher Dashboard, go to **Management > Pricing**, and then click the **Settings** tab. 2. In the **Currencies to Localize** section, click the **Currencies** drop-down menu. 3. Select the currencies you want to display, and then click **Apply**. ### Currency exchange rates To keep localized prices in sync with current exchange rates, you can update exchange rates manually or schedule automatic updates. These updates directly affect how your prices are calculated across different currencies, ensuring accurate and regionally appropriate pricing. For more on how exchange rates are sourced and applied within Appcharge, see [Currency Conversions](/../../merchant-of-record/finance/currency-conversions). Updating exchange rates doesn't override currencies that are configured for localized pricing. #### Update exchange rates manually To manually update exchange rates: 1. In the Publisher Dashboard, go to **Management > Pricing**, and then click the **Settings** tab. 2. In the **Update Exchange Rates** section, click **Update**. The **Update Exchange Rates** dialog opens. 3. Click the **Currencies** drop-down menu and select the currencies you want to update. 4. Click **Apply**. 5. Select **Update Now**, and then click **Update**. #### Schedule automatic updates To schedule automatic exchange rate updates: You can create only one automatic update schedule, but it can include multiple currencies. 1. In the Publisher Dashboard, go to **Management > Pricing**, and then click the **Settings** tab. 2. In the **Update Exchange Rates** section, click **Update**. The **Update Exchange Rates** dialog opens. 3. Click the **Currencies** drop-down menu and select the currencies you want to update. 4. Click **Apply**. 5. Select **Schedule**. The scheduling options appear. 6. Click the **Repeat** drop-down menu, select the schedule that you want, and complete the relevant required fields below: * **Does Not Repeat**: Select this option to save the schedule as a draft or to pause an existing recurring schedule. * **Every Day** * **Time**: Select the time of day (UTC). * **Every Week** * **Weekday**: Select the day of the week. * **Time**: Select the time of day (UTC). * **Every Month** * **Day of Month**: Select the calendar day (1–31). If you schedule an update on a day that doesn't occur in every month, such as the 31st, the update won't run in those months. * **Time**: Select the time of day (UTC). * **Quarterly**: Updates every quarter of the year, on January 1, April 1, July 1, and October 1. * **Semi-Annual**: Updates twice a year, on January 1 and July 1. * **Annual**: Updates once a year, on July 1. 7. Click **Update** to save your changes. ### ‘Add Tax’ Toggle Users can view the tax details, including whether it is included or excluded and the applicable percentage. This information varies by country and will override the default tax setting if specific price points are provided. * **Functionality**: When turned on, tax will automatically be included in the price calculations. * **Exceptions**: If specific price conversions are uploaded manually or via CSV, the tax will not apply even if the toggle is turned on. ### Rounding rules When the **Rounding Rules** toggle is on, Appcharge applies rounding after it converts your USD price point to the local currency and adds the applicable tax. Rounding behavior depends on the currency type: * **Decimal currencies:** Currencies such as USD and EUR round to endings like .00, .09, .90, or .99. See [Decimal currencies](#decimal-currencies). * **Zero-decimal currencies:** Currencies such as JPY, KRW, and VND round to natural whole-number denominations. See [Zero-decimal currencies](#zero-decimal-currencies). #### Enable rounding rules To enable rounding rules: 1. In the Publisher Dashboard, go to **Management > Pricing**, and then click the **Settings** tab. 2. Scroll to **Rounding Rules**. 3. Turn on the toggle. With the **Rounding Rules** toggle on, rounded prices apply to auto-calculated conversions going forward. Appcharge rounds auto-calculated prices to cleaner endings, such as \$9.99 instead of \$9.97. Rounding doesn't apply in these cases: * **Manual prices:** Prices you enter manually or upload by CSV. Appcharge keeps the exact price you set. * **Rounding disabled:** Auto-calculated prices generated while the **Rounding Rules** toggle is off, or before you enable rounding. * **Missing exchange rate:** If Appcharge can't find the current exchange rate for a currency, it uses the exact converted price after conversion and tax so the player can still pay. * **No rounding rules:** If Appcharge has no rounding rules configured for a currency, it leaves the price unchanged. * **Price Guards:** When Appcharge checks whether a localized price falls within your configured thresholds, it compares against the unrounded converted price. See [Price Guards](#price-guards). #### Decimal currencies Currencies like USD and EUR use cents, so a converted price might land on an awkward number like €15.45. Appcharge adjusts it to a cleaner price, like €14.90, using the rules in the table below. Appcharge chooses the ending in two steps. It doesn't use the mathematically nearest ending. It uses a fixed .50 cutoff on the decimal fraction. * **Exchange rate:** Appcharge looks up the USD-to-local exchange rate used for that currency's conversion. This rate comes from your pricing settings. It is not the converted price. Appcharge matches that rate to a row in the table below. * **Decimal fraction:** Appcharge checks the digits after the decimal point in the converted price. If that fraction is .00 to .49, it uses the left-column ending. If that fraction is .50 to .99, it uses the right-column ending. The following table shows how Appcharge selects the rounded ending based on the exchange rate and the converted price's decimal fraction. In this table, `xy` is the whole-number part of the converted price. For a converted price of 15.45, `xy` is 15. In the **> 200** row, `xyz` represents the integer digits before `.00` in the ending `xyz0.00`. For example, `xyz0.00` becomes **1230.00**, where `xyz` is **123**. In the **Rate has ≥ 5 digits** row, `xxx` works the same way in the ending `xxx00.00`. | USD → local exchange rate | Ending if fraction is .00 – .49 | Ending if fraction is .50 – .99 | | - | - | - | | **≤ 2** | xy.09 | xy.99 | | **> 2 and ≤ 200** | (xy − 1).90 | xy.90 | | **> 200** | xyz0.00 | xyz0.00 | | **Rate has ≥ 5 digits** | xxx00.00 | xxx00.00 | For example, with a USD → local exchange rate of **1.0**, Appcharge selects the **≤ 2** row. For a converted price of **1.52**, the decimal fraction .52 falls in the .50 to .99 range, so the price rounds to **1.99**. With a USD → local exchange rate of **3.0**, Appcharge selects the **> 2 and ≤ 200** row. For a converted price of **15.45**, the decimal fraction .45 falls in the .00 to .49 range, so the price rounds to **14.90**. #### Zero-decimal currencies Zero-decimal currencies use whole numbers only, such as JPY, KRW, and VND. Appcharge rounds 16 of these currencies to the nearest configured denomination using round half up. Unlike decimal currencies, Appcharge picks the mathematically nearest denomination. It doesn't use the .50 decimal-fraction ending lookup. Depending on the currency, Appcharge applies either tiered or fixed-unit rounding. Tiered rounding uses a larger denomination once the price crosses a threshold. Fixed-unit rounding always uses the same denomination. **Tiered rounding** JPY and KRW use different denominations below and above a price threshold. | Currency | Price tier | Rounds to nearest | Example | | - | - | - | - | | **JPY** | Below ¥2,000 | 10 | ¥1,983 → **¥1,980** | | **JPY** | ¥2,000 and above | 100 | ¥3,870 → **¥3,900** | | **KRW** | Below ₩20,000 | 100 | ₩14,732 → **₩14,700** | | **KRW** | ₩20,000 and above | 500 | ₩26,880 → **₩27,000** | **Fixed-unit rounding** The other 14 zero-decimal currencies always round to the same denomination, regardless of price. For example, VND rounds to the nearest 1,000, so 12,450 becomes **12,000**. The following table lists each currency and the denomination it rounds to. | Currency | Rounds to nearest | | - | - | | VND, PYG, UGX, GNF, MGA | 1,000 | | CLP, XAF, XOF, BIF, KMF, RWF | 100 | | VUV, XPF, DJF | 10 | ### Tax and rounding examples The following examples show how tax display and rounding can appear together. Rounding endings still follow the decimal and zero-decimal rules above. 1. **Paris, France (tax included)** * **Tax rate:** 20% VAT * **Base price:** €10 * **Final price:** €12.00 (after 20% tax and rounding) * **Player sees:** €12.00 * **Explanation:** The price shown includes VAT. No additional tax is added at checkout. 2. **New York, USA (tax excluded)** * **Tax rate:** 8.875% (city and state tax) * **Base price:** \$10 * **Checkout price:** \$10.99 (after adding tax and rounding) * **Player sees:** \$10.99 * **Explanation:** The base price is displayed. Tax is added at checkout, and the total is rounded. ### Price Guards Price Guards let you monitor localized prices and receive alerts when they fall outside expected ranges based on the latest market exchange rate. Appcharge uses the unrounded converted price for these comparisons so the threshold check is as accurate as possible. You can set percentage-based thresholds for different price ranges to define how much variation from the converted value is acceptable. When a localized price exceeds its threshold, Appcharge flags it in the Publisher Dashboard. To resolve the alert, simply update the localized price or adjust the relevant threshold. #### Example The following example shows how Appcharge detects and reports a threshold breach: * **USD price point:** \$2,000 * **Current exchange rate (USD to EUR):** 1.5 * **Converted price:** €3,000 * **Threshold range:** ±10% If the market exchange rate changes and the converted price becomes €3,450 (a 15% increase), Appcharge detects that the localized price is now outside the allowed range and triggers an alert in the Publisher Dashboard. #### Configure Price Guards To configure price guards: 1. Go to **Pricing**, and click the **Settings** tab. 2. In the **Create Price Guards** section, add a price range and its percentage thresholds: * Specify the **Price range start** and **Price range end**. * Enter a negative number for the **Negative threshold (%)** and a positive number for the **Positive threshold (%)** 3. Click **Add**. # Final Price Calculation The final price for each item is calculated by first converting the USD price to the target currency, then adding the applicable tax, and finally applying the rounding rules. For more details, users can learn more in the tax section of the dashboard. # Supported Countries for Price Points Source: https://docs.appcharge.com/guides/checkout/price-localization/supported-countries Use this reference when configuring [price points](./set-up-price-points). For each country in the price points feature, the table shows the currency Appcharge uses and how it applies tax. If a country is not in the table, Appcharge uses USD. ## How Appcharge applies tax and currency The **Currency** column shows the currency Appcharge uses for price points in that country. This can differ from the country's official currency. The **Tax Model** and **Tax Rate** columns show how Appcharge applies tax: * **Included:** The player sees tax as part of the price, with no additional tax at checkout. * **Excluded:** Appcharge adds tax to the base price at checkout. Appcharge applies the listed rate, then applies rounding. For worked examples, see [Real-Life Examples for Tax and Rounding Rules](./set-up-price-points#real-life-examples-for-tax-and-rounding-rules). ## Supported countries | Country | Currency | Tax Model | Tax Rate | | - | - | - | - | | Albania | USD | Included | 20% | | Andorra | EUR | Included | 4.5% | | Argentina | ARS | Included | 0% | | Australia | AUD | Included | 10% | | Austria | EUR | Included | 20% | | Bangladesh | USD | Included | 0% | | Belgium | EUR | Included | 21% | | Bosnia and Herzegovina | BAM | Included | 17% | | Brazil | BRL | Included | 0% | | Bulgaria | EUR | Included | 20% | | Canada | CAD | Excluded | 5% | | Chile | CLP | Included | 19% | | China | CNY | Included | 0% | | Costa Rica | USD | Included | 13% | | Croatia | EUR | Included | 25% | | Cyprus | EUR | Included | 19% | | Czech Republic | CZK | Included | 21% | | Denmark | DKK | Included | 25% | | Ecuador | USD | Included | 15% | | Egypt | EGP | Included | 14% | | Estonia | EUR | Included | 24% | | Finland | EUR | Included | 25.5% | | France | EUR | Included | 20% | | Georgia | USD | Included | 18% | | Germany | EUR | Included | 19% | | Greece | EUR | Included | 24% | | Guernsey | GBP | Included | 0% | | Hong Kong | HKD | Included | 0% | | Hungary | HUF | Included | 27% | | Iceland | USD | Included | 24% | | India | INR | Included | 18% | | Indonesia | IDR | Included | 12% | | Ireland | EUR | Included | 23% | | Israel | ILS | Included | 18% | | Italy | EUR | Included | 22% | | Japan | JPY | Included | 10% | | Jordan | JOD | Included | 16% | | Kazakhstan | KZT | Included | 16% | | Latvia | EUR | Included | 21% | | Lebanon | USD | Included | 0% | | Lesotho | USD | Included | 0% | | Lithuania | EUR | Included | 21% | | Luxembourg | EUR | Included | 17% | | Macau | USD | Included | 0% | | Malaysia | MYR | Included | 8% | | Maldives | USD | Included | 0% | | Malta | EUR | Included | 18% | | Martinique | EUR | Included | 8.5% | | Mexico | MXN | Included | 16% | | Montenegro | EUR | Included | 21% | | Morocco | MAD | Included | 20% | | Nauru | AUD | Included | 0% | | Netherlands | EUR | Included | 21% | | New Zealand | NZD | Included | 15% | | Nigeria | NGN | Included | 0% | | North Macedonia | USD | Included | 18% | | Norway | NOK | Included | 25% | | Pakistan | PKR | Included | 18% | | Panama | USD | Included | 7% | | Peru | PEN | Included | 18% | | Philippines | PHP | Included | 12% | | Poland | PLN | Included | 23% | | Portugal | EUR | Included | 23% | | Qatar | QAR | Included | 5% | | Romania | RON | Included | 21% | | Saudi Arabia | SAR | Included | 15% | | Serbia | RSD | Included | 20% | | Singapore | SGD | Included | 9% | | Slovakia | EUR | Included | 23% | | Slovenia | EUR | Included | 22% | | South Africa | ZAR | Included | 15% | | South Korea | KRW | Included | 10% | | Spain | EUR | Included | 21% | | Sweden | SEK | Included | 25% | | Switzerland | CHF | Included | 8.1% | | Taiwan | TWD | Included | 5% | | Thailand | THB | Included | 7% | | Turkey | TRY | Included | 20% | | Ukraine | UAH | Included | 20% | | United Arab Emirates | AED | Included | 5% | | United Kingdom | GBP | Included | 20% | | Vietnam | VND | Included | 10% | # About Receipts Source: https://docs.appcharge.com/guides/checkout/receipts/about-receipts Appcharge automatically sends a customized receipt after each purchase. These receipts are tailored to your game’s branding and provide players with essential information about their purchase.
Receipt
## How it works After a player completes a purchase, Appcharge generates and emails a receipt that includes relevant transaction details, such as what was purchased, amounts paid, and any applicable tax or discounts. Receipts are designed to be easy for customers to understand and to give your support team a consistent reference point, such as a receipt number and order ID, when investigating questions about purchases. Purchase and refund receipt emails show the payment date and time in the player's local time zone, with a time zone label. If the player's time zone couldn't be captured, the email uses UTC. You can find the receipt number and order ID in the **Orders** tab of the Publisher Dashboard. To learn more, see [View Orders](/../..//guides/publisher-dashboard/view-orders). Receipts typically include: * Your game’s branding elements such as a customized logo and header. * Receipt number * Order ID * Payment method * Payment date and time * Player country * Itemized list of purchased items * Tax rate (if applicable) * Discounts (if applicable) * Total paid You can also translate receipts so players receive them in their preferred languages. Learn how to [customize and translate receipts](/../../guides/checkout/receipts/customize-receipts). # Customize Receipts Source: https://docs.appcharge.com/guides/checkout/receipts/customize-receipts This article explains how to customize the receipts sent to your players after successful game purchases, including email sender details and receipt branding. To customize receipts: 1. In your Publisher Dashboard go to **Studio > Builder > Receipt.** 2. Configure the following fields: * **Sender Name**: Enter the name you want displayed as the email sender. * **Receipt Logo**: Select or upload an image for the logo on the receipts. * **Receipt Header**: Select or upload a header image for the receipts. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. 3. Click **Save** to finalize the changes. ## Translate receipts Add translations so that your receipts are sent to customers in their preferred languages. To translate receipts: 1. Follow the instructions in the [Translations Guide](/../../guides/translations/about-translations) to add languages and set the translations. 2. Ensure your receipts are set to display the correct language: * **If you have an Appcharge web store:** The receipt is sent in the same language as the player's web store. * **If you don't have an Appcharge web store:** Include the desired locale in the `receiptMetadata` property in your request to the [Create Checkout Session API](/../../api-reference/checkout/checkout-session/create-checkout-session). If the receipt locale can't be rendered, the email uses English. # Set Up Your Checkout Source: https://docs.appcharge.com/guides/checkout/set-up-your-checkout > **Important:** This setup only applies if you don't have an Appcharge web store. 1. Make sure you've [set up your Publisher Dashboard](./../publisher-dashboard/set-up-your-publisher-dashboard). 2. Add your external store's domain name in the Publisher Dashboard. 3. If you want to offer Apple Pay, you must [register and verify your domains](./add-apple-pay) before going live with your checkout. 4. [Create a checkout session](/../../api-reference/checkout/checkout-session/create-checkout-session). 5. Integrate the checkout with your custom store using the [Frontend SDKs](../../sdks/checkout/frontend-sdk/introduction). 6. [Enable real-time order reporting](./orders/about-player-order-reporting) to sync purchases and update player balances. 7. Set up [price points](./price-localization/set-up-price-points). If you want to use Appcharge's checkout with Unity WebGL, use the [Payment Links SDK](../../sdks/payment-links/introduction). For setup instructions, see [Integrate with WebGL](../../sdks/payment-links/unity/integrate-with-webgl). ## Explore additional Checkout features # About the Events Center Source: https://docs.appcharge.com/guides/events/about-the-events-center The Events Center enables you to receive real-time data on key player activities such as logins, web store interactions, and order events. You can choose which events to listen for and use these insights to improve tracking, enhance business intelligence, and respond promptly to player actions. To get started, [create and set up an Events Webhook](/../../api-reference/events/v2/introduction). After setting up your webhook, follow the steps below to register it in the Publisher Dashboard and select the events you want to monitor. > **Note:** We’ve updated Events to V2. Events V1 is still supported, but we recommend using the new and improved Events V2. ## Configure the webhook To register your webhook in the Publisher Dashboard: 1. Navigate to **Settings > Integration**. 2. Enter your webhook URL in the **Events V2 Webhook** field. For example, `https://{publisher-server}/events`. 3. Click **Update** to apply the changes. ## Choose which events to receive > **Note:** This section is for Admins only. Learn how to [manage roles and permissions](./../publisher-dashboard/set-up-your-publisher-dashboard#manage-your-user-roles). In the Publisher Dashboard, you can enable or disable specific events in the **Events Center**. Each event entry includes: * **Trigger:** Name of the event. * **Event Name:** Name of the event as displayed in the webhook request. * **Category:** Sub-type classification of the event. * **Is Active:** Toggle to activate or deactivate the event. Use the search bar to quickly locate events by name, or filter by category to narrow down the list. ## Supported events The following table outlines the events Appcharge supports, grouped by type: | Event Type | Event Name | Description | | | - | - | - | - | | Web Store Events | `Web Store Login Displayed` | Triggered when the login page of the web store is displayed. Used to track login funnel entry. | | | | `Web Store Login Method Selected` | Triggered when a login method in the web store is selected. For example, a social media platform. | | | | `Web Store Login Completed` | Triggered when the player successfully completes the web store login process and is authenticated. | | | | `Web Store Login Canceled` | Triggered when the player closes or leaves the web store login process before completing it. | | | | `Web Store Displayed` | Triggered when the web store page is displayed. | | | | `Offers Loaded` | Triggered when the backend successfully returns the list of offers configured to be shown to the player. This event confirms that the offers are ready to be rendered on the page. | | | | `Offers Displayed` | Triggered when 100% of an offer's visual element is visible to the player. Events are batched every second and include only newly shown offers, excluding previously reported ones. The list resets after a page refresh. | | | | `Offer Popup Closed` | Triggered when a player closes a popup offer in the web store. | | | | `Progress Bar Points Granted` | Triggered when a player is granted Progress Bar points. | | | | `Progress Bar Mission Started` | Triggered when a new Progress Bar mission starts and is revealed to the player. | | | | `Progress Bar Mission Completed` | Triggered when a Progress Bar mission is completed. | | | | `Web Store Approval Request Displayed` | Triggered when the Approval Request in the checkout link offer is displayed. | | | | `Web Store Approval Request Closed` | Triggered when the Approval Request in the checkout link offer is closed. | | | | `Personalization Response Error` | Triggered when the Personalization API returns an unexpected or invalid response. Typical causes include schema mismatches, incorrect data types, timeouts, empty offer lists, or non-existent external IDs. | | | Checkout Events | `Order Created` | Triggered when a new order session is initialized, either from the web store or via direct API call. | | | | `Payment Resolved` | Triggered when a payment is finalized, successfully or unsuccessfully. | | | | `Order Completed` | Triggered when an order is successfully paid and processed, and confirmation is sent to the publisher or game. | | | | `Order Canceled` | Triggered when an order is cancelled by the player or through a system timeout before completion. | | | | `Order Refunded` | Triggered when an order is refunded, either manually or automatically. | | | | `Dispute Opened` | Triggered when a payment dispute is opened, for example, a chargeback is initiated by the player with their payment provider. | | | | `Dispute Resolved` | Triggered when a dispute is resolved in favor of the publisher or Appcharge. | | | Game Portal Events | `Portal Login Displayed` | Triggered event triggered when the login page of the game portal is displayed. Used to track login funnel entry. | | | | `Portal Login Method Selected` | Triggered event triggered when a login method is selected in the game portal. For example, a social media platform. | | | | `Portal Login Completed` | Triggered when the player successfully completes the game portal login process and is authenticated. | | | | `Portal Login Canceled` | Triggered when the player closes or leaves the game portal login process before completing it. | | | | `Portal Page Displayed` | Triggered when a page in the game portal is displayed. | | | | `Portal Content Displayed` | Triggered when content on a game portal page is displayed. | | | | `Portal Approval Request Displayed` | Triggered when the Approval Request in the checkout link offer is displayed. | | | | `Portal Approval Request Closed` | Triggered when the Approval Request in the checkout link offer is closed. | | | | `Portal Footer Clicked` | Triggered when then game portal footer was clicked. | | | | `Portal Block Clicked` | Triggered when a Game Portal block is clicked. | | # About the Game Portal Source: https://docs.appcharge.com/guides/game-portal/about-the-game-portal The Game Portal is a multi-page hub that expands your game’s experience beyond the app. It serves as a central destination where players can stay informed, explore exclusive content, and access your web store. The web store is fully integrated into the portal, so players can browse and make purchases without being redirected or opening a separate link. The portal is designed as a mobile-first experience. It delivers optimal performance and intuitive navigation on smartphones and tablets, giving players a smooth, app-like interface directly in their browser. ## How it works You can manage the portal’s design, layout, and content directly from the Publisher Dashboard. The portal includes a customizable home page and store page that sync automatically with your web store and with the [Personalize Web Store Callback](/../../api-reference/webstore/personalization/personalize-webstore-callback). ### Create pages You can create additional pages or subpages to organize information for players. Pages can include visual elements, announcements, and interactive components. Learn how to [Create and Manage a Game Portal Page](./create-and-manage-a-game-portal-page). ### Design your page layouts with Blocks Each page layout is built using Blocks. Blocks are configurable components that allow you to add videos, calls to action, content previews, and other features. You can reorder, add, or remove Blocks at any time. You can also reuse Blocks across different pages by exporting them from one page and importing them into another. This helps you maintain consistent layouts and speeds up the creation of new pages. Learn how to [Create and Manage Blocks](./create-and-manage-game-portal-blocks). ### Create content Content items include articles or news that players can open to read in full. Content is managed separately from pages, which allows it to be reused across the portal. You can [Create and Manage Game Portal Content](./create-and-manage-game-portal-content) in the Publisher Dashboard or via the [Content API service](/../../api-reference/game-portal/content/introduction). ### Translate your Game Portal You can translate the portal so players see pages, store interface, and content in their preferred language. There are 2 aspects to translating the portal: * **Portal pages and UI:** Use the [Translations feature](../translations/about-translations) in the Publisher Dashboard or the [Translations API service](/../../api-reference/translations/introduction). * **Content items:** [Configure content translations](../translations/translate-game-portal-content) directly in the Content section of the Publisher Dashboard, or via the [Content API service](/../../api-reference/game-portal/content/introduction). ### Publish and manage visibility You can preview pages and content before publishing them. If you want to delay publication, you can mark an item as hidden and schedule it for a future release. You can also set visibility rules so that specific pages or content are available only to authenticated players. ### Configure authentication You can use [any authentication method](../webstore/player-authentication/about-player-authentication#supported-authentication-methods) supported by your game for the Game Portal. To streamline the experience when players access the portal from within the game, use the [Pre-Authenticated Login](../webstore/player-authentication/pre-authenticated-login/about-pre-authenticated-login) method to authenticate them automatically without requiring an additional login. ### Game Portal as a Parking Domain You can use the portal as a parking domain to direct players from your game to your web store in compliance with Apple and Google guidelines. To learn more, see [About Parking Domains](./parking-domains/about-parking-domains). ## Key features * **Preview before publishing:** Preview pages and content before they go live. * **Drafting and scheduling:** Mark a page or content as hidden and schedule it for future publication. * **Visibility:** Set a page or content to be public or restricted to authenticated players. # Create and Manage a Game Portal Page Source: https://docs.appcharge.com/guides/game-portal/create-and-manage-a-game-portal-page This article explains how to create and manage a Game Portal page in the Publisher Dashboard. When adding images, if you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. ## Create a page To create a page: 1. In your Game Portal project, go to the **Pages** tab and click **Create New Page**. 2. In the **Settings** tab, configure the following fields: * **Page Name**: Enter a name for the page. * **Add an Icon**: Upload or select an image for your page icon. * **Portal**: Define a page slug (URL path). * **Page Type**: Select the page type: * **Home:** The home page of the game portal. This is added by default. * **Store:** Your synced web store. This is added by default. * **Content:** Additional pages of content that you can create. - If you are using the Game Portal for [Parking Domains](./parking-domains/about-parking-domains), the **Store** page is disabled. - You can only have one **Home** page and one **Store** page at a time. To create a new one, you must first delete the existing page of that type. * **Page Level**: Choose one of the following: * **Main Page** * **Sub Page** * **Parent Page**: This field becomes active when **Sub Page** is selected. Use the drop-down menu to choose the page under which this page will be nested. * **Priority**: Define the page’s display order: * For **Main Pages**, the priority determines their order in the main navigation. * For **Sub Pages**, priority determines their order within their parent page in the navigation. * **Visibility**: Select the page visibility: * **Visible To All** (default): The page is visible to all visitors. * **Logged In Only**: The page is visible only to players who are logged in. * **Logged Out Only** The page is visible only to players who are logged out. * **Redirect URL:** For the **Store** page only, redirect players to a parking domain URL or an external store URL. * **URL:** Enter the full destination URL. Use a specific page URL, not a generic homepage URL. This field is required. * **Redirect to Web Store:** Check to open the URL outside the game portal. Uncheck to open the URL inside the game portal. * **Segments**: Enter segment names to display the page to select groups of players. * **Metadata**: * Upload an image. * Add a short description. * **Schedule Publication Date**: * Toggle **Enable scheduled publishing**. * **Publish Date**: Set the date that you want the page to be published. 3. In the **Manage Blocks** tab, customize your page layout using [Blocks](/../../guides/game-portal/create-and-manage-game-portal-blocks). 4. At the top of the editor, set the page to **Visible** or **Hidden**. The page is hidden by default. If the page is set to **Hidden**, you can schedule it to be published at a later date. 5. Click **Save** to apply changes. ## Edit a page To edit a page: 1. Go to the **Pages** tab. 2. Click the ellipsis next to the page and select **Edit**. 3. Make changes as needed, and then select **Update** to save. ## Delete a page To delete a page: 1. Go to the **Pages** tab. 2. Click the ellipsis next to the page and select **Delete**. # Create and Manage Game Portal Blocks Source: https://docs.appcharge.com/guides/game-portal/create-and-manage-game-portal-blocks This article explains how to use Blocks in the Publisher Dashboard to customize both the layout and functionality of your Game Portal pages. It guides you through adding, editing, rearranging, and deleting Blocks so you can build the experience you want. Follow the steps below to create and customize your page layout using Blocks. ## Add a Block To add a Block to your page: 1. In your Game Portal project, go to the **Pages** tab and create a new page or edit an existing one. 2. At the top of the page, click the **Manage Blocks** tab. The Blocks editor opens with some default Blocks to help you get started. 3. Click **Add New Block** and select the type of Block you want to add from the drop-down menu: * **Image**: Add images to the page. * **Video**: Add videos to the page. * **Content Preview**: Display previews of your News and Articles. * **CTA**: Insert a call-to-action button. * **HTML**: Embed custom design elements using HTML code. The HTML Block only supports inline styles. * **Daily Bonus**: Display the Daily Bonus panel so they can view their reward directly from the page. * **Progress Bar**: Display the Progress Bar offer so they can track their current progress directly from the page. The Daily Bonus and Progress Bar are only visible to players who are logged in. 4. The new Block is added to the list of Blocks on the page. ## Configure a Block To edit the information in a Block: 1. In your Game Portal project, go to the **Pages** tab and you'll see a list of all your pages. 2. Click the ellipsis of the page you want to edit, and then click **Edit**. 3. Click the **Manage Blocks** tab. 4. Click the Block you want to configure to view the fields you can edit. 5. Complete the required fields for the Blocks you’re using: 1) In the Image Block, click **Item #1**. 2) In **Default Image**, click **Upload** to open the **Upload Image** window. Add an image using one of these methods: * To upload an image from the computer, do one of the following: * Click the **Upload** tab and select a file from your computer. * Drag and drop a file into the window. * To select an existing image from the **Assets Library**: * Click the **Media** tab. * Select an image from the **Assets Library** and click **Save**. * Click the image to reopen the **Upload Image** window and click the **Upload** tab to complete the remaining fields. * To use an online image: * Toggle **Image URL** on. * Enter the image URL. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. 3) Assign the image an **ID Number**. 4) Click the drop-down menu and select an image category such as General or Product. 5) Click **Save**. The window closes. 6) To add a mobile version of the image: * In the **Mobile Image** box, click **Upload**. * Follow the instructions in Step 2. Uploading a **Mobile Image** replaces the **Default Image** when the page is viewed on a mobile device. 7) Add a **Redirect URL**. 8) Click the **Visibility** drop-down menu to select the Block visibility: * **Visible To All** (default): The Block is visible to all visitors. * **Logged In Only**: The Block is visible only to players who are logged in. * **Logged Out Only** The Block is visible only to players who are logged out. 9) In **Segments**, enter segment names to display the Block to select groups of players. 10) Click **Add Item** to add another image. 1. In the Video Block, click **Item #1** to view the fields. 2. In the **Video URL** field, paste the URL of the video. 3. In the **Mobile Video URL** field, paste a video URL to display a mobile version of the video. Entering a Mobile Video URL replaces the Video URL when the page is viewed on a mobile device. 4. Enable **Autoplay** to start the video automatically. 5. Click the **Visibility** drop-down menu to select the Block visibility: * **Visible To All** (default): The Block is visible to all visitors. * **Logged In Only**: The Block is shown only to players who are logged in. * **Logged Out Only**: The Block is shown only to players who are logged out. 6. In **Segments**, enter segment names to display the Block to select groups of players. 7. Click **Add Item** to add another video. 1. In **Content Type**, select which content type to display: **News** or **Article**. 2. In **Title**, enter the title that will appear above the preview. 3. In **Max items**, set the number of content items you want displayed in the preview. 4. Click the **Visibility** drop-down menu to select the Block visibility: * **Visible to Everyone** (default): The Block is shown to all visitors. * **Logged-in Users Only**: The Block is shown only to players who are logged in. * **Logged-out Users Only**: The Block is shown only to players who are logged out. 5. In **Segments**, enter segment names to display the Block to select groups of players. 1. In the CTA Block, open **Item #1**. 2. In **Default Asset**, click **Upload** to open the **Upload Image** window. Add an image using one of these methods: * To upload an image from the computer, do one of the following: * Click the **Upload** tab and select a file from your computer. * Drag and drop a file into the window. * To select an existing image from the **Assets Library**: * Click the **Media** tab. * Select an image from the **Assets Library** and click **Save**. * Click on the image to reopen the **Upload Image** window and click the **Upload** tab to complete the remaining fields. 3. To add a mobile version of the image: * In the **Mobile Asset** field, click **Upload**. * Follow the instructions in Step 2. Uploading a **Mobile Asset** replaces the **Default Asset** when the page is viewed on a mobile device. 4. Add a **Redirect URL**. 5. Select **External Web Store Redirect** if the redirect link as an external web store URL. 6. In **Button Text**, enter a label for the CTA button. 7. Click the **Visibility** drop-down menu to select the Block visibility: * **Visible to Everyone** (default): The Block is shown to all visitors. * **Logged-in Users Only**: The Block is shown only to players who are logged in. * **Logged-out Users Only**: The Block is shown only to players who are logged out. 8. In **Segments**, enter segment names to display the Block to select groups of players. 1. Click the **HTML** Block to view the **HTML** field. 2. Click inside the **HTML** editor box and enter your HTML: * The field is required and you must enter a value. * If you need styling, use inline styles. For example: `
...
`. 3. Click the **Visibility** drop-down menu to select the Block visibility: * **Visible To All** (default): The Block is visible to all visitors. * **Logged In Only**: The Block is visible only to players who are logged in. * **Logged Out Only** The Block is visible only to players who are logged out. 4. In **Segments**, enter segment names to display the Block to select groups of players.
1. In **Default Background Image**, click **Upload** to open the **Upload Image** window. Add an image using one of these methods: * To upload an image from the computer, do one of the following: * Click the **Upload** tab and select a file from your computer. * Drag and drop a file into the window. * To select an existing image from the **Assets Library**: * Click the **Media** tab. * Select an image from the **Assets Library** and click **Save**. The image is saved and the **Upload Image** window closes. * Click on the image to reopen the **Upload Image** window and click the **Upload** tab to complete the remaining fields. * To use an online image: * Toggle **Image URL** on. * Enter the image URL. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. 2. Assign the image an **ID Number**. 3. Click the drop-down menu and select an image category such as General or Product. 4. Click **Save**. The window closes. 5. To add a mobile version of the image: * In the **Mobile Background Image** box, click **Upload**. * Follow the instructions in Step 2. Uploading a **Mobile Image** replaces the **Default Image** when the page is viewed on a mobile device. 6. Add a **Redirect URL**. 7. Select **External Web Store Redirect** if the redirect link as an external web store URL. 8. Click the **Visibility** drop-down menu to select the Block visibility: * **Visible To All** (default): The Block is visible to all visitors. * **Logged In Only**: The Block is visible only to players who are logged in. * **Logged Out Only** The Block is visible only to players who are logged out. 9. In **Segments**, enter segment names to display the Block to select groups of players. 1. In **Default Background Image**, click **Upload** to open the **Upload Image** window. Add an image using one of these methods: * To upload an image from the computer, do one of the following: * Click the **Upload** tab and select a file from your computer. * Drag and drop a file into the window. * To select an existing image from the **Assets Library**: * Click the **Media** tab. * Select an image from the **Assets Library** and click **Save**. The image is saved and the **Upload Image** window closes. * Click on the image to reopen the **Upload Image** window and click the **Upload** tab to complete the remaining fields. * To use an online image: * Toggle **Image URL** on. * Enter the image URL. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. 2. Assign the image an **ID Number**. 3. Click the drop-down menu and select an image category such as General or Background. 4. Click **Save**. The window closes. 5. To add a mobile version of the background image: * In the **Mobile Background Image** box, click **Upload**. * Follow the instructions in Step 2. Uploading a **Mobile Image** replaces the **Default Image** when the page is viewed on a mobile device. 6. Add a **Redirect URL**. 7. Enable **External Web Store Redirect** if the redirect link as an external web store URL. 8. Click the **Visibility** drop-down menu to select the Block visibility: * **Visible To All** (default): The Block is visible to all visitors. * **Logged In Only**: The Block is visible only to players who are logged in. * **Logged Out Only** The Block is visible only to players who are logged out. 9. In **Segments**, enter segment names to display the Block to select groups of players. 10. On the top-right of the page, click **Update** to save your changes. ## Reorder a Block To move the Blocks to different spots in the page layout: 1. In your Game Portal project, go to the **Pages** tab and you'll see a list of all your pages. 2. Click the ellipsis of the page you want to edit, and then select **Edit**. 3. Click the **Manage Blocks** tab. 4. Use the drag handle to hold and drag the Block to the desired position in the layout. ## Delete a Block 1. In your Game Portal project, go to the **Pages** tab and you'll see a list of all your pages. 2. Click the ellipsis of the page you want to edit, and then select **Edit**. 3. Click the **Manage Blocks** tab. 4. Locate the Block you want to delete, and then click the trash icon on the right side of the Block. ## Export and import a Block You can export and import Blocks to resue them in a different page. To export a Block: 1. On the top of the page, click **Export**. 2. The page's Blocks are downloaded as a JSON file. To import a Block: 1. Go to the page where you want to add the Blocks, and then click **Import** to upload the downloaded JSON file from your computer. 2. The imported Blocks will appear on your page. # Create and Manage Game Portal Content Source: https://docs.appcharge.com/guides/game-portal/create-and-manage-game-portal-content This article explains how to create and manage Game Portal content in the Publisher Dashboard. You can also create and manage content using the Game Portal's [Content API service](/../../api-reference/game-portal/content/introduction). To add content to a page, a page must be created first. For instructions, see [Create and Manage a Game Portal Page](./create-and-manage-a-game-portal-page). ## Create content To create content: 1. In your game portal project, go to the **Content** tab and click **Create New Content**. 2. (Optional) If you plan to add content in additional languages, open the **Translations** drop-down menu and select **English** first. Complete all required fields. Then, select the additional language you want to add and fill out the fields again for that language. If you don't see the **Translations** drop-down menu, you’ll need to add at least one language other than English in the **Translations** section of the Publisher Dashboard first. See [Add and Manage Languages](/../../guides/translations/add-and-manage-languages) for instructions. 3. In the **General** section: * Enter a **Title** and **Description**. * Select the **Content type** to control the preview layout. The full content page is the same for both options. * **Article:** Displays as a vertical card within a grid layout. The image appears above the publication date, title, excerpt, and **Read More** button. * **News:** Displays as a full-width horizontal card. The image appears on one side, with the publication date, title, excerpt, and **Read More** button on the other side. * Write your content in the **Body Text**. * Use the built-in editing tools to insert and format text, images, links, and lists. * Enable **Dev Mode** to edit the content directly using Markdown. * Upload a header image and a thumbnail image. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. * Under **Pages** select the pages where you want the content to appear. You can't add content to the **Store** page. * Add **Labels** separated by commas to categorize the content. These labels will appear on the thumbnail image of the selected pages. * Define a slug for the URL path. * Set the content **Visibility** to either: * **Public:** Visible to all Game Portal visitors. * **Segmented:** Visible only to players who are logged into the Game Portal. Content visibility is affected by both page and content settings: * If a page is **Public** and content is **Segmented**, only the players who are logged in can see the content. * If a page is **Segmented** and content is **Public**, only players who are logged in can see the content. * If both are **Segmented**, only players who are logged in can see the content. * Use the **Tag** drop-down menu to add an internal tag for organizing your content. You can manage the tag as follows: * **Assign a tag:** Select an existing tag from the list. * **Create a tag:** Type a tag name in the search field, and then press **Enter**. * **Edit a tag:** Click the ellipsis next to the tag you want to edit, and then click **Edit**. * **Delete a tag:** Click the ellipsis next to the tag you want to delete, and then click **Delete**. Tags are used for internal organization only and aren't visible to players. 4. At the top of the editor, select the content visibility. By default, content is set to **Hidden**, but you can change it to **Visible**. Content assigned to **Hidden** pages will also be hidden. 5. If the content is set to **Hidden**, you can schedule it to be published at a later date: * Go to the **Schedule publication date** section. * Toggle **Enable scheduled publishing**. * Select a desired publish date. ## Edit content To edit content: 1. In your Game Portal project go to the **Content** tab. 2. Click the ellipsis next to the content you want to update and select **Edit**. 3. Make changes as needed, and then click **Update** to save. ## Delete content To delete content: 1. In your Game Portal project go to the **Content** tab. 2. Click the ellipsis next to the content you want to delete, and then click **Delete**. # Design Your Game Portal Source: https://docs.appcharge.com/guides/game-portal/design-your-game-portal This article explains how to customize your Game Portal's appearance and functionality in the Publisher Dashboard. You’ll configure the portal theme, login modal, SEO metadata, and menu navigation. When adding images, if you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. ## Design your Game Portal theme To design the theme: 1. In your Game Portal project, go to the **Builder** tab and click **Portal Theme**. 2. In the **General Settings** section: * Set a **General Background Color** and **Section Text Color**. * Select a **Section Title Font**. * **Background Image (Desktop):** Click **Upload** or the asset library icon to upload or select an image (optional). Use 1920 × 1080 px, PNG or JPEG. * **Background Image (Mobile):** Click **Upload** or the asset library icon to upload or select an image (optional). Use 1:2 vertical ratio, minimum 400 px width, PNG or JPEG. If the image you upload doesn't meet the required dimensions or ratio, the Publisher Dashboard displays a validation message with the expected specifications. Missing desktop or mobile images default to the **General Background Color**. * Upload a **Favicon**. 3. In the **Header** section: * Upload a logo. * Customize the header background, text, and login button colors. * Toggle **Show player name**, **Show player balance**, and **Show language switcher** as needed. 4. In the **Content** section, customize the look of article and news content on your content pages: * Set the **Card background color**, **Card text color**, and **Card button color**. * Set the **Content body text color** and **Content background color**. * Select a **Card Button Font**. * Set the **Header image container opacity** and **Header image container color**. 5. In the **Menu** section, customize your portal's menu: * Choose where the menu appears on the page, either in the **Left Sidebar** or as a **Top Fixed Header**. * Set the **Background Color** of the menu. * Set the **Text Color** of the menu items. * Set the **Tab On-Hover Color** to specify the text color when a player hovers over a menu item. * Set the **Selected Tab Color** to specify the text color of a selected menu item. 6. In the **Footer** section: * Select a background and text color. * Add links for **Privacy Policy**, **Terms & Conditions**, and **Support**. 7. Click **Save** to apply your changes. ## Design your login modal To design the modal: 1. In your Game Portal project, go to the **Builder** tab and click **Login Modal**. 2. Under the **Login modal configuration** section: * Upload a logo and background image. * Add a short welcome text. * Configure your font styles. * Write the modal **Body text**. * Check whether you would like to **Ask for player's active consent before enabling the login methods**. 3. Click **Save** to apply your changes. ## Configure your Game Portal settings To configure the settings: 1. In your Game Portal project, go to the **Builder** tab and click **Portal Settings**. 2. In the **SEO Settings** section: * Set the **SEO Title**, **Description**, and **Keywords**. * Upload a **Social Share Image** to display when your portal is shared on social media. 3. To enable the **Add to Home Screen** button in your Game Portal: This feature is available on mobile devices and tablets only. It lets players save the Game Portal to their mobile device's home screen, creating an app-like shortcut they can open directly. * Check **Activate this feature in your portal**. * Design the button by selecting a **Border and Text Color** and **Background Color**. * Upload a **Button Image**. If no image is uploaded, a default button labeled **Add to Home Screen** is displayed. * Upload an **Icon Image** and set a **Portal Title**. These appear on the player's home screen when the portal is saved as an app-like shortcut. 4. Click **Save** to apply your changes. # About Parking Domains Source: https://docs.appcharge.com/guides/game-portal/parking-domains/about-parking-domains Parking domains allow you to direct players from your game to your web store, in compliance with Apple and Google guidelines worldwide. They’re based on the same framework as the Game Portal but are designed specifically to give players a smooth, compliant path to your web store. Use them to target a wider player audience, increasing traffic and conversion to the web store. Simply add a link from your game to the parking domain. When players click the link, they are redirected and pre-authenticated to the parking domain containing game articles, news, and content. From there, you can add a CTA linking to your web store. When players click this link, they are redirected and pre-authenticated to your web store. ## How it works A parking domain works just like the [Game Portal](../about-the-game-portal) and is managed in the same way through the Publisher Dashboard. The only differences are: * You need to send your parking domain URL to Appcharge for activation. * A parking domain doesn’t include a **Store** page. Instead, you can create content and add CTAs that seamlessly link to your web store, eliminating the need for players to log in again. Learn how to [set up a parking domain](./set-up-a-parking-domain). # Set Up a Parking Domain Source: https://docs.appcharge.com/guides/game-portal/parking-domains/set-up-a-parking-domain Parking Domains are only relevant if you have an existing [web store](../../webstore/about-the-webstore). To set up a parking domain: 1. Configure the [Pre-Authenticated Login Webhook](/../../api-reference/webstore/player-authentication/preauthenticated-login/introduction), allowing you to authenticate players automatically when they go from the game to the parking domain, without requiring an additional login. Once configured, Appcharge will automatically handle pre-authentication from the parking domain to your web store. 2. Create a parking domain to redirect players from your game. For example: * **Your web store's domain:** `myAwesomeGameWebStore.com` * **Your parking domain:** `myAwesomeGamePlayerHub.com` 3. Send your parking domain URL to Appcharge. 4. In the Game Portal section of the Publisher Dashboard: * [Create and manage a page](../create-and-manage-a-game-portal-page) for your parking domain. * [Create and manage content](../create-and-manage-game-portal-content) for your parking domain. * [Design your parking domain](../design-your-game-portal). 5. Add a CTA in your content that links to your web store. # AppsFlyer Integration Source: https://docs.appcharge.com/guides/integrations/appsflyer Integrate with [AppsFlyer](https://www.appsflyer.com/), a Mobile Measurement Partner (MMP), to extend your game analytics to your web store. This code-free integration lets you track player revenue, lifetime value (LTV), and engagement across channels and devices, while connecting player activity between your game and Appcharge. With minimal setup, you get a complete view of the player journey, as events are shared in both directions. This gives you deeper insights into player behavior and helps optimize your marketing strategy. When a player logs in to your game, AppsFlyer sends Appcharge the player's [CUID](https://support.appsflyer.com/hc/en-us/articles/207032016-Customer-User-ID-field-CUID) and AppsFlyer ID for identification. When that player makes a purchase or receives a refund through Appcharge, Appcharge sends the event back to AppsFlyer for campaign attribution. ## AppsFlyer integration setup Follow these steps to configure the AppsFlyer integration on both Appcharge and AppsFlyer's side. ### Configure in AppsFlyer To configure the integration in AppsFlyer: 1. Log in to your [AppsFlyer HQ account](https://hq1.appsflyer.com/auth/login?next=L2F1dGgvbG9naW4mZW5jb2RlZD0x), or create one if needed. 2. Follow the instructions to [go to the token page](https://support.appsflyer.com/hc/en-us/articles/360004562377-Managing-AppsFlyer-tokens#reaching-the-tokens-page), and then follow the steps to [create a new S2S (server-to-server) token or retrieve an existing one](https://support.appsflyer.com/hc/en-us/articles/360004562377-Managing-AppsFlyer-tokens#manage-your-tokens). You must be an AppsFlyer account admin to view or manage tokens. 3. Copy and save the S2S token for later. 4. Follow [AppsFlyer's documentation](https://support.appsflyer.com/hc/en-us/articles/36292113943825-Appcharge-integration-with-AppsFlyer#setting-up-appcharge) on how to set up the integration with Appcharge. As part of this setup: * Set up integrations for all your AppsFlyer apps that you want to integrate with Appcharge, and save all the app IDs for later. * In the [in-app event postbacks](https://support.appsflyer.com/hc/en-us/articles/36292113943825-Appcharge-integration-with-AppsFlyer#inapp-event-postbacks) section, add all your game login events and make sure each includes the player's CUID (player ID) and AppsFlyer ID. When a player logs in, AppsFlyer sends this data to Appcharge to identify the player. Appcharge uses the most recent AppsFlyer ID to identify each player, so attribution is always tied to the last device they logged in on. Attribution is only recorded when a player logs in. If a player is already logged in, Appcharge won't receive their AppsFlyer ID until they log in again. ### Configure in Appcharge To configure the integration in Appcharge: 1. Go to the Publisher Dashboard. In the sidebar menu, go to **Management > Settings > Developer Settings**. If you have a Game Portal, follow the same steps in your Game Portal project. 2. Scroll to **AppsFlyer S2S Integration**, and click **Open Settings**. 3. Complete the following sections: * **AppsFlyer S2S Integration**: Toggle on to enable the integration. * **AppsFlyer S2S Token**: Enter the S2S token saved from AppsFlyer. This token allows Appcharge to send attributed events to AppsFlyer on your behalf. * **Application ID**: Enter the ID of your AppsFlyer app. Click **+ Application ID** to add additional app IDs as needed. * **Event Name Configuration**: Set the event names that Appcharge will use when sending events to AppsFlyer. * **Purchase Event**: The event name to send to AppsFlyer when a player completes a purchase on the Appcharge platform. Defaults to `appcharge-billing-payment`. * **Refund Event**: The event name to send to AppsFlyer when a player receives a refund through Appcharge. Defaults to `appcharge-billing-refund`. 4. In the top right corner, click **Save** to save your changes. ## AppsFlyer event payloads When Appcharge sends purchase and refund events to AppsFlyer, each payload includes the following required fields: * `af_events_api` (`string`): Whether the event was sent through the AppsFlyer Events API. * `appsflyer_id` (`string`): AppsFlyer ID associated with the player. * `customer_user_id` (`string`): Player ID sent as the AppsFlyer customer user ID (CUID). * `eventName` (`string`): AppsFlyer event name configured in Appcharge. * `eventTime` (`string`): Time when the event occurred. * `eventValue` (`string`): A JSON string that includes `af_revenue` and `af_currency`. ### Sample payment event payload ```json theme={"system"} { "af_events_api": "true", "appsflyer_id": "1783597548865-7717036121737115211", "customer_user_id": "330634126", "eventName": "appcharge-billing-payment", "eventTime": "2026-07-13 12:33:26.419", "eventValue": "{\"af_revenue\":\"0.8\",\"af_currency\":\"USD\"}" } ``` ### Sample refund event payload ```json theme={"system"} { "af_events_api": "true", "appsflyer_id": "1783597548865-7717036121737115211", "customer_user_id": "330634126", "eventName": "appcharge-billing-refund", "eventTime": "2026-07-13 12:33:41.813", "eventValue": "{\"af_revenue\":\"-0.8\",\"af_currency\":\"USD\"}" } ``` # Welcome to Appcharge Source: https://docs.appcharge.com/guides/introduction Appcharge is a monetization platform built by game makers from leading mobile gaming companies. Designed for the unique challenges of game development, it gives you full control over your monetization strategy, helping you boost revenue and build a sustainable, high-performing games business. Whether you're building your first game or optimizing a large-scale release, Appcharge provides the tools and infrastructure to streamline your operations and maximize earnings. This documentation will guide you through everything you need to integrate, launch, and optimize with Appcharge. ## Get started Start by [setting up your Publisher Dashboard](./publisher-dashboard/set-up-your-publisher-dashboard), the first required step for all Appcharge solutions. Then, **choose the solution** that best fits your game and follow the integration instructions. Create a fully customized web store powered by Appcharge, featuring proven monetization strategies and a robust, secure checkout experience. Integrate Appcharge’s seamless, secure checkout with support for multiple APMs and a robust, localized payment flow. Accept payments in your iOS or Android game by linking players directly to a secure checkout experience. Skip the login screen. Send players from game to web store already signed in, with a secure, frictionless experience that drives engagement. Reach players through your favorite communication channels with exclusive web store offers, segmented for each audience. Create a game portal for your players with special content including news and exclusive offers. Once you’ve completed setup, explore the available products and features in the [Guides](/guides/introduction) to see what works best for your needs. Use the [API Reference](../../api-reference/introduction) or [SDK documentation](../../sdks/introduction) for implementation support whenever needed. # Implement A/B Testing Source: https://docs.appcharge.com/guides/measurement-tools/implement-ab-testing A/B testing allows you to compare 2 versions of a feature, experience, or campaign to see which performs better based on player behavior. This method helps optimize performance by revealing what drives player engagement and revenue. You can use A/B testing in both the web store and checkout to evaluate product features, creative assets, pricing strategies, or promotional campaigns. ## How it works 1. Divide players into 2 groups and show each group a different experience, such as a background, price, or value. 2. Tag players with a group-specific attribute using the [Personalization API](/../../api-reference/webstore/personalization/introduction) or [Create Checkout Session API](/../../api-reference/checkout/checkout-session/create-checkout-session). 3. Track performance in the **A/B Test** tab on the **Analytics** page in the Publisher Dashboard to see which offer performs best. The following example shows how to set up and analyze a pricing test. ## Sample use case Suppose you're launching a Halloween campaign and want to test 2 pricing strategies, Buy 1 Get 1 Free and 50% Off to see which performs best. The original offer is \$10 for 100 coins. ### Step 1 | Define your test groups Divide your players into 2 groups: * **Group A:** Buy 1 Get 1 Free — \$10 for 200 coins * **Group B:** 50% Off — \$5 for 100 coins ### Step 2 | Create the offers in the web store Create the 2 offers in your web store and ensure each player group sees the correct one. The setup differs depending on whether you use the Appcharge web store or a custom web store. #### Appcharge web store If you have the Appcharge web store: 1. Use the [Offers API](/../../api-reference/webstore/offers-v2/introduction) to create the 2 offers. In this example, we create a special offer by calling [Create Special Offer](/../../api-reference/webstore/offers-v2/special-offers/create-special-offer):

```js theme={"system"} { "publisherOfferId": "offer1", "productsSequence": [ { "index": 0, "products": [ { "publisherProductId": "22356758900ff", "quantity": 200 // 200 coins } ], "priceInUsdCents": 1000 // $10 } ] } ``` ```js theme={"system"} { "publisherOfferId": "offer2", "productsSequence": [ { "index": 0, "products": [ { "publisherProductId": "22356758900ff", "quantity": 100 // 100 coins } ], "priceInUsdCents": 500 // $5 } ] } ``` 2. When a player from each group logs in to the web store, call the [Personalization API](/../../api-reference/webstore/personalization/introduction) to display the correct offer and tag the player with their group.

```js theme={"system"} { "offers": [ { "publisherOfferId": "offer1", "productsSequence": [ { "index": 0, "products": [ { "publisherProductId": "22356758900ff", "quantity": 200, // 200 coins "priority": "Main" } ] } ] } ], "attributes": { "price_test": "A" // Group A } } ``` ```js theme={"system"} { "offers": [ { "publisherOfferId": "offer2", "productsSequence": [ { "index": 0, "products": [ { "publisherProductId": "22356758900ff", "quantity": 100, // 100 coins "priority": "Main" } ] } ] } ], "attributes": { "price_test": "B" // Group B } } ``` If you have an Appcharge web store, skip Step 3 and go directly to Step 4. #### Custom web store If you have a custom web store, create 2 separate offers in your own system and implement display logic so each group sees the correct one. You don’t need to call the Personalization API in this step. Instead, proceed to Step 3, where you’ll pass the player’s group attribute when creating the checkout session. ### Step 3 | Update prices in the checkout This step is only relevant for custom web stores. When a player clicks an offer in the web store, call the [Create Checkout Session API](/../../api-reference/checkout/checkout-session/create-checkout-session) with both the pricing and group assignment. ```js theme={"system"} { "priceDetails.price": 10, "items.quantity": 200, "attributes": { "price_test": "A" } } ``` **Group B:** ```js theme={"system"} { "priceDetails.price": 5, "items.quantity": 100, "attributes": { "price_test": "B" } } ``` ### Step 4 | Compare results in the Publisher Dashboard [Analyze the results of the A/B test](./../publisher-dashboard/view-analytics#a%2Fb-test) and review which group generated more revenue. Use these insights to decide which pricing strategy to roll out, or to refine future campaigns. # About Payment Links Source: https://docs.appcharge.com/guides/payment-links/about-payment-links Payment Links allow you to sell digital goods or services in your app through a secure, branded web checkout, without relying on traditional in-app purchases. Instead, players are directed to a fast, mobile-optimized checkout page where they can buy items like coin packs, character skins, or bundles. This feature reflects recent changes to Apple and Google's guidelines in certain regions, which now permit developers to direct players to external websites to complete purchases.
## How it works When a player selects an offer in your game, such as a character skin or power-up bundle, your server generates a unique payment link. This link opens a secure, responsive checkout page hosted by Appcharge. It supports multiple payment methods, displays localized pricing, and can be customized to match your game's brand. Once the player completes the payment, players are redirected back to your game either via a [Universal Link](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content/) for iOS devices or [Deep Link](https://developer.android.com/training/app-links/create-deeplinks) for Android devices. The redirect URL includes a status parameter that indicates whether the purchase was successful, failed, or canceled, so your game can respond accordingly. Appcharge finalizes the transaction, handles payment processing, and securely delivers the purchase details to your backend through a callback API. We recommend implementing Payment Links using the [Payment Link SDK](/../../sdks/payment-links/introduction), which provides a native experience by keeping players inside your game through an embedded browser. This approach mirrors existing checkout flows and helps prevent UX drop-off from external redirects, while also avoiding browser compatibility issues that may occur with external link-outs. Alternatively, you can implement the feature [without the SDK](./link-out-without-sdk) by integrating directly with the Appcharge APIs. ## Key features * **No-code setup**: Launch quickly without building or hosting your own payment flow. * **Custom checkout design**: Tailor the look and feel of the checkout page to match your game’s branding. Customize layout, fonts, colors, button text, and payment methods. * **Localized pricing**: Display region-specific prices for a smoother global experience. * **Redirect back to game:** Direct players back to your app after payment. * **Integrated tracking**: Continue tracking player purchases and lifetime value through Mobile Measurement Partners like AppsFlyer. * **Complete transaction management**: Appcharge acts as your Merchant of Record. It handles tax calculation and payment, supports global payment methods, and includes built-in tools for fraud prevention and chargeback management. ## Mobile Measurement Partner (MMP) If you use a Mobile Measurement Partner (MMP) like AppsFlyer, you can continue tracking player revenue and lifetime value. When a player completes a purchase through a payment link, Appcharge sends the purchase data to your backend. Your server can forward this to your MMP as you would for native in-app purchases. You can set up this tracking flow with minimal effort using our built-in [AppsFlyer integration](./../integrations/appsflyer). # Link Out Without SDK Source: https://docs.appcharge.com/guides/payment-links/link-out-without-sdk This article explains how to link out players from your app to a web checkout for both Android and iOS. To do this using our SDK, refer to the [Payment Link Flow](/../../sdks/payment-links/payment-link-flow). ## Before you begin Before you get started, ensure you've completed the following steps: 1. Develop and expose a an API endpoint to receive player transaction updates from Appcharge, following the [Grant Award Callback](/../../api-reference/checkout/awards/grant-award-callback) schema. 2. Enter your API endpoint URL in the Publisher Dashboard under **Settings -> Integration**. 3. Configure a `redirectURL` to return players to your app after a successful payment: * [Set Up a Universal Link (iOS)](./set-up-universal-link) * [Set Up a Deep Link (Android)](./set-up-deep-link) ## Step 1 | Send offer ID to your game server When a player selects an offer in your game, such as a coin pack or a character skin, send the offer ID from the game client to your game server. Your game server uses the offer ID to retrieve the offer details and prepare the data required to create a checkout session in the next step. ## Step 2 | Call the Create Checkout Session API Follow the steps below to create the checkout session: 1. From your game server, call the [Create Checkout Session API](/../../api-reference/checkout/checkout-session/create-checkout-session) with the offer data retrieved in Step 1. Include the following in the request: * Offer name and ID * Item list and images * Item prices * Redirect URL (Universal Link or Deep Link that returns the player to the app) * Player country code in [ISO-3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. If not provided, Appcharge determines the customer's country from the player's IP address. Manually setting a country will determine the applicable tax jurisdiction and rates. Ensure that any country values passed via the API comply with your regulatory and business requirements. 2. Appcharge returns the following: | Parameter | Type | Description | | - | - | - | | `checkoutSessionToken` | String | A unique token that identifies and validates the checkout session. | | `purchaseId` | String | A unique ID to track the transaction. | | `url` | URL | The base URL for the Appcharge checkout page. | | `parsedUrl` | URL | New checkout session URL hosted on Appcharge. | 3. Return the session data to the game client. 4. Copy the `parsedUrl` value. ## Step 3 | Open the checkout Paste the `parsedUrl` value in the browser to open the Appcharge checkout page. You may want to notify players that they’ll briefly leave the app to complete their purchase securely in a mobile browser. ## Step 4 | Receive checkout transaction data if relevant During checkout, the player selects a payment method and completes the purchase. The [Grant Award Callback](/../../api-reference/checkout/awards/grant-award-callback) is triggered, and your game server receives a POST request with the complete transaction data. If the player doesn't complete the purchase, the checkout session will automatically expire after 1 hour or when the player actively closes the checkout page. To cancel an open checkout session at any time, such as when multiple checkout tabs are open, call the [Cancel Checkout Session API](/../../api-reference/checkout/checkout-session/cancel-checkout-session). You can listen for [order events](/../../api-reference/events/v2/order/order_created) that are triggered based on different checkout outcomes. ## Step 5 | Redirect player to the game Once the payment is processed, the browser will display a **Return to game** button. Players can tap this button to be redirected back to your app. Appcharge handles the redirection using the `redirectUrl` you provided in the Create Checkout Session API request. The URL includes the following query parameter: | Parameter | Type | Description | | - | - | - | | `status` | String | Indicates the result of the payment process.
One of:
  • `?status=success`: The purchase was completed successfully.

  • `?status=fail`: An error occurred during the purchase process, or the player closed the checkout window.

  • `?status=cancel`: The player actively canceled the purchase.
  • | **Example iOS URL:** ``` https://www.my-game.com/?status=success ``` **Example Android URL:** ``` my-prefix-my-game://action?status=success ``` The redirect URL may trigger a confirmation dialog. ## Step 6 | Validate the purchase and fulfill the order After the player returns to your game via the `redirectUrl`, parse the URL to extract the `status`. If `status=success`, send this data to your game server to validate the transaction against the data received from the Grant Award Callback. If the purchase is valid, apply the corresponding items to the player’s account. # Migrate to the Payment Links SDK Source: https://docs.appcharge.com/guides/payment-links/migrate-to-the-payment-links-sdk This article explains how to migrate your Payment Links integration from the [Link Out flow](./link-out-without-sdk) to the Payment Links SDK flow. With the SDK, Appcharge handles more of the checkout handoff for supported mobile platforms, so your app can rely less on custom redirect logic. Use this article alongside the Payment Links SDK for your specific platform. It focuses on what changes from an existing Link Out integration, including return link configuration, checkout session creation, checkout launch, and purchase result handling. The SDK supports Android, iOS, and Unity. If your app uses another engine or platform, contact your account manager to scope a custom bridging plan before migrating. ## Link Out vs Payment Links SDK | Capability | Link Out (API Only) | Payment Links SDK | | - | - | - | | Checkout launch | The app opens `parsedUrl` in a browser. | The app passes `purchaseId` and `parsedUrl` to the SDK, and the SDK opens checkout. | | Return URL setup | `redirectUrl` is required when creating a checkout session. | SDK configuration defines the return link. Don't pass `redirectUrl` in the Create Checkout Session API request. | | Redirect handling | The app receives the redirect URL and parses `?status=success`, `?status=fail`, or `?status=cancel`. | The app passes incoming URLs to the SDK. The SDK completes transaction handling and triggers success or failure callbacks. | | Success and failure callbacks | The app infers the result from the URL status parameter. | The SDK returns `onPurchaseSuccess` and `onPurchaseFailed` callbacks. | | Purchase validation | The application backend validates against the [Grant Award Callback](../../api-reference/checkout/awards/grant-award-callback) before fulfillment. | No change. The application backend still validates against the Grant Award Callback before fulfillment. | | Browser type awareness | N/A | The SDK handles internal and external flows. | | Supported platforms | Any platform with manual implementation. | iOS, Android, Unity. | | Maintenance | Managed by the application team. | Managed by Appcharge. | Server-side checkout, validation, and fulfillment on the application side stay the same. Before migrating, make sure the Link Out integration already validates purchases with the Grant Award Callback and can look up purchase state by `purchaseId`. SDK callbacks are client-side signals, not proof of payment. Use the `purchaseId` from the SDK callback as a lookup key, then validate and fulfill the purchase on the application backend using the Grant Award Callback data. # Migration process Follow the SDK documentation for your platform to implement the SDK. Use the steps below to identify the Link Out-specific changes you need to make during that implementation. For the full end-to-end SDK implementation, see the [Payment Links SDK flow](../../sdks/payment-links/payment-link-flow). ## Step 1 | Implement and configure the SDK First, import, configure, and initialize the Payment Links SDK for your platform. During setup, move your return handling from the Link Out `redirectUrl` API field into the SDK configuration. If your Link Out flow already uses a universal link for iOS, you can use the same universal link in the SDK configuration. If your Link Out flow uses a deep link for Android, you need to update the deep link scheme in the SDK configuration. Complete these SDK pages: 1. [Import the SDK.](../../sdks/payment-links/ios/import-payment-links-sdk) 2. [Set Up Your Project.](../../sdks/payment-links/ios/set-up-your-project) 3. [Initialize the SDK.](../../sdks/payment-links/ios/initialize-the-ios-payment-links-sdk) During setup, add the URL scheme `acnative-$(PRODUCT_BUNDLE_IDENTIFIER)`, set the associated domain to your Link Out universal link domain using `applinks:{YOUR_DOMAIN}`, and pass the universal link you created in the Link Out flow as `redirectUrl` in the iOS SDK `ConfigModel`. Complete these SDK pages: 1. [Setup.](../../sdks/payment-links/android/setup) 2. [Initialize the SDK.](../../sdks/payment-links/android/initialize-the-android-payment-links-sdk) During setup, add the SDK checkout activity to your manifest and add the deep link scheme ``. Replace `{IDENTIFIER}` with the last sequence of your package name, as described in the Android setup guide. Reuse your existing Link Out app link handling, but set the SDK return scheme to `acnative-{IDENTIFIER}`. If your existing scheme is different, add the SDK scheme and pass incoming URLs to the SDK. Complete these SDK pages: 1. [Import the Unity SDK.](../../sdks/payment-links/unity/import-payment-links-sdk) 2. [Configure the SDK.](../../sdks/payment-links/unity/configure-the-sdk) 3. [Initialize the SDK.](../../sdks/payment-links/unity/initialize-the-payment-links-sdk) 4. For iOS builds, [Integrate with iOS](../../sdks/payment-links/unity/integrate-with-ios). 5. For Android builds, [Integrate with Android](../../sdks/payment-links/unity/integrate-with-android). ## Step 2 | Remove `redirectUrl` from checkout session requests In the non-SDK flow, you passed `redirectUrl` in the body of the Create Checkout Session API request. The browser used this URL to redirect the player back to your app after payment. With the SDK, the player is redirected using the link configured in your SDK setup file, so you must remove the `redirectUrl` parameter from your API request. ```json Before with Link Out theme={"system"} { "offerName": "Coin Pack 500", "offerId": "offer_abc123", "items": ["..."], "playerCountry": "US", "redirectUrl": "https://www.my-game.com/" } ``` ```json After with SDK theme={"system"} { "offerName": "Coin Pack 500", "offerId": "offer_abc123", "items": ["..."], "playerCountry": "US" } ``` The Appcharge response stays the same. You still receive `purchaseId` and `parsedUrl`. In the next step, you'll use the `parsedUrl` to launch the checkout. ## Step 3 | Open checkout through the SDK The checkout session response still includes values such as `purchaseId` and `parsedUrl`. Return the session response to your client, then pass those values to the SDK instead of opening `parsedUrl` directly in a browser: * **Native iOS:** Call `ACBridgeAPI.openCheckout(purchaseId, parsedUrl)`. See [Launch the Checkout](../../sdks/payment-links/ios/launch-the-checkout). * **Native Android:** Call `BridgeAPI.openCheckout(purchaseId, parsedUrl)`. See [Launch the Checkout](../../sdks/payment-links/android/launch-the-checkout). * **Unity:** Call `PaymentLinksController.Instance.OpenCheckout(purchaseId, parsedUrl)`. See [Launch the Checkout](../../sdks/payment-links/unity/launch-the-checkout). The session response values must be passed exactly as received. Modifying `purchaseId`, `parsedUrl`, or other session values may cause checkout to fail. ## Step 4 | Replace URL status parsing with SDK callbacks Remove client code that parses the returned URL for `?status=success`, `?status=fail`, or `?status=cancel`. After the player returns to your app through the SDK-configured return link, pass the incoming URL to the SDK and handle the SDK callbacks instead: * **Native iOS:** Implement the [Callbacks](#native-ios-sdk-setup). * **Native Android:** Implement the [Callbacks](../../sdks/payment-links/android/implement-the-callbacks). * **Unity:** Implement the [Callbacks](../../sdks/payment-links/unity/implement-callbacks). Use these callbacks to replace the purchase status you parsed from the returned URL: | Native callback | Unity callback | When it fires | | - | - | - | | `onPurchaseSuccess` | `OnPurchaseSuccess` | Purchase completed successfully. | | `onPurchaseFailed` | `OnPurchaseFailed` | Checkout was closed, canceled, failed, or a server-to-server error occurred during purchase handling. | When `onPurchaseSuccess` or `OnPurchaseSuccess` fires, use the returned `OrderResponseModel` to identify the purchase. The model includes `purchaseId`, `orderId`, `customerId`, purchased items, `price`, `currency`, and related order data. The `purchaseId` is a lookup key, not proof of payment, so you must validate the purchase with the game server before fulfillment. The application backend should match the purchase against the Grant Award Callback data before granting items to the player. ## Step 5 | Test the migrated flow Before you move to production, test the full purchase flow in your sandbox environment: 1. Create a checkout session from the game server without `redirectUrl`. 2. Open checkout through the SDK. 3. Complete a successful purchase and verify that the success callback fires. 4. Close or cancel checkout and verify that the failure callback fires. 5. Confirm the application backend receives the Grant Award Callback. 6. Confirm the application backend validates and fulfills only valid purchases. 7. Test player return behavior for internal and external browser modes that your app supports. ​ ## Migration checklist 1. Import and configure the SDK for your platform. 2. Configure the deep link/universal link in the SDK config file: * **iOS**: uses a .plist file. * **Android**: uses a manifest file. * **Unity**: uses an Appcharge config file. 3. Initialize the SDK in your app. 4. Implement callback methods, including `onPurchaseSuccess` and `onPurchaseFailed`. 5. Remove `redirectUrl` from the Create Checkout Session API call. 6. Configure your app to pass incoming URLs to the SDK. 7. Remove manual URL status parsing from the game client. 8. Test the full purchase flow in a sandbox environment. ## Related articles Review the full Payment Links SDK integration flow. Import and configure the Payment Links SDK for native iOS. Set up and configure the Payment Links SDK for native Android. Import and configure the Payment Links SDK for Unity. Resolve common issues with Payment Links SDK integrations. Review the callback used to validate and fulfill completed purchases. # Sell Outside IAP (U.S.) Source: https://docs.appcharge.com/guides/payment-links/sell-outside-iap The mobile app economy in the United States has entered a new era. Following landmark court rulings against both Apple and Google in 2025, app publishers now have the freedom to implement alternative payment solutions for the first time in over a decade. This shift enables publishers to reclaim 20–25% of revenue previously lost to platform fees while gaining complete control over customer relationships and pricing strategies. Recent legal and regulatory decisions have also compelled Apple and Google to update their in-app payment policies. These changes create new opportunities for publishers to manage transactions independently and design user experiences that align with their business models. ## Apple’s policy change On May 1, 2025, Apple eliminated all commissions on external payments for U.S. apps following a ruling by Judge Gonzalez Rogers on April 30, 2025. U.S. apps no longer require Apple’s permission to include external payment links. There are no entitlement applications, mandatory StoreKit APIs, commissions, or anti-steering restrictions. **Publishers can now:** * Communicate freely about pricing. * Promote external offers. * Direct users to web-based checkout flows. * Conduct transactions without paying Apple commissions. ### iOS implementation Although Apple no longer mandates a specific technical implementation for external payment links, Safari View Controller (SFSafariViewController or SFSVC) remains the optimal choice for iOS payment flows for both user experience and security. This approach offers a combination of simplicity, reliability, and compliance that makes it well suited for implementing external payment flows on iOS. The following sections describe its main advantages. #### Security and trust * Operates out of process from the app, protecting user credentials. * Provides automatic SSL validation and familiar Safari security indicators. * Supports iCloud Keychain autofill and built-in content blockers. * Offers a consistent, trusted interface that reduces friction. #### Apple Pay integration * Enables Apple Pay directly within SFSVC-based web checkouts. * Supports one-tap payments with Face ID, stored cards, and shipping addresses. * Delivers conversion rate increases of 20–40% compared with manual card entry. #### Implementation steps * Add a clear “Buy on Web” button in your app with messaging about better pricing or exclusive offers. * When tapped, use the Appcharge iOS SDK to open your mobile checkout page in SFSVC. * The Appcharge Checkout screen displays automatically, and users can complete payment using Apple Pay, credit cards, PayPal, or other supported methods. ## Google’s policy change The December 11, 2023, jury verdict in *Epic Games v. Google* found that Google engaged in illegal monopolistic practices. The permanent injunction issued on October 7, 2024, and upheld by the Ninth Circuit on July 31, 2025, required broad changes. **As of October 29, 2025, Google can no longer:** * Require Google Play Billing. * Prohibit alternative payment methods. * Restrict communication about external payment options. * Enforce price parity between in-app and external channels. For U.S. publishers, these rulings create an opportunity for complete freedom to implement payment solutions that return revenue directly to their businesses. ### Android implementation Google Play’s policy changes on October 29, 2025, established an open payment environment for the U.S. market. There are no requirements to use Google Play Billing, no restrictions on alternative payment methods, and no enforcement of price parity. For Android apps, direct in-app payment integration provides the best experience. Android’s architecture supports embedded payment flows, and users expect seamless checkout within the app. To achieve this experience effectively and maintain consistency across devices, developers should follow the best practices outlined below. #### Best practices * Implement Google Pay alongside traditional credit card entry directly within the app. * Offer Google Pay in the Appcharge Checkout. * Display the user’s last-used card and last four digits to create a personalized one-tap checkout experience. #### Compliance considerations While U.S. apps now have full payment flexibility, publishers distributing in other regions must comply with local regulations: * The European Economic Area requires compliance with the Digital Markets Act (DMA). * South Korea, Japan, and India maintain their own alternative billing requirements. * A complete payment solution should include geolocation awareness and automatic compliance with regional policies. # Set Up a Deep Link (Android) Source: https://docs.appcharge.com/guides/payment-links/set-up-deep-link This article explains how to set up a [Deep Link](https://developer.android.com/training/app-links/create-deeplinks) for redirecting Android players from the checkout back to your app. To configure a Deep Link: 1. To enable deep linking, declare a custom URL scheme in your **AndroidManifest.xml** file. Locate the activity that handles your store or game logic, and add the following intent filter inside it: ```xml xml theme={"system"} ``` 2. This intent filter defines your deep link as `{PREFIX_GAME_NAME}://action`. For example, if your game name prefix is `my-awesome-company`, and your game name is `royal-blast`, your deep link will look like this: ``` my-awesome-company-royal-blast://action ``` When a purchase is completed, this link redirects the player back to your app’s activity associated with that scheme. # Set Up a Universal Link (iOS) Source: https://docs.appcharge.com/guides/payment-links/set-up-universal-link This article explains how to set up a [Universal Link](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content/) for redirecting iOS players from the checkout back to your app. To configure a Universal Link: 1. Set up a dedicated subdomain. For example, `my-subdomain.appcharge.com`. For more information, see Apple’s official guide on [supporting associated domains](https://developer.apple.com/documentation/xcode/supporting-associated-domains). 2. On this subdomain, host a public `.well-known/apple-app-site-association` file. This file allows iOS to recognize the redirect URL as a Universal Link, so your app can open automatically after payment. Without this file, players will see a confirmation dialog asking if they want to open the app. > **Note:** The file cannot be a `.json` extension, and must be served with the `application/json` MIME type. 3. Run the following command with your domain to verify the MIME type: ```bash curl theme={"system"} curl -I https://my-subdomain.appcharge.com/.well-known/apple-app-site-association ``` The file content should follow this structure: ```json json theme={"system"} { "applinks": { "details": [ { "appIDs": [ "{YOUR_TEAM_ID}.{YOUR_BUNDLE_ID}" ], "components": [ { "/": "/checkout*", "comment": "Matches any URL whose path starts with /checkout" } ] } ] } } ``` Make sure to prefix your App ID with your Apple Developer Team ID, located on the [Apple Developer Membership page](https://idmsa.apple.com/IDMSWebAuth/signin?appIdKey=891bd3417a7776362562d2197f89480a8547b108fd934911bcbea0110d07f757\&path=%2Faccount%2F\&rv=1). When a purchase is completed, this link redirects the player back to your app. # About the Publisher Dashboard Source: https://docs.appcharge.com/guides/publisher-dashboard/about-the-publisher-dashboard The Appcharge Publisher Dashboard is a centralized platform designed to simplify the management of multiple game stores through a single interface. This documentation offers an overview of the integration and authentication processes, as well as key features, benefits, roles, and permissions, to help publishers maximize the effectiveness of this powerful tool. ## Key Features * **Multi-Project Access:** Effortlessly manage and switch between multiple projects. * **Aggregated Data:** View and analyze data aggregated across all projects. * **Rules and Permissions:** Implement and enforce rules and permissions to control access and capabilities within projects. # Add an Asset Source: https://docs.appcharge.com/guides/publisher-dashboard/add-an-asset The Assets Library stores all the visual files for your project. Each project in your account has its own library, where you can create and manage assets to use across the project. This ensures everyone working on the project has access to the relevant files, improving efficiency and consistency. You can also create and manage assets in the Assets Library using the [Assets API](/../../api-reference/media/assets-library/introduction). ## Add an asset To add an asset: 1. Go to the **Assets Library** tab and click **Upload Asset**. 2. Select **Upload image** to upload a local file, or select **Use external URL** to provide a publicly accessible image URL. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. 3. In the **ID** field, enter a unique identifier for the asset. > **Note:** You will need this ID when configuring elements such as products and offers in your web store. 4. In the **Category** field, select the asset type. Note that the asset will only be available for use in the category you select. For example, an asset set to **Product** can only be used when configuring products. ## Asset upload requirements To ensure your assets display correctly across your web store, refer to the specifications in the table below for each asset category. These requirements may vary slightly depending on your web store template. | Category | Dimensions | File Type | Minimum Width | | :- | :- | :- | :- | | Mobile BG Image | 1:3 | PNG or JPEG | 400 px | | Desktop BG Image | 1920 × 1080 px | PNG or JPEG | 1920 px | | Product | 1:1 | PNG or JPEG | 128 px | | Logo | 1:1 | PNG or JPEG | 320 px | | Prefix | 1:1 | PNG or JPEG | 32 px | | Player Level | 3:1 | PNG or JPEG | 800 px | | Badge (Emblem) | 1:1 | PNG or JPEG | 128 px | | Badge (Prefix) | 1:1 | PNG or JPEG | 32 px | | BG Bundle (1 in a Row) | 2:1 | PNG or JPEG | 400 px | | BG Bundle (2 in a Row) | 1:1 | PNG or JPEG | 400 px | | BG Bundle (3 in a Row) | 2:1 | PNG or JPEG | 400 px | | BG Popup (Square) | 1:1 | PNG or JPEG | 400 px | | BG Popup (Vertical) | 2:3 | PNG or JPEG | 400 px | | Banner | 3:1 | PNG or JPEG | 800 px | | Offer Header | 1:1 | PNG or JPEG | 32 px | | Favicon | 1:1 | PNG or JPEG | 32 px | | Section | 1:1 | PNG or JPEG | 32 px | | Button Image | 1:1 | PNG or JPEG | 32 px | | Icon Image | 1:1 | PNG or JPEG | 32 px | | Player Profile Image | 1:1 | PNG or JPEG | 128 px | | Back To Game Button | n/a | PNG or JPEG | 48 px | # Add Terms & Policies Source: https://docs.appcharge.com/guides/publisher-dashboard/add-terms-and-policies To ensure compliance and transparency, it's essential to correctly set up the Privacy Policy and Terms and Conditions links in the Publisher Dashboard. This guide explains the steps to update these links and provides solutions if they do not function properly with our iframe. ### Steps to Update Privacy Policy and Terms and Conditions Links: 1. **Login to the Appcharge Dashboard:** * Go to the Appcharge dashboard and log in with your admin credentials. 2. **Navigate to the Company Tab:** * In the dashboard menu, click on the **Admin** section. * Select the **Company** tab. 3. **Fill in the Required Fields:** * Locate the fields labeled **'Terms and Conditions'** and **'Privacy Policy'**. * Enter the URLs for your Privacy Policy and Terms and Conditions in the respective fields. 4. **Save Your Changes:** Click the **Update** button to save the new links. ### If Your Links Do Not Work with Our Iframe: If you find that the provided links are not working within our iframe, consider the following solutions: 1. **Modify Your Page to Be Compatible with Iframes:** * Ensure that your webpage's security settings allow it to be displayed in an iframe. This may involve modifying the X-Frame-Options header to permit the page to be embedded. 2. **Use an Alternative Tag:** * Use a tag in your web application that allows the page to run within an iframe. This can involve altering the HTML or using a specific script to make the content compatible with iframe requirements. By following these steps, you can ensure that your Privacy Policy and Terms and Conditions are accessible to your users in a compliant manner. # Configure Authentication Settings Source: https://docs.appcharge.com/guides/publisher-dashboard/configure-authentication-settings This article explains how to enable one or more login methods for authenticating players in your Appcharge Web Store or Game Portal. To learn more, see [About Player Authentication](../webstore/player-authentication/about-player-authentication) for an overview of the available login methods. Use the toggles on the Authentication page to enable or disable login methods. Below is a breakdown of each authentication method and how to configure it. ## SSO Login You can enable the following Single Sign-On (SSO) methods: ### Facebook SSO To enable Facebook SSO: 1. Turn on the **Facebook App** toggle. 2. Follow the instructions in the [Facebook SSO Login Guide](../webstore/player-authentication/sso-login/set-up-facebook-sso), and then enter the App ID of your game registered in Meta for Developers in the **Facebook App ID** field. 3. Click **Update** to save your changes. ### Google SSO To enable Google SSO: 1. Turn on the **Google App** toggle. 2. Follow the instructions in the [Google SSO Login Guide](../webstore/player-authentication/sso-login/set-up-google-sso), and then enter the App ID of your game registered in Google in the **Google App ID** field. 3. Click **Update** to save your changes. ### Apple SSO To enable Apple SSO: 1. Turn on the **Apple App** toggle. 2. Follow the instructions in the [Apple SSO Login Guide](../webstore/player-authentication/sso-login/set-up-apple-sso), and then enter the App ID of your game registered in Apple in the **Apple App ID** field. 3. Click **Update** to save your changes. ## Password Login To enable password-based login: 1. Turn on the **Username and Password** toggle. To learn more, see [About Password Login](../webstore/player-authentication/password-login/about-password-login). 2. Click **Update** to save your changes. ## Player ID Login To enable Player ID Login: 1. Turn on the **Player ID** toggle. 2. In the **Find Your Player ID: Link Title** field, add link text that will appear on the login page. For example, **Where can I find my Player ID?**. 3. In the **Find Your Player ID: Link URL** field, provide a URL linking to an article that helps players locate their Player ID. 4. Click **Update** to save your changes. To learn more, see [About Player ID Login](../webstore/player-authentication/player-id-login/about-player-id-login). ## Game Redirect Login To enable Game Redirect Login: 1. Turn on the **OTP** toggle. 2. In the **Initiate Game Auth Callback** field, paste the URL for generating OTP links. This URL should be the webhook endpoint that generates OTPs for your web store. 3. From the **Desktop Text Model** drop-down, select the number of digits for the player code (4 or 6). 4. Click **Update** to save your changes. To learn more, see [About Game Redirect Login](../webstore/player-authentication/game-redirect-login/about-game-redirect-login). ## Pre-Authenticated Login To enable Pre-Authenticated Login: 1. Turn on the **OTP** toggle. 2. Leave the **Initiate Game Auth Callback** field empty, unless you are also implementing Game Redirect Login. 3. From the **Desktop Text Model** drop-down, select the number of digits for the player code (4 or 6). 4. Click **Update** to save your changes. To learn more, see [About Pre-Authenticated Login](../webstore/player-authentication/pre-authenticated-login/about-pre-authenticated-login). # Configure Developer Settings Source: https://docs.appcharge.com/guides/publisher-dashboard/configure-developer-settings This article explains the technical settings required to connect your systems with Appcharge, including your project identity, credentials, callbacks, and webhooks. These settings allow your backend services to authenticate with Appcharge and receive or respond to platform events during player authentication, purchases, and other interactions. You can also test callbacks and webhooks directly from the Publisher Dashboard. Testing sends a simulated Appcharge request or event to your endpoint so you can verify delivery and response handling before going live. Test payloads don't represent real players or transactions and aren't validated against your business logic. Your system is responsible for validating and processing the payload appropriately. ## Get started To configure your Developer Settings: 1. In the Publisher Dashboard, select the project you want to configure in the **Projects** section of the sidebar menu. 2. In the sidebar menu, under **Management**, click **Settings**. 3. Make sure you're in the **Developer Settings** tab. If the project you selected is a Web Store that has a corresponding Game Portal, you'll see a note explaining that Developer Settings are configured in the Portal Dashboard. Click **Portal Dashboard** to open and configure the Developer Settings there. 4. Review and complete the relevant sections described below. ### Project info View and manage your project details: * **Project Name:** Enter or update the name of your project. * **Project ID:** View your project ID. * **Domain:** Enter your domain name. This field is relevant only for Appcharge Web Stores or Game Portals. ## Credentials View the keys and tokens required to authenticate API, SDK, and checkout requests: * **Main Key:** Optional secret key used to sign and verify request payloads between your backend and Appcharge. Keep this key private and never expose it in client-side code. For implementation details, see [Secure Communication with the Appcharge Platform](/../../merchant-of-record/security/appcharge-to-publisher-secure-communication). * **Publisher Token:** Token used to authenticate your system when calling Appcharge APIs, as well as for securing webhooks and callbacks. * **Checkout Public Key:** Public key used for checkout-related communication between your platform and Appcharge. This key can be safely embedded in frontend code. Relevant only for external web stores using Appcharge Checkout or Payment Links. Credentials settings in the Publisher Dashboard ### Rotate credentials Credential rotation lets you replace your tokens and keys without interrupting your integration. You rotate a credential by generating a new token or key, updating your integration to use it, and then invalidating the original one. When you generate a new credential, Appcharge adds it as a second active credential, so both remain valid while you transition your backend. Once you've confirmed the new credential works, you invalidate the old one so that only a single credential stays active. You can rotate both the **Main Key** and the **Publisher Token**, each described in the sections below. Only users with Administrator or Developer roles can generate new credentials. **When to rotate** Generate new credentials in the following scenarios: * Routine security rotation. * Personnel changes. * Suspected credential leaks. #### Rotate the Main Key The **Main Key** signs all outbound webhooks from Appcharge to your backend, including authentication, personalization, and awarding callbacks. When one **Main Key** is active, Appcharge signs each outbound webhook and callback request with that key and sends the signature in the `signature` header as `v1`: ```text Single Signature header theme={"system"} signature: t=,v1= ``` When you generate a second Main Key, Appcharge temporarily signs each request with both the old and new keys. After you generate a new Main Key and before you invalidate your current one, update your backend to validate either `v1` or `v2` in the `signature` header. While two Main Keys are active, Appcharge sends dual signatures on every outbound webhook: ```text Dual Signature header theme={"system"} signature: t=,v1=,v2= ``` When you invalidate the old Main Key, the `signature` header drops `v2` and sends only the new credential as `v1`, which then becomes the current credential. If you later generate another key, it becomes the new `v2`, while `v1` stays the same. Invalidating `v2` instead of `v1` also leaves `v1` unchanged. Don't validate against the full `signature` header string. If you do, all webhook calls fail when the second key is generated. Invalidating the original Main Key before updating your backend to work with the new Main Key will immediately break your entire webhook integration. To rotate the Main Key: 1. Before you generate a new Main Key, make sure your backend validates against whichever signature version you want to use, either `v1` or `v2`. Then deploy the update and confirm it's live. Don't rely on the new **Main Key** being specifically in the `v2` position, as it moves into `v1` after you invalidate the old **Main Key**. 2. In the Publisher Dashboard, go to **Settings** > **Developer Settings** > **Credentials**, then click **Generate New** next to the **Main Key**. Your current key stays active as `v1`, and Appcharge adds the new key as `v2`, signing every outbound request with both. 3. Verify that all incoming webhooks from Appcharge, including authentication, personalization, and awarding, validate correctly against the new Main Key before you continue. 4. On the **Credentials** page, click the delete icon next to the old **Main Key** (`v1`), enter the key in the textbox, and click **Invalidate**. Appcharge then sends only the new key, which becomes your `v1`. Invalidated credentials can't be restored. #### Rotate the Publisher Token The Publisher Token authenticates inbound requests from your backend to Appcharge. Rotating the Publisher Token doesn't affect any webhook signature format or header structure. Both tokens are accepted simultaneously during rotation, and no backend preparation is required before generating the new one. To rotate the Publisher Token: 1. In the Publisher Dashboard, go to **Settings** > **Developer Settings** > **Credentials**, then click the **Generate New** button next to the **Publisher Token**. 2. Update your backend to send the new token on all API calls to Appcharge. 3. Deploy your changes and validate that all calls to Appcharge are working correctly. 4. Return to the **Credentials** page and invalidate the old **Publisher Token**. 5. Click the delete icon next to the **Publisher Token**, then copy the key into the textbox and click **Invalidate**. Invalidated credentials can't be restored. ## Callbacks Callbacks allow Appcharge to communicate with your backend systems. They're synchronous requests that require an immediate response from your system during a user flow, such as when authenticating a player. To implement a callback, create and expose a publicly accessible HTTPS endpoint that follows the structure defined in the documentation. When Appcharge calls the configured endpoint, it instructs your system to perform a specific action. Each callback can be configured and tested directly from the Publisher Dashboard before going live. This callback is relevant only for Appcharge Web Stores, Game Portals, and Parking Domains. To configure and test the callback: 1. Enter your endpoint URL in the **URL** field, and then click **Save**. 2. Click **Docs** to view the available callback fields and their definitions. You can refer to this documentation while testing the callback. 3. Click **Test** to open the test configuration panel. 4. Use the **Hide optional fields** checkbox to simplify the payload view. You can uncheck it at any time to include optional properties in your test. 5. In the **Player Authentication Method** drop-down menu, select the player authentication method you want to test. The available fields update dynamically based on the selected authentication type. 6. Customize the test payload by editing required and optional properties. Use these fields to simulate different player authentication methods and validate your endpoint’s behavior. 7. In the top-right corner, click: * **Test** to send the request directly from the Publisher Dashboard, or * **Copy cURL** to run the request externally. 8. Verify that your endpoint returns the expected HTTP status code and response body. This callback is relevant only when implementing Game Redirect Login for Appcharge Web Stores and Game Portals. [Set up Game Redirect Login](/../../webstore/player-authentication/game-redirect-login/set-up-game-redirect-login). To configure and test the callback: 1. Enter your endpoint URL in the **URL** field, and then click **Save**. 2. Click **Docs** to view the available callback fields and their definitions. You can refer to this documentation while testing the callback. 3. Click **Test** to open the test configuration panel. 4. Use the **Hide optional fields** checkbox to simplify the payload view. You can uncheck it at any time to include optional properties in your test. 5. In the **Desktop Digits** drop-down menu, select one of the following: * **4 Digits:** Generates a 4-digit authentication code. * **6 Digits:** Generates a 6-digit authentication code. * **Mobile Only:** Enables authentication for mobile devices only. 6. Customize the test payload by editing required and optional properties. Use these fields to simulate different devices and validate your endpoint’s behavior. 7. In the top-right corner, click: * **Test** to send the request directly from the Publisher Dashboard, or * **Copy cURL** to run the request externally. 8. Verify that your endpoint returns the expected HTTP status code and response body. To configure and test the callback: 1. Enter your endpoint URL in the **URL** field, and then click **Save**. 2. Click **Docs** to view the available callback fields and their definitions. You can refer to this documentation while testing the callback. 3. Click **Test** to open the test configuration panel. 4. Use the **Hide optional fields** checkbox to simplify the payload view. You can uncheck it at any time to include optional properties in your test. 5. Customize the test payload by editing required and optional properties. Use these fields to simulate the purchase or collection of an offer in your checkout and validate your endpoint’s behavior. 6. In the top-right corner, click: * **Test** to send the request directly from the Publisher Dashboard, or * **Copy cURL** to run the request externally. 7. Verify that your endpoint returns the expected HTTP status code and response body. This callback is relevant only if you choose to implement real-time personalization for your Appcharge Web Store. To configure and test the callback: 1. Enter your endpoint URL in the **URL** field, and then click **Save**. 2. Click **Docs** to view the available callback fields and their definitions. You can refer to this documentation while testing the callback. 3. Click **Test** to open the test configuration panel. 4. Use the **Hide optional fields** checkbox to simplify the payload view. You can uncheck it at any time to include optional properties in your test. 5. Customize the test payload by editing required and optional properties. Use these fields to simulate different players and validate your endpoint’s behavior. 6. In the top-right corner, click: * **Test** to send the request directly from the Publisher Dashboard, or * **Copy cURL** to run the request externally. 7. Verify that your endpoint returns the expected HTTP status code and response body. ## Webhooks Webhooks allow your systems to receive notifications when specific events occur in your Appcharge products. Unlike callbacks, webhooks are asynchronous. Appcharge sends the event after the action occurs, and your system processes it independently. To use a webhook, create and expose a publicly accessible HTTPS endpoint that can receive event notifications and process them according to the webhook schema defined in the documentation. Configure and test the webhook directly from the Publisher Dashboard before going live: To configure and test the webhook: 1. Enter your endpoint URL in the **URL** field, and then click **Save**. 2. Click **Docs** to view the event schema and field descriptions for the events you want to test. Refer to this documentation while testing different event types. 3. Click **Test** to open the test configuration panel. 4. Use the **Hide optional fields** checkbox to simplify the payload view. You can uncheck it at any time to include optional properties in your test. 5. In the **Event Name** drop-down menu, select the event you want to test. The available fields update dynamically based on the selected event type. 6. Customize the test payload by editing the event's properties. Modify required and optional fields to simulate different scenarios and validate how your endpoint handles various webhook payloads. 7. In the top-right corner, click: * **Test** to send the event directly from the Publisher Dashboard, or * **Copy cURL** to run the request externally. 8. Verify that your webhook endpoint receives the event and returns the expected response. # Configure Store Settings Source: https://docs.appcharge.com/guides/publisher-dashboard/configuring-store-settings This article explains how to configure the way numbers, such as prices and quantities, are displayed in your web store and web store offers. Use the controls on the Store Settings page—dropdown menus, toggles, and numeric inputs—to set these formats. Below is a breakdown of each store setting and how to configure it. ### Configure number formats and abbreviations **To configure number formats and abbreviations:** 1. In the Publisher Dashboard, go to **Settings** > **Store Settings**. 2. Locate the section you want to configure: * **Bundle and Popup** * **Balance** * **Special Offer** * **Rolling Offer** * **Progress Bar** 3. Configure the settings for each section: * **Thousands separator:** Symbol used to separate thousands, for example, `1,000` or `1.000`. * **Decimal separator:** Symbol used to indicate a decimal place, for example, `1.0`. * **Magnitude abbreviation:** Select **Yes** or **No** to enable each abbreviation (K, M, B, T, Q, Qi). * **Digits-based abbreviation:** Select **Yes** or **No** to set the abbreviation threshold by digit count rather than by magnitude. * **Max digits without shorthand:** Enter a value to set the maximum number of digits displayed before a number is abbreviated. 4. Click **Update** to save your changes. ### Magnitude abbreviations Control whether large numbers are shortened using a letter suffix. Each magnitude can be enabled independently: | Field | Abbreviation | Example | | - | - | - | | Abbreviate thousands (K) | K | 1,000 → 1K | | Abbreviate millions (M) | M | 1,000,000 → 1M | | Abbreviate billions (B) | B | 1,000,000,000 → 1B | | Abbreviate trillions (T) | T | 1,000,000,000,000 → 1T | | Abbreviate quadrillions (Q) | Q | 1,000,000,000,000,000 → 1Q | | Abbreviate quintillions (Qi) | Qi | 1,000,000,000,000,000,000 → 1Qi | # Manage User Roles and Permissions Source: https://docs.appcharge.com/guides/publisher-dashboard/manage-user-roles-and-permissions This article explains how to manage your team's access to projects in the Publisher Dashboard. You can view and manage users across all projects where you are an Administrator. Each project can have one or more Administrators. Administrators can invite users, assign roles, grant or remove project access, and find users with search and filters. Users can belong to multiple projects. Their roles and permissions can differ by project. To learn more, see the section below on [roles and permissions](#roles-and-permissions). ## View and manage users To view and manage users: 1. In the Publisher Dashboard sidebar, below the company name, click **User Management**. The table lists users from projects where you are an Administrator. 2. Use the table to find users and review their roles, projects, and statuses. ### Review user access The following columns in the table show access details: * **Role:** If a user has multiple roles, the table shows one role and the number of additional roles. Click the value to view and edit the user's roles by project. * **Projects:** The table shows a project name, the number of projects, or **All Projects** when the user can access every project in your Administrator scope. Click the value to view existing projects or add the user to more projects. * **Status:** There are two statuses: * **Active:** The user has logged in to the Publisher Dashboard at least once. Active status remains when the user is added to new projects. * **Pending:** The user hasn't yet logged in. Use the table controls to view users: * Search by name or email address. * Filter by role, project, project type, or status. * Sort by **Name**, **Email**, or **Status**. * Selected users remain selected when you move between pages, and the selection count includes users from all pages. Changing the search term or filters clears your selections. ### Invite new users You can invite up to 20 users at once. All users in the bulk invitation receive access to the same selected projects, but you can assign each user a different role. To invite users: 1. In the top right corner, click **Invite New Users**. A panel opens. 2. Under **Invite New Users**, enter each user's full name and email address, and then use the drop-down menu to select their role. For guidance, see the roles and permissions table below. Click **+ Add More** to add another user. To remove an entry, click the close icon next to it. 3. Click **Continue** to move to the **Add to Projects** tab. 4. Under **Select Projects**, search for and select one or more projects. There's no limit to the number of projects you can select. 5. Click **Review** and review the following groups: * **New invites:** Users who don't yet have an account in the Publisher Dashboard. * **Skipped:** Existing users. Each entry shows whether the user already has access to all selected projects or will gain access to additional projects. * **Projects:** The projects included in the invitation. 6. Click **Send Invitations**. The outcome depends on whether the users are new or already have accounts: * New users are added with the **Pending** status and receive an invitation email. They must open the link in the email to confirm access. * Existing users who gain access to additional projects remain **Active** and receive an expanded-access email. If they have a different role in another selected project, the role selected in the invitation replaces it. ### Add existing users to projects You can grant one or more users access to the same projects. Each user can have a different role, but that role applies to all projects selected in the same action. To grant users access to different projects, select one user at a time and repeat this process. To add existing users to projects: 1. To add a user, select the checkbox next to their name and click **Add to Projects** in the menu at the bottom of the page. 2. Under **Select Projects**, search for and select one or more projects. * If adding one user, review their existing projects, which appear preselected and can't be changed in this flow. These projects aren't part of the new selection, so their existing roles won't change. You can also view them under **Existing Projects List**. * If adding multiple users, select the projects without viewing the users' existing project access. 3. Click **Continue**. 4. For each user, select a role from the drop-down menu. For guidance, see the roles and permissions table below. 5. Click **Review** to move to the next tab and review the selected users, projects, and roles. 6. Click **Confirm Access Grant**. The outcome depends on the user's existing access: * If the user doesn't have access to a selected project, access is granted. * If the user already has the selected role in a project, no change is made. * In a bulk action, if the user has a different role in a selected project, the selected role replaces their existing role. Users who gain access to at least one new project receive an expanded-access email. A role change without a new project grant doesn't trigger an email. ### Edit a user's roles You can edit roles for only one user at a time. Changes apply independently to each project and don't affect the user's roles in other projects. To edit a user's roles: 1. Select the checkbox next to the user's name and click **Edit Role** in the menu at the bottom of the page. 2. Find the project where you want to change the user's role. If the user has access to at least 10 projects, you can search for a project. 3. Select a new role from the project's drop-down menu. Repeat this step for any other roles you want to change. 4. Click **Save changes**. The user's roles are updated for those projects. ### Remove user access You can remove access for only one user at a time. You can remove access from specific projects or every project the user can access. To remove access: 1. Click the ellipsis next to the user and click **Remove Access**. Alternatively, select the checkbox next to the user's name, and then click **Remove Access** in the menu at the bottom of the page. 2. A panel opens. Under **Select Projects**, search for and select one or more of the user's current projects. If you remove access from only some projects, the user remains in the table with access to their other projects. To remove all access, click **Select all**. If you select all projects, the user immediately loses access to the Publisher Dashboard and is removed from the table. To restore access, follow the steps in [Invite new users](#invite-new-users). The user is treated as a new invitee and must open the link in their invitation email to confirm access. 3. Click **Review** and verify the user and projects. 4. Click **Remove from \[N] projects**, where `[N]` is the number of selected projects. ### Resend an invitation You can resend an invitation only to a user with the **Pending** status: 1. Open the user's actions menu. 2. Click **Resend Invitation**. The user receives a new copy of the original invitation email. The previous invitation link no longer works. ## Roles and permissions The following table compares the permissions for each Publisher Dashboard role: | Permission | Administrator | Developer | Project Owner | Operations/Editor | Finance | Support | | - | - | - | - | - | - | - | | **Analytics** | View | None | View | None | View | None | | **Asset Library** | Manage | Manage | Manage | Manage | None | None | | **Authentication** | Manage | Manage | Manage | None | None | None | | **Badges** | Manage | Manage | Manage | Manage | None | View | | **Builder** | Manage | Manage | Manage | None | None | None | | **Bundles** | Manage | Manage | Manage | Manage | None | View | | **Checkout Links** | Manage | Manage | Manage | Manage | None | View | | **Company** | Update details + View | Update details + View | Update details + View | Home page only | Home page only | Home page only | | **Coupons** | Manage | None | Manage | Manage | None | None | | **Event Center** | Manage | Manage | Manage | View | View | View | | **Evidence** | Submit + View | None | Submit + View | None | Submit + View | Submit + View | | **Financial Report** | Generate + View | None | Generate + View | None | Generate + View | None | | **Integration** | Manage | Manage | Manage | None | None | None | | **Offer Design** | Manage | Manage | Manage | Manage | None | View | | **Offers** | Manage | Manage | Manage | Manage | None | View | | **Orders** | Refund + View | None | Refund + View | None | Refund + View | Refund + View | | **Payouts** | View | None | View | None | View | None | | **Popups** | Manage | Manage | Manage | Manage | None | View | | **Portal Content** | Manage | Manage | Manage | Manage | None | None | | **Portal Pages** | Manage | Manage | Manage | Manage | None | None | | **Pricing** | Manage\* | View | Manage\* | View | View | View | | **Products** | Manage | Manage | Manage | Manage | None | View | | **Promotions** | Manage | Manage | Manage | Manage | None | View | | **Rolling** | Manage | Manage | Manage | Manage | None | View | | **Users** | Manage | None | None | None | None | None | The **Rounding Rules** and **Display Tax-Inclusive Prices** sections under the **Pricing** tab have View access. # View Analytics Source: https://docs.appcharge.com/guides/publisher-dashboard/view-analytics The Analytics page in the Publisher Dashboard provides key insights into player behavior, revenue, and engagement, helping you make data-driven decisions. You'll find metrics such as revenue, deposits, player activity, and conversion rates, with flexible date filtering and time frame comparisons to help track performance trends. The page is organized into 3 tabs: * **Business:** Core player and revenue metrics. * **Finance:** Payment performance and chargeback data. * **A/B Test:** Performance analytics for tested features. ## Business This tab displays key metrics related to player activity and revenue. You can sort and compare data across attributes and time frames. ### Set up the Business tab To view business analytics: 1. In the top-left corner, click the **Attribute Name** button and search for the attribute you want to analyze. 2. Click the **Attribute Values** button and select the values you want to compare. 3. In the top-right corner, click the date range selector to choose your time frame. 4. To compare data over two periods, click **Compare Dates** and select a second date range. ### Business metrics Appcharge provides the following business metrics you can track: | **Metric** | **Description** | | - | - | | **Active Users** | This metric counts the number of unique players engaged with the web store (post login) within the specific time frame. It helps measure the player engagement and the active reach of the web store business. | | **ARPPU (Average Revenue Per Paying User)** | This metric calculates the average revenue generated from each paying player. It helps publishers understand the value derived from players who contribute directly to revenue, highlighting spending patterns and the effectiveness of monetization strategies. | | **ARPU (Average Revenue Per User)** | This metric averages the total revenue generated by all active players, whether they pay or not. It is an important measure of overall revenue generation capability per web store player, providing insight into the overall economic value of the player base. | | **Average Daily Active Users** | This metric shows the average number of unique players actively using (post login) the web store daily. It helps track daily player engagement and the service's stickiness. It is relevant only if you choose more than one day in the time picker. | | **Average Deposits Per Depositor** | This metric shows the average deposits/transactions count per depositor. Understanding how much each player typically contributes to deposits is crucial, helping to gauge player engagement and financial behavior. | | **Conversion Rate** | Appcharge measures the player conversion rate percentage as the number of depositors divided by active users. It’s crucial for evaluating the effectiveness of conversion strategies and player interest. | | **Depositors** | This count reflects the number of unique players who have made at least one deposit. It is useful for assessing the size of your engaged player base. | | **Deposits Per Price Point** | The number of deposits for each price point. | | **Revenue Per Price Point** | The total revenue for each price point. | | **Total Deposits** | This metric indicates the number of successful deposits/transactions by players within a specific period. | | **Total Revenue** | The total revenue including taxes and fees. | | **Total Revenue Without Tax** | This metric represents the sum of all revenue generated by the web store, excluding any taxes applied. It provides a clear view of the company’s income from sales before fee deductions. | | **Total Sessions** | This number represents the total count of individual sessions initiated by all players within a given period. It's useful for understanding player engagement levels and the frequency of interaction with the web store. Appcharge considered a session to be any activity within a one-hour period. | ## Finance This tab provides visibility into payment performance and risk-related metrics, such as chargebacks and refunds. You can compare these across different periods. ### Set up the Finance tab To view financial analytics: 1. In the top-right corner, click the date range selector to choose your time frame. 2. To compare data across two periods, click **Compare Dates** and select an additional time frame. ### Financial metrics Appcharge provides the following financial metrics you can track: | **Metric** | **Description** | | - | - | | **Chargeback Amount Rate** | The percentage of total revenue that was lost due to chargebacks. | | **Chargeback Cases: In Progress** | The number of chargebacks that are still under review or awaiting resolution. | | **Chargeback Cases: Lost** | The number of chargebacks that were lost after dispute resolution. | | **Chargeback Cases: Won** | The number of chargebacks that were successfully won. | | **Chargeback Rate** | The percentage of completed orders that resulted in a chargeback. | | **Chargeback Win Rate** | The percentage of chargebacks that were successfully disputed and won. | | **Order Success Rate** | The percentage of successful orders out of all payment attempts. | | **Payment Method Distribution** | Breakdown of transactions by payment method used. | | **Refund Amount Rate** | The percentage of total revenue that was refunded. | | **Refund Rate** | The percentage of completed orders that were refunded. | ## A/B Test This tab allows you to analyze how different player segments or experimental groups perform across key business metrics. It's especially useful for evaluating feature changes, pricing strategies, creative assets, or promotional campaigns. You can sort by attribute and view metrics for each attribute value side by side. This makes it easy to compare different groups over a selected time frame. For example, if you've segmented VIP players into Group A and Group B, you can compare their performance this month using metrics like: * Total Revenue * ARPPU * Average Deposits Per Depositor ### Set up the A/B Test tab To view A/B testing analytics: 1. In the top-left corner, click **Attribute Name** and choose the attribute you want to analyze. 2. Click **Attribute Values** and select the specific values or groups to compare. 3. In the top-right corner, click the date range selector to choose your time frame. To learn how to assign players to groups using attributes and run an A/B test in your web store or checkout, see [Implement A/B Testing](./../measurement-tools/implement-ab-testing). # View Blocked Players Source: https://docs.appcharge.com/guides/publisher-dashboard/view-blocked-players Players may sometimes engage in behavior that violates Appcharge's security guidelines or terms of service. This can include excessive disputes, a high risk of fraud, or suspension requests from the publisher or other players. In such cases, we may need to take action by temporarily suspending or permanently blocking them from accessing your web store or checkout. The **Players** tab in the Publisher Dashboard provides a database of blocked player information, including current status and any history of suspensions. The table includes the following fields: * **Player ID:** The player ID. * **First Blocked:** Date when the player was first blocked. * **Last Blocked:** Date when the player was last blocked. * **Blocked Until:** Date until when the player is blocked. After this date, the player will be unblocked. * **Reason:** The reason the player was blocked. * **Dispute Count:** Total number of disputes a player has opened during their account lifetime. * **Status:** The status of the blocked player. Can be Blocked or Unblocked. # View Financial Reports Source: https://docs.appcharge.com/guides/publisher-dashboard/view-financial-reports ### Overview The Financial Report feature within our dashboard helps publishers access and understand their financial data better. It enables them to generate reports for specific time ranges, providing details on orders and payments associated with their account. The data is available in CSV format and ready for download directly from the dashboard. ### Generating a Report Creating a report is simple. Access the "Financial Report" feature and input your desired timeframe by providing the start and end dates as prompted. This initiates the report generation process seamlessly. ### Downloading Insights Once the report is ready, the system provides a download link for the generated report in CSV format. Use this link to download the report to your local device or system for further analysis. ### Understanding Your Report The downloaded CSV file contains detailed information regarding transactions made during the specified period. Here's a breakdown of the columns typically present in the CSV file: * **offerName**: The name of the purchased offer. * **offerExternalId**: The SKU of the purchased offer. * **transactionDateUTC**: The UTC date of the transaction. * **transactionTimeUTC**: The UTC time of the transaction. * **publisherTransactionId**: The external transaction ID; this is the ID the publisher sends when an order is made. * **transactionType**: The type of the transaction (e.g., 'Completed successfully', 'Refunded', 'Dispute lost'). * **orderId**: The ID generated by Appcharge when an order is made. * **paymentMethod**: The payment method used for this transaction. * **playerId**: This is the ID Appcharge generates when an order is made. * **playerCountry**: The two-letter code of the player's country. * **playerState**: The player's state reported for tax charges (available for the US and Canada only). * **playerCurrency**: The three-letter code of the currency used for the transaction. * **amountTotal**: The total amount in the player's currency paid by the player, including tax. * **amountInDollar**: The total amount in dollars paid by the player, including tax. * **appchargeCurrencyExchangeCost**: The cost for currency conversion. There is no conversion cost for USD; for other currencies, the exchange cost is fixed at 1%. * **feeAppcharge**: The fee charged by Appcharge for this transaction. * **feeRefund**: 0 * **feeChargeback**: 0 * **taxTotalLocalCurrency**: The currency conversion tax in the player's currency is charged by the payment system. * **taxTotalInDollar**: The currency conversion tax in dollars the payment system charges. * **publisherNetAmount**: The net amount in the player's currency paid by the player, without taxes and fees. These columns provide a comprehensive breakdown of your transactions, enabling detailed analysis and insights into your financial activities within the specified time frame. # View Orders Source: https://docs.appcharge.com/guides/publisher-dashboard/view-orders The Main Dashboard offers a complete view of combined analytics and lets users filter orders and reports by project for specific insights. ### Analytics View aggregated analytics for all projects. Filter analytics by selecting specific projects from the "All projects" dropdown menu. Filters are also available by date range. ### Orders * **Orders tab:** See orders across all projects. Filter by project, date range, order ID, player ID, player email, transaction ID, receipt number, device OS, and payment status. The following tables describes all possible order statuses in the Appcharge dashboard: | Status | Description | | - | - | | **Pending** | Order created and awaiting payment confirmation. | | **Succeeded** | Payment and item awarding completed successfully. | | **Canceled** | Order was canceled manually or due to timeout. | | **Failed (Not charged)** | Order failed; player was neither charged nor awarded. | | **Failed (Charged)** | Order failed; player was charged but not awarded. | | **Refunded** | Payment was returned for this order. | | **Dispute open** | A dispute has been initiated for a specific transaction. | | **Evidence submitted** | Evidence has been submitted for the dispute. | | **Dispute lost** | Dispute resolved in favor of the player. | | **Dispute won** | Dispute resolved in favor of the publisher or Appcharge. | | **Dispute Canceled** | Dispute was canceled by the player. | * **Free Orders Tab:** View free orders like daily bonuses and promotions. The filter is similar to the Orders tab but specific to free transactions. ### Reports * **Financial Reports Tab:** Download financial reports in CSV format. Select specific or multiple projects and set the desired date range before generating the report. * **Payouts Reports Tab:** Download monthly payouts reports for all projects combined in CSV format. **This report does not support filtering by individual projects.** # View Segments Source: https://docs.appcharge.com/guides/publisher-dashboard/view-segments In Appcharge, segments can be configured to target specific player groups based on various criteria. Once you have configured segments, you can view them in the 'Segments' Tab of the Appcharge dashboard. **Steps to View Segments:** 1. **Navigate to the Dashboard:** Log in to the Appcharge dashboard. 2. **Access the Segments Tab:** From the main menu, select the Segments Tab. 3. **View Configured Segments:** Here, you will see a list of all segments that have been configured. Each segment displays its name, description, and criteria. Segments are essential for creating personalized offers and targeting specific audiences based on demographics, behavior, or other attributes. # Space Race Game Demo Source: https://docs.appcharge.com/guides/space-race-demo The Space Race game demo offers an interactive experience to see Appcharge in action. Explore a web store that demonstrates the [pixel perfect](https://www.appcharge.com/blog/pixel-perfect-web-stores) design our game UI experts deliver, ensuring players feel right at home the moment they land on your store. There, you'll find our battle-tested monetization and engagement features that keep players coming back, along with a checkout solution optimized for trust and convenience. Whether evaluating our solution or exploring the player journey, this demo highlights how Appcharge drives revenue and makes your web store feel like an extension of your game. > **Note:** All transactions are simulated, ensuring no real money is charged during the process. ## Get started with the demo 1. Open the [Space Race Game Demo](https://shop.spaceracegame.com/shop). 2. Before you log in to the Space Race game, read the Privacy Policy and Terms and Conditions. 3. You can experiment with the different login methods. For fast login, click **Login with Player ID**. Then enter any 4 characters and click **Login**. ## Explore the web store features The web store includes bonuses, special offers, coupons, and other monetization tools designed to enhance conversion and retention. These features work seamlessly with your game's existing player segments and monetization rules in real time to provide a deeply personalized experience without extra leg work. Browse the web store and experience some of the functionalities Appcharge has to offer: ### Daily Bonus When you log in, one or more Daily Bonus popups will appear. This feature is designed to increase player retention by offering a free gift in response to specific triggers. Click **Collect** to see how players can claim these offers. Learn more about [daily bonuses](./webstore/offers/popups/create-a-daily-bonus). ### Post Purchase Popup These offers are special incentives that appear as popups. They are offered immediately after a player makes a purchase to drive further engagement. Learn more about [post purchase popups](./webstore/offers/popups/create-a-post-purchase-popup). ### Special Offer Special offers feature one or more products that can be scheduled to appear at specific times. These offers typically appear in a rotating gallery at the top of the web store, and are often used to highlight time-limited deals. Learn more about [special offers](./webstore/offers/special-offers/about-special-offers). ### Rolling Offer Rolling offers appear in a sequence. Unlock offers one at a time by claiming or purchasing them. You'll then see that as an offer is unlocked, the next one is revealed. This feature encourages repeat interactions, increasing revenue. Learn more about [rolling offers](./webstore/offers/rolling-offers/create-and-manage-a-rolling-offer). ## View the web store policies Use the footer links in the web store to access the Space Race game policies: * Privacy Policy * Terms and Conditions * Support Page ## Experience the checkout The checkout supports over 100 currencies and 500 payment methods, powering any web store or even your in-app payments through our Unity or Native mobile SDKs. To experience our checkout, simulate a transaction: 1. Click an offer. 2. Proceed to checkout and select a payment method. 3. Enter payment details, including an email address to trigger the receipt email, and a promo code to try out the discount code feature. 4. Complete the transaction. 5. Check your email for the receipt from [receipt@appcharge.com](mailto:receipt@appcharge.com). Here you can review the details and breakdown of the transaction. # About Translations Source: https://docs.appcharge.com/guides/translations/about-translations Translate your web store, checkout, and game portal so customers can view content in their preferred language. This creates a familiar, region-specific experience across global markets. ## How it works In the Publisher Dashboard, you can add languages, manage translations, and control each language’s visibility. A region may support multiple languages, and each language can be used across multiple regions. By default, all text appears in English until you provide translations. Each time you add a new element to your web store, checkout, or game portal such as a product, badge, or offer, make sure to add its translation. If you don't, some content may appear partly in English. Once you add translations, language behavior depends on your Appcharge solution: * **External web store with Appcharge Checkout:** If you use an external web store with Appcharge Checkout, determine the player's locale and pass it to the Checkout through the Frontend SDK. Learn more about [translating your checkout using the Frontend SDK](/../../sdks/checkout/frontend-sdk/translate-your-checkout). * **Appcharge-managed Web Store or Game Portal:** If you use the Appcharge Web Store, Game Portal, or another Appcharge-managed solution, Appcharge automatically displays the language that matches the customer’s locale. If multiple languages are available for the same locale, Appcharge uses the first language you added in the Publisher Dashboard as the default. Customers can override this by selecting a different option from the language picker displayed at the bottom of the screen, and their choice is remembered for future visits. Learn how to [Set and Manage Translations](./set-and-manage-translations). You can also manage translations programmatically through the [Translations API service](/../../api-reference/translations/introduction). ## Translate the Game Portal If you want to translate Game Portal pages, including the web store page, you can translate them as usual through the Publisher Dashboard or APIs. If you want to translate Game Portal content such as in-game text or assets, see [Translate Game Portal Content](./translate-game-portal-content) for details. ## Translatable content There are 2 types of content you can translate: * **Static:** Fixed interface elements such as button labels and headers. * **Dynamic:** Content-specific values you define, such as product prefixes. Appcharge generates 2 CSV files, one for static fields and one for dynamic fields. Each file contains a current list of translatable items based on the latest data. For example, when you create a new offer or add dynamic content, the related fields automatically appear in the list. ## Key features * Display your web store, checkout, and game portal in the customer's preferred language. * Manage both static and dynamic content. * Add multiple languages and control when they are visible. ## Best practices * Use the Sandbox environment to preview translations before activating them. * Only activate a new language once it’s fully translated. * Keep translations current by tracking new or updated offers, products, and content. # Add and Manage Languages Source: https://docs.appcharge.com/guides/translations/add-and-manage-languages This article explains how to add and manage languages for your web store, checkout, and game portal. ## Add a language To add a language: 1. Go to the **Localization** tab in the Publisher Dashboard. 2. Under **Manage Languages**: * **Language Display Name:** Enter a display name for the language, such as **Español** for Spanish. * **Language Code:** Select the language code in the dropdown. This code must match the language code provided by your Payment Service Provider (PSP). * **Country:** In the dropdown, select one or more countries where this language will be available. Each region can support multiple languages, and each language can be used across multiple regions. 3. Click **Add New**. * Newly added languages remain inactive and hidden by default until you toggle them on, allowing you to set translations before making the language available to customers. * For each newly added language, a new column is created in the CSV files, and a new object is added to the API for each field. ## Enable or disable a language To enable a language, toggle it on, and to disable a language, toggle it off. ## Edit a language To edit a language: 1. Click the 3 dots next to the language you want to edit. 2. Update the language details as desired. 3. Click **Save**. ## Remove a language To remove a language: 1. Click the 3 dots next to the language you want to delete. 2. Click **Delete**, and then **Approve**. Removing a language deletes its column from the CSV files in the Publisher Dashboard. # Set and Manage Translations Source: https://docs.appcharge.com/guides/translations/set-and-manage-translations This article explains how to set and manage translations in the Publisher Dashboard. You can also set and manage translations using the [Translations API service](/../../api-reference/translations/introduction). Updates made through the API appear in the CSV file, and any changes to the CSV file are synced back to the API. ## Set translations Follow these steps to translate content: ### Step 1 | Add languages [Add your languages](./add-and-manage-languages) in the Publisher Dashboard. Each time you add a language, a new column is created in the CSV files. ### Step 2 | Download the translation files Download the 2 CSV translation files to view all translatable fields: 1. Go to the **Localization** tab. 2. Scroll to **Download Up-to-Date Translations File**. 3. Click **Download Static Strings** and **Download Dynamic Strings** to download both CSV files. ### Step 3 | Add translations Add translations for each string in the appropriate language column in both the static and dynamic CSV files. To add translations: 1. Open the 2 CSV files. They contain the following columns: | Column | Description | | - | - | | **Key** | The identifier for the string. | | **English** | The default English text that requires translation. | | **Other Languages** | Columns where you can add translations for each language. | 2. Enter your translations in the appropriate language columns and save the files. * You can't modify or delete the English text. * Column headers are fixed and cannot be changed. ### Step 4 | Upload translations After adding your translations, upload the files back into the Publisher Dashboard: 1. In the **Localization** tab, scroll to **Upload New Translations Files**. 2. Upload the 2 CSV files that contain your translations. ### Step 5 | Activate the languages To activate the languages: 1. In the **Localization** tab, scroll to **Manage Languages**. 2. Turn on the toggle for each language you want to make available to customers. To keep translations current, repeat steps 2- 4 regularly. ## Edit or delete translations To edit or delete translations: 1. Go to the **Localization** tab. 2. Scroll to **Download Up-to-Date Translations File**. 3. Click **Download Static Strings** and **Download Dynamic Strings** to re-download the CSV files. 4. Edit or delete the translations in the appropriate language columns and save the files. 5. Scroll to **Upload New Translations Files** and upload the updated files back into the Publisher Dashboard. If you delete a translation, the text will revert to the default English version. # Translate Game Portal Content Source: https://docs.appcharge.com/guides/translations/translate-game-portal-content This article explains how to translate Game Portal Content in the Publisher Dashboard. You can also translate Content via the [Content API service](/../../api-reference/game-portal/content/introduction). To translate Game Portal Pages, including the web store page, you can translate them as usual through the [Publisher Dashboard](./set-and-manage-translations) or [Translations API service](/../../api-reference//translations/introduction). ## Add or update translations To add or update translations for your Game Portal content: 1. [Add your languages](./add-and-manage-languages) in the Publisher Dashboard. 2. Go to the **Content** tab. 3. Either click **Create New Content** or click the 3 dots next to the content you want to translate, and then click **Edit**. 4. Click the **Localization** dropdown to select your language. Each time you add a new language in the Publisher Dashboard, it appears as an option here. 5. Edit the content including text and images for the selected language. 6. Click **Update** to save your changes. ## Delete translations To delete translations for your Game Portal content: 1. Go to the **Content** tab. 2. Click the 3 dots next to the content you want to delete the translation for, and then click **Edit**. 3. Delete the content in all fields. 4. Click **Update** to save your changes. A popup will appear, and then click **Save Anyway** If you delete a translation, the text reverts to the default English version. # About the Web Store Source: https://docs.appcharge.com/guides/webstore/about-the-webstore Appcharge empowers you to create a pixel-perfect web store that integrates seamlessly with your game ecosystem. Designed as a true extension of your brand, the store showcases your exclusive offers and promotions, enhancing the direct B2C experience for your players. With our platform, you can leverage powerful, customizable monetization features tailored to your unique needs, delivering a captivating, branded experience that drives engagement and maximizes revenue potential. The Publisher Dashboard empowers publishers with a highly customizable store builder, complete with a real-time preview feature for seamless design and iteration. You have the tools to personalize every aspect of your store’s layout, style, and branding, ensuring it aligns with your unique requirements. Whether you’re crafting your store's initial setup or making ongoing adjustments, Appcharge provides dynamic API solutions to keep your web store responsive to evolving needs without requiring a full redesign. # About the Add to Home Screen Button Source: https://docs.appcharge.com/guides/webstore/design/about-the-add-to-home-screen-button The Add to Home Screen button allows players to add your store directly to their device’s home screen for quick and easy access. Once the store is added to the home screen, the button will no longer appear when the player accesses the store from their home screen. > **Note:** This button is available only on mobile devices and tablets. Players will not see this option when accessing the store via desktop browsers. ## Benefits * **Convenience:** Players can access the store quickly without needing to open a browser. * **User Experience:** Adds an app-like experience to the web store. ## High Level Flow 1. **Publisher Configures Add to Home Screen Button:** The publisher configures the Add to Home Screen button in the Store Page within the Builder tab. 2. **Publisher Configures Language Localization:** The publisher enables language localization for the button text and popup instructions. This allows the publisher to provide localized instructions to players.
    ***Note:** If a custom Button Image is used, the default text will be hidden, and localization will only apply to the popup instructions.* 3. **Player Opens Store:** The button appears at the bottom left corner of the store screen on the player’s device. 4. **Player Clicks the Button:** When the player clicks the Add to Home Screen button, a pop-up appears based on the platform (iOS or Android). 5. **Player Saves Store to Home Screen:** The player is prompted to name the shortcut and save it based on the platform (iOS or Android). 6. **Player Reopens Store via Home Screen:** The player adds the store to their home screen and can now access it directly from there, just like an app. The Add to Home Screen button will no longer appear when the player opens the store from the home screen. ## Publisher Journey When adding images, if you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. 1. **Navigate to the Builder tab:** * Open the Builder tab in the publisher dashboard and make sure you are in General Settings in the header menu. 2. **Choose Your Font:** * Select the font for the button in the Font section. This will be the same font used in your web store. 3. **Navigate to the Store Page:** * Navigate to the Store Page within the Builder Tab. 4. **Customize Your Button:** * **Border and Text Color:** Choose the colors for the button’s border and text. These settings apply only when no image is uploaded for the button. * **Background Color:** Set the background color for the button (overridden if a button image is uploaded). * **Button Image (Optional):** Upload a custom image for the button. If added, the custom image will replace the button's default text ("Add to Home Screen") and background color. To revert to the default settings, clear the Button Image field.
    ***Note:** Ensure the image meets the Button Image Requirements mentioned below.* 5. **Configure the Button Position:** * **Vertical Offset(%):** Set the button's vertical position on the screen by entering a value between **0 and 100**. A value of **0** keeps the button in its default position, and a value of **100** moves it to the top of the screen. The positions of the Add to Home Screen button and [Back to Game button](/../../guides/webstore/design/configure-the-back-to-game-button) are linked, so changes made to one also affect the other. * Changing the vertical offset of the Add to Home Screen button also moves the Back to Game button to the same vertical position. * The Add to Home Screen button always appears on the left side of the screen. When the Back to Game button is also positioned on the left, the Add to Home Screen button shifts further left. 6. **Set Icon Image and Store Title:** * **Icon Image:** Upload an icon to represent your store in the native browser popup and modal window. This field is required and defaults to a placeholder if not configured. ***Note:** Ensure the image meets the Icon Image Requirements mentioned below.* * **Store Title:** Enter a title for the store, which will appear in the modal window and browser popup. This field is required and defaults to "Gaming Store" if not customized. 7. **Save Changes:** * Click Save to apply your configurations. ### Image Size and Format Requirements When configuring the Add to Home Screen button, ensure that the images meet the following requirements: 1. **Icon Image:** * **Aspect Ratio:** 1:1 * **Max Dimensions:** 192px by 192px * **Format:** PNG or SVG 2. **Button Image:** * **Aspect Ratio:** 3:1 * **Dimensions:** 120px width and 40px height * **Format:** PNG or JPEG ***Note:** Using images that do not meet these specifications may result in display issues or incorrect rendering.* ## Player Journey The behavior of the Add to Home Screen button differs slightly depending on whether the player is using iOS or Android. Below are the platform-specific steps and how the player interacts with the button: ### iOS: 1. The player clicks the Add to Home Screen button, and an instructional modal appears: "This site has app functionality. Add it to your Home Screen for easier access and better experience. Follow the instructions to add to your home screen." 2. The player follows the provided instructions to add the store to their home screen. 3. After adding the store, the button will no longer appear when accessed from the home screen. 4. To remove the store, the player can press and hold the app icon on their home screen and select the Remove App option.
    ### Android: 1. The player clicks the Add to Home Screen button, triggering a native Android popup. * The player is prompted to name the shortcut and save it. 2. After adding the store, the button will no longer appear when accessed from the home screen. 3. To remove the store, the player can press and hold the app icon and drag it to the Remove or Delete option at the top of the screen. ## Configuration Configure the Add to Home Screen button in the **External Buttons** tab of the [Brand Kit](../design/template-studio/template-editor/set-up-your-brand-kit#external-buttons) in the Template Editor. # About the Back to Game Button Source: https://docs.appcharge.com/guides/webstore/design/about-the-back-to-game-button The Back to Game button lets players quickly return to your game from the web store or after completing a purchase. You can enable or disable it in the Publisher Dashboard, and set its on-screen position to match your game layout. This button is available only on mobile devices and tablets. Players won't see this option when accessing the store through desktop browsers. ## Configuration Configure the Back to Game button in two places: * **Web store:** In the **External Buttons** tab of the [Brand Kit](../design/template-studio/template-editor/set-up-your-brand-kit#external-buttons) in the Template Editor. * **Checkout:** In the [Completed Page](/../../guides/checkout/design-your-checkout#customize-the-completed-page), so players can return to the game immediately after purchase. # Add a Banner Source: https://docs.appcharge.com/guides/webstore/design/add-a-banner A banner is a prominent horizontal image displayed at the top of the web store that highlights important content such as promotions, announcements, or seasonal messages. As one of the first elements players see when they open the web store, it helps create a strong first impression by aligning the store’s visuals with your brand and driving engagement with specific content or offers. You can add a banner in the Publisher Dashboard or display personalized banners for individual players using the [Personalize Web Store Callback](/api-reference/webstore/personalization/personalize-webstore-callback).
    To add a banner: 1. In your Publisher Dashboard, go to **Studio > Builder** and select the **Store Page** tab. 2. Scroll down to the **Banner** section. 3. Upload or select an image. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. 4. At the top-right of the page, click **Save**. ## Player Level Banners You can optionally configure banners to display dynamically based on a player’s level. This feature isn't supported in all templates. To request access, contact your account manager. # Add a Section Source: https://docs.appcharge.com/guides/webstore/design/add-a-section This feature currently supports Bundles and Special Offers only. Sections organize your web store into structured, themed areas. You can group related offers by assigning them to a Section under a shared title. Each Section includes a title displayed as the section header and an optional image shown on both sides of the title to enhance branding and visibility. This article explains how to create and manage Sections in the Publisher Dashboard. When adding images, if you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. ## Create a Section To create a Section: 1. In the sidebar menu, go to **Studio** > **Builder**. 2. In the **Store Settings** tab, scroll to **Sections**, and then click the arrow to expand the component. 3. Complete the following fields: * **Section Name**: Enter the Section title that will appear in the web store. * **Section ID**: Enter an ID for the Section. * **Section Type**: Select **Bundle** or **Promotion** (Special Offers). * **Icon**: Select or upload an image icon to appear on both sides of the Section title. 4. Click \**Add Section*. The section appears in the table below, grouped under either **Bundles** or **Promotions** (Special Offers). 5. Click **Save** in the top-right corner of the page to apply your changes. ## Assign or unassign an offer to a Section Once you create a section, you can assign Bundles or Special Offers to it. You can also assign or unassign offers using the [Bundles API](/../api-reference//webstore/offers-v2/bundles/introduction) or [Special Offers API](/../api-reference/webstore/offers-v2/special-offers/introduction). ### Assign an offer To assign an offer to a Section: 1. In the sidebar menu, go to **Offers** > **Bundles** or **Promotions**. 2. Create a new offer, or click the ellipsis next to an existing offer and select **Edit**. 3. In the **Settings** tab, under **General**, select your section from the **Section** drop-down menu. 4. Click **Save** in the top-right corner of the page to apply your changes. ### Unassign an offer To unassign an offer to a Section: 1. In the sidebar menu, go to **Offers** > **Bundles** or **Promotions**. 2. Click the ellipsis next to the offer and select **Edit**. 3. In the **Settings** tab, under **General**, select **None** from the **Section** drop-down menu. 4. Click **Save** in the top-right corner of the page to apply your changes. ## Reorder sections You can control the order in which sections appear in your web store. To reorder Sections: 1. In the sidebar menu, go to **Studio** > **Builder**. 2. Open the **Store Page** tab. 3. Scroll to **Sections**. Existing sections are grouped under **Bundles** or **Promotions** (Special Offers). 4. Use the drag handle (dots on the left) to move a Section to a new position within its group. 5. Click **Save** in the top-right corner of the page to apply your changes. ## Edit a Section To edit a Section: 1. In the sidebar menu, go to **Studio** > **Builder**. 2. Open the **Store Page** tab. 3. Scroll to **Sections**. 4. Click the **Edit** icon next to the section you want to update. 5. Modify the Section as needed. 6. Click **Save** in the top-right corner of the page to apply your changes. ## Remove a Section To remove a Section: 1. In the sidebar menu, go to **Studio** > **Builder**. 2. Open the **Store Page** tab. 3. Scroll to **Sections**. 4. Click the **Remove** icon next to the Section you want to remove. 5. Click **Save** in the top-right corner of the page to apply your changes. # Add a Tab Source: https://docs.appcharge.com/guides/webstore/design/add-a-tab * To get access to this feature, contact your account manager. * This feature currently supports bundles, special offers, and rolling offers only. Tabs allow you to organize and display different offers in your web store. You can assign an offer to a single tab or to all tabs. When players click a tab, they'll see the offers assigned to it. Tabs can appear as icons or as text labels, depending on your setup. A tab will only appear in the web store if at least 1 offer is assigned to it, either directly or by assigning the offer to all tabs.
    ## Set up tabs To set up tabs in the Publisher Dashboard, first create a tab, and then assign offers to it. You can also assign offers to a tab using the `publisherTabId` property via the [Offers API](/../../api-reference/webstore/offers-v2/introduction). When adding images, if you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. ### Create a tab To create a tab: 1. In the sidebar menu, go to **Studio** > **Builder**. 2. In the **Store Settings** tab, scroll to **Tabs**, and then click the arrow to expand the component. 3. Complete the following fields: * **Tab Name**: Enter the Tab title that will appear in the web store. * **Tab ID**: Enter an ID for the Tab. * **Icon**: Select or upload an image icon representing the Tab. This icon is what players click to select the tab. If you don't upload an icon, the tab will be displayed as text, using the tab name you provided. 4. Click **Add Tab**. The tab appears in the table below. 5. Click **Save** in the top-right corner of the Store Settings page. ### Assign a tab to an offer To assign a tab: 1. Go to the offer you want to assign a tab to. For example, **Bundles**. 2. Either create a new offer, or edit an existing one by clicking the 3 dots and selecting **Edit**. 3. In the **General** section, open the **Tab** dropdown and select either: * **A single tab**: The offer will only appear in that tab. * **All**: The offer will appear in every tab. ### Edit a tab To edit a tab: 1. Go to the **Store Page** tab in the **Builder**. 2. Scroll to **Tabs** and locate the table of existing tabs. 3. Click the **Edit** icon next to the tab you want to update. 4. Update the tab details, and then click **Save**. 5. Click **Save** again in the top-right corner to update the Store Page. ### Remove a tab To remove a tab: 1. Go to the **Store Page** tab in the **Builder**. 2. Scroll to **Tabs** and locate the table of existing tabs. 3. Click the **Delete** icon next to the tab you want to remove. 4. Click **Save** in the top-right corner to confirm the changes. # About the Template Studio Source: https://docs.appcharge.com/guides/webstore/design/template-studio/about-the-template-studio The Template Studio is a centralized workspace where you design and manage templates for your web store layout. Templates define the structure and visual style of your web store. They control how the store is organized, including which sections appear, how they are arranged on the page, and how the store is branded. You can create multiple templates, edit them independently, and activate the one you want players to see. The active template determines the layout displayed in your live web store. ## How it works The Template Studio provides a collection of professionally designed web store templates created by Appcharge designers and monetization experts. These templates provide a starting point for building your store layout. You can then customize a template in the Template Editor to match your game’s visual identity and monetization goals. ## Template Editor With the Template Editor, you can configure the layout and visual style of your store. For example, you can hide, show, and reorder store sections, configure how each section is displayed on the page, and apply global branding and design settings such as fonts, colors, and images. The editor also includes a live preview so you can see how the store will appear before activating a template. If you use web store personalization, you can preview how the store renders when personalization data is applied. For a detailed walk-through of the editor interface, see [Tour the Template Editor](./template-editor/tour-the-template-editor). ## Template states A template has one of two states: * **Draft:** A saved template that isn't live in your web store. * **Active:** A template currently used in your live web store. Only one template can be active at a time. Activating a different template automatically replaces the currently active template. ## Reusing templates for campaigns Templates can also be reused to launch new store experiences more quickly. For example, when running seasonal campaigns or special events, you can create an event template and reuse it for similar campaigns in the future. Instead of rebuilding the same layout each time, you can simply update the assets, such as images or banners, to match the new event. This approach allows you to define store structures once and reuse them whenever needed, making it easier to launch campaigns and create multiple store variants. ## Key features * **Faster web store launch:** A ready-made web store layout lets you get started in minutes. * **Self-serve customization:** Update your store independently without developer support. * **Professional store layouts:** Choose from templates designed by Appcharge monetization experts. * **Live preview:** See how your store will look before activating a template. * **Personalization testing:** Preview how your store renders when personalization data is applied. Learn how to [create and manage a template](./create-and-manage-template). # Create and Manage a Template Source: https://docs.appcharge.com/guides/webstore/design/template-studio/create-and-manage-template This article explains how to create and manage a template in the Template Studio of the Publisher Dashboard. ## Create a new template To create a template: 1. Go to **Studio > Template Studio**, and then click **Create Template**. The Template Editor opens. 2. In the Top Bar, click the **Template Name** placeholder on the left, and enter a name for the template. 3. In the Left Sidebar, configure the Blocks you want, and their specific settings, and reorder or hide blocks as needed. To learn more about Blocks and how to edit them, see the Template Editor. 4. In the Right Sidebar, use the Brand Kit to configure your global design settings: font, button colors, logo, background images, and other brand assets. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. 5. Configure the **Add To Home Screen** and **Back To Game** buttons as needed. 6. In the top-right corner, click **Save**. The template is saved as a draft and is not visible to players until you activate it. ## Activate and deactivate a template Activating a template makes it live on your web store. You can only have one active template at a time. To deactivate a template, you must activate a different one. To activate a template: 1. Go to **Studio > Template Studio**. 2. Click the ellipsis next to the template you want to activate, and then click **Activate**. Activating a template replaces your current web store design and automatically deactivates the previously active template. You can switch to another template at any time. ## Edit a template To edit an existing Template: 1. Go to **Studio > Template Studio**. 2. Click the ellipsis next to the template you want to edit, and then click **Edit**. 3. Modify the template as desired. 4. In the top-right corner, click **Save**. ## Duplicate a template To duplicate a Template: 1. Go to **Studio > Template Studio**. 2. Click the ellipsis next to the template you want to duplicate, and then click **Duplicate**. The duplicated template appears in the template list. ## Export a template Exporting a template downloads its configuration as a JSON file. Note that assets (images) are not included in the export and must be re-uploaded manually in the target environment. To export a template: 1. Go to **Studio > Template Studio**. 2. Click the ellipsis next to the template you want to export, and then click **Export**. The exported template downloads to your device. ## Import a template Importing a template creates a new template instance from a previously exported JSON file. After importing, re-upload any assets in the Brand Kit and External Buttons tabs before activating. To import a template: 1. Go to **Studio > Template Studio**. 2. In the top-right corner, click **Import**. 3. Upload a JSON file containing the template data, and then click **Import**. ## Delete a template You can only delete draft templates. The active template cannot be deleted. To delete a template: 1. Go to **Studio > Template Studio**. 2. Click the ellipsis next to the template you want to delete, and then click **Delete**. 3. In the confirmation popup, click **Delete**. # Customize Your Web Store Layout Using Blocks Source: https://docs.appcharge.com/guides/webstore/design/template-studio/template-editor/customize-your-web-store-layout-using-blocks This article explains how to customize your web store layout in the Template Editor using Blocks. Blocks represent sections of the store page, such as the header, bundles, banners, or footer. Use Blocks to control how each section appears in the store and where it appears in the page layout. In this article, you'll learn how to: * **Configure a Block:** Adjust settings such as theme, layout style, and the number of offers that appear per row. * **Reorder a Block:** Change where a section appears in the page layout. * **Hide or show a Block:** Control whether a section appears in the store. * **Group Blocks:** Group blocks to appear in a single row in the store. * **Ungroup Blocks:** Separate grouped blocks. Blocks control the layout of the store, not the content. Your active offers and Publisher Dashboard configurations determine the offers and other data that appear in each section. For example, if you hide the **Bundles** Block, Bundle offers won't appear in the store even if they are active. If you show the **Bundles** Block but haven't created any Bundle offers, the store doesn't show the section. ## Configure a Block Each Block includes configuration settings that control how its section appears in the web store. These settings vary by Block and may include layout style, the number of offers that appear per row, or the visual theme. A theme controls the organization of each section. Use the Center Panel to preview your Blocks and page layout. The preview uses placeholder designs from the Assets Library. To configure a Block: 1. In the Left Sidebar, click the Block you want to configure. 2. Adjust the available settings for that Block: The header is the top section of the web store. To configure the header, complete the following fields: * **Show Logo:** Toggle on to display your logo in the top-right corner of the web store. * **Show Player Name:** Toggle on to display the player's name in the top-left corner. * **Show Player ID:** Toggle on to display the player's ID in the top-left corner. * **Sticky Header:** Toggle on to keep the header at the top when the player scrolls. * **Background Opacity (%):** Set the opacity of the header background image. * **Text Color:** Select a color for header text. The popup displays an offer in an overlay modal when specific actions occur in the web store. You can preview the Daily Bonus in the following states: * Badge * Popup The Daily Bonus preview shows how the Block appears in your web store store. You can preview the Daily Bonus in the following states: * Badge * Popup The popup preview supports the following aspect ratios: * **1:1 Ratio:** Square. * **2:3 Ratio:** Vertical rectangle. Select an aspect ratio to preview the popup. The same popup ratio appears in both mobile and desktop previews. The Reward Calendar preview shows how the Block appears in your web store store. You can preview the Reward Calendar in the following states: * Badge * Popup * **Themes:** Use the drop-down menu to select a visual theme for your Bundles. * **Offer Per Row (Mobile):** Choose how many offers appear per row on mobile devices. Note that some themes have a set amount of offers per row. Display the player's current game level. Select the Progress Bar design you want to use. * **Themes:** Use the drop-down menu to select a visual theme for your Special Offers. * **Gallery View:** Toggle on to enable. * **Offers Per Row (Desktop):** Select a desktop-only layout that shows one, two, or three offers per row. The **Offers Per Row** setting appears only when **Gallery View** is turned on. Use the text box to add custom rich text content to the store. Select the Banner design you want to use. * **Desktop Layout:** Use the drop-down menu to select the direction of the Rolling Offer on desktop. * **Themes:** Use the drop-down menu to select a visual theme for your Rolling Offers. * **Show Appcharge Logo:** Toggle on to display the Appcharge logo in the store footer. 3. To save your changes, click **Update**. ## Reorder a Block You can reorder Blocks to change where the sections appear in the page layout. You can't reorder **Header** and **Popup** Blocks. To reorder a Block: 1. Hover over the Block you want to move. A drag handle appears on the left side of the Block. 2. Click and hold the drag handle, and then drag the Block to the desired position. ​ ## Hide or show a Block Hide or show a Block to control whether its section appears in the store. When you hide a Block, you remove the section from the web store without deleting its configuration. You can't hide **Header** and **Popup** Blocks. To hide or show a Block: 1. Hover over the Block you want to hide or show. The eye icon appears on the right side of the Block. 2. Click the eye icon to toggle the Block’s visibility: * When you hide a Block, the eye icon appears closed and the Block text turns gray. * When you show a Block, the eye icon appears open and the Block text turns black. You can toggle the eye icon at any time to re-enable a hidden Block. ## Group Blocks You can combine multiple eligible Blocks into one visual group so their badges appear side by side in the web store. To group Blocks, make sure each Block has a badge that can align with the others. You can group the following Blocks: * Daily Bonus * Triggered Popups * Reward Calendar To group your Blocks: 1. In the Blocks list, move two eligible Blocks next to each other, then hover between them. The **Group** indicator appears only when eligible Blocks touch. 2. Click the **Group** indicator. 3. To add more Blocks to the group, repeat the process with eligible Blocks. The preview automatically displays grouped Block badges side by side. If the badges exceed the row width, they wrap to the next line. Published templates use the same layout in the live web store. Grouping Blocks After you group Blocks, you can't reorder them in the group. To reorder grouped Blocks, ungroup them, reorder them, and then group them again. ### Move Grouped Blocks Grouped Blocks move together as a single unit using the **drag handle:**
    Drag Handle
    ## Ungroup Blocks To ungroup your Blocks, click the **Unlock** icon on any Block to remove it from the group. If only one Block remains, the gray container disappears.
    Drag Handle
    # Preview the Web Store with Personalization Data Source: https://docs.appcharge.com/guides/webstore/design/template-studio/template-editor/preview-the-webstore-with-personalization-data When configuring your store layout in the Template Editor, you can preview how the web store appears to players in the Center Panel. If you are using the [Web Store Personalization feature](../../../personalization/about-personalization), you can also preview how your store will appear when personalization data is applied. This article explains how to preview your web store using personalization data in the Template Editor. ## Test and preview web store personalization 1. In the Top Bar, click the **Code icon** to open **Test personalization response**. A code editor opens with a sample response from the [Personalize Web Store Callback](/../../api-reference/webstore/personalization/personalize-webstore-callback). 2. Either edit the existing code, or click **Clear** to remove it and paste your own JSON response values. 3. (Optional) Use the editor tools to format or copy the JSON: * **Format icon:** Automatically formats the JSON. * **Copy icon:** Copies the JSON from the editor. 4. Click **Preview** to render the store preview in the Center Panel using the provided personalization data. # Set Up Your Brand Kit Source: https://docs.appcharge.com/guides/webstore/design/template-studio/template-editor/set-up-your-brand-kit This article explains how to configure the Brand Kit in the Template Editor. Use the Brand Kit to apply consistent branding across your web store template, including fonts, colors, logos, and images. Changes made in the Brand Kit apply across the entire template. The Brand Kit appears in the Right Sidebar of the Template Editor and is open by default. You can toggle it on or off by clicking the **Brand Kit icon** in the Top Bar. The Brand Kit includes two tabs: * **Branding:** Global design settings for your store. * **External Buttons:** Configuration for the **Back to Game** and **Add to Home Screen** buttons. ## Branding The Branding tab contains the global design settings for your template. Use these settings to define the visual style of your web store. Configure the following settings: * **Font Family:** Use the drop-down menu to select the font for all text in your template. * **Button Color:** Select the color for all buttons across the template, except for the **Back to Game** and **Add To Home Screen** buttons. * Use the drop-down menu and select **Solid** to apply a single color, or * Select **Linear** to apply a gradient. Then choose two colors, and use the second drop-down menu to select the gradient direction. * **Button Text Color:** Use the drop-down menu to select the color for the button text. * **Logo:** Upload the logo to display in your web store. * **Banner Image:** Upload the banner image to display in the store. * **Background Image (Mobile):** Upload a background image to display on mobile devices. * **Background Image (Desktop):** Upload a background image to display on desktop devices. * **Footer Image (Mobile):** Upload the image to display in the footer on mobile devices. * **Footer Image (Desktop):** Upload the image to display in the footer on desktop devices. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. ## External Buttons The External Buttons tab includes the settings for the optional **Back to Game** and **Add To Home Screen** buttons. These floating buttons appear on top of the store and move together when their position is adjusted. Configure the following settings: * **External Buttons Position** * **Vertical Offset (%):** Enter a value from 0-100 to control how far the buttons appear from the bottom of the page. * **Add To Home Screen:** The **Add to Home Screen** button allows players to add the web store to their device home screen. * **Activate this feature in your store:** Toggle this setting on to display the button. * **Store Title:** Enter a name for the shortcut that will be created on the player's home screen. * **Border and Text Color:** Select the color for the button border and text. You can upload a button image instead. * **Background Color:** Select the button background color. * Use the drop-down menu to select **Solid** to apply a single color, or * Select **Linear** to apply a color gradient. Then choose two colors, and use the second drop-down menu to select the gradient direction. * **Button Image:** Upload a custom button image instead of using color and text styling. * **Icon Image:** Upload the icon to display on the player's home screen shortcut. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. * **Back To Game:** The **Back to Game** button allows players to return to the game from the web store. * **Activate this feature in your store:** Toggle this setting on to display the button. * **Button Side Position:** Use the drop-down menu to select the side of the screen where the button appears. * **Button Image:** Upload an image for the button. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. # Tour the Template Editor Source: https://docs.appcharge.com/guides/webstore/design/template-studio/template-editor/tour-the-template-editor The Template Editor is where you design and customize your web store template. It allows you to arrange store sections, apply branding, and preview how your store will look to players. This article guides you through each part of the interface so you can quickly and easily understand how to navigate and use the Template Editor. The Template Editor is organized into four main areas: * **Left Sidebar:** Manage the Blocks that make up your store layout. * **Center Panel:** Preview your web store in real time. * **Right Sidebar:** Apply global branding and style settings using the Brand Kit. * **Top Bar:** Access template tools and preview options. ## Left Sidebar The Left Sidebar displays the list of pre-configured Blocks that define the structure and layout of your web store. Each Block represents a section of the store, such as the header, bundles, banners, or footer, and includes settings specific to that section. From the Left Sidebar, you can: * Hide or show Blocks to control which sections appear in the store. * Configure Blocks to control how a section is displayed in the store. * Reorder Blocks to change where a section appears in the page layout. Blocks control the layout of the store, not the content. The content displayed in each section depends on your active offers and other configurations in the Publisher Dashboard. To learn more about working with Blocks, see [Customize Your Web Store Layout Using Blocks](customize-your-web-store-layout-using-blocks). ## Center Panel The Center Panel shows a live preview of your web store. As you make changes in the Template Editor, the preview updates automatically so you can see how your store will look before saving or activating. By default, the preview displays the web store as it would appear on a mobile device. You can switch between **mobile** and **desktop** views using the controls in the Top Bar. ## Right Sidebar The Right Sidebar contains the Brand Kit, where you configure global design and style settings for the template. While you can't modify the internal structure of layouts, such as text position, or card spacing, the Brand Kit allows you to apply consistent branding across your entire store, including: * Fonts * Button colors * Logos * Background images * Footer images Changes made in the Brand Kit apply across multiple Blocks at once, making it the fastest way to style your store. The Brand Kit includes two sections: * **Branding:** Global design settings for the template. * **External Buttons:** Style settings for optional buttons such as **Back to Game** and **Add to Home Screen**. The Brand Kit is open by default. If you don't see it, click the **Brand Kit icon** in the Top Bar to open it. ## Top Bar The Top Bar runs across the top of the Template Editor and provides tools for managing your template. From the Top Bar, you can: * Rename the template. * Preview the store on mobile or desktop. * Undo or redo changes made while editing. * Open the Brand Kit. * Test personalization responses. * Save your changes. * Go back to the list of templates. ### Rename the template To edit the template name: 1. Hover over the template name. 2. Click the **Edit icon**. 3. Enter a new name and press **Enter**. ### Test Personalization Response The Test Personalization Response tool allows you to preview how your store will appear when using the [Web Store Personalization feature](../../../personalization/about-personalization). Open this tool from the Top Bar, and when you configure it, you'll see the preview in the Center Panel. You can paste a JSON response from the [Personalize Web Store Callback](/../../api-reference/webstore/personalization/personalize-webstore-callback), and the Template Editor renders the personalized store preview in the Center Panel. For step-by-step instructions, see [Preview the Web Store with Personalization Data](./preview-the-webstore-with-personalization-data). # About Offers Source: https://docs.appcharge.com/guides/webstore/offers/about-offers Offers are promotional tools for selling digital products to players for real currency. The web store supports several offer types, each suited to a different sales strategy. Offers appear to players when they are active and the player matches any configured segment or personalization rules. You can use these rules to control which players see each offer. You can control which players see each offer by creating player segments and assigning offers to specific groups. You can also use [Web Store Personalization](../personalization/about-personalization) to decide exactly which offers appear for each player. If no offers are active or available, you can [configure an empty state](../settings/configure-general-store-settings#empty-state-for-no-offers) so players don't see a blank storefront. ## Offer types Supported offer types: ### Special Offers Promotions featuring one or more products that can be scheduled to appear at specific times. These offers typically appear in a rotating gallery at the top of the web store, and are often used to highlight time-limited deals. ### Bundles Offers that include one or more products sold at a discounted rate or with added value. Unlike special offers, bundles can't be scheduled in advance and remain active until disabled. ### Daily Bonuses Free rewards that appear as popups when players open the web store, encouraging them to return regularly. ### Reward Calendars 7-day calendar popup offers that show players a week's worth of upcoming rewards and let them collect the current day's reward. Reward Calendars encourage players to return on consecutive days by showing what they can earn now, what they can earn later, and when the next reward becomes available. ### Rolling Offers Rolling Offers unlock new sub-offers as players progress. Each offer reveals the next, motivating repeat interactions before the promotion resets. These time-sensitive offers are scheduled, with a countdown timer showing how long the current offer is active. If players don't unlock all the offers before time runs out, the sequence resets. ### Triggered Popups Popups are promotional offers that appear as a modal in the web store. They are useful when you want to direct a player's attention to a specific reward or follow-up offer. #### Post Purchase Special incentives appear as popups. They are offered immediately after a player makes a purchase to drive further engagement. #### Store Refresh Special incentives appear as popups. They are offered immediately after a player makes a purchase to drive further engagement. ### Checkout Link Offers A personalized offer delivered directly to players via a deeplink, taking them straight to the checkout with the offer preloaded. The link can be shared through any distribution platform, such as social media, DMs, and email. Checkout links can be used for various purposes, including sending unique deals to a VIP player for a more personalized experience. ### Progress Bars A type of offer that works alongside other offers to encourage players to purchase additional offers or collect free rewards. Players earn points by purchasing or collecting contributing offers, advancing toward configured targets with rewards at each stage. Progress Bars support two types, which determine what a target is called and how targets are displayed on the bar: * **Classic:** The target is called a mission. One mission displays at a time and the bar resets between missions. * **Milestones:** The target is called a milestone. All milestones display at once along a single bar. ## Add an offer to your web store After you choose an offer type, follow the process below in order before creating the offer in your web store: 1. [Design the offer](./offer-design/design-an-offer). 2. [Create products](./offer-design/add-a-product) for the offer. 3. (Optional) [Create a badge](./offer-design/add-a-badge) to add to the offer. 4. Create the specific offer, adding products and any badges to it. # About Bundles Source: https://docs.appcharge.com/guides/webstore/offers/bundles/about-bundles Bundles allow you to group multiple products into a single promotional package, presenting players with an enticing deal that increases value while simplifying purchase decisions. By combining several useful items into one ready-made offer, Bundles remove the need for players to compare options or decide which items to buy separately. This encourages them to purchase more than they would normally choose on their own. It also introduces players to related items they might not have planned to purchase, which supports cross-selling. As a result, Bundles create a convenient and appealing “all-in-one” offer that stands out in your web store and drives stronger purchase behavior.
    ## How it works When creating a Bundle, you decide which products it includes, how the offer is displayed, and whether the pricing is discounted, fixed, or proportional. Bundles can be featured anywhere in your store and configured to match seasonal events, special promotions, or evergreen value packs. When a player purchases a Bundle, they immediately receive all included products as part of a single transaction. Learn how to [Create and Manage a Bundle](/../../guides/webstore/offers/bundles/create-and-manage-a-bundle). # Create and Manage a Bundle Source: https://docs.appcharge.com/guides/webstore/offers/bundles/create-and-manage-a-bundle This article explains how to design, create, and manage a Bundle offer for your web store in the Publisher Dashboard. Alternatively, you can create and update a Bundle using the [Bundles API service](/../../api-reference/webstore/offers-v2/bundles/introduction). ### Design a Bundle Before creating a Bundle, you need to design it: 1. In the **Studio** section go to **Offers Design**, and click **Add New Design**. 2. In the **Type** field, select **Bundle** from the drop-down menu. The form updates to display all fields relevant to a Bundle. 3. Complete the following sections: * **Offer Settings** * **Name:** Enter a name for the offer design so you can easily identify it when creating an offer. * **External ID:** Enter an ID for the design. * **Offer Assets** * **Background Image**: Upload or select a background image. * **Background Color**: Select a solid color or choose **Linear** to apply a gradient. * **Button Suffix Badge**: Add an image or JSON animation to highlight your call-to-action button. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. To get access to this feature, contact your account manager. 4. Click **Save** to finalize the design. ### Create a Bundle After designing the Bundle, you can create the offer itself: 1. In the **Offers** section go to **Bundles** and click **Add New Bundle**. 2. Complete the following sections: * **General** * **Name**: Enter a name for the Bundle offer. This name appears in the checkout unless you provide an alternative in the **Display Name** field. * **Display Name**: Enter a name for the Bundle offer to display in the checkout. This value overrides the one in the **Name** field. If left blank, the value from the Name field is displayed in the checkout. * **Description**: Provide a description for the Bundle. * **External ID**: Enter an ID for the Bundle. * **Offer Design**: Select the design you want to use from the drop-down menu. * **Section**: Choose where the Bundle appears in the store. * **Price**: Enter a price for the Bundle. * **Segments**: Enter the segment names to display the offer to specific groups of players. * **Badges**: Select a badge from the drop-down menu to help highlight the Bundle. * **Sale & Discounts** * **Product Sale**: Enter a sale value for the product. Setting this field adds a Sale Badge to your Bundle. * **Type**: Click the drop-down menu to select the discount type, **Percentage**, **Multiplier** or **Fixed Amount**. * **Price Discount**: Enter a discount value, and the full price will appear crossed out next to the sale price. * **Progress Bar** This section is only relevant if you have a Progress Bar offer configured. Define how many points the Bundle adds to a Progress Bar when it is collected or purchased. * **Bar ID**: ID of the Progress Bar this offer to contributes to. * **Bar Points**: Number of points awarded toward the Progress Bar. * **Products**: To add products to the Bundle, configure the fields below, and then click **Add Product**. You'll see the products displayed in a table at the bottom of the page. * **Product Name:** Select a product to add from the drop-down list. * **Product Types**: Choose how the product is displayed within the Bundle: * **Main:** A primary product displayed prominently in the Bundle. * **Sub**: A secondary product displayed in a smaller layout. Sub products can appear on their own or under a Main product. * **Web Only**: Select **Web Only** to promote items that are available exclusively in the Web Store. To get access to this feature, contact your account manager. * **Quantity**: Enter the number of units of this product included in the offer. 3. Click **Save** to create the Bundle. ## Edit a Bundle To edit an existing Bundle: 1. Go to the **Bundles** section. You’ll see a list of all your existing Bundles. 2. Click the ellipsis of the offer you want to edit, and then click **Edit**. 3. Modify the Bundle as desired. 4. Click **Save** to apply changes. ## Duplicate a Bundle To duplicate a Bundle: 1. Go to the **Bundle** section. You’ll see a list of all your existing Bundles. 2. Click the ellipsis of the offer you want to duplicate, and then click **Duplicate**. 3. Modify the Bundle as desired. 4. Click **Save** to apply changes. ## Delete a Bundle To delete a Bundle: 1. Go to the **Bundles** section. You’ll see a list of all your existing Bundles. 2. Click the ellipsis of the offer you want to delete, and then click **Delete**. # About Checkout Link Offers Source: https://docs.appcharge.com/guides/webstore/offers/checkout-link-offers/about-checkout-link-offers This feature now uses [Game Redirect Login](../../player-authentication/game-redirect-login/about-game-redirect-login) for authentication. If you're using the legacy [JWT authentication method](./use-jwt-method), see the dedicated article for setup instructions. A checkout link offer is a personalized offer shared directly with players through a unique deeplink, which can also be distributed as a QR code. When a player clicks the link or scans the QR code, they are redirected to the game for authentication and then sent straight to the checkout page, where the offer is preloaded and ready for purchase. You can share this link across any platform, such as social media, direct messages (DMs), email, or include it as a QR code in digital or printed materials. Use the [Personalization](../../personalization/about-personalization) feature to customize the product amount, pricing, and availability, allowing for deeper segmentation strategies. You can also schedule when the offer becomes active to align with live game events or campaigns. Since this offer doesn't appear in the web store, it's ideal for exclusive promotions and targeted campaigns. This gives you full control over who receives the offer, how it is delivered, and how often it can be purchased. It also helps you balance the game economy, prevent abuse, and manage purchase frequency.
    ## How it works To begin, set up [Game Redirect Login](../../player-authentication/game-redirect-login/set-up-game-redirect-login) to securely identify and verify players. Then, [create and manage the checkout link offer](./create-and-manage-a-checkout-link-offer) in the Publisher Dashboard or via the [Checkout Link Offers API](/../../api-reference/webstore/offers-v2/checkout-link-offers/introduction). Unlike other types of offers, a checkout link offer doesn't require design. The checkout page only displays the relevant product details such as item quantity and icon. ## Key features * **Send exclusive offers:** Send players offers that aren't available in your web store or game to create a sense of FOMO (fear of missing out). * **Increased player trust:** Players are routed to the game for authentication, and then back to checkout, building player trust and improving conversion rates. * **Broader player reach:** Distribute the offers via DMs and social channels, enabling marketing teams to engage player communities directly. ## Use cases Below are some use cases that show how checkout link offers can support your marketing, retention, and monetization strategies across different player segments and channels. ### 1. VIP level treatment for all players Send exclusive offers that can only be redeemed through personalized links shared via your DM channels. **Messaging strategies:** * Emphasize the unique value of each offer. * Connect the promotion to events like birthdays, holidays, new features, currency launches, or game milestones. * Personalize the message using account manager profiles to enhance trust and boost conversions. **Key KPIs:** ARPPU, Deposits ### 2. Re-engage dormant payers Target players who haven’t made recent purchases or are at risk of churning. For example, focus on players who haven't made a purchase in the past 14 days. **Messaging strategies:** * Offer higher discounts or lower-priced bundles to encourage return. * Match the offer’s value to the player’s historical spending behavior. * Create urgency with limited-time availability. **Key KPIs:** ARPU, Conversions, Deposits ### 3. Engage your social communities Share special offers on platforms like Facebook, Discord, or WhatsApp. Boost posts to reach more followers and increase conversions. **Messaging strategies:** * Publish checkout link offers tied to in-game or calendar-based events. * Use interactive formats such as quizzes, AMAs (Ask Me Anything), and polls to drive comments and reactions. * Promote seasonal offers and themed offers such as Black Friday, holidays, and anniversaries. **Key KPIs:** ARPU, Paying Users (PU), Deposits ### 4. Go all-in on big spenders Increase wallet share by targeting high-value players who haven’t yet adopted your web store or DTC channels. **Messaging strategies:** * Present offers slightly above their daily average spend to spark interest. * Highlight exclusive, high-value deals they haven’t seen before. * Reinforce urgency with limited availability or one-time purchase conditions. **Key KPIs:** ARPU, Deposits ## Monitor checkout link offers Measure performance and ROI via: * **The Publisher Dashboard:** View all checkout link offers from the **Checkout Links** tab, and filter by **External ID**. * **Webhook events:** Enable real-time [event tracking](/../../api-reference/events/v2/introduction) for interactions with checkout link offers. Filter [Offer Events](/../../api-reference/events/v2/order/order_created) by `offer.externalId` or `offer.type = CheckoutLink`. * **UTM tracking:** You can add UTM attributes via the following: * The offer's deeplink. When you receive the checkout link via the Publisher Dashboard or Checkout Link Offers API, before sending it to players you can append UTM attributes to the URL with query params as follows: ```js theme={"system"} https://best-game.appcharge.com/login/campaign/YL2bAHqnu?utmSource=Facebook&utmCampaign=VipCampaign ``` * [Authenticate Player Callback](/../../api-reference/webstore/player-authentication/authenticate-player-callback) to monitor campaign effectiveness. These attributes appear in events such as: * [Web Store Login Displayed](/../../api-reference/events/v2/webstore/login/webstore_login_displayed) * [Web Store Displayed](/../../api-reference/events/v2/webstore/login/webstore_store_displayed) # Create and Manage a Checkout Link Offer Source: https://docs.appcharge.com/guides/webstore/offers/checkout-link-offers/create-and-manage-a-checkout-link-offer This article explains how to create and manage a checkout link offer in the Publisher Dashboard. Alternatively, you can create and update checkout link offers using the [Checkout Link Offers API](/../../api-reference/webstore/offers-v2/checkout-link-offers/introduction). If you're using the [Personalization](../../personalization/about-personalization) feature to send offers to players, make sure to include the checkout link offer in the [Personalization API](/../../api-reference/webstore/personalization/introduction) payload. Although this offer doesn't appear in the web store, it is still valid and must be explicitly sent to the player through the API. ## Prerequisites Before creating a checkout link offer, make sure [Game Redirect Login](../../player-authentication/game-redirect-login/set-up-game-redirect-login) is set up. If you're using the legacy [JWT authentication method](./use-jwt-method), see the dedicated article for setup instructions. ## Create a checkout link offer To create a checkout link offer: 1. Go to **Offers > Checkout Links** and click **Create New Link**. 2. In the **Settings** tab, provide the offer details, including price, products, and quantity. 3. Go to the **Schedule** tab to manage when the checkout link offer is available and how often it can be purchased by each player. You'll find three scheduling options: * **Permanent**: The offer is always available, but you can limit how many times each player can purchase it. * **Intervals:** The offer will appear according to the set time intervals. If the offer link is opened outside these intervals, it will not be available, and the player will have the option to return to the web store or game. * **Schedule:** The offer will be available for purchase in specific quantities only during the time frames you define. If the offer link is opened outside these time periods, it will be unavailable, and the player will have the option to return to the web store or the game. 4. Once you’ve filled in the necessary information, click **Save** to create the deeplink. 5. Return to the **Checkout Links** page and choose how you want to share the offer with players: * Click on the link icon to copy the deeplink to your clipboard. * Click the QR code image to download the QR code to your computer. If you're using the legacy JWT method, follow the steps in the [Use JWT to Create a Checkout Link Offer](./use-jwt-method#make-the-checkout-link-functional) article to secure the deeplink with a signed JWT. 6. The following step is only relevant if you're using the legacy JWT method. If you'd like to customize the approval request, go to the **Approval Request** tab in the **Builder** tab. If you choose not to customize the popup, the default Appcharge configuration is displayed. ## Edit a checkout link offer To edit an existing checkout link offer: 1. Go to the **Checkout Links** tab. 2. Click the ellipsis next to the link you want to edit, then click **Edit**. 3. Modify the checkout link as necessary. For example, update the price or change the schedule. 4. Click **Save** to apply the changes. ## Activate or deactivate a checkout link offer To activate or deactivate a checkout link offer: 1. Go to the **Checkout Links** tab. 2. Click the ellipsis next to the link you want to activate or deactivate, and then click **Activate** or **Deactivate**. ## Delete a checkout link offer To permanently delete a checkout link offer: 1. Go to the **Checkout Links** tab. 2. Click the ellipsis next to the link you want to delete, and then click **Delete**. # Use JWT Authentication to Create a Checkout Link Offer Source: https://docs.appcharge.com/guides/webstore/offers/checkout-link-offers/use-jwt-method This is a legacy authentication method. We recommend you use [Game Redirect Login](../../player-authentication/game-redirect-login/set-up-game-redirect-login) instead. With JWT authentication, when a player clicks the deeplink to open the checkout page, they are automatically authenticated using their player ID. An approval request appears, showing the player's name and image, and asks them to confirm their identity. If the player approves, they are directed to the checkout page. If they decline or close the prompt, they are logged out and must reopen the link to try again. This confirmation popup appears only once per session to reduce friction and avoid interrupting the player experience repeatedly. ## Set up the checkout link offer using JWT Follow the steps below to set up your checkout link offer using the JWT authentication method. ### Step 1 | Integrate Appcharge with your platform Before creating a checkout link offer, follow the steps to integrate Appcharge with your broadcast platform or custom distribution system: 1. Go to the **Settings** tab in the Publisher Dashboard and click **Integration**. 2. Toggle on **Enable Deeplink JWT Secret** to generate a secret key. 3. Copy the value of the generated **Deeplink JWT Secret**. 4. Add the secret to your broadcast platform configuration, or if you are using your own custom distribution system, save the secret to use after you’ve created the checkout link offer. ### Step 2 | Create and manage your checkout link offer Follow the steps in the article to [create and manage a checkout link offer](./create-and-manage-a-checkout-link-offer) in the Publisher Dashboard. Alternatively, you can create and update checkout link offers using the [Checkout Link Offers API](/../../api-reference/webstore/offers-v2/checkout-link-offers/introduction). ### Step 3 | Design the approval popup (optional) You can fully customize the approval request screen to match your branding: In the Publisher Dashboard, go to **Builder > Approval Request** to customize the popup. If you choose not to customize the popup, it will use the default Appcharge configuration. ### Step 4 | Add JWT and distribute the deeplink Once you’ve created a checkout link offer, you’ll receive a deeplink. Before sharing it with players, secure the deeplink with a signed JWT, then distribute it according to your platform or system. #### Broadcast platform If you're using a broadcast platform, such as a social media automation tool, add the deeplink to your platform’s distribution message. Make sure your JWT secret is added to the platform’s configuration settings, as described above. #### Custom distribution system If you're using a custom distribution system, you’ll need to manually generate a signed token (JWT) and append it to the deeplink. This makes the link secure and targeted for each player. To do this: 1. Create a JWT object with the following parameters and sign it using HS256 Algorithm: | Parameter | Required? | Type | Description | | - | - | :-: | - | | `playerId` | Yes | Number | Player ID. | | `originalLink` | Yes | String | Deeplink offer URL. | | `iat` | Yes | Timestamp | UNIX Timestamp in seconds when the player was redirected to the web store. | **Example code** ```js theme={"system"} import * as jwt from 'jsonwebtoken'; const secret = 'YOUR_SECRET'; // Your Deeplink JWT Secret from the Publisher Dashboard const originalLink = 'YOUR_DEEPLINK_OFFER_URL'; // The deeplink created earlier const signed = jwt.sign( { playerId: 'PLAYER_ID', iat: CREATION_TIME_IN_SECONDS, originalLink: originalLink, }, secret, { algorithm: 'HS256' }, ); ``` 2. Append the signed JWT token as a query parameter to the deeplink: ```js theme={"system"} const redirectUrl = `${originalLink}?acjwt=${signed}`; ``` 3. Distribute this `redirectUrl` to players. Always generate and sign JWTs on your backend. Never expose your Deeplink JWT Secret in client-side code. # About Daily Bonuses Source: https://docs.appcharge.com/guides/webstore/offers/daily-bonuses/about-daily-bonuses Daily Bonuses are free rewards that encourage players to visit your web store every day. Each Daily Bonus can include a sequence of reward products, with one product available to collect per day.
    ## How it works A Daily Bonus appears as a popup the first time a player enters the web store each day. The player can collect the reward or dismiss the popup and continue browsing. After the player collects or dismisses the popup, that popup disappears and isn't shown again that day. You can display a Daily Bonus badge with a countdown timer of when the bonus will be available again. Players can click the badge to view which product they can collect next. ## Daily reset Each Daily Bonus remains available until the daily reset, at 00:00 in the timezone set in the Publisher Dashboard. Learn how to [set the daily reset timezone](../../settings/configure-general-store-settings#daily-reset-timezone). The default timezone is UTC+00:00. After the daily reset, the player can collect the next available product in the sequence. ## Reward sequence Each Daily Bonus can include up to 31 reward products. Products are shown one at a time in the order you define. Whether a player collects the reward or dismisses the popup, the Daily Bonus advances to the next product in the sequence. The skipped reward isn't offered again, and the next product is shown with a locked icon and a countdown timer that indicates when it can be collected. If the player misses a day and doesn't interact with the Daily Bonus at all, the sequence restarts from the first product. After the final product in the sequence is collected, the Daily Bonus ends. You can also configure the sequence to restart automatically. For example, if the sequence ends on Day 5 and the player collects the Day 5 reward, they see the Day 1 reward again on Day 6. ## Multiple Daily Bonuses If multiple Daily Bonuses are available, the player sees each one in the web store. For example, if three Daily Bonuses are configured in the Publisher Dashboard and available to that player, all three appear on Day 1. Daily Bonus popups are shown one after another. When the player collects or dismisses the first popup, the next available popup opens. You can assign each Daily Bonus a priority to control the order in which active Daily Bonuses appear. Lower priority numbers appear first. Daily Bonuses without a priority appear last. If multiple Daily Bonuses have the same priority, the one created first appears first. For example, this table shows the priority among Daily Bonuses: | Daily Bonus | Priority | Product sequence | | - | - | - | | Daily Bonus A | 1 | Gold → Gems → Energy | | Daily Bonus B | 2 | Booster → Ticket | | Daily Bonus C | 3 | Chest | In this setup, the player sees Daily Bonus A first, then Daily Bonus B, then Daily Bonus C. Each Daily Bonus advances independently. Priority also applies across all eligible offers that use a popup modal such as Store Refresh Popups and Reward Calendars, and determines the display order. ## Example player experience Using the Daily Bonus example above, this is what the player sees if they collect every available reward: | Day | Daily Bonus A | Daily Bonus B | Daily Bonus C | | - | - | - | - | | Day 1 | Gold | Booster | Chest | | Day 2 | Gems | Ticket | No longer shown, unless configured to restart | | Day 3 | Energy | No longer shown, unless configured to restart | No longer shown, unless configured to restart | If the player dismisses a reward instead of collecting it, that reward is skipped. For example, if the player dismisses Gold on Day 1, Daily Bonus A offers Gems on Day 2. If the player misses a day and doesn't interact with Daily Bonus A at all, the sequence restarts from Gold. # Create a Daily Bonus Popup Source: https://docs.appcharge.com/guides/webstore/offers/daily-bonuses/create-a-daily-bonus This article explains how to design, create, and manage a Daily Bonus offer in the Publisher Dashboard. You can also create and update Daily Bonuses using the [Daily Bonuses API service](/../../api-reference/webstore/offers-v2/daily-bonuses/introduction). ### Design a Daily Bonus Before creating a Daily Bonus, you need to design it: 1. In the **Studio** section go to **Offers Design**, and click **Create New Offer Design**. 2. Select **Daily Bonus**. 3. Complete the following sections: * **Daily Bonus** * **Name:** Enter a name for the offer design so you can easily identify it when creating an offer. * **External ID:** Enter an ID for the design. * **Daily Bonus Design** * **Background Color**: Select a solid color or choose **Linear** to apply a gradient. * **Background Image**: Upload or select a background image. * **Badge Image**: Add an image for the badge. Configure this if you want to display a badge that players can click to view the next product available to collect, and when it will be available to collect. * **Border** * **Fill Color:** Select a solid color or choose **Linear** to apply a gradient. * **Width:** Enter the border width in px. * **Title** * **Title Name:** Enter a title for the offer. * **Color:** Select a color for the text. * **Size:** Enter a number for the text size. * **Weight:** Select a weight for the text. 4. Click **Save** to finalize the design. ### Create a Daily Bonus After designing the Daily Bonus, you can create the offer itself: 1. In the **Offers** section go to **Daily Bonus**, and click **Add New Daily Bonus**. 2. In the **Settings** tab, complete the following sections: * **General** * **Name**: Enter a name for the Daily Bonus offer. This name appears in the checkout unless you provide an alternative in the **Display Name** field. * **Display Name**: Enter a name for the Daily Bonus offer to display in the checkout. This value overrides the one in the **Name** field. If left blank, the value from the Name field is displayed in the checkout. * **Description**: Provide a description for the Daily Bonus. * **External ID**: Enter an ID for the Daily Bonus. * **Offer Design**: Select the design you want to use from the drop-down menu. * **Priority**: Enter a priority number. Lower numbers appear first when multiple Daily Bonuses are available. 3. Go to the **Configuration** tab, and complete the following sections: * **Segments** * **Segment Name**: Enter segment names to display the offer to specific groups of players. * **Products**: Add the products in the order you want them to appear in the Daily Bonus sequence. * **Product Name**: Enter a product name. * **Product Type**: Choose how the product is displayed within the Daily Bonus: * **Main:** A primary product displayed prominently in the Daily Bonus. * **Sub**: A secondary product displayed in a smaller layout. Sub products can appear on their own or under a Main product. * **Web Only**: Select this option to promote items that are available only in the Web Store. To get access to this feature, contact your account manager. * **Quantity**: Enter the number of units of this product included in the offer. 4. Click **Add Product**. 5. To add more products, repeat the fields in the **Products** section and click **Add Product** after each one. 6. To repeat the sequence after the final product is collected, toggle on **Restart After Completion**. 7. Click **Save**. ## Edit a Daily Bonus To edit an existing Daily Bonus: 1. Go to the **Daily Bonuses** section. You’ll see a list of all your existing Daily Bonuses. 2. Click the ellipsis of the offer you want to edit, and then click **Edit**. 3. Modify the Daily Bonus as desired. 4. Click **Save** to apply changes. ## Duplicate a Daily Bonus To duplicate a Daily Bonus: 1. Go to the **Daily Bonus** section. You’ll see a list of all your existing Daily Bonuses. 2. Click the ellipsis of the offer you want to duplicate, and then click **Duplicate**. 3. Modify the Daily Bonus as desired. 4. Click **Save** to apply changes. ## Delete a Daily Bonus To delete a Daily Bonus: 1. Go to the **Daily Bonuses** section. You’ll see a list of all your existing Daily Bonuses. 2. Click the ellipsis of the offer you want to delete, and then click **Delete**. # Add a Badge Source: https://docs.appcharge.com/guides/webstore/offers/offer-design/add-a-badge This feature currently supports Bundles, Special Offers, and Rolling Offers. Badges are visual markers that highlight important offers in your web store, appearing above an offer as either an image or text. For example, you can add a “Most Popular" or "Best Value" Badge to make an offer stand out. They help emphasize top-rated items, special discounts, and limited-time promotions, guiding players toward the packages you want to promote. This article explains how to create and manage Badges in the Publisher Dashboard. Alternatively, you can create and manage Badges using the [Badges API](/../../api-reference/webstore/offer-components/badges/introduction). ## Badge types There are three types of Badges you can add to an offer: * **Emblem**: A custom Badge image that you upload. This option is ideal for creating a fully branded Badge using your game logo, icon, or stylized promotional artwork. * **Ribbon**: A text-based Badge where you define the text, text color, and background color. This Badge isn’t enabled by default. To enable this feature, contact your account manager. * **Sale**: An automatic Badge that appears when you add a product sale to an offer. It displays the sale amount and type. For example, if the product sale amount is 15 and the type is Percentage, the badge displays 15%. To customize this Badge, contact your account manager.
    ## Create a Badge To create a Ribbon or Emblem Badge: 1. In the Publisher Dashboard, go to **Studio > Badges**. 2. Click **Add New Badge**. The Badge editor opens. 3. Complete the following fields: * **Name**: A descriptive name for the Badge. * **External ID**: A Badge ID. * **Type**: Select either **Ribbon** or **Emblem**. * **Ribbon**: Enter a text value and select a background and text color. * **Emblem**: In the **Image** field, upload a 1:1 image file, or select an existing image from dropdown. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. 4. Click **Save**. Your new Badge is added to the Assets Library, and is now able to be assigned to an offer. ## Assign a Badge to an offer Once you’ve created a Ribbon or Emblem Badge, you can assign it to a Bundle, Special Offer, or Rolling Offer. Sale Badges are automatically added when you configure a product sale. To assign a Badge to a Bundle or Special Offer: 1. Go to **Offers** and click on **Bundles** or **Promotions**. 2. Create a new offer, or select the offer you want to assign the Badge to. 3. In the **Badges** field, click the drop-down menu to select the Badge you want to assign. 4. Under **Sale & Discounts** configure a product sale: * **Min Product Sale**: Enter a sale value for the product. Setting this field adds a Sale Badge to your offer. * **Type**: Click the drop-down menu to select **Percentage**, **Multiplier**, or **Fix Amount**. 5. Click **Save**. To assign a Badge to a Rolling Offer: 1. Go to **Offers > Rolling**. 2. Create a new offer, or select the offer you want to assign the Badge to. 3. Click on the **Configuration** tab and in the **Offer** field deselect the **Set as Free** box. The fields for the Badge settings will appear below. 4. Fill out the following fields: * **Min Product Sale:** Enter a sale value to automatically add a Sale Badge. * **Emblem Badge**: Click the drop-down menu to select the Badge you want to assign. 5. Click **Save**. # Add a Product Source: https://docs.appcharge.com/guides/webstore/offers/offer-design/add-a-product Products are the game items that players receive when collecting or purchasing an offer, such as coins, treasure chests, or swords. Products are created independently and then added to offers, allowing the same Product to be reused across multiple offers. This article explains how to create and manage Products for your offers in the Publisher Dashboard. Alternatively, you can create and manage Products using the [Products API](/../../api-reference/webstore/offer-components/products/introduction).
    ## Create a Product To create a Product: 1. In the **Studio** section, go to **Products**, and then click **Add New Product**. 2. Complete the following sections: * **General** * **Name**: Enter a name for the Product. This name appears in the checkout unless you provide an alternative in the **Display Name** field. * **Display Name**: Enter a name for the Product to display in the checkout. This value overrides the one in the **Name** field. If left blank, the value from the Name field is displayed in the checkout. * **Description**: Provide a description for the Product. * **External ID**: Enter an ID for the Product. * **Type**: Select how the product value is represented: * **Quantity**: Displays the number of units included in the offer. * **Time**: For time-based Products, this field displays how long the Product is active, measured in minutes. * **Prefix**: Enter text or numbers shown before the product value. * **Suffix**: Enter text or numbers shown after the product value. * **Font Color** * **Fill Color**: Select the color used for the product value, including any prefix or suffix characters. * **Product Assets** * **Product Image**: Upload or select an image for the Product. * **Prefix Image**: Upload or select an image that appears before the product value. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. 3. Click **Save Product**. ## Add a Product to an offer After you've created a Product, you can include it in an offer: 1. In the **Offers** section, select the offer to which you want to add a Product. For example, **Bundles**. 2. Either create a new offer, or edit an existing one by clicking the ellipsis and selecting **Edit**. 3. Scroll down to the **Products** section and complete the following fields: * **Product Name**: Select the Product you configured. * **Products Type**: Choose how the Product is displayed in the store. * **Main**: A primary Product displayed prominently in the offer. * **Sub**: A secondary Product displayed in a smaller layout. Sub Products can appear on their own or under a Main Product. * **Web Only**: Select Web Only to promote Products that are available exclusively in the Web Store. * **Quantity**: Defines the value granted by the Product in this offer. * For a **Quantity** Product, enter the number of units included. * For a **Time** Product, enter the duration the Product is active, in minutes. 4. Click **Add Product** to assign it to the offer. You'll see the Product displayed in a table at the bottom of the page. ## Edit a Product To edit an existing Product: 1. In the **Studio** section, select **Products**. You'll see a list of all your Products. 2. Click the ellipsis of the Product you want to edit, and then click **Edit**. 3. Modify the Product as needed. 4. Click **Update Product** to apply your changes. ## Duplicate a Product To duplicate a Product: 1. In the **Studio** section, select **Products**. You'll see a list of all your Products. 2. Click the ellipsis of the Product you want to duplicate, and then click **Duplicate**. 3. Modify the Product as needed. 4. Click **Update Product** to apply your changes. ## Delete a Product To delete a Product: 1. In the **Studio** section, select **Products**. You'll see a list of all your Products. 2. Click the ellipsis of the Product you want to delete, and then click **Delete**. # Design an Offer Source: https://docs.appcharge.com/guides/webstore/offers/offer-design/design-an-offer Field description: | Field name | Description | | - | - | | Name | The name of the Offer UI. The link to the offer configuration will be done by name or internal ID | | Type | If the UI is for a store tile or for a promotion | | Background image | What is the background image of the offer | | BG color | Relevant for bundles only - what’s the background color of the offer | | Title | Not mandatory - offer’s title | | Color | Offer title’s header | | Size | Offer title’s size - currently is not editable | | Weight | Offer title’s weight - currently is not editable | If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. # About Progress Bars Source: https://docs.appcharge.com/guides/webstore/offers/progress-bars/about-progress-bars A Progress Bar is a type of offer in the web store that works alongside other offers to encourage players to purchase additional offers or collect free rewards. Players progress toward the bar's targets by purchasing or collecting offers you've assigned to contribute. Each contributing offer adds a configured number of accumulated items to the target, which are represented as points. Each target has its own configured reward. By making advancement visible and goals easy to understand, the Progress Bar reinforces a sense of achievement at every stage. As a monetization tool, it keeps players motivated and supports long-term engagement.
    ## How it works Progress Bars support two types, **Classic** and **Milestones**. You can configure multiple targets for either type. The type determines what a target is called and how targets are displayed on the bar. When a player completes a target, they receive their reward and a free order is created. The [Grant Award Callback](/api-reference/checkout/awards/grant-award-callback) is called and [order events](/api-reference/events/v2/introduction) are triggered. After the player completes all targets, the Progress Bar and Points Ribbons are removed from the web store. If you're using the [Web Store Personalization API service](/api-reference/webstore/personalization/introduction), you can customize each target's reward by specifying the product and quantity players receive upon completion. ### Classic Progress Bar The target is called a mission. You can configure multiple missions, but the bar displays one mission at a time. Players advance through them sequentially. When a mission is completed and additional missions are available, the Progress Bar automatically transitions to the next mission. The bar visually clears and begins filling again to represent progress toward the new mission's point requirement. This reset is visual only and doesn't remove any earned points. The next mission is revealed with an animation, while Points Ribbons remain visible on contributing offers. If a single purchase completes more than one mission, the bar fill animation continues through each mission without pausing, repeating this transition after each completion.
    ### Milestone Progress Bar The target is called a milestone. You can configure multiple milestones, and the bar displays all of them at once. Players can see every reward ahead of them, including the grand reward at the final milestone. If one purchase earns enough points to pass multiple milestones, the bar fill animation continues through each milestone without pausing. A completion mark is applied to each passed milestone.
    ## Assign Progress Bar points to offers Using the Publisher Dashboard or the [Offers V2 API](/api-reference/webstore/offers-v2/introduction), choose which offers contribute points toward the Progress Bar and how many points each offer grants. In the web store, contributing offers display a Points Ribbon showing how many points players earn when collected or purchased. Daily Bonuses, Reward Calendars, and Checkout Link offers don't contribute points toward the Progress Bar. ## Rollover points Points earned beyond the current target's requirement roll over to the next target. This ensures no progress is lost and that completing one target contributes to the next. If no targets remain, the Progress Bar is considered complete. If you later add a new target, any rollover points are automatically applied toward it. If a Progress Bar is deleted from the Publisher Dashboard, or if a scheduled Progress Bar ends, both the Points Ribbons and any accumulated rollover progress are permanently lost. ## Lifecycle and updates This section covers changes you can make to a Progress Bar after it has been created, including how inactivity, scheduling, and target configuration updates affect current and future player progress. ### Set a Progress Bar to inactive If you set a Progress Bar to inactive, it's removed from the web store, but player points are preserved. If the Progress Bar is later reactivated, players see it with their existing progress. ### Schedule a Progress Bar You can schedule a Progress Bar to appear during specific time periods. When scheduled, a countdown timer is displayed, creating a sense of urgency for players. When the scheduled time ends, the Progress Bar is removed from the web store. ### Update target configuration Appcharge doesn't recalculate or redistribute player progress when you update a mission or milestone, such as changing its required points or the total number of targets. Completed targets remain completed, and players keep rewards they've already received. Appcharge doesn't grant rewards retroactively for targets the player didn't complete under the original configuration. The point requirement for a target is locked when the player has completed it or is in the middle of it. Only targets the player hasn't reached use the updated configuration. If the Progress Bar is inactive when you update it, the same rules apply when it becomes active again. #### Add or remove targets When you change the total number of targets, the player continues their current mission or milestone. Appcharge doesn't move the player backward or recalculate progress. If you reduce the number of targets so that fewer targets remain than the target the player is currently on: * Their current mission or milestone becomes the final target. * The Progress Bar ends after the player completes that mission or milestone. * The player doesn't receive rewards for removed missions or milestones. If you add a target at an index the player has already passed, the player doesn't receive rewards for the inserted mission or milestone. If you add a target after the player's current position, the new target uses the updated configuration when the player reaches it. #### Update required points If you update the number of required points, the same no-recalculation rules apply. For example, a player has earned 25 total points with this original sequence: * **Mission/Milestone 1 (10 points):** Completed, and the player received the reward. * **Mission/Milestone 2 (20 points):** Active, with 15 of 20 points earned. * **Mission/Milestone 3 (30 points):** Not yet reached. If you update the mission or milestone requirements to 10, 10, and 10 points: * **Mission/Milestone 1:** Remains completed, and the player keeps the reward. * **Mission/Milestone 2:** Retains its original 20-point requirement and the player's existing progress of 15 points. * **Mission/Milestone 3:** Uses the updated 10-point requirement when the player reaches it. The player remains in Mission/Milestone 2 with 15 of 20 points. No additional rewards are granted, and no progress is recalculated. ## Monitor Progress Bars You can track Progress Bars by: * Viewing all Progress Bars in **Offers > Progress Bar** in the Publisher Dashboard, where you can filter by external ID and status. * Setting up [webhook events](/api-reference/events/v2/introduction) for real-time updates on player activity, offer interactions, and orders. Learn how to [create and manage a progress bar](./create-and-manage-a-progress-bar). # Create and Manage a Progress Bar Source: https://docs.appcharge.com/guides/webstore/offers/progress-bars/create-and-manage-a-progress-bar This article explains how to design, create, and manage a Progress Bar for your web store in the Publisher Dashboard. Alternatively, you can design a Progress Bar using the [Progress Bar Offer Design API](/../../api-reference/webstore/offer-components/offer-designs/progress-bars/introduction) and create and update it via the [Progress Bar API](/../../api-reference/webstore/offers-v2/progress-bars/introduction). ## Design a Progress Bar Before creating a Progress Bar, you need to design it: 1. In the sidebar menu, go to **Studio > Offers Design**, and then click **Create New Offer Design**. 2. Select **Progress Bar**. 3. Complete the following sections: * **Progress Bar** * **Progress Bar Type:** Use the drop-down menu to select which progress bar type you want to create, **Classic** or **Milestones**. The preview and some fields in the **Progress Bar Design** section below update according to the selected type. * **Name:** Enter a descriptive name for the design. * **External ID:** Enter an ID for the design. * **Progress Bar Frame** * **Background Color:** Use the drop-down menu to select a color for the frame background. Alternatively, you can upload a background image for the frame in the **Background Image** field below. * **Background Opacity:** Enter a number for the background color opacity percentage. This field doesn't apply if you have a background image. * **Frame Radius:** Enter a number for the rounding percentage of the frame radius. * **Background Image:** Upload an image for the frame background. Alternatively, you can select a background color for the frame in the **Background Color** field above. * **Title** * **Title Name:** Enter a name for the Progress Bar title. * **Title Font Weight:** Use the drop-down menu to select a font weight for the title, **Regular**, **Medium**, or **Bold**. * **Title Font Size:** Enter a number for the title's font size. * **Font Color:** Use the drop-down menu to select a font color for the title. * **Subtitle** * **Subtitle:** Enter a name for the Progress Bar subtitle. * **Subtitle Font Weight:** Use the drop-down menu to select a font weight for the subtitle, **Regular**, **Medium**, or **Bold**. * **Subtitle Font Size:** Enter a number for the subtitle's font size. * **Font Color:** Use the drop-down menu to select a font color for the subtitle. * **Progress Bar Design** * **Font Color:** Use the drop-down menu to select a font color for the text in the progress bar, such as the milestone points indicator text and the **Ends In** timer. This color doesn't include the title and subtitle. * **Bar Fill Color:** Use the drop-down menu to select a color used for filling the bar as progress is made. * **Border Color:** Use the drop-down menu to select a color for the bar's border. * **Bar Background Color:** Use the drop-down menu to select a color for the bar's background. * **Bar Radius:** Enter a number for the rounding percentage of the bar radius. * **Border Width:** Enter a number for the width of the bar's border. * **Tooltip Background Color:** Use the drop-down menu to select a background color for the milestone's tooltip. The tooltip displays when a player clicks a milestone to view its rewards. Relevant only for type **Milestones**. * **Accumulated Item Image:** Upload an image for the accumulated item. * **Accumulated Item Ribbon Image:** Upload an image for the ribbon displayed on contributing offers showing how many accumulated items the offer contributes. * **Header Image:** Upload an image for the Progress Bar header. * **Milestone Completed Icon Image:** Upload an image for the checkmark icon displayed on a milestone when completed. Relevant only for type **Milestones**. 4. Click **Save** in the top-right corner to finalize the design. ## Create a Progress Bar Currently you can only have one Progress Bar per web store. After designing a Progress Bar, you can create the offer: 1. In the sidebar menu, go to **Offers > Progress Bar**, and then click **Create New Progress Bar**. 2. In the **Settings** tab, complete the following sections: * **General** * **Bar External ID:** Enter an ID for the Progress Bar. * **Bar Name:** Enter a name for the Progress Bar. * **Bar Offer Design:** Use the drop-down menu to select the design you want to use. Make sure you select a classic design type if you want to create a Classic progress bar, and a milestones design type if you want to create a Milestones progress bar. The **Configuration** tab and preview update according to the design you select. * **Segments** * **Segment Name:** Enter segment names to display the offer to specific groups of players. 3. Go to the **Configuration** tab. 4. If you selected a classic progress bar design, configure the Classic progress bar: * **Mission 1** * **Bar Size:** Enter the number of accumulated items (points) required to complete the mission. The mission size matches what players see filling the bar. * **Product**: Use the drop-down menu to select a product to add to the mission. * **Amount**: Enter a number for the product quantity. * **Add:** Click to add additional missions. The fields are the same as in Mission 1. 5. If you selected a milestones progress bar design, configure the Milestones progress bar: * **Milestone 1 (Final Reward)** * **Bar Size**: Enter the number of accumulated items (points) required to reach the milestone. This is each milestone's point requirement, not the full length of the visible bar because the bar displays all milestones at once. * **Product**: Use the drop-down menu to select a product to add to the milestone. This first milestone configuration represents the grand reward. * **Product Type**: Use the drop-down menu to select the product type: * **Main**: A primary product displayed prominently in the offer. * **Sub**: A secondary product displayed in a smaller layout. Sub products can appear on their own or under a Main product. * **Web Only**: Select **Web Only** to promote items that are available exclusively in the Web Store. * **Amount**: Enter a number for the product quantity. * **Add milestone:** Click to add additional milestones. The fields are the same as in Milestone 1. 6. Go to the **Schedule** tab, and select **Permanent** to keep the Progress Bar as a permanent offer in your web store, or **Schedule** to display it for a limited time. * **Schedule** * **Pick a date:** Use the calendar modal to select the date range and time for the Progress Bar to be active, and then click **Apply**. * **Notes:** Add any relevant notes. * **Add Appearance:** Click to add the appearance in the web store. Repeat the schedule fields to add more appearances. 7. Click **Save** to complete the Progress Bar creation process. ## Edit a Progress Bar To edit an existing Progress Bar: 1. In the sidebar menu, go to **Offers > Progress Bar** to view your existing Progress Bars. 2. Click the ellipsis next to the Progress Bar you want to edit, and then click **Edit**. 3. Modify the Progress Bar as needed. 4. Click **Save** to apply the changes. If you update the **Bar Size** field after players have already earned points, Appcharge doesn't recalculate or redistribute player progress. Completed missions or milestones remain completed, and players keep any rewards they already received. Changes apply only to missions or milestones the player hasn't yet reached, and rewards aren't granted retroactively. Learn more about [updating required points](./about-progress-bars#update-required-points) and [how configuration changes affect player progress](./about-progress-bars#update-target-configuration). ## Duplicate a Progress Bar To duplicate a Progress Bar: 1. In the sidebar menu, go to **Offers > Progress Bar** to view your existing Progress Bars. 2. Click the ellipsis next to the Progress Bar you want to duplicate, and then click **Duplicate**. 3. Edit the duplicated Progress Bar as desired. 4. Click **Save** to apply the changes. ## Deactivate a Progress Bar To deactivate a Progress Bar: 1. In the sidebar menu, go to **Offers > Progress Bar** to view your existing Progress Bars. 2. Click the ellipsis next to the Progress Bar you want to deactivate, and then click **Deactivate**. 3. The Progress Bar is now marked as **Inactive** and hidden from the web store. ## Activate a Progress Bar A new Progress Bar is active by default. You can also activate a previously deactivated one: 1. In the sidebar menu, go to **Offers > Progress Bar** to view your existing Progress Bars. 2. Click the ellipsis next to the Progress Bar you want to activate, and then click **Activate**. 3. The Progress Bar now appears in the web store. ## Delete a Progress Bar To delete a Progress Bar: 1. In the sidebar menu, go to **Offers > Progress Bar** to view your existing Progress Bars. 2. Click the ellipsis next to the Progress Bar you want to delete, and then click **Delete**. 3. The Progress Bar is permanently removed from the web store. # About Reward Calendars Source: https://docs.appcharge.com/guides/webstore/offers/reward-calendars/about-reward-calendars A Reward Calendar is a 7-day calendar popup that shows players a week's worth of upcoming rewards and lets them collect the current day's reward. Players progress by returning to the web store on consecutive days. Reward Calendars encourage players to return each day by showing what they can earn now, what they can earn later, and when the next reward becomes available.
    ## How it works Each Reward Calendar displays 7 days of rewards. You can configure up to 10 weeks, and each week contains its own 7-day reward sequence. Each day has its own reward. Days 1-6 are sub rewards displayed as regular calendar day tiles. Day 7 is the main reward and appears as a larger, wider featured reward tile. A reward can include one or more products. The web store displays a persistent Reward Calendar badge that players can click to open the calendar, view upcoming rewards, and see when the next reward becomes available. You can configure whether the calendar popup opens automatically when a player becomes eligible for a reward, or only after the player clicks the badge. The badge remains visible in both modes. When a player is eligible for the next reward, the current day appears as collectible in the calendar. If the player isn't eligible yet, the Reward Calendar appears as a badge with a countdown timer for the next available reward. ## Reward collection You can choose how players collect daily rewards: * **Forced collection:** The player must collect the reward and can't dismiss the popup. * **Manual collection:** The player can collect the reward or close the popup and collect it later that day. After a reward is collected, the calendar shows that day as collected and locks upcoming rewards. The badge then shows a countdown timer for the next day's reward. Players can still click the badge to open the calendar and preview upcoming rewards. If a player closes the popup without collecting the reward, the badge remains collectible. The player can click the badge to open the calendar and collect the current day's reward. ## Calendar progression Reward Calendars support multi-week progression. After a player completes Week 1, the player advances to Week 2, and so on until the final configured week. After the player completes all configured weeks, you can choose whether the calendar restarts from Week 1 or ends for that player. ## Missed day reset behavior If a player misses a day, the calendar resets according to the reset behavior you configure: * **Complete Reset:** The player restarts from Week 1, Day 1. * **Weekly Reset:** The player restarts from Day 1 of the current week. For example, if a player is on Week 3, Day 5 and misses a day: * With **Complete Reset**, the player returns to Week 1, Day 1. * With **Weekly Reset**, the player returns to Week 3, Day 1. ## Daily reset Each day's reward in the Reward Calendar remains available and collectible until the daily reset, at 00:00 in the timezone set in the Publisher Dashboard. Learn how to [set the daily reset timezone](../../settings/configure-general-store-settings#daily-reset-timezone). The default timezone is UTC+00:00. After the daily reset, the player can collect the next day's reward in the calendar. ## Priority You can assign each Reward Calendar a priority to control the order in which active Reward Calendars appear. Lower priority numbers appear first. If multiple Reward Calendars have the same priority, the one created first appears first. Priority also applies across all eligible offers that use a popup modal such as Store Refresh Popups and Daily Bonus offers, and determines the display order. ## Key features * **7-day calendar:** Show players a full week of rewards. * **Multi-week progression:** Configure up to 10 weeks of daily rewards. * **Persistent badge:** Keep the calendar accessible from the web store. Learn how to [create and manage a Reward Calendar](./create-and-manage-a-reward-calendar). # Create and Manage a Reward Calendar Source: https://docs.appcharge.com/guides/webstore/offers/reward-calendars/create-and-manage-a-reward-calendar This article explains how to design, create, and manage a Reward Calendar for your web store in the Publisher Dashboard. You can also create and update Reward Calendars using the [Reward Calendars API service](/../../api-reference/webstore/offers-v2/reward-calendars/introduction). ## Design a Reward Calendar Before creating a Reward Calendar, you need to design it: 1. In the **Studio** section, go to **Offers Design**, and click **Create New Offer Design**. 2. Select **Reward Calendar**. 3. Complete the following sections: * **Reward Calendar** * **Name:** Enter a descriptive name for the design. * **External ID:** Enter an ID for the design. * **Main Design** * **Header Image:** Upload an optional image displayed at the top of the calendar. * **Collectible Badge Image:** Upload or select an image for the badge shown when a reward is available to collect. * **Locked Badge Image:** Upload or select an image for the badge shown when a reward is locked. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. * **Sub Design** * **Background Color:** Select a background color for the calendar days. * **Day Font Color:** Select a color for the day text. * **Sub Reward Background Image:** Upload an optional background image for sub rewards, which are displayed as regular calendar day tiles. If no image is uploaded, the **Background Color** is used. * **Main Reward Background Image:** Upload an optional background image for the main reward, which is displayed as a larger, wider featured tile. If no image is uploaded, the **Background Color** is used. * **Collect Icon Image:** Upload or select the icon shown on days where the rewards have been collected. * **Locked Icon Image:** Upload or select the icon shown on days where the rewards are locked. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. 4. Click **Save** to apply changes. ## Create a Reward Calendar After designing a Reward Calendar, you can create the offer: 1. In **Offers**, go to **Reward Calendars** and click **Create New Reward Calendar**. 2. In the **Settings** tab, complete the following sections: * **General** * **Name:** Enter a name for the Reward Calendar. * **External ID:** Enter an ID for the Reward Calendar. * **Priority:** Enter a priority number. Lower numbers appear first when multiple Reward Calendars are available. * **Offer Design:** Select the design you want to use from the drop-down menu. * **Segments** -**Segment Name:** Enter segment names to display the offer to specific groups of players. 3. Go to the **Configuration** tab. **Week 1** is added by default. You must configure all days in Week 1 before adding another week. You can configure up to 10 weeks. 4. Click **Day 1** to open the modal and configure the first reward. 5. From the drop-down list, select a product to add, and then enter the number of units included in the offer. To add another product for that day, click **Add Product** and repeat this step. When done, click **Continue to the next day** until you've added rewards for the first 6 days. 6. On the 7th day, from the drop-down list, select a product to add. Then enter the number of units included in the offer, and click **Add Product**. To add another product for that day, repeat this step. When done, close the modal. 7. Click **+ Week** and repeat steps 4-6 to configure rewards for another week, or click **Save** to save your changes. 8. In the **Offer Behavior** tab, configure the calendar rules: * **Restart After Completion:** Choose whether the calendar restarts from Week 1 after the player completes all configured weeks. * **Missed Reward Reset:** Choose what happens when a player misses a day: * **Complete Reset:** Player progress resets to Week 1, Day 1. * **Weekly Reset:** Player progress resets to Day 1 of the current week. * **Pop-Up Trigger:** Choose how the calendar popup opens: * **Automatic:** Open automatically when a reward becomes available. * **On Click:** Open only when the player clicks the Reward Calendar badge. * **Reward Collection:** Choose how players collect daily rewards: * **Forced Collection:** When the Reward Calendar popup is displayed, the player must click the **Collect** button to collect the daily reward. The popup closes automatically after collection. * **Manual Collection:** When the Reward Calendar popup is displayed, the player can collect the daily reward using the **Collect** button, or close the popup. The player can then click the corresponding Reward Calendar badge to collect the reward at another time that day. 9. Click **Save** in the top-right corner to save your changes. ## Edit a Reward Calendar To edit an existing Reward Calendar: 1. Go to the **Reward Calendars** section. 2. Click the ellipsis next to the Reward Calendar you want to edit, and then click **Edit**. 3. Modify the Reward Calendar as needed. 4. Click **Save** to apply the changes. ## Duplicate a Reward Calendar To duplicate a Reward Calendar: 1. Go to the **Reward Calendars** section. 2. Click the ellipsis next to the Reward Calendar you want to duplicate, and then click **Duplicate**. 3. Modify the duplicated Reward Calendar as needed. 4. Click **Save** to create the new Reward Calendar. ## Deactivate a Reward Calendar To deactivate a Reward Calendar: 1. Go to the **Reward Calendars** section to view your existing Reward Calendars. 2. Click the ellipsis next to the Reward Calendar you want to deactivate, and then click **Deactivate**. 3. The Reward Calendar is now marked as **Inactive** and hidden from the web store. ## Activate a Reward Calendar A new Reward Calendar is active by default. You can also activate a previously deactivated one: 1. Go to the **Reward Calendars** section to view your existing Reward Calendars. 2. Click the ellipsis next to the Reward Calendar you want to activate, and then click **Activate**. 3. The Reward Calendar now appears in the web store. ## Delete a Reward Calendar To delete a Reward Calendar: 1. Go to the **Reward Calendars** section. 2. Click the ellipsis next to the Reward Calendar you want to delete, and then click **Delete**. 3. The Reward Calendar is permanently removed from the web store. # About Rolling Offers Source: https://docs.appcharge.com/guides/webstore/offers/rolling-offers/about-rolling-offers A rolling offer is a dynamic promotion that allows players to progressively unlock offers. Each unlocked offer reveals the next, building anticipation and engagement. Rolling offers encourage repeat interactions and increase revenue.
    ## How it works Rolling offers appear in a sequence. Players unlock offers one at a time by claiming or purchasing them. As an offer is unlocked, the next one is revealed. Each rolling offer has a number representing the priority. If you have multiple rolling offers, only the one with the highest priority will be shown in the web store. Rolling offers with the same priority number will be sorted by created date in ascending order, meaning the earliest created offer will appear first. Once a player completes a rolling offer by purchasing all sub offers, the next rolling offer from the sorted list is displayed. These offers are time sensitive and scheduled. A countdown timer shows how long the current appearance remains active. If players don't unlock all offers before the timer expires, the sequence resets. This encourages frequent engagement to avoid missing out on offers. ![](https://files.readme.io/838d271bd8dbf0103aefbbcf481913a12c7f78950631688b8cc7988005a21025-1.gif) ## Key features * **Customizable design:** Modify the design of main and sub offers to match your needs. * **Timed appearances:** Each appearance has a countdown timer to track its remaining time. ## Monitor rolling offers You can track rolling offers by: * Viewing all rolling offers in the **Rolling** section of the Publisher Dashboard, where you can filter by SKU, name, or number of sub offers. * Setting up webhooks for real-time updates on player activity and offer interactions. Learn how to [create and manage rolling offers](./create-and-manage-a-rolling-offer). # Create and Manage a Rolling Offer Source: https://docs.appcharge.com/guides/webstore/offers/rolling-offers/create-and-manage-a-rolling-offer This article explains how to design, create, and manage a Rolling Offer for your web store in the Publisher Dashboard. Alternatively, you can create and update a Rolling Offer using the [Rolling Offer API](/../../api-reference/webstore/offers-v2/rolling-offers/introduction). ## Design a Rolling Offer Before creating a Rolling Offer, you need to design it: 1. In the **Studio** section go to > **Offer Designs** and click **Add New Design**. 2. In the **Type** field, select **Rolling Offer** from the drop-down menu. The form will update to display all fields relevant to a Rolling Offer. 3. Complete the following sections: * **Offer Settings** * **Name:** Enter a descriptive name for the offer. * **External ID:** Enter an ID for the offer. * **Main Offer Design** * **Vertical Image:** Upload or select a background image for the vertical Rolling Offer layout as displayed in mobile view. * **Horizontal Image:** Upload or select a background image for the horizontal Rolling Offer layout as displayed in desktop view. * **Offer Background Color:** Select a background color. * **Background Opacity:** Enter a transparency level for the background color. * **Arrows Default Color:** Choose the color used for the arrows between sub offers when a custom arrow image is not provided. * **Arrows Image:** Upload a custom image to replace the default arrow between sub offers. We recommend a 1:1 ratio image that's 24px by 24px. If you don't upload an image, Appcharge uses the **Arrows Default Color**. * **Offer Border:** Select a color for the border around sub offer tiles. * **Offer Border Width:** Enter the width of the border. * **Offer Header:** Upload an image header. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. * **Sub Offer Design** * **Offers Background Image:** Upload a background image. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. * **Offers Background Color:** Select a background color. * **Collect Text:** Enter the text displayed at the bottom of sub offers that award a free item, such as “Collect” or “Free.” 4. Click **Save** to apply changes. ## Create a Rolling Offer After designing a Rolling Offer, you can now create the offer: 1. Go to the **Rolling** section and click **Add New Rolling Offer**. 2. In the **Settings** tab, provide the required details, including the Rolling Offer priority with lower numbers indicating higher priority. * If you have multiple Rolling Offers, only the one with the highest priority will be shown in the web store. Rolling offers with the same priority number will be sorted by created date in ascending order, meaning the earliest created offer will appear first. * Once a player completes a Rolling Offer by purchasing all sub offers, the next Rolling Offer from the sorted list is displayed. 3. In the **Configuration** tab, you can add up to 50 sub offers to your rolling offer. You must have a minimum of 2. To add more sub offers, click **Add Offer**. You can also duplicate or delete a sub offer by clicking the ellipsis in the offer's modal, and then **Duplicate**. 4. Set the price for each sub offer. The default is free (\$0). To set a price, uncheck the **Set as Free** box and enter a price. 5. This step is only relevant if you have a Progress Bar offer configured. Define how many points the Rolling Offer adds to a Progress Bar when it is collected or purchased. * **Bar ID**: ID of the Progress Bar this offer to contributes to. * **Bar Points**: Number of points awarded toward the Progress Bar. 6. You can apply the following discounts: * **Main Product Sale:** If a sub offer contains only 1 product, you can offer more quantity at the same price. * **Price Discount:** Apply a discount on the total price of the sub offer. 7. Add 1-3 products per sub offer. 8. After creating your sub offers, go to the **Schedule** tab to set the start and end times of the Rolling Offer, and then click **Add Appearance**. You must have at least 1 appearance. Click the ellipsis next to an appearance to edit or delete. 9. Click **Save** to complete the Rolling Offer creation process. ## Edit a Rolling Offer To edit an existing Rolling Offer: 1. Go to the **Rolling** section. You'll see a list of all your existing Rolling Offers. 2. Click the ellipsis of the offer you want to edit, and then click **Edit**. 3. Modify the Rolling Offer as desired. 4. Click **Save** to apply changes. ## Duplicate a Rolling Offer To duplicate a Rolling Offer: 1. Go to the **Rolling** section. You'll see a list of all your existing Rolling Offers. 2. Click the ellipsis of the offer you want to duplicate, and then click **Duplicate**. 3. Modify the Rolling Offer as desired. 4. Click **Save** to apply changes. ## Delete a Rolling Offer To delete a Rolling Offer: 1. Go to the **Rolling** section. You'll see a list of all your existing Rolling Offers. 2. Click the ellipsis of the offer you want to delete, and then click **Delete**. # About Special Offers Source: https://docs.appcharge.com/guides/webstore/offers/special-offers/about-special-offers Special Offers are promotions in your web store that can be available permanently or scheduled for specific time periods. They are commonly used to highlight high-impact deals, seasonal offers, or limited-time promotions. You can design Special Offers to match your brand's visual elements and showcase products and discounted pricing. Urgency cues such as timers or purchase limits help drive conversions. When multiple Special Offers are active, they are displayed in a slideshow to maintain a clean browsing experience across devices.
    ## How it works Special Offers are configured in the Publisher Dashboard and can be set to display in one of the following ways: * **Permanent**: Keep the offer available in the web store at all times. Special Offers are permanent by default. * **Intervals**: Set the offer to appear at regular intervals such as daily, weekly, or monthly. * **Schedule**: Set start and end dates to define when the offer appears. When the period ends, the offer is hidden until the next scheduled appearance. ## Key features * **Flexible scheduling**: Run limited-time promotions with defined start and end times and repeat intervals. * **Player targeting**: Show offers to specific player segments. * **Offer limits**: Specify how many times a player can purchase each Special Offer. * **Merchandising tools**: Add Badges and configure how sales and discounts are displayed. * **Offer composition**: Build offers with one or more products, including support for Main and Sub product layouts and web-only items. ## Monitor Special Offers You can manage and review Special Offers by: * Viewing all Special Offers in the Promotions section of the Publisher Dashboard, where you can filter by name or ID. * Setting up webhooks for real-time updates on player activity and offer interactions. Learn how to [Create and Manage a Special Offer](/../../guides/webstore/offers/special-offers/create-and-manage-a-special-offer). # Create and Manage a Special Offer Source: https://docs.appcharge.com/guides/webstore/offers/special-offers/create-and-manage-a-special-offer This article explains how to design, create, and manage a Special Offer for your web store in the Publisher Dashboard. Alternatively, you can create and update a Special Offer using the [Special Offers API service](/../../api-reference/webstore/offers-v2/special-offers/introduction). ## Design a Special Offer Before creating a Special Offer, you need to design it: 1. In the **Studio** section, go to **Offer Design** and click **Add New Design**. 2. Complete the following sections: * **Offer Settings** * **Name**: Enter a descriptive name for the design. * **Type**: Select Special Offer from the drop-down menu. The form updates to display all fields relevant to a Special Offer. * **External ID**: Enter an ID for this design. * **Free Offer Default Text**: Enter the text that you want to appear on offers marked as “free” (optional). * **Offer Assets** * **Background Image**: Upload or select a background image. * **Background Color**: Select a solid color or choose **Linear** to apply a gradient. * **Button Suffix Badge**: Add an image or JSON animation to highlight your call-to-action button. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. To get access to this feature, contact your account manager. * **Title**: Configure the appearance of the offer title. * **Title Text**: Enter the text shown in the offer. * **Color**: Select the title color. * **Size**: Choose the font size. * **Weight**: Select the font weight. 3. Click **Save** to finalize the design. ## Create a Special Offer After designing the Special Offer you can create the offer itself: 1. In **Offers**, go to **Promotions** and click **Add New Promotion**. 2. In the **Settings** tab complete the following fields: * **General** * **Name**: Enter a name for the Special Offer. This name appears in the checkout unless you provide an alternative in the **Display Name** field. * **Display Name**: Enter a name for the Special Offer to display in the checkout. This value overrides the one in the **Name** field. If left blank, the value in the **Name** field is displayed in the checkout. * **Description**: Provide a description for the offer. * **External ID**: Enter an ID for the offer. * **Offer Design**: Select the design you created from the drop-down menu. * **Section**: Choose where the Special Offer appears in the store. * **Price**: Enter a price for the offer. * **Set as Free**: Select this option to display the **Free Offer Default Text** defined in the design. * **Segments**: Enter the segment names to display the offer to specific groups of players. * **Badges**: Select a Badge from the drop-down menu to help highlight the offer. * **Sale & Discounts** * **Min Product Sale**: Enter a discount value for the product. Setting this field adds a Sale Badge to your offer. * **Type**: Click the drop-down menu to select the discount type, **Percentage**, **Multiplier**, or **Fixed Amount**. * **Advanced Pricing & Discounts**: Highlight a discount by showing both the full and discounted price. * **Crossed Price**: Enter the original full price. * **Price Discount**: Enter the discount amount that reduces the price. * **Progress Bar** This section is only relevant if you have a Progress Bar offer configured. Define how many points the Special Offer adds to a Progress Bar when it is collected or purchased. * **Bar ID**: ID of the Progress Bar this offer to contributes to. * **Bar Points**: Number of points awarded toward the Progress Bar. * **Products**: To add products to the Special Offer, configure the fields below, and then click **Add Product**. You’ll see the products displayed in a table at the bottom of the page. * **Product Name**: Select a product to add from the drop-down list. * **Product Types**: Choose how the product is displayed in the store: * **Main**: A primary product displayed prominently in the offer. * **Sub**: A secondary product displayed in a smaller layout. Sub products can appear on their own or under a Main product. * **Web Only**: Select **Web Only** to promote items that are available exclusively in the Web Store. To get access to this feature, contact your account manager. * **Quantity**: Enter the number of units of this product included in the offer. When multiple Special Offers are active, they are displayed in a slideshow. On mobile devices, this occurs when there is more than one offer, and on desktop when more than three offers are available. 3. At the top of the page click the **Schedule** tab to schedule the offer to appear at specific dates and times. Scheduling an offer is optional and only needed if you want the offer to refresh periodically. 4. Schedule the Special Offer as follows: * **Availability**: Enter a number representing how many times a player can purchase this offer. * **Hide Availability**: Select this option to hide the offer's availability text in the web store. If unselected, and **Availability** is set to `5`, the web store displays `Available 5/5`. When a player collects or purchases the offer, the displayed availability decreases, for example to `Available 4/5`. * Select one of the following: * **Permanent**: Keep the offer permanently available in the web store. Note that Special Offers are **Permanent** by default. * **Intervals**: Schedule how often the offer is displayed. * **Repeat**: Set the desired frequency, Every Day, Every Week, or Every Month. * **Hour**: Set the time of day you want the offer to be displayed. * **Schedule**: Set a time frame for when the offer begins and ends. * **Pick a Date**: Choose a start and end date for the Special Offer. An **Interval** box will appear displaying the number of days until the end of the Special Offer. * **Notes**: A free text box where you can include internal notes. * **Add Appearance**: Click **Add Appearance** to save the new schedule and to add additional schedules, if needed. You’ll see the saved schedules displayed in a table at the bottom of the page. 5. Click **Save** to create the Special Offer. ## Edit a Special offer To edit an existing Special Offer: 1. Go to the **Promotions** section. You’ll see a list of all your existing Special Offers. 2. Click the ellipsis of the offer you want to edit, and then click **Edit**. 3. Modify the Special Offer as desired. 4. Click **Save** to apply changes. ## Duplicate a Special Offer To duplicate a Special Offer: 1. Go to the **Promotions** section. You’ll see a list of all your existing Special Offers. 2. Click the ellipsis of the offer you want to duplicate, and then click **Duplicate**. 3. Modify the Special Offer as desired. 4. Click **Save** to apply changes. ## Delete a Special Offer To delete a Special Offer: 1. Go to the **Promotions** section. You’ll see a list of all your existing Special Offers. 2. Click the ellipsis of the offer you want to delete, and then click **Delete**. # About Triggered Popups Source: https://docs.appcharge.com/guides/webstore/offers/triggered-popups/about-triggered-popups Triggered popups are time-sensitive offers displayed as on-screen overlays when a specific action occurs in the player journey. Use them to present targeted, high-value offers when a player completes a purchase or refreshes the store. Triggered popups can be configured as paid offers or free rewards. ## How it works Triggered popups appear when their trigger conditions are met. You can control when they appear using frequency, scheduling, cooldowns, and priority, depending on the trigger type. When a popup appears, the player can collect or purchase the offer, or close the popup and continue browsing the web store. ## Triggers Triggered popups support the following trigger types: * **Post Purchase:** Displays the popup after a player completes a purchase. * **Store Refresh:** Displays the popup when the web store is refreshed, including after player login, browser refresh, or an explicit store reload. ## Post Purchase Popups Each Post Purchase Popup includes a single product and appears after a player closes the [Completed Page](/guides/checkout/design-your-checkout), also known as the purchase success screen. You can configure a Post Purchase Popup to appear after every purchase, only after specific offers are purchased, or after a set number of purchases that match the configured offer conditions. Use frequency to define how often the popup appears when the trigger conditions are met. For example, if frequency is set to `3`, the popup appears after 3 matching purchases. If frequency is set to `1`, the popup appears after every matching purchase. When the popup appears, the player must either collect or buy the offer, or close the popup. Both actions reset the popup's frequency counter. The configured frequency value doesn't change, but the player must complete the required number of matching purchases again before the popup can appear again. You can create multiple Post Purchase Popups and prioritize them. If multiple Post Purchase Popups have the same configuration and are eligible for the completed purchase based on their frequency and offer ID settings, players see each popup one after another, with lower priority numbers appearing first. ## Store Refresh Popups Each Store Refresh Popup includes up to 20 products. You can configure a Store Refresh Popup to appear after a set number of eligible store refreshes. Use frequency to define how many store refreshes must occur before the popup is displayed. For example, if frequency is set to `3`, the popup appears after 3 eligible store refreshes. You can also set a cooldown, which defines the number of minutes that must pass before the popup can appear again. Frequency and cooldown periods must both pass before the popup is shown. Store Refresh Popups are permanent by default, which means they are always available and not scheduled. You can also schedule them to start and end at specific times. Priority applies across all eligible offers that use a popup modal such as Daily Bonus offers and Reward Calendars, and determines the display order. When the popup appears, the player must either collect or buy the offer, or close the popup. If the player closes the popup, the offer disappears unless you configured a badge. The badge acts as a visual reminder and lets the player reopen the popup to collect or purchase the offer later. The offer remains available in the badge until the player collects or purchases it, at which point the badge disappears. If the offer is still available when the store refreshes, the popup opens again. # Create a Triggered Popup Source: https://docs.appcharge.com/guides/webstore/offers/triggered-popups/create-a-triggered-popup This article explains how to design, create, and manage a Triggered Popup offer in the Publisher Dashboard. Alternatively, you can create and update a Triggered Popup using the [Triggered Popups API service](/../../api-reference/webstore/offers-v2/triggered-popups/introduction). ### Design a Triggered Popup Before creating a Triggered Popup, you need to design it: 1. In the **Studio** section go to **Offers Design**, and click **Create New Offer Design**. 2. Select **Triggered Popup**. 3. Complete the following sections: * **Triggered Popup** * **Name:** Enter a name for the offer design so you can easily identify it when creating an offer. * **External ID:** Enter an ID for the design. * **Triggered Popup Design** * **Background Color**: Select a solid color or choose **Linear** to apply a gradient. * **Background Image**: Upload or select a background image. * **Badge Cover Image**: Add an image for the badge. This field is relevant only for Store Refresh Popups. Configure this if you want to display a badge that players can click to view the current available Store Refresh Popup offer. * **Title** * **Title Name:** Enter a title for the offer. * **Color:** Select a color for the text. * **Size:** Enter a number for the text size. * **Weight:** Select a weight for the text. 4. Click **Save** to finalize the design. ### Create a Triggered Popup After designing the Triggered Popup, you can create the offer itself: 1. In the **Offers** section go to **Triggered Popups** and click **Create New Triggered Popup**. 2. In the **Settings** tab, complete the following sections: * **General** * **Name**: Enter a name for the Triggered Popup offer. This name appears in the checkout unless you provide an alternative in the **Display Name** field. * **Display Name**: Enter a name for the Triggered Popup offer to display in the checkout. This value overrides the one in the **Name** field. If left blank, the value from the Name field is displayed in the checkout. * **Description**: Provide a description for the Triggered Popup. * **External ID**: Enter an ID for the Triggered Popup. * **Offer Design**: Select the design you want to use from the drop-down menu. * **Price**: Enter a price for the Triggered Popup. * **Priority**: Enter a priority number. Lower numbers appear first when multiple Triggered Popups of the same type and configuration are available. * **Set As Free**: Check if you want the Triggered Popup to be free. 3. Go to the **Configuration** tab. First, complete the fields for your popup type: * **Triggers** * **Action**: From the drop-down menu, select **Purchase Completed**. * **Frequency**: Enter the number of matching purchases required before the popup is displayed. For example, `3` means the popup appears after 3 matching purchases. * **Offer ID**: Select one or more offer IDs if you want this popup to appear only when the selected offers are purchased. * **Triggers** * **Action**: From the drop-down menu, select **Store Refresh**. * **Frequency**: Enter the number of store refreshes required before the popup is displayed. For example, `3` means the popup appears after 3 eligible store refreshes. * **Cooldown**: Enter the number of minutes that must pass before the popup can appear again. * **Scheduled Offer**: Click one of the following tabs to set the offer schedule, and then complete its specific fields: * **Permanent**: The offer is always available. * **Availability**: Enter a number representing how many times a player can purchase this offer. * **Hide Availability**: Select this option to hide the offer's availability text in the web store. If unselected, and **Availability** is set to `5`, the web store displays `Available 5/5`. When a player collects or purchases the offer, the displayed availability decreases, for example to `Available 4/5`. * **Intervals**: The offer is available at specific times. * **Availability**: Enter a number representing how many times a player can purchase this offer. * **Hide Availability**: Select this option to hide the offer's availability text in the web store. If unselected, and **Availability** is set to `5`, the web store displays `Available 5/5`. When a player collects or purchases the offer, the displayed availability decreases, for example to `Available 4/5`. * **Repeat**: Use the drop-down menu to select how often this offer is displayed. * **Schedule**: The offer is available during a specific date and time. * **Availability**: Enter a number representing how many times a player can purchase this offer. * **Hide Availability**: Select this option to hide the offer's availability text in the web store. If unselected, and **Availability** is set to `5`, the web store displays `Available 5/5`. When a player collects or purchases the offer, the displayed availability decreases, for example to `Available 4/5`. * **Pick A Date**: Select the date and time period when the offer is available. * **Note**: Add any notes. * **Add Appearance**: Once you're finished, click **Add Appearance**. You must have at least 1 appearance. Click the ellipsis next to an appearance to edit or delete. Then, complete the shared sections for both popup types: * **Segments** * **Segment Name**: Enter segment names to display the offer to specific groups of players. * **Badges** * **Badge**: Select a Badge from the drop-down menu to help highlight the offer. * **Sale & Discounts** * **Min Product Sale**: Enter a discount value for the product. Setting this field adds a Sale Badge to your offer. * **Type**: Click the drop-down menu to select the discount type, **Percentage**, **Multiplier**, or **Fixed Amount**. * **Price Discount**: Enter a discount value, and the full price will appear crossed out next to the sale price. This field is relevant only for paid offers. * **Progress Bar** This section is only relevant if you have a Progress Bar offer configured. Define how many points the Triggered Popup adds to a Progress Bar when it is collected or purchased. * **Bar ID**: ID of the Progress Bar this offer to contributes to. * **Bar Points**: Number of points awarded toward the Progress Bar. * **Products**: To add products to the Triggered Popup, configure the fields below, and then click **Add Product**. You'll see the products displayed in a table at the bottom of the page. * **Product Name:** Select a product to add from the drop-down list. * **Product Types**: Choose how the product is displayed within the Triggered Popup: * **Main:** A primary product displayed prominently in the Triggered Popup. * **Sub**: A secondary product displayed in a smaller layout. Sub products can appear on their own or under a Main product. * **Web Only**: Select **Web Only** to promote items that are available exclusively in the Web Store. To get access to this feature, contact your account manager. * **Quantity**: Enter the number of units of this product included in the offer. 4. Click **Save** to create the Triggered Popup. ## Edit a Triggered Popup To edit an existing Triggered Popup: 1. Go to the **Triggered Popups** section. You’ll see a list of all your existing Triggered Popups. 2. Click the ellipsis of the offer you want to edit, and then click **Edit**. 3. Modify the Triggered Popup as desired. 4. Click **Save** to apply changes. ## Duplicate a Triggered Popup To duplicate a Triggered Popup: 1. Go to the **Triggered Popup** section. You’ll see a list of all your existing Triggered Popups. 2. Click the ellipsis of the offer you want to duplicate, and then click **Duplicate**. 3. Modify the Triggered Popup as desired. 4. Click **Save** to apply changes. ## Delete a Triggered Popup To delete a Triggered Popup: 1. Go to the **Triggered Popups** section. You’ll see a list of all your existing Triggered Popups. 2. Click the ellipsis of the offer you want to delete, and then click **Delete**. # About Web Store Personalization Source: https://docs.appcharge.com/guides/webstore/personalization/about-personalization Web Store Personalization lets you tailor the web store experience for each player. You configure this by defining the content each player sees based on their in-game activity, such as level, balance, and segment. This includes personalized offers as well as visual elements like player profile images and promotional banners. Each player sees a version of the web store that reflects their current status and behavior. Learn how to [configure personalization](./configure-personalization) for your web store. ## How it works Appcharge retrieves the latest player activity and data from your server during key moments: * When the player logs in to the web store * When the player completes a purchase or collects a free offer such as a daily bonus * Every five minutes after the last sync These automatic data refreshes keep each player's offers, visuals, and other personalized elements up to date. ## Live store sync (optional) You can also decide when Appcharge retrieves player data, allowing you to refresh a player's web store at any time. This is useful when you want to update a player's experience on demand. Manual updates are pushed directly to the player's device, giving you more control over the experience for players who are actively browsing the web store. You can trigger a manual refresh for specific players or for all active players. When refreshing data for all active players, Appcharge identifies everyone currently browsing the web store, and updates their store view in real time. Manual refresh is helpful when timing matters. For example, a player may run out of resources and you may want to show a refill offer immediately. It also supports operational needs, such as correcting an invalid offer before it affects additional players. ## Key features * **Real-time personalization:** Update offers instantly based on live player data, with no caching or delays. * **Live error correction:** Fix incorrect rewards, visuals, or mistimed offers without interrupting the player experience and help prevent lost revenue. * **Behavior-triggered offers:** Display targeted offers when players reach key in-game moments, like running out of resources. * **Event-based monetization:** Launch limited-time sales like “Happy Hour” or seasonal bundles on-demand. Personalization # Choose a Personalization Model Source: https://docs.appcharge.com/guides/webstore/personalization/choose-a-personalization-model Gaming web stores can greatly improve user satisfaction and boost sales by implementing effective personalization strategies. As part of the solutions and integration phases together with the Appcharge team, the best model for the publisher's needs will be chosen. Appcharge offers two powerful approaches to achieve this: ### 1. Offers List The **Offers List** model focuses on engaging users with timely and relevant promotions based on their classification by the game. The platform uses data analytics to determine the best offers for each player, including: * Discounts * Multipliers * One-time Deals * Campaigns * Player Birthdays * Frequently Viewed but Not Purchased Offers These base offers are configured in the Appcharge system. During player activity, the system retrieves the offers and their dynamic product details, including quantities, based on calculations by the game system, using the relevant API. ### 2. Using Segments Personalization through **Segmentation** involves categorizing players based on common traits such as their purchasing behavior, game preferences, and engagement levels. For example, a game might identify segments such as: * Hardcore Gamers * New Players * Frequent Spenders By analyzing user data and purchase histories, stores can tailor their interfaces, recommendations, and promotions to match the specific preferences of each segment. This could include offering special promotions, bonuses, or bundles relevant to each group. With Appcharge, you can leverage segmentation to create targeted offers. Once a player logs into the store, the Personalization API retrieves their segment information as defined by the game logic, and presents personalized offers accordingly. ### How Both Models Work Both segmentation and offers list models utilize the [Personalization API](/../../api-reference/webstore/personalization/introduction) but in different ways. They are triggered under these conditions: * Immediately after login * Every 5 minutes * Immediately after purchasing an offer or collecting a bonus By implementing these personalization techniques, gaming web stores can enhance player experiences and drive increased engagement and sales. # Configure Web Store Personalization Source: https://docs.appcharge.com/guides/webstore/personalization/configure-personalization To set up the Personalization feature for your web store: 1. Create and expose an API endpoint that returns personalized web store data based on the [Personalize Web Store Callback](/../../api-reference/webstore/personalization/personalize-webstore-callback) structure. 2. Register the endpoint in the Publisher Dashboard: * In **Settings**, go to the **Integration** tab. * In the **Personalize Web Store Callback** field, enter your server's endpoint URL. ## Live store sync (optional) To manually refresh data at any time: * **For specific players:** Call the [Personalization Trigger API](/../../api-reference/webstore/personalization/trigger-webstore-personalization-by-player-id) to trigger the Personalize Web Store Callback on demand by player ID. * **For all players:** Call the [Personalization Trigger API](/../../api-reference/webstore/personalization/trigger-webstore-personalization) to trigger the Personalize Web Store Callback on demand for all players. Configure personalization # About Player Authentication Source: https://docs.appcharge.com/guides/webstore/player-authentication/about-player-authentication Before players can log in to your web store, you must [set up player authentication](./set-up-player-authentication). Player authentication allows you to confirm a player's identity when they log in to your web store. Appcharge provides several secure and convenient login methods you can implement. These options help protect against account spoofing and unauthorized access, while ensuring an enhanced player experience. ## How it works When a player opens the web store, they’ll be prompted to log in using one of the authentication methods you’ve set up. After the player attempts to log in, Appcharge sends you their login details for verification. Once verified, the player is logged into the web store. The player will remain logged in on the same device and browser until they either log out manually or are automatically signed out after 30 days of inactivity. ## Supported authentication methods Appcharge supports the following authentication methods: * [SSO Login](./sso-login/about-sso-login): Let players log in using external identity providers such as Google. * [Player ID Login](./player-id-login/about-player-id-login): Use a unique ID from your game to authenticate players. * [Password Login](./password-login/about-password-login): Enable players to log in with the same username and password they use in your game. * [Game Redirect Login](./game-redirect-login/about-game-redirect-login): Redirect players to your game app for authentication. * [Pre-Authenticated Login](./pre-authenticated-login/about-pre-authenticated-login): Players are pre-authenticated when logging in to the web store from your game. # About Game Redirect Login Source: https://docs.appcharge.com/guides/webstore/player-authentication/game-redirect-login/about-game-redirect-login Implement Game Redirect Login to direct the player from the web store login page to the game for authentication. Once verified, the player is redirected back to the web store with a player code. This allows the game to handle secure login while giving players access to the store without separate credentials. To enable this authentication method, follow the instructions to [set up Game Redirect Login](./set-up-game-redirect-login). ## Game Redirect Login flow The following flow describes how the Game Redirect Login process works: 1. A player opens your web store and chooses to log in with your game. 2. Appcharge sends a request to your [Initiate Game Auth Callback](/../../api-reference/webstore/player-authentication/initiate-game-auth-callback) with the following properties to initiate an authentication session in your game: * The player's device type (mobile or desktop). * The current date. 3. Your server responds with: * A deeplink to redirect the player to your game. * An access token. * An option to automatically redirect players logging into the web store on desktop straight to your game. Set `desktopAutoRedirect` to `true` to enable it. When `false` or omitted, they see a QR code of the deeplink and must scan it with their phone to open the game. Appcharge redirects the player to the deeplink you provide without modification. If you'd like to pass any additional query params beyond those needed for authentication, include them in your deeplink. 4. Appcharge saves this access token and redirects the player to your game for authentication. On mobile, the player is automatically redirected using the deeplink from the previous step. On desktop, Appcharge follows the redirect option configured in the previous step. 5. Your game identifies the player via this deeplink and generates a unique 4- or 6-digit player code. 6. The player returns to the web store. On mobile, and on desktop when automatic redirect is enabled, your game redirects the player back via a URL containing the player code and the same access token issued in step 3. For example: ```mdx theme={"system"} https://your-web-store/login?proofKey=&token= ``` * `proofKey`: The player code. * `token`: The same access token issued in step 3. The access token is passed again in case the player uses a different browser. On desktop, when automatic redirect isn't enabled, your game displays the player code and instructs the player to return to the web store and enter it manually. 7. Appcharge sends the player code and access token to your [Authenticate Player Callback](/../../api-reference/webstore/player-authentication/authenticate-player-callback) for validation. 8. If the credentials are valid, your server responds with the player's details. Appcharge then successfully logs the player in and completes the flow. # Set Up Game Redirect Login Source: https://docs.appcharge.com/guides/webstore/player-authentication/game-redirect-login/set-up-game-redirect-login To enable Game Redirect Login for your web store: 1. Create a deeplink in the following format to redirect players from your game back to the web store: `https://your-web-store/login?proofKey=&token=`, where: * `proofKey`: The player code. * `token`: The access token. 2. Create an API endpoint that follows the [Initiate Game Auth Callback](/../../api-reference/webstore/player-authentication/initiate-game-auth-callback) format. 3. In the Publisher Dashboard: * Go to **Settings → Authentication**. * Scroll to the **OTP** section and toggle it on. * In the **Initiate Game Auth Callback** field, enter the API URL you created. * Use the **Desktop Text Model** dropdown to choose how many digits your player code will have (4 or 6). This setting applies to both the Game Redirect Login and [Pre-Authenticated Login](../pre-authenticated-login/about-pre-authenticated-login) methods. If you plan to implement both methods, you must use the same number of digits for your player code across both. # About Password Login Source: https://docs.appcharge.com/guides/webstore/player-authentication/password-login/about-password-login You can enable players to log in to your web store using the same username and password they use in your game. This ensures a seamless experience and consistent identity management across platforms. To enable this authentication method, follow the instructions to [set up Password Login](./set-up-password-login). ## Password Login flow Here’s how the Password Login process works: 1. A player chooses to log in using the same credentials they use in the game. 2. The player enters their username and password in the login page. 3. Appcharge sends the login information and the following properties to the [Authenticate Player Callback](/../../api-reference/webstore/player-authentication/authenticate-player-callback) to verify the player's identity and complete authentication: * `authMethod: "userPassword"` * `userName`: The username entered by the player. * `password`: The password entered by the player. 4. If the credentials are valid, your server responds with the player's details. Appcharge then successfully logs the player in and completes the flow. # Set Up Password Login Source: https://docs.appcharge.com/guides/webstore/player-authentication/password-login/set-up-password-login To enable Password Login in your web store: 1. In the Publisher Dashboard, go to **Settings → Authentication**. 2. Scroll to the **Username and Password** section and toggle it on. # About Player ID Login Source: https://docs.appcharge.com/guides/webstore/player-authentication/player-id-login/about-player-id-login You can enable players to log in to your web store using the Player ID assigned to them in your game. This provides a secure and direct way to authenticate players and is particularly useful for personalized experiences. Because players might not always know where to find their Player ID, you can guide them by adding a helpful link to your login page. This link should point to an article explaining how to locate their Player ID. To enable this authentication method, follow the instructions to [set up Player ID Login](./set-up-player-id-login). ## Player ID Login flow Here’s how the Player ID Login process works: 1. A player chooses to log in to your web store using their Player ID. If they don’t know where to find their Player ID, they can click the link you provide on the login page to access an article with instructions. 2. After locating their Player ID, the player enters it in the login field. 3. Appcharge then sends the login information with the following properties to the [Authenticate Player Callback](/../../api-reference/webstore/player-authentication/authenticate-player-callback) to verify the player's identity and complete authentication: * `authMethod: "userToken"` * `token: "player_id"` 4. If the credentials are valid, your server responds with the player's details. Appcharge then successfully logs the player in and completes the flow. # Set Up Player ID Login Source: https://docs.appcharge.com/guides/webstore/player-authentication/player-id-login/set-up-player-id-login To enable Player ID Login in your web store: 1. In the Publisher Dashboard, go to **Settings → Authentication**. 2. Scroll to the **Player ID** section and toggle it on. 3. Add link text that will appear on the login page. For example, `Where can I find my Player ID?`. 4. Provide a URL linking to an article that helps players locate their Player ID. # About Pre-Authenticated Login Source: https://docs.appcharge.com/guides/webstore/player-authentication/pre-authenticated-login/about-pre-authenticated-login Implement Pre-Authenticated Login to enable players to log in to the web store or game portal from the game, already authenticated. This is especially useful for deep-linking or promoting in-game offers, as it avoids requiring the player to re-authenticate. To enable this authentication method, follow the instructions to [set up Pre-Authenticated Login](./set-up-pre-authenticated-login). ## Pre-Authenticated Login flow Here’s how the Pre-Authenticated Login process works: 1. A player opens a link to your web store or game portal from your game. 2. The player is sent to the web store or game portal via the URL you created, containing the player code and access token. 3. Appcharge extracts the player code and access token from the URL and sends it as part of the request to your [Authenticate Player Callback](/../../api-reference/webstore/player-authentication/authenticate-player-callback) for validation. 4. If the credentials are valid, your server responds with the player's details. Appcharge successfully logs the player in, completing the flow. # Set Up Pre-Authenticated Login Source: https://docs.appcharge.com/guides/webstore/player-authentication/pre-authenticated-login/set-up-pre-authenticated-login To enable Pre-Authenticated Login for your web store or game portal: 1. Create a URL in the following format to send players from your game to the web store or game portal: `https://your-web-store/login?proofKey=&token=`, where: * `proofKey`: The player code. * `token`: The access token. 2. In the Publisher Dashboard: * Go to **Settings → Authentication**. * Scroll to the **OTP** section and toggle it on. * Leave the **Initiate Game Auth Callback** field empty, unless you also plan on implementing [Game Redirect Login](../game-redirect-login/about-game-redirect-login). * Use the **Desktop Text Model** dropdown to choose how many digits your player code will have (4 or 6). This setting applies to both the Pre-Authenticated Login and the [Game Redirect Login](../game-redirect-login/about-game-redirect-login) methods. If you plan to implement both methods, you must use the same number of digits for your player code across both. # Set Up Player Authentication Source: https://docs.appcharge.com/guides/webstore/player-authentication/set-up-player-authentication This article explains how to set up player authentication for your web store and receive player login data. To set up player authentication: 1. Create and expose an API endpoint on your server that follows the [Authenticate Player Callback](/../../api-reference/webstore/player-authentication/authenticate-player-callback) structure. Appcharge will call this endpoint with player authentication data whenever a player logs in to your web store. 2. Register the endpoint in the Publisher Dashboard: * In **Settings**, go to the **Integration** tab. * In the **Authenticate Player Callback** field, enter your server's endpoint URL. 3. Configure one or more of the [supported authentication methods](./about-player-authentication#supported-authentication-methods). Appcharge will now send player login details directly to your system. # About SSO Login Source: https://docs.appcharge.com/guides/webstore/player-authentication/sso-login/about-sso-login Implement SSO Login to allow players to log in to your web store using a single sign-on (SSO) token issued by a third-party authentication provider. This enables a unified login experience across multiple platforms. ## How it works When players choose to sign in with an SSO provider, your web store redirects them to the provider’s login screen. After logging in, the player grants permission to share selected details like name, email, or profile picture. If they’re already authenticated, this step may be skipped. Once authorized, the provider returns a token to Appcharge. Appcharge then passes this token along with login data to your [Authenticate Player Callback](/../../api-reference/webstore/player-authentication/authenticate-player-callback) for verification. After a successful response, the player is logged in. The SSO token itself doesn't contain any personal data, rather it acts as a temporary, unique identifier. Appcharge never stores or processes any personally identifiable information (PII) from the token. ## Supported SSO providers Appcharge supports integration with the following SSO providers. Refer to each article for implementation steps: * [Google SSO](./set-up-google-sso) * [Apple SSO](./set-up-apple-sso) * [Facebook SSO](./set-up-facebook-sso) # Set Up Apple SSO Source: https://docs.appcharge.com/guides/webstore/player-authentication/sso-login/set-up-apple-sso This article explains how to set up Apple SSO Login for your web store. ## In the Apple dashboard Follow the steps below to configure the login in Apple's dashboard: ### Create an App ID 1. Go to the [Apple Developer Portal](https://developer.apple.com/account) and sign in with your Apple Developer account. 2. Go into your [account](https://developer.apple.com/account). 3. In the **Certificates, Ids & Profiles** section, select **[Identifiers](https://developer.apple.com/account/resources/identifiers/list)**. 4. Click the **+** button to create a new **App ID**. 5. Edit your existing app by selecting your app and and clicking **Continue**. 6. Fill in the required fields: * Description * Bundle ID * Under **Capabilities** select **Sign in with Apple**. Click **Continue**, and then click **Register** to create the App ID. After registering you should be redirected back to the identifiers page. ### Create a Service ID for your web application 1. In the **Certificates, Ids & Profiles** section, select **[Identifiers](https://developer.apple.com/account/resources/identifiers/list)**. 2. Click the **+** button and select ****Services IDs****, and then click **Continue**. 3. Fill in the required fields: * Description * Identifier - reversed domain click **Continue** and then click **Register**. After registering you should be redirected back to the identifiers page. 4. Click on the newly created Service ID, and a details page will open. Select the checkbox next to the **Sign in with Apple** capability, and then click **Configure**. 5. Add your domain and redirect URLs as follows: * Add your domain in the **Domains and Subdomains** section. You'll need to verify your domain by following the instructions provided by Apple. * Example for store domain: [https://shop.sweetsugarbakery.com](https://shop.sweetsugarbakery.com) * Add your redirect URL(s) in the **Return URLs** section. This is where the user will be redirected after a successful authentication. After a successful configuration, confirm the list you’d like to add to this Services ID and click **Done**. To complete the process, click **Continue**, and then click **Save**. * Example for return URL: [https://shop.sweetsugarbakery.com/login?apple=true](https://shop.sweetsugarbakery.com/login?apple=true) ### Create a private key for client authentication 1. In the **Certificates, Ids & Profiles** section, click **[Keys](https://developer.apple.com/account/resources/authkeys/list)**. 2. Click the **+** button to create a new key. 3. Fill in the key name, check **Sign in with Apple** and click **Configure**. 4. Select the primary App ID you created earlier, then click **Save** and **Continue**. 5. Review the key details and click **Register**. 6. Download the private key (.p8 file) and securely store it. You'll need this to authenticate your server. ### Example This example demonstrates how to open the player token generated when a player clicks the **Sign in with Apple** button in the web store login page: ```python python theme={"system"} import jwt from datetime import datetime, timedelta client_id = 'CLIENT_SERVICE_ID' team_id = 'APPLE_DEVELOPER_TEAM_ID' private_key = '''-----BEGIN PRIVATE KEY----- YOUR PRIVATE KEY -----END PRIVATE KEY-----''' # Private key in PEM format header = { 'alg': 'ES256', 'kid': YOUR_PRIVATE_KEY_ID # Key ID for your private key } payload = { 'iss': team_id, 'iat': datetime.utcnow(), 'exp': datetime.utcnow() + timedelta(days=180),# 180 days expiration time 'aud': 'https://appleid.apple.com', 'sub': client_id } client_secret = jwt.encode(payload, private_key, algorithm='ES256', headers=header) print(client_secret) ``` ### Supported methods for Apple sign in Appcharge supports both `code` and `id_token` methods for Apple Sign-In. * **`id_token`:** A JWT (JSON Web Token) issued by Apple containing information about the authenticated user. * **`code`:** A short-lived authorization code used for server-to-server communication to fetch access tokens. Both methods will be sent to your [Authenticate Player Callback](/../../api-reference/webstore/player-authentication/authenticate-player-callback). By default, Appcharge uses the `code` method. To adjust this configuration, please contact the Appcharge support team. For further details on Apple’s implementation, refer to their documentation. ## In the Publisher Dashboard Follow the steps below to configure the login in the Publisher Dashboard: 1. Go to **Settings -> Authentication**. 2. Toggle on **Apple App**, and enter your Apple ID in the **Apple App ID** field. 3. The button for logging in with Apple will appear in the web store login page. 4. Once a player selects this method, Apple generates a token. Apppcharge sends this token along with other login information to your [Authenticate Player Callback](/../../api-reference/webstore/player-authentication/authenticate-player-callback) for verification. 5. Once verified, the player is logged into the web store. # Set Up Facebook SSO Source: https://docs.appcharge.com/guides/webstore/player-authentication/sso-login/set-up-facebook-sso This article explains how to set up Facebook SSO Login for your web store. ## In the Facebook dashboard Follow the steps below to configure the login in Facebook's dashboard: 1. Log in to Meta for developers and click on your Facebook App -> **Login with Facebook**. 2. Under **Valid OAuth Redirect URIs**, add your web store's domain using this format: ```js theme={"system"} https\://YOUR\_STORE\_SUB\_DOMAIN.YOUR\_STORE\_DOMAIN.com/login ``` 3. Under **Allowed Domains for the JavaScript SDK** add your web store's domain using this format: ```js theme={"system"} https\://YOUR\_STORE\_SUB\_DOMAIN.YOUR\_STORE\_DOMAIN.com/ ``` ## In the Publisher Dashboard Follow the steps below to configure the login in the Publisher Dashboard: 1. Go to **Settings -> Authentication**. 2. Toggle on **Facebook App**, and enter your Facebook ID in the **Facebook App ID** field. 3. The button for logging in with Facebook will appear in the web store login page. 4. Once a player selects this method, Facebook generates a token. Apppcharge sends this token along with other login information to your [Authenticate Player Callback](/../../api-reference/webstore/player-authentication/authenticate-player-callback) for verification. 5. Once verified, the player is logged into the web store. # Set Up Google SSO Source: https://docs.appcharge.com/guides/webstore/player-authentication/sso-login/set-up-google-sso This article explains how to set up Google SSO Login for your web store. ## In the Google dashboard Follow the steps below to configure the login in Google's dashboard: ### Create a project in the Google Cloud Platform 1. Go to the [Google Cloud Console](https://console.cloud.google.com/) and sign in with your Google account. 2. Click on the project dropdown and select/create the project for which you want to enable Google SSO. 3. Enable the [Google Identity Platform API](https://console.cloud.google.com/flows/enableapi?apiid=identitytoolkit.googleapis.com). ### Set up the OAuth consent screen 1. In **APIs & Services**, go to **[OAuth consent screen](https://console.cloud.google.com/apis/credentials/consent)** on the left sidebar. 2. Select your **User Type**, and then click **Create**. 3. Fill in all required fields, such as **User support email**. 4. Add your domain to the **Authorized domains** section if needed. 5. Click **Save and continue** until you've completed all required steps. ### Create OAuth 2.0 client credentials 1. In **APIs & Services**, go to **[Credentials](https://console.cloud.google.com/apis/credentials)** on the left sidebar. 2. Click the **Create credentials** dropdown button and select **OAuth client ID**. 3. Select **Web application** as the Application type. 4. Fill in all required fields, such as the **Name of the client**. 5. Add your Authorized JavaScript origins (your web app's domain) and Authorized redirect URIs (where users will be redirected to after successful authentication). 6. Click **Create** to generate the client credentials. Save the **Client ID** and **Client Secret** as you'll need these in your frontend and backend configurations. ## In the Publisher Dashboard Follow the steps below to configure the login in the Publisher Dashboard: 1. Go to **Settings -> Authentication**. 2. Toggle on **Google App**, and enter your Google ID in the **Google App ID** field. 3. The button for logging in with Google will appear in the web store login page. 4. Once a player selects this method, Google generates a token. Apppcharge sends this token along with other login information to your [Authenticate Player Callback](/../../api-reference/webstore/player-authentication/authenticate-player-callback) for verification. 5. Once verified, the player is logged into the web store. # Set Up Your Web Store Source: https://docs.appcharge.com/guides/webstore/set-up-your-webstore 1. Make sure you've [set up your Publisher Dashboard](./../publisher-dashboard/set-up-your-publisher-dashboard). 2. Design your web store, beginning by [setting up a custom domain](./../webstore/design/set-up-a-custom-domain). 3. Configure [player authentication](./../webstore/player-authentication/set-up-player-authentication). 4. [Set up real-time player data synchronization with the web store](./../webstore/personalization/configure-personalization) to enable personalized offers. 5. [Enable real-time order reporting](./../checkout/orders/about-player-order-reporting) to sync purchases and update player balances. 6. Set up [price points](./../checkout/price-localization/set-up-price-points). ## Explore additional Web Store features # Choose a Support Model Source: https://docs.appcharge.com/guides/webstore/settings/choose-a-support-model ## Overview To provide seamless support for non-financial player inquiries, Appcharge offers multiple support options directly within the web store. These options facilitate direct communication and quick resolution of player concerns: 1. **Email Support** Players can submit inquiries through a built-in form directly within the web store. This form allows players to provide detailed information about their questions or concerns, enabling effective and personalized support. 2. **Live Chat** A dedicated chat interface is available for immediate assistance. This option allows players to receive real-time responses for quick queries and problem resolution, enhancing the player experience through instant communication with the support team. 3. **External Support Link** For additional support needs outside the web store, players can be directed to comprehensive external support resources. This option ensures players have access to a wide range of support tools and documentation to address various inquiries. ## Configuring Email Support in the Appcharge Dashboard To set up email support for your web store, follow these steps: 1. Log in to your Appcharge dashboard with your admin credentials. 2. Go to the **Admin** section from the main menu. 3. Click on **Company** to access your company settings. 4. Find the **'Support Email'** field and enter the email address where you'd like to receive player support inquiries. 5. Once completed, click **Update** to save the changes and activate email support. For more advanced support configurations or customized support models, feel free to [contact us](https://www.appcharge.com/contact-us). # Configure General Store Settings Source: https://docs.appcharge.com/guides/webstore/settings/configure-general-store-settings This article explains how to configure general web store settings for your store, such as store title, footer, and message when there are no available offers. You can configure these settings from the Publisher Dashboard. ## General settings To configure general settings for your web store: 1. In the sidebar menu, go to **Studio** > **Builder**. 2. In the **Store Settings** tab, scroll to **General Settings**, and then click the arrow to expand the section. 3. Complete the following fields: * **Store Tab Title**: Enter the name of your web store as it will appear in browser tabs. * **Browser Theme Color**: Select a color for the iOS system header and footer bars on the player's mobile screen. If you don't select a color, the bars display white. To learn more about iOS system header and footer bars, see Apple's [Design for Safari 15](https://developer.apple.com/videos/play/wwdc2021/10029/) session. * **Bouncy Overscroll Behavior**: Enable or disable the native overscroll bounce effect on iOS. On Android, the same setting reloads the page when players overscroll. This setting controls the CSS [overscroll-behavior](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/overscroll-behavior) property. * **Default Player Profile**: Upload a default avatar image displayed for players without a profile picture. * **Favicon**: Upload a small icon that represents your store in browser tabs and bookmarks. 4. Click **Save** to apply your changes. ## Daily Reset Timezone Set the timezone for the daily offer reset. Offers reset at 00:00 in the selected timezone. The default is UTC+00:00. To configure the daily reset timezone: 1. In the sidebar menu, go to **Studio** > **Builder**. 2. In the **Store Settings** tab, scroll to **Daily Reset Timezone**, and then click the arrow to expand the section. 3. From the drop-down menu, select the timezone for the daily offer reset. The selected timezone takes effect at the next reset, and the current reset cycle isn't affected. 4. Click **Save** to apply your changes. If you save multiple changes before the next reset, the latest saved timezone is used for that reset. ## Footer The footer appears at the bottom of your web store and can include external links and legal pages. To configure your web store footer: 1. In the sidebar menu, go to **Studio** > **Builder**. 2. In the **Store Settings** tab, scroll to **Footer**, and then click the arrow to expand the section. 3. Under **External links**, select how links open: * **New Tab**: Opens the link in a new browser tab. * **Modal**: Opens the link in an overlay modal within the store. * **Show "Cookie Settings" link**: Enable this toggle to display a cookie preferences link in the store footer. 4. Complete the following fields: * **App Store Link**: Link to your game's App Store listing. * **Google Play Link**: Link to your game's Google Play listing. * **Privacy Policy**: Link to your privacy policy page. * **Terms and Conditions**: Link to your terms and conditions page. * **Support Link**: Link to your external support page or help center. 5. To pass player-specific data through footer links, configure the query parameter names that Appcharge appends to those links: * **Player ID Parameter Name**: The query parameter used to identify the player ID. * **Player Name Parameter Name**: The query parameter used to identify the player name. 6. Click **Save** to apply your changes. ## Empty state for no offers You can configure a message shown to players when no offers are available in the store. To add offers to your web store, see [About Offers](../offers/about-offers). To configure the empty state: 1. In the sidebar menu, go to **Studio** > **Builder**. 2. In the **Store Settings** tab, scroll to **Empty State - No Offers**, and then click the arrow to expand the section. 3. Select either **Text Only** or **Custom Design**. 4. Complete the following fields: * For **Text Only:** * **Empty State Title:** Enter a short headline to display when there are no offers. For example, `No Offers Available`. * **Empty State Body Text:** Enter a supporting message to display below the title. For example, `No offers are available at this moment. Come back soon!`. * For **Custom Design:** * **Background Image:** Upload an image displayed as the background for the empty state page. 5. Click **Save** to apply your changes. # Configure the Login Page Source: https://docs.appcharge.com/guides/webstore/settings/configure-the-login-page The login page is the first screen players see before they sign in to your web store. Customize its appearance, including greeting text, fonts, branding assets, and login button styling. This article covers visual and text customization only. To configure how players sign in, such as SSO, Player ID, or password login, see [About Player Authentication](/guides/webstore/player-authentication/about-player-authentication). ## Configure the login page To configure the login page: 1. In the Publisher Dashboard, go to **Studio > Builder** and click the **Login Page** tab. 2. Complete the following sections: * **Now Say 'Hi':** Customize the greeting players see when they open the login page. * **Text:** Enter the greeting text. * **Color:** Select a text color from the color picker or enter a hex color. * **Size (px):** Enter the font size in pixels. * **Weight:** Select the font weight. * **Font:** Select the font for the login page. * **Error Message:** Control your fallback error messages. * **Title:** Enter the title displayed when a login error occurs. For example, `Whoops!`. * **Subtitle:** Enter the subtitle displayed when a login error occurs. For example, `Login failed`. * **Logout Text Settings:** Customize the confirmation screen that appears when a player taps their profile picture to log out. * **Button Image:** Upload an image (optional). Use 1:1 aspect ratio, minimum width 32 px, PNG or JPEG. * **Custom 'X' Icon:** Upload an icon (optional). Use 1:1 aspect ratio, minimum width 32 px, PNG or JPEG. * **Text:** Enter the logout confirmation message. For example, `Are you sure you want to disconnect?`. This field supports translations. If left empty, the default logout screen text is used. * **Font:** Select the font. * **Color:** Select a text color from the color picker or enter a hex color. * **Size (px):** Enter the font size in pixels. * **Weight:** Select the font weight. * **Assets:** The brand assets you add here appear only on the login page. You can change them at any time. * **Logo:** Upload an image (optional). Use 1:1 aspect ratio, minimum width 320 px, PNG or JPEG. * **Logo Size:** Select how large the logo appears on the login page. * **Login Background Image (Mobile):** Upload an image (optional). Use 1:3 aspect ratio, minimum width 400 px, PNG or JPEG. * **Login Background Image (Desktop):** Upload an image (optional). Use 1920 × 1080 px, PNG or JPEG. If you provide an external image URL, Appcharge saves and uses the URL as-is. Appcharge doesn't download, copy, upload, or host the image. If you use an external image URL, host the image on your own infrastructure and keep it available at the provided URL. We recommend uploading image files instead of using external URLs when possible. Appcharge hosts uploaded files on its CDN. * **OTP:** Design settings for the OTP login method. * **OTP Icon:** Upload an icon (optional). Use 1:1 aspect ratio, minimum width 32 px, PNG or JPEG. * **OTP Button Text:** Enter the button label. * **Button Color:** Select a button color from the color picker or enter a hex color. Click **Reset** to restore the default color. * **Button Text Color:** Select a text color from the color picker or enter a hex color. Click **Reset** to restore the default color. If left empty, the default OTP button styling is used. * **Player ID:** Design settings for the Player ID login method. * **Player ID Icon:** Upload an icon (optional). Use 1:1 aspect ratio, minimum width 32 px, PNG or JPEG. * **Player ID Button Text:** Enter the button label. For example, `Log in with Player ID` or `Log in with Store Code`. This field supports translations. If left empty, the default Player ID button styling is used. * **Button Color:** Select a button color from the color picker or enter a hex color. Click **Reset** to restore the default color. * **Button Text Color:** Select a text color from the color picker or enter a hex color. Click **Reset** to restore the default color. 3. In the preview panel on the right, review your changes in real time. 4. Click **Save** to apply your changes. To add translations for **Logout Text Settings > Text** or **Player ID Button Text**, see [Set and Manage Translations](/guides/translations/set-and-manage-translations). # Set Up a Custom Domain Source: https://docs.appcharge.com/guides/webstore/settings/set-up-a-custom-domain This guide will walk you through the process of setting up a custom domain for your web store. Whether you're connecting an existing domain or creating a new one, these steps will help you establish a branded web address that builds trust and strengthens your business identity. ## Step 1 | Create a subdomain on your game's website To use a custom domain for your web store, you'll need to create a subdomain on your game's website. If you don’t have one yet, you can set it up through your domain service provider. For example, if your website is *`myGameName.com`*, you can create *`shop.myGameName.com`*. Once your subdomain is ready, reach out to the Appcharge team to request the domain change. ## Step 2 | Add a DNS record for SSL validation Appcharge will generate an SSL certificate for your custom domain and provide the required name and value for DNS validation of the certificate. On your domain provider’s platform, create a DNS record using the name and value provided by Appcharge. Include the following fields: * **Host or Name:** The name provided by Appcharge. * **TTL (Time to Live):** Set a default TTL or use your provider's default setting. * **Type:** Select or enter **CNAME**. * **Value:** The value provided by Appcharge. The record should look like this: | Host/Name | TTL | Type | Value | | - | - | - | - | | \{NAME\_PROVIDED\_BY\_APPCHARGE} | 5 Min | CNAME | \{VALUE\_PROVIDED\_BY\_APPCHARGE} | ## Step 3 | Add a second DNS record for your subdomain Appcharge will send you a Cloudfront ID Distribution domain name. On your domain provider’s platform, create a second DNS record using the Cloudfront ID Distribution domain name provided by Appcharge. Include the following fields: * **Host or Name:** The subdomain on your game's website, such as **shop** for *`shop.myGameName.com`*. * **TTL (Time to Live):** Set a default TTL or use your provider's default setting. * **Type:** Select or enter **CNAME**. * **Value:** The Cloudfront ID Distribution domain name provided by Appcharge. The record should look like this: | Host/Name | TTL | Type | Value | | - | - | - | - | | shop | 5 Min | CNAME | \{CLOUDFRONT\_ID} | ## Step 4 | Add your domain to the Publisher Dashboard To add your domain to the Publisher Dashboard: 1. Go to **Settings > Developer Settings**. 2. Under **Project Info**, enter your custom domain in the **Domain** field. For example, *`shop.myGameName.com`*. > **Important:** It may take up to 30 minutes for the changes to take effect. If your web store domain is not live after this time, follow the troubleshooting steps below. ## DNS Troubleshooting If your DNS URL is not resolving, check the following: * **Incorrect DNS settings:** Ensure that the domain's DNS records are configured correctly according to the specifications provided by Appcharge. * **SSL Certificate:** Verify that your SSL certificate is valid and not expired. Confirm that the certificate setup is properly validated through DNS records. * **Hosting provider issues:** Check if the server handling the DNS resolution is operational and isn't experiencing connectivity issues. * **Cached DNS data:** Your local DNS resolver or ISP may be serving outdated cached data. Clear your DNS cache or wait for the cached data to expire. * **Misconfigured firewall or security settings:** Ensure your firewall or security settings aren't blocking DNS resolution. If necessary, adjust the settings to allow DNS traffic. # Set Up a Maintenance Page Source: https://docs.appcharge.com/guides/webstore/settings/set-up-a-maintenance-page You can set up a maintenance page to temporarily take your web store offline while displaying a custom message to players, such as "Web store temporarily under construction. Come back soon!". This is useful when you need to make updates, fix issues, or roll out new content without players encountering a broken or incomplete experience. When enabled, players who access your web store URL see the maintenance page instead of the store, preventing new purchases during planned downtime. When disabled, players will see your web store as usual. To enable or disable this feature, contact your account manager. To set up a maintenance page: 1. In the Publisher Dashboard, go to **Studio > Builder**. 2. In the **Store Settings** tab, scroll down to **Maintenance**, and then click the arrow to expand the field. 3. Enter the text and any formatting or links to display on the maintenance page. 4. Click **Save** in the bottom right corner to save your changes. # Currency Conversions Source: https://docs.appcharge.com/merchant-of-record/finance/currency-conversions 1. **Introduction**
    This policy outlines the approach and procedures for currency conversions associated with international transactions processed by Appcharge, a merchant of record white label solution business operating globally. It aims to ensure transparent, efficient, and fair currency conversion practices in line with the capabilities provided by our various payment processing partners. Appcharge uses the rates that it is being charged and doesn't benefit from currency exchange rate additional fees. 2. **Currency Conversion for Transactions**
    **2.1 Presentment Currency**
    Appcharge supports processing charges in 80+ currencies, allowing prices to be presented in players' native currencies to improve sales and help customers avoid conversion costs. For the Checkout solution, publishers are required to specify the presentment currency when creating a Checkout session. For the Store solution, the localization and selection of the relevant price point and currency will be done by the Appcharge platform.
    **2.2 Settlement Currency**
    Payments will automatically be converted to the publisher's default settlement currency (USD) using the exchange rate at the time of the charge. This policy is designed to protect earnings from rate fluctuations between the payment and anticipated payouts. 3. **Foreign Exchange Rates** Appcharge generally applies the mid-market rate for currency conversions, which is the average between the buy and sell prices of a currency. This rate is sourced from third-party service providers. We refresh these rates six times a day using rates provided by our trusted sources. To view the current currency conversion on Appcharge, you can create a price point in the Appcharge dashboard and see the conversion of \$1 to all supported currencies. The actual exchange rate applied is highly dynamic and is updated approximately every 3 hours. Publishers can view the latest rates in the price points tab in the Appcharge Dashboard. Note that the rate viewed is the baseline for currency conversion costs. 4. **Conversions on Disputes and Refunds** In the event of a dispute or refund for a currency-converted payment, the amount received by the publisher will be converted back to the presentment currency at the current exchange rate. This may result in an amount more or less than the original payment due to market fluctuations. Customers will be refunded the exact amount they paid in the currency they used, regardless of any rate fluctuations. 5. **Policy Amendments** Appcharge reserves the right to amend this policy as necessary to reflect changes in regulations, operational requirements, or agreements with payment processing partners. # Invoice Merchant and Statement Descriptor Source: https://docs.appcharge.com/merchant-of-record/finance/invoice-merchant-and-statement-descriptor Receipts are not only an essential communication tool but also a critical way to ensure transparency and clarity for players regarding their purchases. The following elements on the receipt and payment records help players easily recognize your game and company, reducing confusion and preventing disputes. With these measures in place, players are reassured that their purchase was made with a trusted and recognizable entity, strengthening your relationship with them and enhancing the overall experience. ***Note:** For a detailed explanation of receipt elements, see the [Appcharge Receipts documentation](/../../guides/checkout/orders/about-receipts).* ## Invoice Merchant The Invoice Merchant is the publisher's name as it will appear in: * The receipt itself (displayed prominently). * The email subject line of the receipt notification. This ensures that players know they are being charged by a trusted and recognizable entity—your game store—rather than Appcharge, which may be an unfamiliar name. ## Statement Descriptor The Statement Descriptor refers to how the purchase appears on the player’s bank statement. This includes: * **The Publisher’s Name:** Ensures the player knows which company they interacted with. * **The Appcharge Name:** Adds context by showing the payment processing company. This combination makes it clear which game or company the purchase is associated with, even when viewed outside of the receipt, such as on a bank or credit card statement. # Supported Currencies Source: https://docs.appcharge.com/merchant-of-record/finance/supported-currencies Appcharge supports a diverse range of global currencies, each categorized by: ### Unit Types: **Zero-decimal:** Currencies that are counted in whole numbers without fractional parts.
    **Two-decimal:** Most currencies are divided into 100 subunits.
    **Three-decimal:** Rarely, some currencies are divided into 1,000 subunits. ### Minimum Charge Amount: This denotes the smallest transactional value accepted in each currency, ensuring transactions meet minimum thresholds where applicable. ### Maximum Charge Amount: The highest transaction value permissible in the respective local currency, facilitating transactions across various scales. ### Converting API Monetary Values All Appcharge APIs return monetary amounts in the smallest currency unit. To convert an API value to a display amount, divide by the multiplier based on the currency's **Lowest Unit Type**: | **Lowest Unit Type** | **Multiplier** | **Example API Value** | **Display Amount** | | - | - | - | - | | Zero-decimal | 1 | `1000` (JPY) | ¥1,000 | | Two-decimal | 100 | `1000` (USD) | \$10.00 | | Three-decimal | 1000 | `1234` (BHD) | 1.234 BHD | **Formula:** display amount = API value ÷ multiplier For example, a Create Checkout Session request with `"price": 1000` and `"currency": "USD"` charges \$10.00. The same API value with `"currency": "JPY"` charges ¥1,000. Appcharge is currently supports the following currencies: | **Currency Name** | **Currency Code** | **Currency Symbol** | **Lowest Unit Type** | **Minimum Charge Amount** | **Maximum Charge Amount** | | | - | - | - | - | - | - | - | | Afghan Afghani | AFN | ؋ | Two-decimal | 57.48 | 431,163.64 | | | Albanian Lek | ALL | L | Two-decimal | 75.45 | 565,940.82 | | | Algerian Dinar | DZD | دج | Two-decimal | 85.00 | 816,239.62 | | | Angolan Kwanza | AOA | Kz | Two-decimal | 693.26 | 5,199,478.78 | | | Argentine Peso | ARS | AR\$ | Two-decimal | 738.11 | 5,535,836.05 | | | Armenian Dram | AMD | ֏ | Two-decimal | 314.01 | 4,500,000.00 | | | Aruban Florin | AWG | AWG | Two-decimal | 1.45 | 10,923.15 | | | Australian Dollar | AUD | AU\$ | Two-decimal | 0.85 | 17,000.00 | | | Azerbaijani Manat | AZN | AZN | Two-decimal | 1.37 | 10,291.52 | | | Bahamian Dollar | BSD | BSD | Two-decimal | 0.80 | 6,067.78 | | | Bahraini Dinar | BHD | BHD | Three-decimal | 0.030 | 228.444 | | | Bangladeshi Taka | BDT | BDT | Two-decimal | 75.00 | 712,961.10 | | | Barbadian Dollar | BBD | BBD | Two-decimal | 1.63 | 12,251.30 | | | Belize Dollar | BZD | BZD | Two-decimal | 1.63 | 12,230.41 | | | Bermudian Dollar | BMD | BMD | Two-decimal | 0.80 | 6,060.00 | | | Bolivian Boliviano | BOB | BOB | Two-decimal | 5.59 | 41,925.27 | | | Bosnia-Herzegovina Convertible Mark | BAM | KM | Two-decimal | 1.47 | 18,000.00 | | | Botswanan Pula | BWP | BWP | Two-decimal | 10.91 | 81,886.09 | | | Brazilian Real | BRL | R\$ | Two-decimal | 3.50 | 60,000.00 | | | Brunei Dollar | BND | BND | Two-decimal | 1.09 | 8,224.13 | | | Burundian Franc | BIF | BIF | Zero-decimal | 2,323 | 17,425,975 | | | Cambodian Riel | KHR | KHR | Two-decimal | 3,327.34 | 24,955,081.76 | | | Canadian Dollar | CAD | CA\$ | Two-decimal | 0.86 | 15,000.00 | | | Cape Verdean Escudo | CVE | CVE | Two-decimal | 82.99 | 622,443.82 | | | Cayman Islands Dollar | KYD | KYD | Two-decimal | 0.67 | 5,056.21 | | | Central African CFA Franc | XAF | FCFA | Zero-decimal | 493 | 3,702,864 | | | CFP Franc | XPF | CFPF | Zero-decimal | 89 | 673,220 | | | Chilean Peso | CLP | \$ | Zero-decimal | 765 | 10,000,000 | | | Chinese Yuan | CNY | ¥ | Two-decimal | 5.87 | 78,000.00 | | | Colombian Peso | COP | CO\$ | Two-decimal | 3,340.27 | 42,046,400.00 | | | Comorian Franc | KMF | KMF | Zero-decimal | 370 | 2,779,115 | | | Congolese Franc | CDF | CDF | Two-decimal | 2,314.91 | 17,361,898.45 | | | Costa Rican Colón | CRC | CRC | Two-decimal | 424.50 | 3,183,769.28 | | | Czech Republic Koruna | CZK | Kč | Two-decimal | 15.00 | 230,000.00 | | | Danish Krone | DKK | kr | Two-decimal | 5.62 | 70,000.00 | | | Djiboutian Franc | DJF | DJF | Zero-decimal | 144 | 1,080,336 | | | Dominican Peso | DOP | DOP | Two-decimal | 47.70 | 357,778.89 | | | East Caribbean Dollar | XCD | \$ | Two-decimal | 2.18 | 16,377.45 | | | Egyptian Pound | EGP | E£ | Two-decimal | 30.00 | 550,000.00 | | | Ethiopian Birr | ETB | ETB | Two-decimal | 46.70 | 350,324.19 | | | Euro | EUR | € | Two-decimal | 0.50 | 10,000.00 | | | Falkland Islands Pound | FKP | FKP | Two-decimal | 0.63 | 4,754.68 | | | Fijian Dollar | FJD | FJD | Two-decimal | 1.83 | 13,738.93 | | | Gambian Dalasi | GMD | GMD | Two-decimal | 54.74 | 410,563.59 | | | Georgian Lari | GEL | GEL | Two-decimal | 2.26 | 16,990.41 | | | Ghanaian Cedi | GHS | GHS | Two-decimal | 12.37 | 92,831.71 | | | Gibraltar Pound | GIP | GIP | Two-decimal | 0.63 | 4,754.68 | | | Guatemalan Quetzal | GTQ | GTQ | Two-decimal | 6.28 | 47,146.87 | | | Guinean Franc | GNF | GNF | Zero-decimal | 6,963 | 52,227,364 | | | Guyanese Dollar | GYD | GYD | Two-decimal | 169.25 | 1,269,443.32 | | | Haitian Gourde | HTG | HTG | Two-decimal | 107.22 | 804,217.96 | | | Honduran Lempira | HNL | HNL | Two-decimal | 20.08 | 150,652.68 | | | Hong Kong Dollar | HKD | HK\$ | Two-decimal | 4.67 | 83,000.00 | | | Hungarian Forint | HUF | Ft | Two-decimal | 298.60 | 3,600,000.00 | | | Indian Rupee | INR | ₹ | Two-decimal | 67.48 | 1,000,000.00 | | | Indonesian Rupiah | IDR | Rp | Two-decimal | 12,000.00 | 180,000,000.00 | | | Iraqi Dinar | IQD | ع.د | Three-decimal | 1,058.480 | 999,999.999 | | | Israeli New Sheqel | ILS | ₪ | Two-decimal | 3.04 | 40,000.00 | | | Jamaican Dollar | JMD | JMD | Two-decimal | 125.87 | 944,062.22 | | | Japanese Yen | JPY | ¥ | Zero-decimal | 93 | 1,800,000 | | | Jordanian Dinar | JOD | JOD | Three-decimal | 0.570 | 8,000.000 | | | Kazakhstani Tenge | KZT | ₸ | Two-decimal | 383.67 | 6,000,000.00 | | | Kenyan Shilling | KES | KES | Two-decimal | 104.03 | 780,226.19 | | | Kuwaiti Dinar | KWD | KWD | Three-decimal | 0.024 | 185.787 | | | Kyrgyzstani Som | KGS | KGS | Two-decimal | 69.77 | 523,279.81 | | | Laotian Kip | LAK | LAK | Two-decimal | 17,853.02 | 133,897,701.97 | | | Lebanese Pound | LBP | LBP | Two-decimal | 72,446.85 | 543,351,436.39 | | | Lesotho Loti | LSL | LSL | Two-decimal | 14.83 | 111,261.69 | | | Liberian Dollar | LRD | LRD | Two-decimal | 157.26 | 1,179,518.78 | | | Libyan Dinar | LYD | LYD | Three-decimal | 3.940 | 29,579.700 | | | Macanese Pataca | MOP | MOP | Two-decimal | 6.51 | 48,826.26 | | | Macedonian Denar | MKD | MKD | Two-decimal | 46.33 | 347,547.03 | | | Malagasy Ariary | MGA | MGA | Zero-decimal | 3,618 | 27,135,423 | | | Malawian Kwacha | MWK | MWK | Two-decimal | 1,400.26 | 10,501,981.79 | | | Malaysian Ringgit | MYR | RM | Two-decimal | 3.81 | 44,000.00 | | | Maldivian Rufiyaa | MVR | MVR | Two-decimal | 12.43 | 93,259.42 | | | Mauritanian Ouguiya | MRU | MRU | Two-decimal | 31.98 | 239,906.05 | | | Mauritian Rupee | MUR | MUR | Two-decimal | 37.93 | 284,515.67 | | | Mexican Peso | MXN | MX\$ | Two-decimal | 16.50 | 200,000.00 | | | Moldovan Leu | MDL | MDL | Two-decimal | 14.49 | 108,699.75 | | | Mongolian Tugrik | MNT | MNT | Two-decimal | 2,787.60 | 20,907,000.59 | | | Moroccan Dirham | MAD | د.م. | Two-decimal | 8.06 | 100,000.00 | | | Mozambican Metical | MZN | MZN | Two-decimal | 51.46 | 385,991.94 | | | Namibian Dollar | NAD | NAD | Two-decimal | 14.83 | 111,259.85 | | | Nepalese Rupee | NPR | NPR | Two-decimal | 108.06 | 810,483.79 | | | Netherlands Antillean Guilder | ANG | ANG | Two-decimal | 1.45 | 10,935.45 | | | New Taiwan Dollar | TWD | NT\$ | Two-decimal | 26.36 | 350,000.00 | | | New Zealand Dollar | NZD | NZ\$ | Two-decimal | 1.33 | 19,000.00 | | | Nicaraguan Córdoba | NIO | NIO | Two-decimal | 29.78 | 223,371.89 | | | Nigerian Naira | NGN | ₦ | Two-decimal | 1,215.63 | 16,000,000.00 | | | Norwegian Krone | NOK | kr | Two-decimal | 7.00 | 120,000.00 | | | Omani Rial | OMR | OMR | Three-decimal | 0.031 | 233.254 | | | Pakistani Rupee | PKR | ₨ | Two-decimal | 170.00 | 3,000,000.00 | | | Panamanian Balboa | PAB | PAB | Two-decimal | 0.80 | 6,067.78 | | | Papua New Guinean Kina | PGK | PGK | Two-decimal | 3.11 | 23,326.13 | | | Paraguayan Guarani | PYG | PYG | Zero-decimal | 6,098 | 45,741,280 | | | Peruvian Nuevo Sol | PEN | S/. | Two-decimal | 3.10 | 38,000.00 | | | Philippine Peso | PHP | ₱ | Two-decimal | 47.52 | 650,000.00 | | | Polish Zloty | PLN | zł | Two-decimal | 3.26 | 40,000.00 | | | Pound Sterling | GBP | £ | Two-decimal | 0.64 | 11,500.00 | | | Qatari Rial | QAR | ﷼ | Two-decimal | 2.94 | 40,000.00 | | | Romanian Leu | RON | lei | Two-decimal | 3.75 | 48,000.00 | | | Rwandan Franc | RWF | RWF | Zero-decimal | 1,055 | 7,915,392 | | | Salvadoran Colón | SVC | SVC | Two-decimal | 7.07 | 53,091.04 | | | Samoan Tala | WST | WST | Two-decimal | 2.26 | 16,971.72 | | | Saudi Riyal | SAR | ﷼ | Two-decimal | 3.03 | 57,100.00 | | | Serbian Dinar | RSD | РСД | Two-decimal | 70.00 | 1,100,000.00 | | | Seychellois Rupee | SCR | SCR | Two-decimal | 11.14 | 83,550.51 | | | Singapore Dollar | SGD | SG\$ | Two-decimal | 0.81 | 14,000.00 | | | Solomon Islands Dollar | SBD | SBD | Two-decimal | 6.81 | 51,142.18 | | | Somali Shilling | SOS | SOS | Two-decimal | 461.36 | 3,460,261.12 | | | South African Rand | ZAR | R | Two-decimal | 14.90 | 180,000.00 | | | South Korean Won | KRW | ₩ | Zero-decimal | 1,122 | 20,000,000 | | | Sri Lankan Rupee | LKR | LKR | Two-decimal | 247.00 | 1,852,513.41 | | | St. Helena Pound | SHP | SHP | Two-decimal | 1.02 | 7,656.51 | | | Surinamese Dollar | SRD | SRD | Two-decimal | 24.91 | 186,881.32 | | | Swazi Lilangeni | SZL | SZL | Two-decimal | 14.83 | 111,259.71 | | | Swedish Krona | SEK | kr | Two-decimal | 6.60 | 100,000.00 | | | Swiss Franc | CHF | CHF | Two-decimal | 0.73 | 9,000.00 | | | Tajikistani Somoni | TJS | TJS | Two-decimal | 8.62 | 64,650.27 | | | Tanzanian Shilling | TZS | TZS | Two-decimal | 2,137.15 | 16,028,698.63 | | | Thai Baht | THB | ฿ | Two-decimal | 29.76 | 340,000.00 | | | Tongan Paʻanga | TOP | TOP | Two-decimal | 1.90 | 14,324.02 | | | Trinidad & Tobago Dollar | TTD | TTD | Two-decimal | 5.49 | 41,208.36 | | | Tunisian Dinar | TND | TND | Three-decimal | 0.254 | 1,905.350 | | | Turkish Lira | TRY | ₺ | Two-decimal | 19.00 | 500,000.00 | | | Ugandan Shilling | UGX | UGX | Zero-decimal | 3,005 | 22,540,409 | | | Ukrainian Hryvnia | UAH | ₴ | Two-decimal | 32.87 | 480,000.00 | | | United Arab Emirates Dirham | AED | د.إ | Two-decimal | 2.96 | 56,000.00 | | | Uruguayan Peso | UYU | UYU | Two-decimal | 31.90 | 239,290.74 | | | US Dollar | USD | \$ | Two-decimal | 0.80 | 15,200.00 | | | Uzbekistani Som | UZS | UZS | Two-decimal | 10,159.46 | 76,195,953.49 | | | Vanuatu Vatu | VUV | VUV | Zero-decimal | 95 | 719,455 | | | Vietnamese Dong | VND | ₫ | Zero-decimal | 20,567 | 290,000,000 | | | West African CFA Franc | XOF | F CFA | Zero-decimal | 493 | 3,702,864 | | | Yemeni Rial | YER | YER | Two-decimal | 202.28 | 1,517,119.59 | | | Zambian Kwacha | ZMW | ZMW | Two-decimal | 19.39 | 145,471.15 | | Appcharge supports every significant currency globally. If an important currency for your players is missing, please get in touch with the Appcharge team. # Supported PayPal Currencies Source: https://docs.appcharge.com/merchant-of-record/finance/supported-paypal-currencies Appcharge supports PayPal in a select number of countries. When [creating a checkout session](/../../api-reference/checkout/checkout-session/create-checkout-session), PayPal only appears as a payment option if `priceDetails.currency` is set to one of the values below. | **Currency** | **Code** | **Country / Region** | | - | - | - | | Australian Dollar | AUD | Australia | | Brazilian Real | BRL | Brazil | | Canadian Dollar | CAD | Canada | | Chinese Renminbi | CNY | China | | Czech Koruna | CZK | Czech Republic | | Danish Krone | DKK | Denmark | | Euro | EUR | Eurozone (Austria, Belgium, Cyprus, Estonia, Finland, France, Germany, Greece, Ireland, Italy, Latvia, Lithuania, Luxembourg, Malta, Netherlands, Portugal, Slovakia, Slovenia, Spain) | | Hong Kong Dollar | HKD | Hong Kong | | Israeli New Shekel | ILS | Israel | | Japanese Yen | JPY | Japan | | Malaysian Ringgit | MYR | Malaysia | | Mexican Peso | MXN | Mexico | | New Zealand Dollar | NZD | New Zealand | | Norwegian Krone | NOK | Norway | | Philippine Peso | PHP | Philippines | | Polish Złoty | PLN | Poland | | Pound Sterling | GBP | United Kingdom | | Singapore Dollar | SGD | Singapore | | Swedish Krona | SEK | Sweden | | Swiss Franc | CHF | Switzerland | | Thai Baht | THB | Thailand | | United States Dollar | USD | United States | # Supported Regions Source: https://docs.appcharge.com/merchant-of-record/finance/supported-regions Appcharge operates globally while adhering to international regulations, delivering Merchant of Record (MoR) services across a diverse range of regions and markets. Our platform is designed to meet various business needs—from Web Store solutions to Checkout and Mobile SDK integrations—and provides comprehensive support wherever we are legally authorized to operate. As a result, we must comply with international sanctions, which restrict our services in certain regions. Currently, these include: * **Belarus** * **Cuba** * **Iran** * **Myanmar** * **North Korea (Democratic People's Republic of Korea)** * **Russia** * **Sudan** * **Syria** * **Venezuela** For these countries, due to compliance with international trade laws and regulations, we are unable to process transactions or offer our MoR services. Appcharge continues to expand and adapt to new markets, and we remain committed to providing secure, compliant, and efficient services globally, where applicable. # Tax Collection and Calculation Source: https://docs.appcharge.com/merchant-of-record/finance/tax-collection-and-calculation Navigating global taxes for digital goods is complex, with regulations and compliance standards varying widely by region. As your Merchant of Record (MoR), Appcharge streamlines this process by handling tax compliance tasks end-to-end. From tax calculation and collection through to filing and remittance, our platform ensures adherence to relevant tax laws, letting you concentrate on delivering quality experiences to your players. This guide outlines Appcharge’s approach to tax compliance and demonstrates how using our MoR service enables seamless, accurate global tax management. # The Role of Appcharge as a Merchant of Record Global tax compliance involves more than just payment processing. As your MoR, Appcharge: * Calculates and collects taxes according to each buyer’s location. * Files all required tax returns and manages remittances in relevant jurisdictions. * Addresses tax audits, reducing compliance-related risks. * Monitors international tax regulations to maintain ongoing compliance. * Provides detailed, transparent tax reporting. # How Taxes Are Calculated and Paid ### 1. Purchase Determination Each transaction begins by identifying the buyer’s location. Appcharge uses IP-based geolocation, ZIP/Postal codes, and other metadata to determine the appropriate tax jurisdiction. * During checkout, taxes are automatically calculated and displayed to the buyer, ensuring transparency and accuracy. * Buyers can update their ZIP/Postal code, and the system will store this information for future transactions. ### 2. Tax Calculation and Collection Appcharge applies the correct tax rates based on the user’s location and local tax rules: * Supports a wide range of tax categories, including VAT, GST, PST, and sales tax. * Presents the tax amount during checkout to maintain clarity. * Collects taxes in local currencies to simplify the buying process. ### 3. Tax Filing and Remittance As MoR, Appcharge manages the complex filing and remittance processes: * **EU VAT Compliance:** Ensures proper VAT registration and adherence to regional directives. * **U.S. Sales Tax Management:** Monitors economic nexus thresholds and meets state-specific obligations. * **Canadian GST, PST, and HST:** Handles both federal and provincial filings. * **Regional Specializations:** Provides solutions tailored to LATAM, APAC, and CIS markets, including unique registration and invoicing requirements. ### 4. Post-Transaction Transparency Buyers receive a confirmation email after purchase, containing: * Total transaction amount. * Applied tax rate and tax amount. * A clear transaction breakdown. # What Sets Appcharge Apart In addition to core compliance functions, Appcharge offers: ### Expert Support and Global Compliance Our compliance specialists and partner advisory firms track evolving tax laws worldwide and provide tailored guidance to maintain adherence across multiple regions. ### Audit Management Appcharge manages tax audits on your behalf, reducing the administrative burden and minimizing risks associated with external compliance reviews. ### Custom Reporting and Analytics Real-time analytics and customizable dashboards enable a granular view of global sales, taxes collected, and regional performance indicators. These tools facilitate data-driven strategy and precise financial planning. ### Localized Invoicing Solutions For regions with distinct invoicing requirements, Appcharge generates compliant, region-specific invoices and delivers them directly to buyers. # Example of a Player’s Checkout Interface During the checkout process, buyers see: * Accurate, upfront tax calculations. * Links to Appcharge’s Privacy Policy, Refund Policy, and Terms & Conditions. * A secure interface designed for compliance without sacrificing simplicity. # Advanced Price Points Management Tools Appcharge provides comprehensive price point management tools, enabling publishers to: * Define, upload, and adjust localized price points in over 80 currencies, factoring in local taxes and market conditions. * Present prices in buyers’ local currencies, creating a more familiar and trustworthy experience. * Maintain consistent net earnings per sale, streamlining financial reporting by eliminating variable currency exchange impacts. * Adjust prices to match local buying power, supporting region-specific promotions and flexible pricing strategies. # About Compliance at Appcharge Source: https://docs.appcharge.com/merchant-of-record/policies/about-compliance-at-appcharge Appcharge is committed to keeping up with the latest compliance regulations and providing our publishers and players with the best security and data privacy. As part of this approach, we continuously monitor and improve our compliance program. We highly prioritize security, compliance, and data protection in every product and technology-building step. We are constantly reviewed, audited, and certificated regarding PCI level 1, SOC 2—Type 2, with all five Trust Principles: Privacy, Security, Availability, Processing Integrity, and Confidentiality. We are also reviewed by external compliance and legal advisors to be aligned with GDPR, COPPA, and CCPA. We partnered with Hub Security and EY as advisors and auditors. **PCI - level 1** Appcharge complies with the Payment Card Industry Data Security Standard (PCI DSS). Our systems are regularly audited to ensure compliance with PCI standards, and AV scans and penetration testing are conducted to identify and address vulnerabilities. Comsec and Hub Security certified us in January 2025 to comply with all the PCI level 1 requirements. **SOC 1 - Type 2** Appcharge holds [SOC 1 Type 2 certification](./soc-1-compliance-at-appcharge) to demonstrate our commitment as a MoR to maintaining controls over financial reporting processes. Independent third-party auditors regularly audit our systems that support billing, transaction processing, and financial transactions to ensure we maintain adequate controls over the completeness, accuracy, and security of financial data. This certification ensures that our merchants and partners can rely on the integrity of our financial systems and processes. Our SOC 1 compliance is validated through EY audits. **SOC 2 - Type 2** Appcharge adheres to all five SOC 2 trust principles of security, availability, processing integrity, confidentiality, and privacy. Regular audits ensure ongoing compliance with SOC 2 requirements. We engage third-party auditors Hub Security and EY to perform rigorous validations to ensure compliance. We have been certified since June 2024 and onwards. **COPPA** Appcharge adheres to the [Children’s Online Privacy Protection Act (COPPA)](./coppa-compliance-policy) and the management of users whose ages meet or exceed the legal age of majority. The obligations and responsibilities detailed herein are divided into two primary domains of operation: Publisher Responsibilities for White-Label Web Store Services and Appcharge Responsibilities as Merchant of Record for Checkout Transactions. **GDPR** [General Data Protection Regulation (GDPR)](./about-gdpr-at-appcharge). GDPR compliance ensures the protection of EU citizens' personal data. Appcharge is committed to saving and protecting all users' private information. We've implemented measures such as data encryption and consent management. Regular audits ensure continuous alignment with GDPR requirements. Hub Security reviews us on a yearly basis and confirms that we comply with all the GDPR requirements. **CCPA** California Consumer Privacy Act (CCPA) compliance ensures transparency and gives California residents control over their personal information​. Appcharge is committed to upholding the privacy rights granted by CCPA, including consumers’ right to know what personal data we collect and how it is used, the right to request deletion of that data, and the right to opt out of any sale of their personal information​. We’ve implemented clear notices at data collection points and in our privacy policy to fulfill CCPA’s transparency requirements, informing users about what information is collected and why​. Regular reviews of our data practices help maintain continuous alignment with CCPA requirements so we stay current with California privacy laws and uphold all related consumer protections. # About GDPR Compliance at Appcharge Source: https://docs.appcharge.com/merchant-of-record/policies/about-gdpr-at-appcharge Appcharge is fully committed to complying with the **General Data Protection Regulation (GDPR)** and protecting the privacy of all players (end-users) and partners. As a Merchant of Record in financial transactions, Appcharge integrates data protection into its financial operations to ensure **personal data is handled lawfully, transparently, and securely** at every step. Appcharge continuously monitors and improves its compliance program to ensure compliance with the latest regulations. We work closely with external compliance and legal experts to ensure complete alignment with GDPR and other data privacy laws. Appcharge partners with reputable auditors (such as EY and Hub Security) who review our systems annually and verify that we meet all GDPR requirements for any significant change. To safeguard personal data, Appcharge has implemented robust measures, including **strong data encryption and consent management systems**. These measures ensure that any personal information we collect from players (for example, during account creation or checkout) is securely stored and used only with appropriate consent or legal basis. We also conduct regular internal and external **audits of our data practices** to maintain continuous alignment with GDPR standards. Under GDPR, individuals have strong rights over their personal data. One key right is the **Right to Erasure** (the "right to be forgotten"), which allows a person to request deletion of their personal data held by an organization. Appcharge fully respects and upholds these data subject rights. We inform players of their privacy rights – including the right to request data deletion – in our **Privacy Policy**, which is readily accessible during the checkout process and provided again on purchase receipts. This ensures that every player knows how their data is used and how they can exercise their GDPR rights. When a player wishes to exercise their right to erasure, **Appcharge provides clear and convenient channels to do so**. We facilitate deletion requests without undue delay, as required by law. Our internal processes are designed to streamline the handling of such requests while maintaining compliance with any necessary legal or financial record-keeping obligations. ## Process for Data Deletion Requests (GDPR Article 17) If a player (end-user) wants their personal data removed from Appcharge’s systems, we have the following **data deletion request process** in place, consistent with GDPR requirements: * **Direct Requests by Players:** Players can contact Appcharge directly via our dedicated privacy email: **[privacy@appcharge.com](mailto:privacy@appcharge.com)** to request deletion of their personal data. For security, the player should include information necessary to identify their account (such as their player ID or the email used for Appcharge services) and a clear statement that they wish to have their data erased. Upon receiving a deletion request, Appcharge will verify the requester’s identity and entitlement to the data (to prevent unauthorized deletions), then proceed to erase or anonymize the player’s personal data in our records. We will also **respond to the player, confirming that data deletion has been completed** or providing information if specific data must be retained for legal reasons. * **Requests via Game Publishers:** Appcharge also recognizes that players might submit data privacy requests to the game publisher (our partner) rather than directly to us. To accommodate this, we enable our **publishers to forward player deletion requests** to Appcharge on the player’s behalf. The publisher should open a support ticket with Appcharge, providing the relevant **player identifiers and details of the request**. Once notified, Appcharge will treat this request with the same urgency as a direct request – our team will perform the necessary deletions of the player’s data from Appcharge systems. After completion, we **report back to the publisher**, confirming that the player’s data has been deleted, so the publisher can, in turn, inform the player. * **Timely Response:** Appcharge is committed to handling GDPR erasure requests swiftly. We aim to **complete data deletion within five working days** of receiving a valid request (whether directly from a player or via a publisher). This SLA is well within the GDPR’s required timeframe (GDPR allows up to 1 month for the fulfillment of erasure requests). Players will be notified once their request has been fulfilled, and all corresponding personal data (subject to the exceptions noted below) will be purged from our active systems. ## GDPR Compliance in Financial Operations and Data Retention As a payments service, Appcharge must balance GDPR obligations with specific financial and legal requirements. We only collect and process personal data that is **necessary for providing our services (for example, billing information for transactions), in line with the GDPR’s principle of data minimization**. If a player’s personal data is no longer needed for these purposes or if the player withdraws consent, we will delete the data upon request in accordance with GDPR. It is important to note that in some cases, **Appcharge may be legally required to retain specific transactional data** even after a deletion request—for example, to comply with financial regulations, tax laws, fraud-prevention laws, or record-keeping laws that mandate retention of payment records for a set period. In such cases, we will **retain only the data that is strictly necessary** and for the minimum duration required by law. Any data kept for legal compliance will remain securely protected and **will not be used for any other purpose** beyond fulfilling those obligations. Apart from such exceptions, all personal information that can be deleted will be thoroughly erased from our systems as part of the erasure process. Appcharge’s approach ensures that GDPR compliance is **integrated with our financial operations**. We uphold players’ privacy rights without compromising the integrity of financial records or our ability to meet legal duties. By doing so, Appcharge maintains trust with both players and publishers: personal data is handled with care, **deletion requests are honored promptly**, and necessary safeguards are observed. This operational philosophy reflects our dual commitment to user privacy and to running a compliant, reliable financial service for the gaming community. # California AB 2426 Compliance Policy Source: https://docs.appcharge.com/merchant-of-record/policies/california-law-compliance-policy In compliance with California law (AB 2426), Appcharge ensures transparency in virtual item purchases for players in California. This is part of our commitment to legal compliance and providing clarity regarding in-game purchases. ### What Are Virtual Items? Virtual items are digital assets purchased or earned within a game or application. These assets are accessed through a player's account and are subject to the terms and conditions established by the publisher. ### Policy Overview For players located in California, the following legal text will appear during the checkout process when purchasing virtual items: `An in-game purchase grants a license to Virtual Items. For full license conditions, visit the partner Terms and Conditions` > **Note:** A link to the publisher's Terms and Conditions will be made available in this text. This message clarifies that the purchase grants a license to use virtual items, rather than ownership of those items. ### Applicability This update is applicable only to players located in California at the time of the purchase. The legal text will automatically display during the checkout process for eligible transactions. ### Why This Update? California Assembly Bill 2426 establishes transparency requirements for virtual purchases, emphasizing the distinction between licensing and ownership of virtual items. By including this message, Appcharge ensures compliance with the law and clear communication of terms to players. # Cookies Policy Source: https://docs.appcharge.com/merchant-of-record/policies/cookies-policy This Cookie Policy is an integral part of Appcharge's approach to privacy and data protection. It complements our Privacy Policy, which outlines how we collect, use, and share data. For more details on our data handling practices, please refer to our Privacy Policy. Cookies are small text files stored on your device by websites you visit. They are widely used to make websites work more efficiently, as well as to provide information to the owners of the site. This document explains the role of cookies at Appcharge, detailing their purposes and how they are used in both our web store and during the checkout process. For more details, please refer to our [Cookie Policy](https://appcharge.com/cookie-policy/). ## Cookies Policy for Web Store ### Introduction At Appcharge, we prioritize your privacy while enhancing your browsing experience. We do not store cookies directly, but our web store integrates with third-party services like Facebook, Google, and Apple, which use cookies for functionality and user engagement. ### Third-Party Services * **Facebook & Google:** Used to enhance user engagement through analytics and social interactions. * **Apple:** Provides seamless functionality across Apple devices, improving device compatibility and enhancing the user experience within our web store. ### Cookie Usage * **Functional Cookies:** Essential for navigating our web store and using features such as secure log-ins. * **Performance Cookies:** These cookies help us collect information on how visitors interact with our web store, aiding in optimizing the site to better meet your needs. ## Cookies Policy for Checkout ### Introduction During the checkout process, Appcharge emphasizes security and efficient transaction handling. We do not store cookies directly but collaborate with third-party providers like Stripe and Nuvei, who employ necessary cookies to secure and streamline your transactions. ### Third-Party Services * **Stripe & Nuvei:** These are critical for secure and efficient payment processing, essential for completing purchases. ### Cookie Usage * **Security Cookies:** Critical for preventing fraud and ensuring the integrity of your transaction. * **Optimization Cookies:** Help refine the checkout process, ensuring it is smooth and efficient by monitoring performance and identifying any issues in real time. # COPPA Policy Source: https://docs.appcharge.com/merchant-of-record/policies/coppa-compliance-policy Appcharge adheres to the Children’s Online Privacy Protection Act (COPPA) and the management of users whose ages meet or exceed the legal age of majority. The obligations and responsibilities detailed herein are divided into two primary domains of operation: Publisher Responsibilities for White-Label Web Store Services and Appcharge Responsibilities as Merchant of Record for Checkout Transactions. # Publisher Responsibilities for White-Label Web Store Services Appcharge provides a white-label service enabling game publishers to operate branded online storefronts. Player login to the web store is approved by the publisher’s system in real time, allowing the publisher to reject unapproved accounts. As a result, Appcharge does not re-verify compliance with COPPA-related terms of use, as these terms are addressed during the player’s first login to the game. Publishers are responsible for verifying user identities and ensuring compliance with regulations, including age restrictions and parental consent under COPPA, before granting access to the game application. Only players approved by the publisher can subsequently log into the web store. Appcharge functions as an extension of the publisher’s platform, providing technical infrastructure without assuming compliance verification responsibilities. # Appcharge Responsibilities as Merchant of Record for Checkout Transactions In its role as Merchant of Record, Appcharge oversees compliance with financial transaction standards. Appcharge’s COPPA and age policy is incorporated into the End-User License Agreement (EULA). Users affirm their age eligibility by agreeing to the EULA, which specifies that they must meet the legal age requirements. Appcharge relies on the publisher’s verification of user compliance. If a user is found to be non-compliant, Appcharge terminates their access to its services. # Player Policies Source: https://docs.appcharge.com/merchant-of-record/policies/player-policies At Appcharge, game publishers can integrate their game-specific policies into the Web Store experience, ensuring that users are presented with the appropriate legal documents at relevant stages of their user journey. Additionally, Appcharge policies govern the Checkout experience. * The Web Store mainly features the publisher’s policies. * The Checkout experience is governed by Appcharge’s policies. * The Web Store includes cookies consent notices which are managed by Appcharge. For more information, please review our [Cookies Policy](https://appcharge.com/cookie-policy/) and our [Cookies Policy documentation](./cookies-policy). ### Cookies Consent and Settings The Web Store interface will present users with a cookies consent notice, located in the footer. This notice allows users to accept or adjust their cookie preferences. Users can choose to accept all cookies or modify their settings as needed. The available cookie categories include: 1. **Strictly Necessary Cookies:** These cookies are essential for the operation of the site, enabling functionality such as user interaction tracking and device-based actions. Necessary cookies are required for logging players in and ensuring a seamless experience. 2. **Analytics Cookies:** These cookies collect data to optimize the website experience, enhancing the site's functionality. These cookies are not mandatory and can be adjusted according to user preferences. By selecting "Adjust cookies," users can manage their preferences for both necessary and analytics cookies. Changes are saved by clicking the "Save settings" button. The cookie consent popup works before player authentication. After a player accepts all cookies or saves partial cookie preferences, the popup doesn't appear again unless they clear their browser cache. Necessary cookies are mandatory for logging the player in and cannot be disabled. ### Web Store: White Labeling Your Brand and Policies After logging in, users accessing the game’s web store will be presented with the game’s Privacy Policy and Terms & Conditions in the footer. These documents are specific to the game and outline the store's terms and data-handling practices. The documents are accessible via a popup, without requiring the user to leave the web store. To display the relevant policies to players, the Privacy Policy and Terms & Conditions must be uploaded to the Appcharge platform. For further guidance, refer to [Privacy Policy and Terms & Conditions Links](/../../guides/publisher-dashboard/add-terms-and-policies). ### Checkout: Appcharge as Merchant of Record At the point of checkout, Appcharge acts as the Merchant of Record (MoR) for all transactions. As the MoR, Appcharge assumes responsibility for payment processing and compliance with applicable regulations and industry standards. During checkout, users will have the opportunity to review Appcharge’s policies, which include: * End User License Agreement (EULA) * Privacy Policy * Refund Policy * Terms & Conditions # SOC 1 Compliance at Appcharge Source: https://docs.appcharge.com/merchant-of-record/policies/soc-1-compliance-at-appcharge ## What is SOC 1? SOC 1 (Service Organization Control 1) is an auditing standard specifically designed for service organizations that process financial transactions or manage controls that could materially impact clients’ financial reporting. Maintained by the American Institute of Certified Public Accountants (AICPA), SOC 1 ensures that a service provider has implemented appropriate controls over financial processes. SOC 1 focuses on the control environment and processes that affect financial transaction processing, reporting accuracy, and the integrity of financial data maintained on behalf of clients. ## Why SOC 1 Matters As a Merchant of Record (MoR) and payment processor, Appcharge handles critical financial operations for our merchants, including transaction processing, billing, revenue management, and financial data handling. Given the material impact these operations have on our merchants’ financial statements and business operations, SOC 1 certification is essential to ensure: * **Financial Accuracy:** Controls over billing, revenue recognition, and transaction recording * **Transaction Integrity:** Safeguards ensuring all transactions are thoroughly and accurately processed * **Financial Data Security:** Protection of sensitive financial information and payment data * **Reliable Reporting:** Assurance that financial reports generated through our systems are accurate and timely * **Audit Trail Maintenance:** Complete and traceable records of all financial transactions ## Appcharge’s SOC 1 Certification Appcharge maintains SOC 1 Type 2 certification, which demonstrates that our controls over financial processes have been tested and validated over an extended period. This Type 2 certification provides the highest level of assurance, showing that our financial controls are not only effectively designed but also operating as intended. **Our SOC 1 compliance program includes:** **Regular Independent Audits:** We engage leading external auditing firms to conduct comprehensive SOC 1 Type 2 audits of our financial systems and processes. These audits evaluate the design and operating effectiveness of our controls. **Financial Transaction Controls:** Appcharge has implemented robust controls over all aspects of financial transaction processing, including transaction validation, billing accuracy, revenue recognition, and financial data integrity. **Access and Security Controls:** We maintain strict access controls over financial systems, ensuring that only authorized personnel can process financial transactions or access sensitive financial data. All access is logged and monitored. **Data Integrity and Reconciliation:** Regular reconciliation procedures ensure that all financial transactions are recorded accurately, completely, and in the correct accounting period. Our systems include built-in controls to detect and prevent errors or anomalies. **System Availability:** We maintain infrastructure and processes to ensure the continuous availability and reliability of financial transaction processing systems, minimizing service disruptions that could impact our merchants’ operations. **Change Management:** All changes to financial systems and processes are subject to formal change management procedures, including testing, approval, and documentation, to ensure that controls remain effective. ## SOC 1 and Your Financial Audit If you’re a merchant working with Appcharge, your external auditors may request access to our SOC 1 report as part of their evaluation of your internal controls over financial reporting. Our SOC 1 Type 2 certification provides the comprehensive evidence auditors need to gain assurance over the controls operating within our systems. We can provide SOC 1 reports and audit evidence to your auditors upon request through our standard compliance inquiry process. ## Continuous Compliance Appcharge treats SOC 1 compliance as an ongoing commitment, not a one-time achievement. To maintain the highest standards, Appcharge: * Conducts regular SOC 1 audits to maintain our Type 2 certification * Continuously monitors and tests our financial controls * Updates our control environment in response to evolving business needs and emerging risks * Works with industry-leading audit firms to ensure ongoing compliance and excellence For questions about Appcharge's SOC 1 compliance or to request documentation for your audit, please contact our compliance team at [compliance@appcharge.com](mailto:compliance@appcharge.com) or reach out through our support portal. # Texas SB 2420 Compliance Policy Source: https://docs.appcharge.com/merchant-of-record/policies/texas-law-compliance-policy Starting January 1, 2026, Texas’s SB2420 takes effect, with Utah (May 7, 2026) and Louisiana (July 1, 2026) following. These laws require app store operators to verify user age and obtain parental consent for any app download or in-app purchase by a minor (under 18). Their purpose is to prevent unauthorized transactions by minors and ensure age-appropriate access to digital content. SB2420 does not expand or go beyond COPPA; these are two separate regulations. SB2420 governs transactions by users under 18, while COPPA governs data collection from users under 13. SB2420 may trigger COPPA obligations because it can create conditions that activate COPPA requirements. ## Age Verification and Parental Consent Appcharge does not verify player ages. Each game publisher is responsible for: * Verifying player age during account creation * Linking any minor’s account to a verified parent or guardian account Based on the age category and parental-consent status stored in the publisher’s system, the publisher must allow or deny that user access to the Appcharge web store and checkout. Appcharge enables compliance by blocking prohibited users before any data is collected. ## Data Use and Privacy Any personal data collected for age verification or parental consent must remain entirely within the publisher’s systems. Appcharge shall not know user ages, and publishers may not share this information with Appcharge. Appcharge relies solely on the publisher’s verification and access-control mechanisms. When the publisher allows a player to enter the web store or redirects the player to Appcharge Checkout, the publisher represents that only users who are permitted to transact are being sent. ## References * [Texas SB 2420 (App Store Accountability Act)](https://capitol.texas.gov/tlodocs/89R/billtext/html/SB02420S.HTM) * [Utah Senate Bill 142 (SB 142)](https://le.utah.gov/~2025/bills/static/SB0142.html) * [Louisiana House Bill 570 (HB 570)](https://www.legis.la.gov/Legis/BillInfo.aspx?i=248616) # About Security at Appcharge Source: https://docs.appcharge.com/merchant-of-record/security/about-security-at-appcharge **Intro: Security at Appcharge** At Appcharge, we are committed to providing our publishers – and their players – with best-in-class security and data privacy. Our platform is built from the ground up with stringent security measures and privacy-by-design principles. We maintain a robust infrastructure and adhere to industry-leading standards to ensure data is safeguarded at every layer. In addition, we continuously update our practices to meet or exceed evolving security benchmarks so that our publishers can trust us with their most sensitive data. This Security Policy outlines our key security and privacy practices, including protecting data, ensuring secure operations, and maintaining compliance. From encryption and data segregation to DDoS protection and fraud prevention, Appcharge implements enterprise-grade controls to protect our platform and customers. We also adhere to leading compliance frameworks such as PCI-DSS Level 1 and SOC 2 Type II, undergo regular audits and penetration testing, and maintain an active security incident response program. **1. Data Security and Privacy** **1.1 Encryption at Rest and Transit:** All sensitive data handled by Appcharge is encrypted at rest and in transit. We use strong encryption algorithms to protect data stored in our databases, file systems, and backups. Likewise, any data in transit between Appcharge and publisher systems or between Appcharge and end-user devices is protected using TLS (Transport Layer Security) encryption. By enforcing HTTPS for all external communication, we prevent eavesdropping and tampering, ensuring that personal information and payment details remain confidential during transmission. **1.2 Secure Data Storage and Backups:** Appcharge follows the best data storage, backup, and retention practices. Our production databases reside in secure, access-controlled environments with encryption to prevent unauthorized access to stored information. We perform regular encrypted backups of critical data and store them for disaster recovery. **1.3 Secure Development Lifecycle**: Security is deeply ingrained in our software development lifecycle. Appcharge follows a “secure by design” philosophy – every feature and system component is planned with security and privacy considerations. Our developers are trained in secure coding practices and follow industry guidelines (such as OWASP best practices) to avoid common vulnerabilities. We conduct thorough code reviews, automated security testing (including static code analysis and dependency vulnerability scanning), and threat modeling for new features. Before deployment, changes pass through quality assurance and security checks to catch and fix potential issues. By integrating these practices into each stage of development, we minimize risks and ensure that our platform remains robust against emerging threats. **2. Secure Communication Between Appcharge and Publishers** All communication between Appcharge and our publishers (as well as any communication with end-user applications) is protected with strong security protocols to prevent interception or unauthorized access. **2.1 HTTPS and Mutual Authentication:** Appcharge requires secure HTTPS (TLS) connections for all interactions with our APIs and web interfaces. This ensures data in transit is encrypted and guarded against eavesdropping or man-in-the-middle attacks. We support mutual TLS authentication (mTLS) for server-to-server integrations that demand extra security. With mTLS, the client and server present digital certificates and verify each other’s identity, establishing a two-way trust. This mechanism is used for sensitive communication channels, adding a layer of assurance that both parties are legitimate. **2.2 API Authentication and Authorization:** Appcharge’s RESTful API access is secured through token-based authentication. Each publisher is issued secure API credentials (such as an API key or OAuth token) that accompany API calls to Appcharge. These tokens are unique to each publisher and carry specific permission scopes, ensuring that API consumers can only perform actions or access data within their authorization. We never transmit sensitive API keys in insecure ways, and publishers can rotate or revoke their credentials in case of compromise. All API requests are validated on our end for proper authentication and are subject to strict authorization checks, so only approved and intended requests succeed. **2.3 Signed Webhooks and Callbacks:** To facilitate real-time communication to our publishers’ systems (for example, to notify about transactions or events), Appcharge uses secure webhooks with signature verification. When Appcharge sends a webhook POST to a publisher-defined endpoint, the payload is accompanied by a cryptographic signature header. This signature is generated using a secret token unique to the publisher. The publisher’s server can compute its own signature of the payload and compare it to the signature provided, thereby verifying that the webhook truly came from Appcharge and was not altered in transit. Additionally, each webhook includes an identifier (such as a publisher account ID or webhook ID) to ensure the receiving system can validate the context of the message. By using signed webhooks and requiring verification, we protect against fraudulent or replayed notifications and ensure secure, reliable communication between Appcharge and publisher systems. **3. DDoS Prevention and Scalable Infrastructure** Appcharge’s infrastructure is engineered for both security and high availability, protecting our platform from attacks while ensuring reliable performance for all publishers. **3.1 Network Security and Hardening:** We host our systems using a Virtual Private Cloud (VPC) architecture in a modern cloud environment. This means our critical servers and databases operate within isolated network segments not directly exposed to the public internet. We carefully limit and monitor the few public entry points to our system (such as our API endpoints). These entry points are further protected by additional layers like load balancers and web application firewalls. All servers are hardened following industry best practices: we regularly apply security patches, disable unnecessary services, and enforce strict security group rules to control network traffic. By minimizing the attack surface and isolating internal components, we significantly reduce the risk of unauthorized intrusion. **3.2 Automated DDoS Mitigation:** To guard against Distributed Denial of Service (DDoS) attacks, Appcharge leverages both cloud provider defenses and our own monitoring systems. Our platform benefits from built-in DDoS protection services offered by our cloud hosting providers, which can absorb and filter large volumes of malicious traffic before it reaches our application. We also utilize content delivery networks (CDNs) and caching layers for our public-facing endpoints, which help disperse traffic globally and mitigate localized traffic floods. Additionally, our infrastructure can automatically scale its capacity (horizontal scaling) during traffic surges, ensuring that legitimate requests continue to be served even under extreme load. These measures allow us to maintain service availability and responsiveness, even when under attack. **3.3 Continuous Monitoring and Anomaly Detection:** Appcharge employs continuous monitoring of network traffic and system performance. We have automated alerting in place that triggers if unusual patterns are detected – for example, a sudden spike in requests, traffic from unexpected regions, or other anomalies that could indicate a DDoS attempt or intrusion. Our security team is notified in real time and can rapidly activate countermeasures, such as traffic filtering rules or scaling adjustments. We integrate advanced tools like Wiz to scan our cloud environment for security issues or misconfigurations, and any findings are addressed promptly. Furthermore, our infrastructure is managed as code using Terraform, which means our environments are consistently configured and can be quickly replicated or restored. This infrastructure-as-code approach, combined with automated security scans, ensures that our deployment remains resilient and any needed fixes can be deployed swiftly. **3.4 Transparency and Uptime:** We believe in being transparent about our system status and performance. Appcharge maintains a public Status Page (accessible at appcharge.instatus.com) that provides real-time updates on our platform’s health, uptime, and any incidents. This allows publishers and users to stay informed about service availability. Our real-time monitoring is directly tied into this status page – if any critical component goes down or experiences issues, the status page is updated promptly so stakeholders have immediate visibility. By openly communicating our uptime and incident history, we demonstrate our commitment to reliability and accountability. In the rare event of an outage or security incident, we update the status page with timely information and resolution progress in addition to executing our incident response procedures. **4. Fraud Prevention** Appcharge takes proactive measures to detect and prevent fraud, ensuring that transactions and platform usage are legitimate and trustworthy. **4.1 Real-Time Transaction Monitoring:** Every transaction and key user action on the Appcharge platform is monitored in real time for signs of fraud or abuse. We use automated systems and analytics to flag unusual patterns – for example, a sudden surge of purchases from a single account, mismatched geolocation data for payments, or repeated failed payment attempts. When our system’s rules or machine learning models identify suspicious activity, they can automatically halt the transaction and mark the account for review. Our fraud prevention team receives alerts of high-risk activity and can investigate immediately, helping to stop fraudulent transactions before they are completed. This protects our publishers from chargebacks, financial loss, and unauthorized usage of their services. **4.2 Secure Request Validation and Anti-Replay:** All requests to Appcharge’s APIs and services undergo strict validation to ensure they are legitimate. We employ techniques like timestamping and nonce tokens on sensitive operations, along with cryptographic signatures (as mentioned for API calls and webhooks), to guard against replay attacks and request tampering. For instance, an API call might require a current timestamp and a unique nonce in addition to the authorization token; if the same request were intercepted and tried again later, it would be rejected as invalid. Similarly, any request with an invalid signature or expired token is not processed. These measures ensure that an attacker cannot simply capture network traffic and reuse it to perform malicious actions on the platform. **4.3 Least Privilege and Internal Audits:** Preventing fraud isn’t just about external threats – we also guard against insider risks and privilege misuse. Appcharge adheres to the principle of least privilege across all internal systems. Employees and service accounts are granted only the minimum access rights required for their duties, and any access to especially sensitive systems (such as financial data or production environments) requires additional managerial approval. We maintain detailed logs of administrative actions and regularly review these logs and user access roles to ensure permissions remain appropriate. These audits verify that no excessive privileges have been given and that access is promptly revoked when an employee’s role changes or they leave the company. By tightly controlling and reviewing internal access, we significantly reduce the risk of insider fraud or unauthorized changes. Additionally, critical actions (such as changing payout details or altering security settings) may require multi-factor authentication or secondary approval, adding extra safeguards against fraudulent changes. **5. Compliance and Security Assurance** In addition to the practices above, Appcharge meets rigorous industry standards and undergoes continuous evaluation to give our customers confidence in our security posture. **5.1 PCI-DSS Level 1 Certified:** As a platform handling payment transactions, Appcharge is fully compliant with the Payment Card Industry Data Security Standard (PCI-DSS) at Level 1 – the highest level of certification. This certification is granted only to organizations that demonstrate the strongest controls over cardholder data. We undergo annual PCI audits and regular network scans by independent Qualified Security Assessors. Our PCI compliance covers areas such as maintaining a secure network, protecting card data at rest and in transit, implementing strong access control measures, and regular testing and monitoring of our networks. For our publishers, this means any payment information processed via Appcharge is handled under strict security requirements set by the major credit card companies. **5.2 SOC 2 Type II Audited:** Appcharge also undergoes SOC 2 Type II examinations by independent auditors. This attestation evaluates the design and operating effectiveness of our security controls over a period of time (typically 6+ months) under the AICPA’s Trust Services Criteria. Our SOC 2 report covers principles including security, availability, and confidentiality, verifying that we have appropriate safeguards in place and that they are functioning continuously. Enterprise customers often require a SOC 2 report as part of their vendor due diligence, and Appcharge is proud to provide this assurance of our operational security. (For interested clients, we can furnish our latest SOC 2 Type II report under NDA upon request.) **5.3 Third-Party Penetration Testing and Reviews:** To ensure our defenses remain strong, Appcharge regularly employs third-party security firms to conduct penetration tests on our applications and infrastructure. These ethical hacking exercises simulate real-world attacks, probing for any vulnerabilities or weaknesses. If any issue is found, we prioritize its remediation and address it immediately. We also use specialized security tools and services (such as vulnerability scanners and code analysis platforms) to continuously test our systems. In addition, our development team performs peer code reviews with a focus on security and uses automated testing in our CI/CD pipeline to catch vulnerabilities before changes reach production. This combination of independent third-party testing and rigorous internal review processes helps maintain a high-security bar. **5.4 Employee Training and Incident Response:** Security is an organization-wide priority at Appcharge. All employees undergo background checks and sign confidentiality and acceptable use agreements when hired. We provide ongoing security awareness training to every team member – covering topics like phishing prevention, data handling policies, and incident reporting procedures – to foster a strong security culture. Appcharge also maintains an up-to-date incident response plan. We have a dedicated on-call response team and defined protocols to address security incidents or data breaches swiftly and effectively. Regular drills and scenario simulations are conducted to ensure readiness. In the event of an incident, we will immediately work to contain and remediate the issue, notify affected parties and authorities as appropriate, and conduct a post-incident analysis to improve our processes. Our commitment to preparedness and continuous improvement means we can react quickly to protect our publishers and their users if a security issue arises. # Appcharge Bug Bounty Program Source: https://docs.appcharge.com/merchant-of-record/security/appcharge-bug-bounty-program At Appcharge, we’re committed to giving developers and players an experience they can count on—smooth, secure, and frustration-free. We continuously test, refine, and strengthen every part of our platform because trust is built on proactive improvement, not quick fixes. Think you’ve spotted a vulnerability or discovered a way we can level-up our processes? Let us know! When your report qualifies for a bounty, we’ll jump on the fix and email you the reward amount and payout timeline. Thanks for helping us keep Appcharge running at the top of the game. Happy hunting! ### Rules of Engagement We welcome detailed, reproducible reports that help us keep the Appcharge platform secure. Please read and follow these guidelines before submitting. *** #### 1. What to Include in Your Report Submit the form below and be as specific as possible. A report without a working proof of concept (PoC) will be closed as **Informational**. * **URL or product** where the issue occurs * **Bug category** (e.g., XSS, IDOR, logic flaw) * **Step-by-step reproduction** and validation steps * **Impact assessment** – why this matters and what harm it could cause * **Your remediation suggestions** *** #### 2. Testing & Conduct Guidelines | Do | Don’t | | - | - | | Use only your own Appcharge test accounts. | Modify, delete, or exfiltrate data that isn’t yours. | | Limit automated tools to **≤ 15 requests/sec** and set your User-Agent to `appcharge-bugbounty-your-email@`. | Run brute-force, denial-of-service, or resource-exhaustion attacks. | | Probe our services responsibly. | Target Appcharge employees, customers, or facilities (no social engineering, phishing, or physical intrusion). | > **Heads-up:** Scans with high QPS trigger automatic blocks. Reinstatement can take time, so please configure it correctly. *** #### 3. After You Send the Bug Bounty Report 1. You’ll receive an automated acknowledgment (and a request for extra details if needed). 2. Our security team reviews and attempts to reproduce your report. 3. If validated, we’ll confirm the finding, prioritize a fix, and update you on bounty eligibility. ### Rewards & Severity We align our payouts with the CVSS 3.1 severity scale. While the ranges below show the maximum typical reward for each level, final amounts are always at Appcharge’s discretion. Exceptional, well-documented findings may earn a bonus, while issues with onerous preconditions or strong compensating controls may be reduced. | Severity | Reward (USD) | | - | - | | **Critical** | **\$1,000 – \$2,000** | | **High** | **\$800** | | **Medium** | **\$500** | | **Low** | **\$100** | **Duplicates & Root-Cause Overlap** * The *first* fully reproducible report wins the bounty. * Several bugs stemming from one underlying flaw are treated as a single vulnerability (one payout). **Timing**\ We award bounties upon validation and keep you in the loop as we work through remediation. Some cases require extra analysis—if so, payment may follow a bit later. ### Payment Options We may choose to use one of these two ways to provide your bounty: 1. **PayPal** – We’ll transfer the funds to your personal account. (You’ll need to confirm the account details belong to you.) 2. **Amazon Gift Card** – We can email you an Amazon gift card for the full reward amount. ### Report email submission All reports should be sent here: [bountyprogram@appcharge.com](mailto:bountyprogram@appcharge.com) Thanks for helping us keep the Appcharge ecosystem secure! # Secure Communication with the Appcharge Platform Source: https://docs.appcharge.com/merchant-of-record/security/appcharge-to-publisher-secure-communication All communication between Appcharge and the system is secure and authenticated using HTTPS, along with authentication methods such as secret tokens and signature hashing. The two systems communicate via APIs and webhooks, depending on the trigger for the communication. For webhooks, Appcharge uses signature hashing to secure data exchange between the platforms. The primary key for this process is available in the Appcharge dashboard, under the Admin panel in the Integration tab. When a request is sent, Appcharge includes a unique account token and generates a hash signature using a secret key. This signature is attached to the request. The publisher’s server then verifies the signature by recalculating the hash with the same secret key and comparing it to the received signature. If the signatures match, the request is authenticated, ensuring data integrity and preventing unauthorized access. For API communication, account tokens are used between the publisher and Appcharge. When a request is made, the publisher includes a unique account token. The Appcharge server receives the request, verifies the token, and if it matches, authenticates the request, ensuring data integrity and preventing unauthorized access. # Web Store & Checkout Cookies Source: https://docs.appcharge.com/merchant-of-record/security/webstore-and-checkout-cookies ## Web Store Here is a table summarizing the various cookies used by our web store with different vendors to enhance user experience and security: | Name | Type | Expiration | Vendor | Description | | - | - | - | - | - | | fbsm\_ | Cookie | 1 Year | Facebook | One of FB cookies used for logging in and saving users info | | fbsr\_ | Cookie | 40 Days | Facebook | One of FB cookies used for logging in and saving users info | | mp\_ | Cookie | 1 Year | Mixpanel | Providing Appcharge logging information | | \_ga | Cookie | \~6 Months | Google | Google Analytics, enables the service to distinguish one visitor from another | | \_clck | Cookie | 1 Year | Microsoft | Cookie created by Microsoft Clarity that gives businesses more accurate analytics | | \_\_stripe\_mid | Cookie | \~1 Year | Stripe | Stripe uses this cookie to provide fraud prevention | | otp\_accessToken | Session | N/A | Appcharge | Appcharge uses this cookie to save the OTP token until the session ends | ## Checkout Here is a table summarizing the various cookies used by our checkout with different vendors to enhance user experience and security: | Name | Type | Expiration | Vendor | Description | | - | - | - | - | - | | mp\_ | Cookie | 1 Year | Mixpanel | Providing Appcharge logging information | | \_\_stripe\_mid | Cookie | \~1 Year | Stripe | Stripe uses this cookie to provide fraud prevention | # Changelog Source: https://docs.appcharge.com/sdks/checkout/frontend-sdk/frontend-sdk-changelog See the changes to the Frontend SDK. Make sure to download the latest version. ## Error codes for fatal failures **Release notes:** * New `error` object present on `onPaymentIntentFailed` and `onOrderCompletedFailed` for fatal failures. For example, when the checkout session fails to open (`onPaymentIntentFailed`), or when there's an issue with the [Grant Award Callback](/../../api-reference/checkout/awards/grant-award-callback), such as an invalid link (`onOrderCompletedFailed`). * Added a [Troubleshooting](./troubleshooting) article that lists the possible error codes returned in the `error.code` parameter of those event callbacks. * Clarified when `onClose` is triggered. ## Price localization guidance **Release notes:** * Removed the article on managing and retrieving price points from the the SDK, as fetching price points from the frontend using the `getPricePoints` function is no longer recommended. Instead, retrieve localized prices on your backend using the [Price Points API](/../../api-reference/checkout/price-localization/introduction), then pass them in the `priceDetails` property when [creating a checkout session](/../../api-reference/checkout/checkout-session/create-checkout-session). * You can also use the Price Points API to localize prices displayed in your external web store, not only when creating a checkout session. If you continue to fetch price points from the frontend, you're responsible for validating prices before passing them to the checkout session. ## Frontend SDK Version 3.0.0 **Release notes:** * Combined all supported platforms into a single article. * Removed the `AppchargeCheckoutInit` component. * Moved the Checkout translations and price localization instructions to their own designated articles. * Removed `sessionToken` and `checkoutToken` properties from the `AppchargeCheckout` component. * Changed the `checkoutUrl` property value from `url` to `parsedUrl` in the [Create Checkout Session API](/../../api-reference/checkout/checkout-session/create-checkout-session). ## ReactJS Version 3.0.0 Changed `publisherToken` (optional) to `checkoutToken` (mandatory). ## VueJS Version 2.0.0 Changed `publisherToken` (optional) to `checkoutToken` (mandatory). ## Angular Version 2.0.0 Changed `publisherToken` (optional) to `checkoutToken` (mandatory). ## JS 2.0.0 Changed `publisherToken` (optional) to `checkoutToken` (mandatory). ## VueJS Version 0.1.13 First version. ## VueJS Version 1.1.0 Added a new `getPricePoints` function to retrieve the localized price points for the individual device/user running the Appcharge Checkout SDK. # Frontend Events Source: https://docs.appcharge.com/sdks/checkout/frontend-sdk/frontend-sdk-events The `AppchargeCheckout` component supports the following optional frontend event function properties: | Event | Description | | - | - | | `onClose` | Triggered when the checkout modal is closed using the **X**, **Back to Store**, or **Back to Game** buttons. | | `onOrderCreated` | Triggered when an order is created. | | `onOrderCompletedFailed` | Triggered when an order fails due to an internal error or publisher reward error. An `error` object is present for fatal failures, such as when there's an issue with the [Grant Award Callback](/../../api-reference/checkout/awards/grant-award-callback), for example, an invalid link. | | `onOrderCompletedSuccessfully` | Triggered when an order is updated with the publisher and confirmation is received. | | `onPaymentIntent` | Triggered when the player clicks **Pay**. | | `onPaymentIntentFailed` | Triggered when the player clicks **Pay** and the payment fails, or when the checkout session fails to open. An `error` object is present for fatal failures, such as when the session fails to open. | | `onPaymentIntentSuccess` | Triggered when the player clicks **Pay** and the payment is charged successfully. | ## Event parameters Below are the parameters that you can pass to the event functions. Not all parameters are available for every event, and ones that are unavailable will be `undefined`. | Name | Description | Event Name | | - | - | - | | `orderId` | Order ID. | All | | `date` | Epoch timestamp. | All | | `bundleId` | Bundle ID. | All | | `bundleName` | Bundle name. | All | | `bundleSKU` | Stock Keeping Unit (SKU) for the bundle. | All | | `products[]` | An array of products included in the order. | All | | `sessionId` | Identifier for the session associated with the order. | All | | `totalSum` | The total sum of the order. | All | | `totalSumCurrency` | Currency of the total sum. | All | | `userCountry` | The country associated with the player. | All | | `userId` | Player ID. | All | | `promoCode` | Promo code applied to the order. Returned only when a coupon was used. | All | | `reason` | Reason for the failure or additional notes. | `onPaymentIntentFailed` `onOrderCompletedFailed` | | `error` | Information about the error. | `onPaymentIntentFailed` `onOrderCompletedFailed` | | `error.code` | Error code. See [Troubleshooting](./troubleshooting) for a list of error codes. | `onPaymentIntentFailed` `onOrderCompletedFailed` | | `error.isFatal` | Whether the error is fatal. Always `true` when `error` is present. | `onPaymentIntentFailed` `onOrderCompletedFailed` | | `error.reason` | Reason for the error. | `onPaymentIntentFailed` `onOrderCompletedFailed` | | `paymentMethodName` | Name of the payment method used for the order. | `onPaymentIntentSuccess` `onOrderCompletedSuccessfully` `onPaymentIntent` `onPaymentIntentFailed` `onOrderCompletedFailed` | | `isSavedPaymentMethodUsed` | Whether the player used or attempted to use a saved card (card on file) during checkout. | `onPaymentIntentSuccess` `onOrderCompletedSuccessfully` `onPaymentIntent` `onPaymentIntentFailed` `onOrderCompletedFailed` | | `isNewPaymentMethodSaved` | Whether the player saved or attempted to save a new card during checkout. | `onPaymentIntentSuccess` `onOrderCompletedSuccessfully` `onPaymentIntent` `onPaymentIntentFailed` `onOrderCompletedFailed` | # Integrate the SDK Source: https://docs.appcharge.com/sdks/checkout/frontend-sdk/integrate-the-sdk This article explains how to integrate Appcharge’s Frontend SDK into your app. ## Step 1 | Install the SDK In your app, install the SDK: ```bash React theme={"system"} npm i appcharge-checkout-reactjs-sdk ``` ```bash Angular theme={"system"} npm i appcharge-checkout-angular-sdk ``` ```bash JavaScript theme={"system"} npm i appcharge-checkout-js-sdk ``` ```bash Vue 2 theme={"system"} npm i appcharge-checkout-vuejs-sdk ``` ```bash Vue 3 theme={"system"} npm i appcharge-checkout-vuejs3-sdk ``` ## Step 2 | Import the checkout component Add the following import statement to the component where you plan to trigger the checkout flow: ```ts React theme={"system"} import { AppchargeCheckout } from "appcharge-checkout-reactjs-sdk"; ``` ```ts Angular theme={"system"} @NgModule({ declarations: [ ... ], imports: [ ..., AppchargeCheckoutModule, ], providers: [], bootstrap: [...] }) ``` ```js Vue 2 theme={"system"} import { AppchargeCheckout } from "appcharge-checkout-vuejs-sdk"; ``` ```js Vue 3 theme={"system"} import { AppchargeCheckout } from "appcharge-checkout-vuejs3-sdk"; ``` For JavaScript, add the following script tag in the `` of your HTML file, before any application script that calls the SDK: ```html theme={"system"} ``` This component must only be rendered after a player performs an action that requires payment, for example, selects an offer in your web store. ## Step 3 | Create a checkout session When a player selects an offer in your web store, your backend calls the [Create Checkout Session API](/../../api-reference/checkout/checkout-session/create-checkout-session) to create a checkout session. ### Localize your checkout prices Include localized pricing in the `priceDetails` property so players see prices in their preferred currency. You can do this in one of two ways: * Pass your own localized price and currency directly in the request. * Retrieve localized prices on your backend using the [Price Points API](/../../api-reference/checkout/price-localization/introduction), then pass them in the request. You can also use the Price Points API to localize prices displayed in your external web store, not only when creating a checkout session. The API responds with the `parsedUrl` value, which is the checkout URL used in the next step. ## Step 4 | Render and configure the checkout component Once you receive the `parsedUrl` returned by your backend, you need to render the checkout component. This example shows a basic setup with minimal configuration, but your implementation may include any of the supported properties listed below: ```javascript React theme={"system"} ``` ```html Angular theme={"system"} ``` ```javascript JavaScript theme={"system"} AppchargeCheckout({ checkoutUrl: parsedUrl }); ``` ```vue Vue 2 theme={"system"} ``` ```vue Vue 3 theme={"system"} ``` ### Properties The `AppchargeCheckout` component supports the properties below, and additional [event properties](./frontend-sdk-events) to enable realtime analytics. | Prop | Type | Required | Params available | Description | | - | - | - | - | - | | `checkoutUrl` | string | Yes | No | The checkout URL as provided by the backend-to-backend request. | | `referrerUrl` | string | No | No | The domain you're coming from, for example, `www.appcharge.com`. The `referrerUrl` must be an HTTPS domain. | | `locale` | string | No | No | Defines the checkout language. For more details, see [Translate your Checkout](./translate-your-checkout). | ### Complete example You'll typically trigger the Checkout after creating the checkout session: ```jsx React theme={"system"} function MyComponent() { const [showCheckout, setShowCheckout] = useState(false); const [checkoutUrl, setCheckoutUrl] = useState(null); useEffect(() => { async function fetchSession() { // Your backend request to the Create Checkout Session API const { parsedUrl } = await createCheckoutSession(); setCheckoutUrl(parsedUrl); setShowCheckout(true); } fetchSession(); }, []); return ( <> {showCheckout && checkoutUrl && ( setShowCheckout(false)} /> )} ); } ``` ```typescript Angular theme={"system"} // component.ts export class MyComponent implements OnInit { showCheckout = false; checkoutUrl: string | null = null; async ngOnInit() { // Your backend request to the Create Checkout Session API const { parsedUrl } = await createCheckoutSession(); this.checkoutUrl = parsedUrl; this.showCheckout = true; } closeCheckout = () => { this.showCheckout = false; } } // component.html ``` ```javascript JavaScript theme={"system"} let showCheckout = false; let checkoutUrl = null; async function initializeCheckout() { // Your backend request to the Create Checkout Session API const { parsedUrl } = await createCheckoutSession(); checkoutUrl = parsedUrl; showCheckout = true; if (showCheckout && checkoutUrl) { AppchargeCheckout({ checkoutUrl: checkoutUrl, onClose: () => { showCheckout = false; } }); } } initializeCheckout(); ``` ```vue Vue 2 theme={"system"} ``` ```vue Vue 3 theme={"system"} ``` # Introduction Source: https://docs.appcharge.com/sdks/checkout/frontend-sdk/introduction This SDK is only relevant if you don’t have an Appcharge web store. The Frontend SDK allows you to integrate your external web store with the Appcharge Checkout. When a player selects an offer in your web store, a checkout session is opened and the player is redirected to the Checkout to complete the purchase. To learn more, see [About the Checkout](/../../guides/checkout/about-the-checkout). ## Get started To get started, follow the instructions to [Integrate the SDK](./integrate-the-sdk). ## Supported platforms The SDK is supported for the following platforms: * React * Angular * Vue 2 * Vue 3 * JavaScript For browser compatibility requirements, minimum screen size, and known environment limitations, see [Supported Environments and Limitations](/api-reference/supported-environments-and-limitations). ## Localize prices Localized pricing ensures players see prices in their preferred currency, both in your external web store and in the Checkout. Learn how to [localize your prices](./integrate-the-sdk#localize-your-checkout-prices). ## Translate your Checkout You can optionally [translate your Checkout](./translate-your-checkout) to allow players to view Checkout content in their preferred language. # Translate Your Checkout Source: https://docs.appcharge.com/sdks/checkout/frontend-sdk/translate-your-checkout This article explains how you can translate your Checkout so players can view content in their preferred language. To learn more, see [About Translations](/../../guides/translations/about-translations). ## Step 1 | Add languages [Add your languages](/../../guides/translations/add-and-manage-languages) in the Publisher Dashboard. ## Step 2 | Set translations [Set translations in the Publisher Dashboard](/../../guides/translations/set-and-manage-translations) directly, or programmatically using the [Translations API service](/../../api-reference/translations/introduction). ## Step 3 | Pass player's locale to the Checkout Determine the player's locale, and then when [rendering the Checkout component](./integrate-the-sdk#step-4-%7C-render-and-configure-the-checkout-component), pass the player's language to the Checkout component using the `locale` property. The format of the `locale` value depends on how the language's Display Name is configured in the Publisher Dashboard: ### Display Name differs from the standard ISO code If the Display Name differs from the standard ISO code, use the following format: ``` locale = displayName;languageISOcode ``` For example, if you added Spanish as a language and set the Display Name to "spanish", set the following: ``` locale = spanish;es ``` ### Display Name matches the standard ISO code If the Display Name matches the standard ISO code, use the ISO code directly: ``` locale = languageISOcode ``` For example, if you added Spanish and set the Display Name to "es", set the following: ``` locale = es ``` ## Complete example Below is a complete code example for displaying the Checkout in the player's language: ```javascript React theme={"system"} console.log("Checkout closed")} onOrderCompletedSuccessfully={(params) => console.log("Order completed", params)} /> ``` ```html Angular theme={"system"} ``` ```javascript JavaScript theme={"system"} AppchargeCheckout({ checkoutUrl: parsedUrl, locale: "spanish;es", referrerUrl: window.location.protocol + "//" + window.location.host, onClose: () => console.log("Checkout closed"), onOrderCompletedSuccessfully: (params) => console.log("Order completed", params) }); ``` ```vue Vue 2 theme={"system"} ``` ```vue Vue 3 theme={"system"} ``` # Troubleshooting Source: https://docs.appcharge.com/sdks/checkout/frontend-sdk/troubleshooting This article lists the Frontend SDK error codes returned in the `error.code` parameter of the `onPaymentIntentFailed` and `onOrderCompletedFailed` event callbacks. For event details, see [Frontend Events](./frontend-sdk-events). ## Error codes | Error Code | Description | When It Occurs | Troubleshoot | | - | - | - | - | | `SESSION_ENDED` | The checkout session has ended and is no longer valid. | When the session time to live (TTL) elapsed, the idle timeout expired, the player canceled the checkout, or the checkout token is missing, malformed, or unrecognized. | Open a new checkout session to continue, or check the integration that generates the session token. | | `SESSION_ALREADY_USED` | The checkout session has already been opened and can't be reused. | When the checkout is reopened or refreshed after the session was already used or closed. | Open a new checkout session to continue. | | `INTERNAL_ERROR` | The request failed due to an unexpected server error. For `onOrderCompletedFailed`, this is the only error code returned. | When an unhandled application error is raised, or on `onOrderCompletedFailed` when there's an issue with the [Grant Award Callback](/../../api-reference/checkout/awards/grant-award-callback), for example, an invalid link. | Retry the request, and contact Appcharge support if it persists. For Grant Award Callback failures, verify your callback URL. | # SDK Documentation Source: https://docs.appcharge.com/sdks/introduction Welcome to Appcharge SDK Documentation. Appcharge streamlines in-game payments through a secure, developer-friendly platform designed for fast and reliable integration. Our SDKs support mobile, web, and backend environments, enabling you to focus on delivering exceptional player experiences while we handle the complexities of payment infrastructure. ## SDK Solutions Integrate Appcharge's checkout into external web stores using React, Angular, Vue.js, or JavaScript. Direct players to a mobile-optimized checkout page via a payment link, bypassing traditional in-app purchases. Supports iOS, Android, and Unity. Embed Appcharge's checkout directly into your Unity WebGL game. ## Key Capabilities * Dynamic pricing and time-limited promotional offers. * Localized payment flows with multi-currency support. * Customizable purchase interfaces to match your game’s design. # Changelog Source: https://docs.appcharge.com/sdks/payment-links/android/changelog Review the latest updates to the Payment Links SDK for native Android and ensure you download the most recent version. ## Android Payment Links SDK 2.0.0 **Release notes:** * Initialization no longer relies on `customerId`. * Improved initialization and deeplink performance. * The `customerId` parameter is now required when opening the checkout. * Price points have been removed and are now managed from the server. * Callback interface now includes `onPurchaseCanceled`. * SDK restores order information on failed or canceled purchases when returning via deeplink. * Removed requirement for `buildConfig = true`. * Replaced the `twa` browser mode with `internal` and removed the `cct` browser mode. You can now only switch between `internal` and `external`. The SDK selects the specific browser implementation. ## Android Payment Links SDK 1.7.0 **Release notes:** * Modified checkout to fully support Checkout 2.0. ## Android Payment Links SDK 1.6.0 **Release notes:** * New event system logic for better reliability and performance, including normalized SDK status codes for consistency across platforms. * Added `orderResponseModel` to the `onPurchaseFailed` callback, allowing you to access full order details, such as `orderId`, `offerName`, and `price` on failed purchases. * SDK now includes network state support with retry functionality to handle cases of internet connection interruptions during order validation. * Updated foreground service type from `dataSync` to `shortService`, reducing Google Play Console declaration requirements. Manifest permissions and service tag are required. * Enriched Debug mode data. * Updated status codes with clearer, more specific statuses that better match current SDK behavior. See the changes in the [Troubleshooting](../troubleshooting) guide. ## Android Payment Links SDK 1.5.0 **Release notes:** * Improved the return-to-game flow via deeplink by reducing order validation processing time, resulting in a faster user experience. * Implemented a togglable foreground service to initiate notification status and keep the game thread active during checkout. (Recommended for older devices and memory-intensive applications, as it reduces the likelihood of Android system process termination.) ## Android Payment Links SDK 1.4.0 **Release notes:** * Updated the namespace from `com.appcharge.core` to `com.appcharge.paymentlinks`. * Improved the checkout flow by using `parsedUrl` instead of `url` and `checkoutSessionToken`. * Improved stability when switching browser modes. * Improved checkout performance and overall stability. * Enhanced debug mode for better troubleshooting. * Fixed a client crash caused by an uninitialized SDK during checkout. * Fixed a connection leak in CCT/TWA. ## Android Payment Links SDK 1.3.1 **Release notes:** * Fixed an issue where the checkout instance could reset after the application remained in the background for an extended period. ## Android Payment Links SDK 1.3.0 **Release notes:** * Added support for external browsers. * The Payment Links SDK is now available via [Maven Central](https://central.sonatype.com/artifact/com.appcharge/android-payment-links). * Added validation for `PurchaseId`. * Improved order validation logic. * Deprecated and removed the client-side `Award` logic (Award Purchase). * Fixed an issue where error code `4001` could occur. * Fixed an issue where some browsers triggered callbacks multiple times. ## Android Payment Links SDK 1.2.0 **Release notes:** * Modified ProGuard rules. * Added external browser support. ## Android Payment Links SDK 1.1.0 **Release notes:** * The SDK now automatically toggles between checkout domains based on the configurations you provide. * Modified error codes. * Improved order validation support. ## Android Payment Links SDK 1.0.0 **Release notes:** * Improved performance for internal browser. * Modified URL Scheme. * The internal browser now locks its orientation based on your application's current orientation. * The consume flow has been renamed to Award for clearer terminology and better alignment with platform conventions. # Implement the Callbacks Source: https://docs.appcharge.com/sdks/payment-links/android/implement-the-callbacks ## Callback methods To implement the Android Payment Links SDK, include the following callback methods: | Method | Description | Argument | Type | | - | - | - | - | | `onInitialized` | Triggered when SDK initialization was successful. | | | | `onInitializeFailed` | Triggered when SDK initialization failed. | `error` | `SdkError` | | `onPurchaseSuccess` | Triggered when a purchase was successful. | `order` | `OrderResponseModel` | | `onPurchaseFailed` | Triggered when a server-to-server error or any other purchase error occurs. Returns a unique integer error code, a detailed message, a raw JSON string if available, and order details. | `error`, `order` | `SdkError`, `OrderResponseModel?` | | `onPurchaseCanceled` | Triggered when the checkout window is dismissed or the purchase is canceled. Returns a unique integer error code, a detailed message, a raw JSON string if available, and order details. | `error`, `order` | `SdkError`, `OrderResponseModel?` | ### OrderResponseModel properties The `OrderResponseModel` argument type contains the following properties: | Property Name | Type | Description | Example | | - | - | - | - | | `date` | `Int` | Unix timestamp of the order. | `1718182312` | | `sessionToken` | `String` | Unique token for the current session. | `"xxxxXXXXxxxxXXXXxxxx"` | | `offerName` | `String` | Name of the purchased offer. | `"Starter Pack"` | | `offerSku` | `String` | SKU identifier for the offer. | `"starter_pack_001"` | | `items` | `[Item]` | List of items included in the purchase. | `[{ name: "Gems", sku: "gem_01", quantity: "100" }]` | | `items.name` | `String` | Display name of the item. | `"Gems"` | | `items.sku` | `String` | Unique SKU code for the item. | `"gem_01"` | | `items.quantity` | `String` | Quantity of the item included. | `"100"` | | `price` | `Int` | Price of the order in minor units. For example, cents for USD. | `499` | | `currency` | `String` | ISO 4217 currency code | `"USD"` | | `customerId` | `String` | ID of the player who made the purchase. | `"cust_98765"` | | `customerCountry` | `String` | Country code of the player in ISO 3166-1 alpha-2 format. | `"US"` | | `paymentMethodName` | `String` | Payment method. | `"Visa"` | | `orderId` | `String` | Order ID. | `"1234567890"` | | `purchaseId` | `String` | A unique ID to track the transaction. | `"pr_xxxxxx"` | ### SdkError properties The `SdkError` argument type contains the following properties: | Property Name | Type | Description | Example | | - | - | - | - | | `code` | `Int` | Error code identifying the failure. | `3002` | | `message` | `String` | Detailed message describing the failure. | `"Purchase canceled because the user closed the checkout interface."` | ## Example code ```kotlin Kotlin theme={"system"} BridgeAPI.init(context, configModel, object : ICheckoutPurchase { override fun onInitialized() { // Handle initialization success } override fun onInitializeFailed(error: SdkError) { // Handle initialization fail } override fun onPurchaseSuccess(order: OrderResponseModel) { // Handle purchase success } override fun onPurchaseFailed(error: SdkError, order: OrderResponseModel? = null) { // Handle purchase failure } override fun onPurchaseCanceled(error: SdkError, order: OrderResponseModel? = null) { // Handle purchase canceled } }) ``` # Initialize the SDK Source: https://docs.appcharge.com/sdks/payment-links/android/initialize-the-android-payment-links-sdk This article explains how to configure and initialize the Payment Links SDK for Android. ## Configure the SDK The Android Payment Links SDK exposes a `ConfigModel`. Create an instance with the following arguments: ```kotlin Kotlin theme={"system"} let config = ConfigModel( checkoutPublicKey: "{YOUR_CHECKOUT_PUBLIC_KEY}", environment: "sandbox" ) ``` | Argument | Type | Description | | - | - | - | | `checkoutPublicKey` | `String` | The Checkout Public Key. You can find it by going to the **Publisher Dashboard → Settings → Integration**. | | `environment` | `String` | The checkout environment. One of:
    - `sandbox`: For testing.
    - `production`: For live operations. | ## Initialize The SDK To initialize the SDK, call the method below using the `ConfigModel`. We recommend doing this on application load: ```kotlin Kotlin theme={"system"} BridgeAPI.init( context: Context, configModel: ConfigModel, callback: ICheckoutPurchase) ``` | Argument | Type | Description | | - | - | - | | `context` | `Context` | Application or Current context. | | `configModel` | `ConfigModel` | Configuration model for initializing the SDK. | | `callback` | `ICheckoutPurchase` | Interface callback. | # Launch the Checkout Source: https://docs.appcharge.com/sdks/payment-links/android/launch-the-checkout To launch the checkout, follow these steps: 1. From your server, call the [Create Checkout Session API](/../../api-reference/checkout/checkout-session/create-checkout-session) to create a checkout session. * When calling the Create Checkout Session API, don't pass the `redirectUrl` parameter. The SDK already handles the redirect automatically using the configuration file. * Call the API from your server to ensure session integrity and security. Never invoke this endpoint from your client-side code. 2. After receiving the API response on your server, extract the values from the session object: ```json theme={"system"} { "checkoutSessionToken": "session_token_identifier", "purchaseId": "pr_purchase_id", "url": "https://checkout-v2-sandbox.appcharge.com", "parsedUrl": "https://checkout-v2-sandbox.appcharge.com/session_token_identifier#boot=checkout_boot_data" } ``` | Parameter | Description | | - | - | | `checkoutSessionToken` | A unique token to identify and validate the checkout session. | | `purchaseId` | ID to track the purchase. | | `url` | The base URL of the Appcharge checkout page. | | `parsedUrl` | The base URL with data configurations. | 3. Use the values returned in the Create Checkout Session API response to open the checkout on the client, and pass your player's `customerId`. The SDK uses this ID with the session `purchaseId` to validate the order if the player closes the browser during checkout and later returns to the game. It also identifies the correct player when multiple players share the same device. ```kotlin Kotlin theme={"system"} BridgeAPI.openCheckout( purchaseId: "PURCHASE_ID", parsedUrl: "PARSED_URL", customerId: "CUSTOMER_ID" ) ``` The session response values must be passed exactly as received. Modifying them may result in the checkout failing to load. 4. You can also configure how the checkout page is opened (optional): ```kotlin Kotlin theme={"system"} // Open the checkout in the device’s default browser BridgeAPI.setBrowserMode("external") // Open the checkout with an internal Trusted Web Activity BridgeAPI.setBrowserMode("internal") // <-- Default ``` Running the checkout in an external browser may cause inconsistent behavior across devices and Android versions, including session loss, incomplete transactions, or app unexpected lifecycle behavior. # Setup Source: https://docs.appcharge.com/sdks/payment-links/android/setup This article describes how to set up the Payment Links SDK for Android. ## Requirements | | | | - | - | | Minimum target level | **24** | ## Step 1 | Import the SDK To import the Android Payment Links SDK, add the following implementation to your `build.gradle` file: ```js theme={"system"} implementation("com.appcharge:android-payment-links:2.0.0") ``` Then add the following to your `settings.gradle` file: ```js theme={"system"} repositories { mavenCentral() } ``` ## Step 2 | Add Permissions In the Manifest file, add the necessary permissions to access the network state and enable incoming deeplink over HTTPS: ```xml xml theme={"system"} ``` ## Step 3 | Configure a URL Scheme Next, add support for checkout activity and deeplink scheme: ```xml xml theme={"system"} ``` The **`intent-filter`** includes a scheme **`"acnative-{IDENTIFIER}"`**. Change the **\{IDENTIFIER}** to the last sequence of your package name. For example, if your package name is **`com.appcharge.mysupergame`**, the identifier will be **`mysupergame`**. This name must be lowercase with no spaces, according to the [Android code style guide](https://source.android.com/docs/core/architecture/hidl/code-style). ## Step 4 | Set up foreground service for your checkout (Optional) To improve checkout stability, you can enable a foreground service. This keeps your app prioritized while the checkout is open, helping prevent Android from closing or deprioritizing it during payment and network operations. To set up the checkout service: 1. Add the following permissions to your `AndroidManifest.xml` file: ```xml xml theme={"system"} ``` 2. Then register the service inside the `` tag. When this service is enabled, Android may display a notification from your game while the checkout is open. To make sure the notification uses your game name instead of the package name, set `android:label` on the `` tag: ```xml xml theme={"system"} ``` If you're upgrading an existing integration that already includes the `CheckoutService` declaration, update `android:foregroundServiceType` from `dataSync` to `shortService` in your manifest. 3. After SDK initialization or before launching checkout, enable or disable the service in code: ```kotlin Kotlin theme={"system"} BridgeAPI.setCheckoutServiceMode(true) // Enable BridgeAPI.setCheckoutServiceMode(false) // Disable ``` By default, `setCheckoutServiceMode` is enabled. If you don't want to use the checkout service, remove the related permissions and the `CheckoutService` declaration from your manifest file, or disable it using the SDK Bridge method above. # Introduction Source: https://docs.appcharge.com/sdks/payment-links/introduction The Payment Links SDK allows you to integrate a mobile checkout experience directly into your app. Instead of using traditional in-app purchases, players are sent to a fast, mobile-optimized checkout page via a payment link, where they can purchase items like coin packs, character skins, or bundles. For a step-by-step guide to integrating this flow, see the [SDK Payment Link Flow](./payment-link-flow). ## Before you begin Before integrating the SDK, make sure you've: 1. Developed and exposed an API endpoint to receive player transaction updates from Appcharge, following the [Grant Award Callback](/../../api-reference/checkout/awards/grant-award-callback) schema. 2. Entered your API endpoint URL in the Publisher Dashboard under **Settings -> Integration**. ## Supported engines and platforms The Payment Links SDK supports the following engines and platforms: * [Unity](./unity/setup) * [Native iOS](./ios/setup) * [Native Android](./android/setup) If your app uses another engine or platform, contact your account manager to scope a custom bridging plan before integrating the SDK. ## Integrate the SDK To integrate the SDK: 1. Follow the setup instructions for your platform to import and configure the Payment Links SDK. 2. Initialize the SDK. 3. Implement the SDK callback methods. 4. Launch the checkout. # Changelog Source: https://docs.appcharge.com/sdks/payment-links/ios/changelog Review the latest updates to the Payment Links SDK for iOS native and ensure you download the most recent version. ## iOS Payment Links SDK 2.0.0 **Release notes:** * Initialization no longer relies on `customerId`. * Improved initialization and deeplink performance. * The `customerId` parameter is now required when opening the checkout. * Price points have been removed and are now managed from the server. * Callback interface now includes `onPurchaseCanceled`. * SDK restores order information on failed or canceled purchases when returning via deeplink. * Replaced the `sfsvc` browser mode with `internal`. You can now only switch between `internal` and `external`. The SDK selects the specific browser implementation. ## iOS Payment Links SDK 1.9.0 **Release notes:** * Modified checkout to fully support Checkout 2.0. ## iOS Payment Links SDK 1.8.0 **Release notes:** * New event system logic for better reliability and performance, including normalized SDK status codes for consistency across platforms. * The main bridge delegate moved to be part of the initialization process. * Added `orderResponseModel` to the `onPurchaseFailed` callback, allowing you to access full order details on failed purchases. * SDK now includes network state support with retry functionality to handle cases of internet connection interruptions during order validation. * Enriched Debug mode data. * Updated status codes with clearer, more specific statuses that better match current SDK behavior. See the changes in the [Troubleshooting](../troubleshooting) guide. ## iOS Payment Links SDK 1.7.0 **Release notes:** * Migrated SDK distribution from CocoaPods to Swift Package Manager (SPM). The SDK is now publicly available via GitHub, resulting in improved version management, accessibility, and developer experience. * Improved the return-to-game flow via deeplink by reducing order validation processing time, resulting in a faster user experience. ## iOS Payment Links SDK 1.6.1 **Release notes:** * Added SafariService declaration to the `h.` file. ## iOS Payment Links SDK 1.6.0 **Release notes:** * Improved the checkout flow by using `parsedUrl` instead of `url` and `checkoutSessionToken`. * Improved checkout performance and overall stability. * Improved SDK initialization stability. * Fixed an issue where SDK validation was triggered by any deep link. ## iOS Payment Links SDK 1.5.1 **Release notes:** * Fixed an issue where re-initializing the SDK retained the previous `customerId`. ## iOS Payment Links SDK 1.5.0 **Release notes:** * Added internal `.mm` file for better bridging support. * Added an option to enable debug mode. * Improved `Obj-C` headers. * Improved orientation lock. * You can now import the SDK via Cocoapods. ## iOS Payment Links SDK 1.4.2 **Release notes:** * Exposed public headers to support Objective-C integration. * Renamed `ACCheckoutPurchaseDelegate` to `ACPaymentLinksDelegate`. * Renamed `ACCheckoutSDK` namespace to `ACPaymentLinks`. * Updated and modified the `ACPaymentLinksDelegate` protocol. ## iOS Payment Links SDK 1.4.1 **Release notes:** * Added `Device Orientation Lock`. You can now present the checkout on portrait mode even if the application is compiled to use landscape only. * Changed `.framework` to `.xcframework` to allow compilation on both emulators and real devices. ## iOS Payment Links SDK 1.4.0 **Release notes:** * Improved order validation timeout and polling rate. * Improved `SFSVC` presentation type. * Better support for Unity Engine. ## iOS Payment Links SDK 1.3.0 **Release notes:** * Modified logging and events. * Added a browser presentation option to configure between the external and internal browser. ## iOS Payment Links SDK 1.1.0 **Release notes:** * Modified logging and events. * Added a browser presentation option to configure between the external and internal browser. ## iOS Payment Links SDK 1.0.1 **Release notes:** * Modified the `OrderResponseModel`. * Modified the Swift Native Code (Bridging). * The `sessionMetaData` in `onPurchaseSuccess` and `onPurchaseFail` is now redundant for server-to-server communications in the client. Metadata on the session creation remains the same. ## iOS Payment Links SDK 1.0.0 **Release notes:** * Initial alpha release version. * SDK initialization with the configuration model. * Delegate callback support. * Support for both internal and external checkout flows. * Deeplink handling. # Implement the Callbacks Source: https://docs.appcharge.com/sdks/payment-links/ios/implement-the-callbacks ## Callback methods To implement the iOS Payment Links SDK, include the following callback methods: | Method | Description | Argument | Type | | - | - | - | - | | `onInitialized` | Triggered when SDK initialization was successful. | | | | `onInitializeFailed` | Triggered when SDK initialization failed. | `error` | `ACErrorMessage` | | `onPurchaseSuccess` | Triggered when a purchase was successful. | `order` | `OrderResponseModel` | | `onPurchaseFailed` | Triggered when a server-to-server error or any other purchase error occurs. Returns a unique integer error code, a detailed message, a raw JSON string if available, and order details. | `error`, `order` | `ACErrorMessage`, `OrderResponseModel?` | | `onPurchaseCanceled` | Triggered when the checkout window is dismissed or the purchase is canceled. Returns a unique integer error code, a detailed message, a raw JSON string if available, and order details. | `error`, `order` | `ACErrorMessage`, `OrderResponseModel?` | ### OrderResponseModel properties The `OrderResponseModel` argument type contains the following properties: | Property Name | Type | Description | Example | | - | - | - | - | | `date` | `Int` | Unix timestamp of the order. | `1718182312` | | `sessionToken` | `String` | Unique token for the current session. | `"xxxxXXXXxxxxXXXXxxxx"` | | `offerName` | `String` | Name of the purchased offer. | `"Starter Pack"` | | `offerSku` | `String` | SKU identifier for the offer. | `"starter_pack_001"` | | `items` | `[Item]` | List of items included in the purchase. | `[{ name: "Gems", sku: "gem_01", quantity: "100" }]` | | `items.name` | `String` | Display name of the item. | `"Gems"` | | `items.sku` | `String` | Unique SKU code for the item. | `"gem_01"` | | `items.quantity` | `String` | Quantity of the item included. | `"100"` | | `price` | `Int` | Price of the order in minor units. For example, cents for USD. | `499` | | `currency` | `String` | ISO 4217 currency code | `"USD"` | | `customerId` | `String` | ID of the customer who made the purchase. | `"cust_98765"` | | `customerCountry` | `String` | Country code of the customer in ISO 3166-1 alpha-2 format. | `"US"` | | `paymentMethodName` | `String` | Payment method. | `"Visa"` | | `orderId` | `String` | Order ID. | `"1234567890"` | | `purchaseId` | `String` | A unique ID to track the transaction. | `"pr_xxxxxx"` | ### ACErrorMessage properties The `ACErrorMessage` argument type contains the following properties: | Property Name | Type | Description | Example | | - | - | - | - | | `code` | `Int` | Error code identifying the failure. | `3002` | | `message` | `String` | Detailed message describing the failure. | `"Purchase canceled because the user closed the checkout interface."` | ## Example code ```swift Swift theme={"system"} extension ViewController: ACPaymentLinksDelegate { func onInitialized() { print("SDK initialization was successful.") } func onInitializeFailed(error: ACErrorMessage) { print("SDK initialization failed: \(error)") } func onPurchaseSuccess(order: OrderResponseModel) { print("Purchase was successful: \(order.orderId)") } func onPurchaseFailed(error: ACErrorMessage, order: OrderResponseModel?) { print("Purchase failed: \(order?.orderId ?? "No order ID found.")") } func onPurchaseCanceled(error: ACErrorMessage, order: OrderResponseModel?) { print("Purchase canceled: \(order?.orderId ?? "No order ID found.")") } } ``` ```c Objective-C theme={"system"} @interface ViewController () @end @implementation ViewController - (void)onInitialized { NSLog(@"SDK initialization was successful."); } - (void)onInitializeFailedWithError:(ACErrorMessage *)error { NSLog(@"SDK initialization failed: %@", error); } - (void)onPurchaseSuccessWithOrder:(OrderResponseModel *)order { NSLog(@"Purchase was successful: %@", order.orderId); } - (void)onPurchaseFailedWithError:(ACErrorMessage *)error order:(OrderResponseModel * _Nullable)order { NSLog(@"Purchase failed: %@", order.orderId ?: @"No order ID found."); } - (void)onPurchaseCanceledWithError:(ACErrorMessage *)error order:(OrderResponseModel * _Nullable)order { NSLog(@"Purchase canceled: %@", order.orderId ?: @"No order ID found."); } @end ``` # Import the Payment Links SDK Source: https://docs.appcharge.com/sdks/payment-links/ios/import-payment-links-sdk This article explains how to import the Payment Links SDK for iOS. You can install it via Swift Package Manager (SPM) or manually. ## Requirements | | | | - | :- | | iOS | **13.0** or higher | | Framework | Static `.xcframework` | | Swift | **5.7 – 5.10** | | Xcode | **15.0** or higher | ### Distribution methods * [Swift Package Manager](https://github.com/Appcharge/ios-payment-links) ## Import the SDK via SPM To import the Payment Links SDK for iOS via SPM: 1. Open your iOS project in Xcode. 2. Go to **File > Add Package Dependencies**. 3. Enter the iOS Payment Links SDK repository URL: `https://github.com/Appcharge/ios-payment-links`. Add GitHub repository 4. Use the dropdown-menu to select your **Dependency Rule**: * **Up to Next Major Version:** for the latest major version. (Recommended) Major version * **Up to Next Minor Version:** for the latest minor version. Major version 5. Use the **Add to Project** drop-down menu to select your app target. Add to Project ## Import the SDK manually To import the Payment Links SDK for iOS manually: 1. Clone the Appcharge [Payment Links](https://github.com/Appcharge/ios-payment-links) repository to your local machine. 2. Drag the `ACPaymentLinks.xcframework` folder into your Xcode project navigator. 3. In the popup, make sure **Copy items if needed** is checked. 4. Select your target and go to the **General tab > Frameworks, Libraries, and Embedded Content**. Set the SDK to **Embed & Sign**. # Initialize the SDK Source: https://docs.appcharge.com/sdks/payment-links/ios/initialize-the-ios-payment-links-sdk This article explains how to configure and initialize and configure the Payment Links SDK for iOS. ## Configure the SDK The Payment Links SDK for iOS exposes a `ACConfigModel`. Create an instance with the following arguments: ```swift Swift theme={"system"} let config = ConfigModel( checkoutPublicKey: "{YOUR_CHECKOUT_PUBLIC_KEY}", environment: "sandbox", redirectUrl: "https://your-universal-link-redirect-url.com" ) ``` ```c Objective-C theme={"system"} ACConfigModel *config = [[ACConfigModel alloc] initWithCheckoutPublicKey:@"{YOUR_CHECKOUT_PUBLIC_KEY}" environment:@"sandbox" redirectUrl:@"https://your-universal-link-redirect-url.com"]; ``` | Argument | Type | Required? | Description | | - | - | - | - | | `checkoutPublicKey` | `string` | Yes | The checkout public key, located in the Publisher Dashboard. In the sidebar menu, click **Settings**, then select the **Integration** tab. Copy the **Checkout Public Key** value. | | `environment` | `string` | Yes | The checkout environment. One of:
    - `sandbox`: For testing.
    - `production`: For live operations. | | `redirectUrl` | `string` | For external browser only | The URL to redirect the player back to your game after checkout. Set the value to `https://{YOUR_ASSOCIATED_DOMAIN_VALUE}.`. | ## Initialize the SDK To initialize the SDK, call the method below using the `ACConfigModel`. We recommend doing this on application load, ideally within the `viewDidLoad` lifecycle method: ```swift Swift theme={"system"} import ACPaymentLinks class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let config = ACConfigModel( checkoutPublicKey: "{YOUR_CHECKOUT_PUBLIC_KEY}", environment: "sandbox", redirectUrl: "https://your-universal-link-redirect-url.com" ) // Initialize the SDK with the delegate ACBridgeAPI.initialize(configModel: config, delegate: self) } } ``` ```c Objective-C theme={"system"} #import #import @interface ViewController : UIViewController @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; ACConfigModel *config = [[ACConfigModel alloc] initWithCheckoutPublicKey:@"{YOUR_CHECKOUT_PUBLIC_KEY}" environment:@"sandbox" redirectUrl:@"https://your-universal-link-redirect-url.com"]; // Initialize the SDK [ACBridgeAPI initializeWithConfigModel:config delegate:self]; } @end ``` ## Re-initialize the SDK Re-initialize the SDK when you change between `sandbox` and `production` environments: ```swift Swift theme={"system"} ACBridgeAPI.initialize(configModel: config, delegate: self) ``` ```c Objective-C theme={"system"} [ACBridgeAPI initializeWithConfigModel:config delegate:self]; ``` ## Lock checkout orientation You can force the Checkout page to display in portrait orientation, even if the app is currently in landscape mode. ```swift Swift theme={"system"} // Checkout opens using the app’s current orientation (default) ACBridgeAPI.portraitOrientationLock = false // Checkout is locked to portrait orientation ACBridgeAPI.portraitOrientationLock = true ``` ```c Objective-C theme={"system"} // Checkout opens using the app’s current orientation (default) [ACBridgeAPI setPortraitOrientationLock:@0]; // Checkout is locked to portrait orientation. [ACBridgeAPI setPortraitOrientationLock:@1]; ``` ## Enable debug mode Enable debug mode to view detailed logs from all parts of the SDK. This provides deeper visibility into the SDK’s behavior: ```swift Swift theme={"system"} ACBridgeAPI.setDebugMode = true ``` ```c Objective-C theme={"system"} [ACBridgeAPI setSetDebugMode:@YES]; ``` # Launch the Checkout Source: https://docs.appcharge.com/sdks/payment-links/ios/launch-the-checkout To launch the checkout, follow these steps: 1. From your server, call the [Create Checkout Session API](/../../api-reference/checkout/checkout-session/create-checkout-session) to create a checkout session. * When calling the Create Checkout Session API, don't pass the `redirectUrl` parameter. The SDK already handles the redirect automatically using the configuration file. * Call the API from your server to ensure session integrity and security. Never invoke this endpoint from your client-side code. 2. After receiving the API response on your server, extract the values from the session object: ```json theme={"system"} { "checkoutSessionToken": "session_token_identifier", "purchaseId": "pr_purchase_id", "url": "https://checkout-v2-sandbox.appcharge.com", "parsedUrl": "https://checkout-v2-sandbox.appcharge.com/session_token_identifier#boot=checkout_boot_data" } ``` | Parameter | Description | | - | - | | `checkoutSessionToken` | A unique token to identify and validate the checkout session. | | `purchaseId` | ID to track the purchase. | | `url` | The base URL of the Appcharge checkout page. | | `parsedUrl` | The base URL with data configurations. | 3. Use the values returned in the Create Checkout Session API response to open the checkout on the client, and pass your player's `customerId`. The SDK uses this ID with the session `purchaseId` to validate the order if the player closes the browser during checkout and later returns to the game. It also identifies the correct player when multiple players share the same device. ```swift Swift theme={"system"} ACBridgeAPI.openCheckout( purchaseId: "PURCHASE_ID", parsedUrl: "PARSED_URL", customerId: "CUSTOMER_ID" ) ``` ```c Objective-C theme={"system"} [ACBridgeAPI openCheckoutWithPurchaseId:@"PURCHASE_ID" parsedUrl:@"PARSED_URL" customerId:@"CUSTOMER_ID"]; ``` The session response values must be passed exactly as received. Modifying them may result in the checkout failing to load. 4. You can also configure how the checkout page is opened (optional): * **External browser**
    Open the checkout in the device’s default browser. This flow will use the `redirectUrl` provided in the initialization to return back to the app. ```swift Swift theme={"system"} ACBridgeAPI.setBrowserMode(.external) ``` ```c Objective-C theme={"system"} [ACBridgeAPI setBrowserMode:0]; ``` Running the checkout in an external browser may cause inconsistent behavior across devices, incomplete transactions, or app unexpected lifecycle behavior. * **Non-external browser (default)**
    The checkout opens in the device's internal browser or [SFSafariViewController](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller). This flow will use the url scheme provided in the **plist** file to return back to the app. For more information, see [Sell Outside IAP](/../../guides/payment-links/sell-outside-iap). ```swift Swift theme={"system"} ACBridgeAPI.setBrowserMode(.internal) ``` ```c Objective-C theme={"system"} [ACBridgeAPI setBrowserMode:1]; ``` # Set Up Your Project Source: https://docs.appcharge.com/sdks/payment-links/ios/set-up-your-project This article describes how to set up your iOS Payment Links SDK project. ## Step 1 | Set up a URL scheme URL Schemes allow your app to handle redirects from embedded checkout flows, including in-app browsers. To set up a URL scheme in Xcode: 1. Open your project, select your target, and navigate to the **info.plist** file. 2. In the **Information Property List**, expand the **URL types** section. If it doesn't exist, create it by clicking **+**. 3. Add an **Item** section if it doesn't already exist, and set it to the following: * **URL identifier**: `action` * **URL Schemes**: `acnative-$(PRODUCT_BUNDLE_IDENTIFIER)` URL Scheme ## Step 2 | Configure a Universal Link To allow players to return to your game after completing checkout in an external browser, such as Safari, you need to set up a [Universal Link](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app). Then, in Xcode: 1. Open your project and select your main project file. 2. Go to the **Signing & Capabilities** tab. 3. Click **+ Capability** and search for **Associated Domains**. If you don't see it, ensure you're using a real device configuration. 4. Under **Domains**, add: ``` applinks:{YOUR_DOMAIN} ``` For example: ``` applinks:my-best-game.com ``` We recommend configuring both a URL Scheme and a Universal Link to ensure your app can handle checkout redirects from embedded checkout flows (including in-app browsers) and external browsers. ## Step 3 | Register deeplink handlers After a player completes a purchase or exits the checkout, they are redirected back to your app via a deeplink. Your app must capture this URL and forward it to the Appcharge SDK to finalize the transaction. If your app already handles deeplinks, call the Bridge `handleDeepLink` method within your existing handlers to forward the URL to the Appcharge SDK. If your app doesn't already handle deeplinks, add the following methods in your `SceneDelegate`: ```swift Swift theme={"system"} import ACPaymentLinks // When the app is opened via URL Scheme func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { guard let url = URLContexts.first?.url else { return } ACBridgeAPI.handleDeepLink(url) } // When the app is opened via Universal Link func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { if userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL { ACBridgeAPI.handleDeepLink(url) } } ``` ```c Objective-C theme={"system"} #import #import // When the app is opened via URL Scheme - (void)scene:(UIScene *)scene openURLContexts:(NSSet *)URLContexts { NSURL *url = URLContexts.anyObject.URL; if (url) { [ACBridgeAPI handleDeepLink:url]; } } // When the app is opened via Universal Link - (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity { if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { NSURL *url = userActivity.webpageURL; if (url) { [ACBridgeAPI handleDeepLink:url]; } } } ``` If you don't have a `SceneDelegate`, use the `AppDelegate`: ```swift Swift theme={"system"} import ACPaymentLinks func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { ACBridgeAPI.handleDeepLink(url) return false } ``` ```c Objective-C theme={"system"} - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { [ACBridgeAPI handleDeepLink:url]; return NO; } ``` # Payment Link Flow Source: https://docs.appcharge.com/sdks/payment-links/payment-link-flow This article explains how to set up a payment link in your app for both Android and iOS using the Payment Links SDK. It walks through the full integration flow, from starting a checkout session to handling callbacks and completing the purchase. To learn more, see the [Payment Links feature](/../../guides/payment-links/about-payment-links). ## Step 1 | Create a server-to-server checkout session When a player selects an offer in your game, such as a coin pack or a character skin, send the offer ID from the game client to your game server. Your game server uses the offer ID to retrieve the offer details. It then creates a checkout session by calling the [Create Checkout Session API](/../../api-reference/checkout/checkout-session/create-checkout-session) with this data. * When calling the Create Checkout Session API, don't pass the `redirectUrl` parameter. The SDK already handles the redirect using the configuration file. ## Step 2 | Use the SDK to open the checkout page Implement the SDK for your desired engine or platform to launch the Appcharge checkout page. See a list of [supported engines and platforms](./introduction#supported-engines-and-platforms). ## Step 3 | Receive the payment notification event if relevant The player selects a payment method and completes the purchase. The [Grant Award Callback](/../../api-reference/checkout/awards/grant-award-callback) is then triggered, and your game server receives a POST request with full transaction data. If the player doesn't complete the purchase, the checkout session will automatically expire after 1 hour or when the player actively closes the checkout page. To cancel an open checkout session at any time, such as when multiple checkout tabs are open, call the [Cancel Checkout Session API](/../../api-reference/checkout/checkout-session/cancel-checkout-session). You can listen for [order events](/../../api-reference/events/v2/order/order_created) that are triggered based on different checkout outcomes. ## Step 4 | Redirect the player back to your app After a player completes a purchase or exits the checkout, the redirect behavior depends on the browser type: * **Internal browser**: Player is automatically redirected from the checkout back to your game by default (unless you specifically ask your account manager to enable the back to game button feature for you). * **External browser**: Whether the player is automatically redirected depends on their browser type. If the player isn't redirected automatically, they'll see the **Return to game** button. When clicked, this button redirects the player back to your app. Appcharge handles this redirection using the link you configured in the SDK setup. Your app must capture the incoming URL and pass it to the SDK to complete the transaction. ## Step 5 | Handle success & failure callbacks Appcharge receives the URL, validates the transaction against the callback data, and dispatches a success or failure event. ## Step 6 | Validate the purchase with your server If the purchase is successful, the `onPurchaseSuccess` (native) or `OnPurchaseSuccess` (Unity) callback is triggered with an `OrderResponseModel` argument containing the `purchaseId`. You can use this to validate the purchase with your game server. The `purchaseId` also serves as the identifier for the transaction, allowing you to track the purchase and retrieve the offer item details associated with it. Once validated, fulfill the order by granting the purchased items to the player’s account. # Troubleshooting Source: https://docs.appcharge.com/sdks/payment-links/troubleshooting Use this guide to troubleshoot Payment Links SDK status codes and possible integration issues. ## Available status codes The following status codes apply to Unity 3.0.0, Android 2.0.0, iOS 2.0.0, and above:
    | SDK Status Code | Description | | - | - | | `1000` | An internal server error occurred because the server isn't responding or is down. | | `1001` | A general server error occurred. | | `1002` | Unable to reach the service. Please check your network connection and try again. | | `1007` | Checkout token validation failed due to a token mismatch. | | `1008` | The SDK method isn't supported on the current platform and returns the message `"This method is unsupported."` | | `2000` | Failed to initialize checkout due to configuration issues not covered by another initialization error. | | `2001` | Invalid, missing, or empty environment configuration. | | `2002` | Invalid, missing, or empty checkout token. | | `2003` | Missing or empty Customer ID. | | `2004` | Invalid redirect URL configuration. Relevant for iOS only. | | `2005` | SDK initialization is already in progress. | | `2006` | Boot settings couldn't be found, or an error occurred while parsing boot settings. | | `3000` | The player closed the browser using OS-level controls. | | `3002` | Purchase canceled because the player closed the checkout interface. | | `3003` | Purchase failed on the server side. | | `3004` | Timeout during order validation. | | `3005` | The browser closed before the checkout page fully launched. | | `3006` | The client-side SDK configuration, Publisher Token, and/or Checkout Token don't match the server-side session environment. | | `3007` | Customer ID validation failed because the `customerId` in `OrderResponseModel` doesn't match the `customerId` passed when opening the checkout. | | `4000` | Couldn't find any available browser on the device. | | `4002` | The browser can't be opened due to a malformed parsed URL. | | `8000` | Open checkout failed because the Purchase ID argument is invalid. | | `8001` | Open checkout failed because the parsed URL argument is invalid. | | `9001` | The request can't be handled due to no internet connectivity. | | `9999` | An unknown error occurred. |
    ## Checkout session expiry Checkout session expiry isn't returned as a separate SDK status. If checkout is opened with an expired checkout session, the browser loads and displays `Something went wrong.`. The SDK currently treats this as a purchase cancellation (`3002`) because it can't distinguish between a canceled purchase and an expired session. # Changelog Source: https://docs.appcharge.com/sdks/payment-links/unity/changelog Review the latest updates to the Payment Links SDK for Unity and ensure you download the most recent version. Before installing a new SDK version, remove the previous SDK version to ensure stability and prevent conflicts. ## Unity Payment Links SDK 3.0.0 **Release notes:** * Updated the Android SDK to v2.0.0., and the iOS SDK to v2.0.0. * Improved WebGL support. * Added Unity Thread Dispatcher option. * Initialization no longer relies on `customerId`. * The `customerId` parameter is now required when opening the checkout. * Price points have been removed and are now managed from the server. * Callback interface now includes `OnPurchaseCanceled`. * Improved initialization and deeplink performance. * Improved Android Post-Process support. * SDK restores order information on failed or canceled purchases when returning via deeplink. * Removed requirement for `buildConfig = true` from the Android SDK. * Replaced `AndroidBrowserMode.TWA` with `AndroidBrowserMode.Internal` and `iOSBrowserMode.SFSVC` with `iOSBrowserMode.Internal`, and removed `AndroidBrowserMode.CCT`. You can now only switch between `Internal` and `External`. The SDK selects the specific browser implementation. ## Unity Payment Links SDK 2.6.0 **Release notes:** * Introduced WebGL platform support. * Updated Android platform version to v1.7.0. * Updated iOS platform version to v1.9.0. ## Unity Payment Links SDK 2.5.0 **Release notes:** * Updated Android platform version to v1.6.0. * Updated iOS platform version to v1.8.0. * Added `orderResponseModel` to the `onPurchaseFailed` callback, you to access full order details on failed purchases. * Updated bundled Android foreground service type from `dataSync` to `shortService`. * **Exclude Add Framework Search Paths** entitlement was removed due to the SPM migration. The iOS XCFramework is already included. * Updated status codes with clearer, more specific statuses that better match current SDK behavior. See the changes in the [Troubleshooting](../troubleshooting) guide. ## Unity Payment Links SDK 2.4.0 **Release notes:** * Updated Android platform version to v1.5.0. * Updated iOS platform version to v1.7.0. * Implemented a foreground service for Android to initiate notification status and keep the game thread active during checkout. (Recommended for older devices and memory-intensive applications, as it reduces the likelihood of Android system process termination.) ## Unity Payment Links SDK 2.3.0 **Release notes:** * Updated Android platform version to v1.4.0. * Updated iOS platform version to v1.6.0. * The SDK now supports Xcode version 15.0 and above. * Improved the checkout flow by using `parsedUrl` instead of `url` and `checkoutSessionToken`. * Improved checkout performance and overall stability. * Improved Android platform post-process. * The SDK is now distributed through UPM only. ## Unity Payment Links SDK 2.2.0 **Release notes:** * Updated Android platform version to v1.3.0. * Updated iOS platform version to v1.5.0. * Improved iOS configuration support and added more flexible build options. * `PaymentLinksController` now supports browsing mode on each platform. * Added Unity Package Manager (UPM) support for the Payment Links SDK. ## Unity Payment Links SDK 2.1.0 **Release notes:** * Configuration file will now generate automatically. * Improved clarity of the configuration file. * Improve iOS build Post-Process. ## Unity Payment Links SDK 2.0.0 **Release notes:** * Added cross-platform support for iOS and Android. * Enabled **Editor-Mode testing and execution** at runtime. * Added support for **Trusted Web Activity (TWA)** and **external browser** on Android. * Added support for **SFSafariViewController (SFSVC)** and **external browser** on iOS. * Added **Portrait Orientation Lock** mode for iOS. * **Browser Mode** can now be toggled at runtime. * Updated and simplified the configuration file. * Implemented **automatic dependency injection** during compilation (can be disabled for manual configuration control). * Improved the Appcharge integration process for both iOS and Android. * Enhanced ARM support for both **v7a** and **v8** architectures. * Optimized **plist** and **AndroidManifest** post-build processing. * Reorganized Appcharge folders and assemblies for better project structure. * Improved overall stability and performance. # Configure the SDK Source: https://docs.appcharge.com/sdks/payment-links/unity/configure-the-sdk This guide explains how to configure the Unity Payment Links SDK. ## Step 1 | Locate the Appcharge configuration file Make sure your Unity project contains the Appcharge configuration file, `AppchargeConfig`, located under `Assets` → `Resources` → `Appcharge`. This file defines the connection between your project and Appcharge services, and is required for the SDK to function correctly. ### If the file doesn’t exist If the file isn't there, create one manually: 1. Right-click in your Project window. 2. Select `Create` → `Appcharge` → `Configuration` → `AppchargeConfig`. This configuration file **must** be located at `Assets` → `Resources` → `Appcharge`. ### If Unity shows that the file is missing Missing Configurations If Unity reports that the configuration file is missing, as shown above, fix it using one of the following options: 1. Delete the existing configuration file and re-create it, **or** 2. Select and apply the missing `AppchargeConfig` file. Fix Missing Configurations ## Step 2 | Integrate platform-specific settings After verifying your configuration file, continue by integrating Appcharge for your target platform. Each platform requires additional settings to ensure Appcharge Payment Links works correctly. * [Integrate with iOS](/sdks/payment-links/unity/integrate-with-ios). * [Integrate with Android](/sdks/payment-links/unity/integrate-with-android). * [Integrate with WebGL](/sdks/payment-links/unity/integrate-with-webgl). # Implement the Callbacks Source: https://docs.appcharge.com/sdks/payment-links/unity/implement-callbacks ## Callback methods To implement the Unity Payment Links SDK, include the following callback methods: | Method | Description | Argument | Type | | - | - | - | - | | `OnInitialized` | Triggered when SDK initialization was successful. | | | | `OnInitializeFailed` | Triggered when SDK initialization failed. | `error` | `ErrorMessage` | | `OnPurchaseSuccess` | Triggered when a purchase was successful. | `order` | `OrderResponseModel` | | `OnPurchaseFailed` | Triggered when a server-to-server error or any other purchase error occurs. Returns a unique integer error code, a detailed message, a raw JSON string if available, and order details. | `error`, `order` | `ErrorMessage`, `OrderResponseModel` | | `OnPurchaseCanceled` | Triggered when the checkout window is dismissed or the purchase is canceled. Returns a unique integer error code, a detailed message, a raw JSON string if available, and order details. | `error`, `order` | `ErrorMessage`, `OrderResponseModel` | ### OrderResponseModel properties The `OrderResponseModel` argument type contains the following properties: | Property Name | Type | Description | Example | | - | - | - | - | | `date` | `Int` | Unix timestamp of the order. | `1718182312` | | `sessionToken` | `String` | Unique token for the current session. | `"xxxxXXXXxxxxXXXXxxxx"` | | `offerName` | `String` | Name of the purchased offer. | `"Starter Pack"` | | `offerSku` | `String` | SKU identifier for the offer. | `"starter_pack_001"` | | `items` | `[Item]` | List of items included in the purchase. | `[{ name: "Gems", sku: "gem_01", quantity: "100" }]` | | `items.name` | `String` | Display name of the item. | `"Gems"` | | `items.sku` | `String` | Unique SKU code for the item. | `"gem_01"` | | `items.quantity` | `String` | Quantity of the item included. | `"100"` | | `price` | `Int` | Price of the order in minor units. For example, cents for USD. | `499` | | `currency` | `String` | ISO 4217 currency code | `"USD"` | | `customerId` | `String` | ID of the player who made the purchase. | `"cust_98765"` | | `customerCountry` | `String` | Country code of the player in ISO 3166-1 alpha-2 format. | `"US"` | | `paymentMethodName` | `String` | Payment method. | `"Visa"` | | `orderId` | `String` | Order ID. | `"1234567890"` | | `purchaseId` | `String` | A unique ID to track the transaction. | `"pr_xxxxxx"` | ### ErrorMessage properties The `ErrorMessage` argument type contains the following properties: | Property Name | Type | Description | Example | | - | - | - | - | | `code` | `Int` | Error code identifying the failure. | `3002` | | `message` | `String` | Detailed message describing the failure. | `"Purchase canceled because the user closed the checkout interface."` | ## Example code ```csharp C# theme={"system"} using Appcharge.PaymentLinks.Models; using Appcharge.PaymentLinks.Interfaces; using UnityEngine; public class AppchargeCallbackImpl : ICheckoutPurchase { public void OnInitialized() { Debug.Log("SDK initialization was successful."); } public void OnInitializeFailed(ErrorMessage error) { Debug.Log("SDK initialization failed."); } public void OnPurchaseSuccess(OrderResponseModel order) { Debug.Log("Purchase was successful: " + order.orderId); } public void OnPurchaseFailed(ErrorMessage error, OrderResponseModel order) { Debug.Log("Purchase failed: " + (order != null ? order.orderId : "no order found")); } public void OnPurchaseCanceled(ErrorMessage error, OrderResponseModel order) { Debug.Log("Purchase canceled: " + (order != null ? order.orderId : "no order found")); } } ``` # Import the Payment Links SDK Source: https://docs.appcharge.com/sdks/payment-links/unity/import-payment-links-sdk This article explains how to set up the Payment Links SDK for Unity via UPM (Unity Package Manager). ## Requirements | Platform | Requirement | | - | :- | | Unity | Version **2021.3.45f2** or higher | | iOS |
    • **iOS:** Minimum version **13.0** or higher
    • **Xcode:** Version **15.0** or higher
    | | Android | Minimum target level: **24** | ## Import the SDK via UPM To import the SDK into your Unity project using UPM: 1. Copy the URL below to use in a later step: ``` https://github.com/Appcharge/unity-payment-links.git ``` 2. Open your Unity project. 3. Go to **Window > Package Manager**. 4. In the **Package Manager** window, click the `+` button and select **Add package from git URL**. UPM Import 5. Paste the copied HTTPS URL, and click **Add**. # Initialize the SDK Source: https://docs.appcharge.com/sdks/payment-links/unity/initialize-the-payment-links-sdk Use the following function to initialize the SDK: ```csharp C# theme={"system"} PaymentLinksController.Instance.Init(callback) ``` | Argument | Type | Description | | - | - | - | | Callback | `ICheckoutPurchase` | Implementation of the callback interface. | This initialization method is sufficient if you've already set the **Environment** and **Checkout Public Key** fields in the configuration file. If you prefer to set these values programmatically, use the initialization method described in the next section. ## Re-initialize the SDK You may need to re-initialize the SDK in the following cases: 1. When switching environments at runtime, for example, when testing the SDK. 2. When certain configuration details are managed manually instead of being defined in the configuration file. In such cases, re-initialize the SDK using the extended method below: ```csharp C# theme={"system"} PaymentLinksController.Instance.Init("CHECKOUT_PUBLIC_KEY", "ENVIRONMENT", callback) ``` | Argument | Type | Description | | - | - | - | | Environment | `string` | The checkout environment. One of:
    - `sandbox`: For testing.
    - `production`: For live operations. | | Checkout Public Key | `string` | The public key from the Publisher Dashboard.Go to Settings → Integration and copy the Checkout Public Key. | | Callback | `ICheckoutPurchase` | Implementation of the callback interface. | Always ensure the correct `environment` and `checkoutPublicKey` are used when re-initializing. Incorrect values can cause failed checkout validations. # Integrate with Android Source: https://docs.appcharge.com/sdks/payment-links/unity/integrate-with-android This article explains how to integrate Unity Payment Links with the Android platform. To integrate with Android: 1. Go to the **Build Settings** window and make sure your Unity project is set to **Android**. Once set, the `AppchargeConfig` file updates to display Android-specific configuration options. Android Build Settings 2. Click **Player Settings > Publisher Settings**, and scroll to the **Build** section. 3. Expose (enable) the following android plugin files or the build process will be passed without changes: * Custom Main Manifest (`AndroidManifest.xml`) * Custom Main Gradle Template (`mainTemplate.gradle`) * Custom Gradle Properties Template (`gradleTemplate.properties`) Android Editor Configurations 4. Your configuration settings should look like this: Android Configurations ## Publisher Info These settings can also be changed at runtime, but doing so requires [re-initializing the SDK](./initialize-the-payment-links-sdk#re-initialize-the-sdk). | Property | Type | Description | | - | - | - | | Environment | `Enum` | Sets the checkout environment. Use `Sandbox` for testing and `Production` for live payments. | | Checkout Public Key | `String` | Defines the checkout public key. You can find it by going to the **Publisher Dashboard → Settings → Integration**. | ## Configuration Settings | Property | Type | Description | | - | - | - | | Enable Main Thread Dispatcher | `boolean` | The SDK works outside of the Unity main thread. This option allows you to wrap callback methods with Unity main thread. | | Enable Debug Mode | `Boolean` | When enabled, prints a summary of automatic integration changes after the build completes. | | Browser Mode | `Enum` | Sets how the checkout is opened. Use `External` for the device's default browser or `Internal` for Trusted Web Activity (TWA). | ## Integration Settings Enables automatic integration of required Android dependencies and manifest entries during the build process. Use the following options to exclude parts of the build process. By doing so, you may need to implement part of the process manually. | Property | Type | Description | | - | - | - | | Enable Integration Options | `Boolean` | Determines whether the SDK automatically applies required Android configurations during build. If disabled, you’ll need to configure them manually. | | Exclude Android X | `Boolean` | Exclude the `useAndroidX` property from the `gradleTemplate.properties` file. | | Exclude Jetifier | `Boolean` | Exclude the `enableJetifier` property from the `gradleTemplate.properties` file. | ``` **Unity Standart Settings goes here** **ADDITIONAL_PROPERTIES** android.useAndroidX=true android.enableJetifier=true ``` | Property | Type | Description | | - | - | - | | Exclude Core Ktx | `Boolean` | Exclude Kotlin core dependency from the `mainTemplate.gradle` file. | | Exclude Activity Ktx | `Boolean` | Exclude Kotlin activity dependency from the `mainTemplate.gradle` file. | | Exclude Android Browser Helper | `Boolean` | Exclude the `AndroidBrowserHelper` dependency from the `mainTemplate.gradle` file. | | Exclude Android X Browser | `Boolean` | Exclude the `Android X` dependency from the `mainTemplate.gradle` file. | | Exclude Kotlin Serialization Json | `Boolean` | Exclude the `Serialization` dependency from the `mainTemplate.gradle` file. | | Exclude Kotlin Coroutines Core | `Boolean` | Exclude the `Coroutine Core` dependency from the `mainTemplate.gradle` file. | ``` **---------------** dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.core:core-ktx:1.13.1' implementation 'androidx.activity:activity-ktx:1.3.0' implementation 'com.google.androidbrowserhelper:androidbrowserhelper:2.4.0' implementation 'androidx.browser:browser:1.8.0' implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1' **DEPS** } **---------------** ``` | Property | Type | Description | | - | - | - | | Exclude Internet Permission | `Boolean` | Exclude the Internet permission from `AndroidManifest.xml`. | | Exclude Queries Block | `Boolean` | Exclude Appcharge’s HTTPS scheme query block from the manifest. | | Exclude Checkout Service | `Boolean` | Exclude the checkout foreground service permissions and service declaration. | ### Exclude Appcharge Activity By default, the SDK adds the Appcharge Checkout activity, its exported attribute, and the deeplink intent filter to `AndroidManifest.xml`. Use the options below to skip parts of that setup if you manage them in your own manifest. | Property | Type | Description | | - | - | - | | Exclude Appcharge Activity | `Boolean` | Skips adding the Appcharge Checkout activity declaration. | | Exclude Exported Attribute | `Boolean` | Skips adding `android:exported="true"` on the Checkout activity. | | Exclude Discouraged Api Tool | `Boolean` | Skips adding `` on the Checkout activity. | | Exclude Appcharge Activity Intent Filters | `Boolean` | Skips adding the deeplink intent filters on the Checkout activity. | | Exclude Custom Scheme | `Boolean` | Skips adding the `` deeplink entry. | | Exclude Custom Host | `Boolean` | Skips adding the `` deeplink entry. | * If **Exclude Checkout Service** isn't checked, the SDK automatically adds the required permissions and the `CheckoutService` declaration to your manifest file without duplicating existing permissions. If **Exclude Checkout Service** is checked, the SDK doesn't modify your manifest file. * If you're upgrading an existing integration that already includes the `CheckoutService` declaration, update `android:foregroundServiceType` from `dataSync` to `shortService` in your manifest. ### Example Manifest If the options above are **not** excluded (disabled), your final Manifest will look like this: ```xml xml theme={"system"} ``` The **`intent-filter`** includes a scheme **`"acnative-{IDENTIFIER}"`**. Change the **\{IDENTIFIER}** to the last sequence of your package name. For example, if your package name is **`com.appcharge.mysupergame`**, the identifier will be **`mysupergame`**. This name must be lowercase with no spaces, according to the [Android code style guide](https://source.android.com/docs/core/architecture/hidl/code-style). # Integrate with iOS Source: https://docs.appcharge.com/sdks/payment-links/unity/integrate-with-ios This article explains how to integrate Unity Payment Links with the iOS platform. On some Unity versions, the **Back to Game** button won't return players to the game after checkout. See [Fix deeplinks on affected Unity versions](#fix-deeplinks-on-affected-unity-versions) to check whether your version is affected, and if so, complete the `Info.plist` workaround. To integrate with iOS: 1. Go to the **Build Settings** window and make sure your Unity project is set to **iOS**. Once set, the `AppchargeConfig` file updates to display iOS-specific configuration options. iOS Build Settings 2. Your configuration settings should look like this: iOS Configurations By default, the configuration file is preconfigured for integration. However, you must set the required **Environment** and **Checkout Public Key** fields under **Publisher Info**. ## Publisher Info These settings can also be changed at runtime, but doing so requires [re-initializing the SDK](./initialize-the-payment-links-sdk#re-initialize-the-sdk). | Property | Type | Description | | - | - | - | | Environment | `Enum` | Sets the checkout environment. Use `Sandbox` for testing and `Production` for live payments. | | Checkout Public Key | `String` | Defines the checkout public key. You can find it by going to the **Publisher Dashboard → Settings → Integration**. | ## Configuration Settings | Property | Type | Description | | - | - | - | | Enable Main Thread Dispatcher | `Boolean` | The SDK works outside of the Unity main thread. This option allows you to wrap callback methods with Unity main thread. | | Enable Debug Mode | `Boolean` | When enabled, prints a summary of automatic integration changes after the build completes. | | Browser Mode | `Enum` | Sets current browser mode: `External` for opening default browser or `Internal` for embedded Safari. | | Associated Domain | `String` | Specifies the domain used to redirect players back to your game (without the HTTP protocol). Example: `my.best-app.com`. The domain must be served via **https**, not **http**. | | Portrait Orientation Lock | `Boolean` | Force the internal browser to open in portrait mode even if the application is set to landscape.

    **Note:** You can update this property programmatically before launching the checkout. | ## Integration Settings Enables automatic integration of required iOS frameworks, entitlements, and URL schemes during the Xcode build process. Use the following options to exclude parts of the build process. By doing so, you may need to implement part of the process manually. | Property | Type | Description | | - | - | - | | Enable Integration Options | `Boolean` | Determines whether the SDK automatically applies required Xcode configurations during build. If disabled, you’ll need to configure them manually in Xcode. | Disabling **Enable Integration Options** prevents the automatic configuration required for the Checkout SDK from functioning correctly. If disabled, you must manually configure each required file in Xcode. ### Enable iOS Framework Integration By default, the SDK configures Swift libraries, runpaths, signing, and adds the Appcharge XCFramework during the Xcode build. Use the options below to skip parts of that setup if you manage them yourself. | Property | Type | Description | | - | - | - | | Enable iOS Framework Integration | `Boolean` | Determines whether the SDK automatically applies framework integration during the Xcode build. | | Exclude Set Swift Standard Libraries For Framework | `Boolean` | Skips configuring Swift standard libraries for embedded frameworks. | | Exclude Set LD Runpath Search Paths | `Boolean` | Prevents modifying `LD_RUNPATH_SEARCH_PATHS` for framework loading. | | Exclude Set Swift Version | `Boolean` | Skips setting the Swift language version for the framework target. | | Exclude Set Swift Standard Libraries For Main | `Boolean` | Prevents configuring Swift standard libraries for the main app target. | | Exclude Set Code Sign Entitlements | `Boolean` | Skips modifying code signing entitlements related to framework integration. | | Exclude Set Code Sign Style | `Boolean` | Prevents changes to the code signing style (Automatic/Manual). | | Exclude Add XC Framework | `Boolean` | Skips adding the Appcharge XCFramework to the Xcode project. | ### Enable iOS Entitlements Integration By default, the SDK creates or updates the entitlements file and associated domains during the Xcode build. Use the options below to skip parts of that setup if you manage them yourself. | Property | Type | Description | | - | - | - | | Enable iOS Entitlements Integration | `Boolean` | Determines whether the SDK automatically applies entitlements integration during the Xcode build. | | Exclude Create Entitlements File | `Boolean` | Skips creating or modifying the app entitlements (`.entitlements`) file. | | Exclude Create Associated Domains Key | `Boolean` | Prevents adding the `com.apple.developer.associated-domains` key to the entitlements file. | | Exclude Add Associated Domain | `Boolean` | Skips adding the Appcharge associated domain value to the entitlements configuration. | ### Enable iOS URL Scheme Integration By default, the SDK adds the Appcharge URL scheme entries to `Info.plist` during the Xcode build. Use the options below to skip parts of that setup if you manage them yourself. | Property | Type | Description | | - | - | - | | Enable iOS URL Scheme Integration | `Boolean` | Determines whether the SDK automatically applies URL scheme integration during the Xcode build. | | Exclude Set URL Scheme Type Role | `Boolean` | Skips setting the URL scheme type role (e.g., Viewer/Editor) in the app’s Info.plist. | | Exclude Set URL Scheme Name | `Boolean` | Prevents setting or modifying the URL scheme display name in the Info.plist. | | Exclude Add URL Scheme | `Boolean` | Skips adding the Appcharge URL scheme entry to the app’s URL types configuration. | ## Fix deeplinks on affected Unity versions Some Unity versions add a `UIApplicationSceneManifest` key to `Info.plist`. This prevents `Application.deepLinkActivated`, which the Payment Links SDK uses to return players to the game after checkout. Known affected Unity versions: * `2022.3.75f1` * `6000.0.68f1` * `6000.0.69f1` * `6000.3.10f1` * `6000.4.0b11` * `6000.5.0a7` * `6000.6.0a1` If you're using one of these versions, after each iOS build open `Info.plist` in the generated Xcode project and remove the `UIApplicationSceneManifest` key and its contents. Unity regenerates `Info.plist` on each build, so repeat this workaround after every iOS build. Unity `6000.3.78f1` or later includes the official fix. You can upgrade instead of applying the `Info.plist` workaround. Test the upgrade thoroughly before releasing. # Integrate with WebGL Source: https://docs.appcharge.com/sdks/payment-links/unity/integrate-with-webgl This article explains how to integrate Unity Payment Links with the WebGL platform. To integrate with WebGL: 1. Go to the **Build Settings** window and make sure your Unity project is set to **WebGL**. Once set, the `AppchargeConfig` file updates to display WebGL-specific configuration options. WebGL Build Settings 2. Your configuration settings should look like this: WebGL Configurations By default, the configuration file is preconfigured for integration. However, you must set the required **Environment** field under **Publisher Info**. ## Publisher Info These settings can also be changed at runtime, but doing so requires [re-initializing the SDK](./initialize-the-payment-links-sdk#re-initialize-the-sdk). | Property | Type | Description | | - | - | - | | Environment | `Enum` | Sets the checkout environment. Use `Sandbox` for testing and `Production` for live payments. | ## Configuration Settings | Property | Type | Description | | - | - | - | | Enable Main Thread Dispatcher | `Boolean` | The SDK works outside of the Unity main thread. This option allows you to wrap callback methods with Unity main thread. | | Enable Debug Mode | `Boolean` | When enabled, prints a summary of automatic integration changes after the build completes. | # Launch the Checkout Source: https://docs.appcharge.com/sdks/payment-links/unity/launch-the-checkout To launch the checkout, follow these steps: 1. From your server, call the [Create Checkout Session API](/../../api-reference/checkout/checkout-session/create-checkout-session) to create a checkout session. * When calling the Create Checkout Session API, don't pass the `redirectUrl` parameter. The SDK already handles the redirect automatically using the configuration file. * Call the API from your server to ensure session integrity and security. Never invoke this endpoint from your client-side Unity Project. 2. After receiving the API response on your server, extract the values from the session object: ```json theme={"system"} { "checkoutSessionToken": "session_token_identifier", "purchaseId": "pr_purchase_id", "url": "https://checkout-v2-sandbox.appcharge.com", "parsedUrl": "https://checkout-v2-sandbox.appcharge.com/session_token_identifier#boot=checkout_boot_data" } ``` | Parameter | Description | | - | - | | `checkoutSessionToken` | A unique token to identify and validate the checkout session. | | `purchaseId` | ID to track the purchase. | | `url` | The base URL of the Appcharge checkout page. | | `parsedUrl` | The Parsed URL of the Appcharge checkout page. | 3. Use the values returned in the Create Checkout Session API response to open the checkout on the client, and pass your player's `customerId`. The SDK uses this ID with the session `purchaseId` to validate the order if the player closes the browser during checkout and later returns to the game. It also identifies the correct player when multiple players share the same device. ```csharp C# theme={"system"} PaymentLinksController.Instance.OpenCheckout( purchaseId: "PURCHASE_ID", parsedUrl: "PARSED_URL", customerId: "CUSTOMER_ID" ) ``` The session response values must be passed exactly as received. Modifying them may result in the checkout failing to load. 4. For WebGL integrations, no additional checkout display setup is required. The checkout opens as an iframe within the WebGL game. ## Optional Android and iOS checkout behavior The following optional settings are only relevant for Android and iOS integrations. 1. Control whether the Android foreground checkout service is enabled:
    The foreground service is enabled by default and helps keep your app prioritized while checkout is open, reducing the risk of Android closing or deprioritizing it during payment and network operations. You can enable or disable the service during runtime using: ```csharp C# theme={"system"} PaymentLinksController.Instance.SetConfiguration("setCheckoutServiceMode", true); // Enable PaymentLinksController.Instance.SetConfiguration("setCheckoutServiceMode", false); // Disable ``` The foreground service runs only if the required manifest permissions and service declaration are properly configured. If you don't want to use the foreground service, remove `CheckoutService` declaration from your manifest file and disable it during runtime using the method above. The foreground permissions can remain, as they may be used by other services in your app. 2. You can also override at runtime how the checkout page is opened: * **External browser**
    Open the checkout in the device’s default browser. This flow will redirect the player back to the app. ```csharp C# theme={"system"} // Unity Android PaymentLinksController.Instance.SetConfiguration("browserMode", AndroidBrowserMode.External) // Unity iOS PaymentLinksController.Instance.SetConfiguration("browserMode", iOSBrowserMode.External); ``` Running the checkout in an external browser may cause inconsistent behavior across devices, incomplete transactions, or app unexpected lifecycle behavior. * **Non-external browser (default)**
    Open the checkout in a non-external browser. This flow uses the URL scheme defined for the SDK to return to the app.

    For Android, the checkout opens in a Trusted Web Activity (TWA). For iOS, the checkout opens via [SFSafariViewController](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller). For more information regarding iOS, see [Sell Outside IAP](/../../guides/payment-links/ios-payment-links/sell-outside-iap). ```csharp C# theme={"system"} // Unity Android with an internal Trusted Web Activity (TWA) PaymentLinksController.Instance.SetConfiguration("browserMode", AndroidBrowserMode.Internal) // Unity iOS (SFSafariViewController) PaymentLinksController.Instance.SetConfiguration("browserMode", iOSBrowserMode.Internal); ``` 3. For Unity iOS only, you can force the Checkout page to display in portrait orientation, even if the app is currently in landscape mode: ```csharp C# theme={"system"} PaymentLinksController.Instance.SetConfiguration("portraitOrientationLock", "true") ```