# LemonSqueezy Checkout Source: https://docs.paritydeals.com/api-reference/checkout/lemonsqueezy-checkout /frontend-integration/openapi.json post /lemon-squeezy-checkout/ This endpoint creates a checkout session with LemonSqueezy and applies geographic pricing and discounts as configured in ParityDeals. It returns a checkout URL. # Stripe Checkout Source: https://docs.paritydeals.com/api-reference/checkout/stripe-checkout /frontend-integration/openapi.json post /stripe-checkout/ This endpoint creates a checkout session with Stripe and applies geographic pricing and discounts as configured in ParityDeals. It returns a checkout URL. # Promotion Details Source: https://docs.paritydeals.com/api-reference/promotions/promotion-details /frontend-integration/openapi.json get /deals/discount/ This endpoint provides dynamic discount information based on various criteria like user location, holidays, etc. It supports both client-side and server-side API calls with different parameter requirements. # LemonSqueezy buy now button Source: https://docs.paritydeals.com/buy-now-button/lemonsqueezy-buy-now-button The ParityDeals buy now button enhances LemonSqueezy's checkout link by creating dynamic checkout links that adjust prices based on user location, holidays, and other criteria set in ParityDeals. #### Overview To integrate ParityDeals with LemonSqueezy, replace your existing LemonSqueezy checkout link with the corresponding ParityDeals buy now button on your website. For security reasons, this link functions only when accessed directly from the specified website. #### Example ```tsx theme={null} Buy Now ``` #### Parameters * **`store_id`** (required): The unique identifier for the store on LemonSqueezy. * **`variants`** (required): A comma-separated list of product variant IDs available for purchase. The first ID in this list will be pre-selected in the checkout session. * **`product_id`** (required): The ParityDeals product identifier used to apply specific pricing and discounts. * **`success_url`** (required): The URL to which a user will be redirected after a successful purchase. #### Behavior * **Geographic Pricing**: When a user accesses the checkout page via the generated buy-now link, the API automatically fetches and applies pricing based on the user's location, holidays and other criteria set in ParityDeals. For example, if the product is priced at `$100` in the US and `$50` in India, a user from India will see the price as `$50` at checkout. * **Variant Handling**: In cases where multiple product variants are available, the API sets the first variant in the `variants` parameter as the default selection. If a user switches between variants, a temporary discount coupon is generated to maintain the correct price.
This coupon: * Can be used only once. * Expires in 30 minutes. * Is automatically applied to ensure the price adjusts without reverting to the default. # Stripe buy now button Source: https://docs.paritydeals.com/buy-now-button/stripe-buy-now-button The ParityDeals buy now button enhances Stripe's system by creating dynamic payment links that adjust prices based on user location, holidays, and other criteria set in ParityDeals. ### Overview To integrate ParityDeals with Stripe, replace your existing Stripe checkout link with the corresponding ParityDeals buy now button on your website. For security reasons, this link functions only when accessed directly from the specified website. ### Parameters * **`payment_id`** (required): The unique identifier for the product on Stripe. * **`product_id`** (required): The ParityDeals product identifier used to apply specific pricing and discounts. * **`success_url`** (required): The URL to which a user will be redirected after a successful purchase. ### Behavior * **Geographic Pricing**: When a user accesses the checkout page via the generated buy-now link, the API automatically fetches and applies pricing based on the user's location, holidays and other criteria set in ParityDeals. For example, if the product is priced at `$100` in the US and `$50` in India, a user from India will see the price as `$50` at checkout. ### Example Usage Here is how you can construct a URL for integrating the API with a buy-now button on a website: ```tsx theme={null} Buy Now ``` # JS Promotions UI Source: https://docs.paritydeals.com/frontend-integration/js-promotions-ui Documentation for integrating the ParityDeals JavaScript SDK to display dynamic and localized pricing on your website. # Quick Start Get dynamic, localized pricing on your site in just two steps: ## 1. Add the Script Paste this snippet just before the closing `` tag on your pricing page: ```html theme={null} ``` ## 2. Initialize the SDK Copy your product ID from the listing or promotion details page: ```js theme={null} PDPromotionUI.init({ productId: 'promo_7e2de26fb47644e58e867a20i898j748', // Replace with your product ID of the promotion showBanner: true, }); ``` This will automatically display a discount banner if the user is eligible for a discount. *** # Displaying Dynamic Prices (Basic) The easiest way to show dynamic prices is to add the `data-pd-price` attribute to a wrapper element, and place a child element with `data-pd-price-formatted` where you want the price to appear. The SDK will automatically update this with the correct price for each visitor. **Example:** ```html theme={null}

Basic Plan

$99

``` **That's it!** The SDK will find and update these prices automatically. *** # Customizing Price Display (Basic) If you want to style different parts of the price (like the currency symbol or decimals), you can break the price into parts using these attributes **inside** a container with `data-pd-price`: | Data Attribute | Description | | :-------------------------------- | :----------------------------------------- | | `data-pd-price-formatted` | The full formatted price (e.g., "\$99.50") | | `data-pd-currency-symbol` | Only the currency symbol (e.g., "\$") | | `data-pd-currency-code` | 3-letter currency code (e.g., "USD") | | `data-pd-price-integer` | Integer part of the price (e.g., "99") | | `data-pd-price-decimal` | Decimal part (e.g., "50") | | `data-pd-price-decimal-separator` | The decimal separator (e.g., ".") | **Example:** ```html theme={null}
``` *** # SDK Configuration Options | Option | Type | Default | Description | | ------------------------ | -------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------- | | `productId` | string | '' | The product ID to display | | `showBanner` | boolean | true | Whether to show the discount banner | | `localizePricing` | boolean | true | Convert to local currency | | `baseCurrencyCode` | string | USD | If you use any base currency other than USD, you must provide this. Currency conversion will be done using this code. | | `baseCurrencySymbol` | string | \$ | If you use any base currency other than USD, you must provide this. Only for the displaying purpose, but still important. | | `currencyDisplay` | `symbol\|code\|name` | symbol | The currency display format. This only works on the `data-pd-price-formatted` element. | | `showDecimal` | boolean | false | Whether to show decimals | | `minimumDecimalDigits` | number | 0 | The minimum number of decimal digits | | `maximumDecimalDigits` | number | 2 | The maximum number of decimal digits. Maximum is 2. | | `banner.*` | object | — | Customization for the discount banner | | `banner.noStyles` | boolean | false | if true, no styling will be applied to the banner | | `banner.showCloseButton` | boolean | true | Control close button visibility. This setting will work only if close button is enabled from the ParityDeals banner settings | | `banner.placement` | `top\|bottom` | 'top' | The placement of the discount banner | | `banner.container` | string | null | The container for the discount banner | | `banner.backgroundColor` | string | '#f0f0f0' | The background color of the discount banner | | `banner.fontColor` | string | '#333333' | The font color of the discount banner | | `banner.borderRadius` | string | '0px' | The border radius of the discount banner | | `banner.fontSize` | string | '14px' | The font size of the discount banner | *** ## data-props override You can override the default properties of the price elements by adding a `data-props` attribute to the element. **Example:** In the below example, we override the `showDecimal` property to false. ```html theme={null}
``` #### Supported attributes * `data-pd-show-decimal` - Whether to show decimals * `data-pd-localize-pricing` - Whether to localize the pricing * `data-pd-minimum-decimal-digits` - The minimum number of decimal digits * `data-pd-maximum-decimal-digits` - The maximum number of decimal digits * `data-pd-currency-display` - The currency display format *** # Advanced Usage ## Grouping and Strikethrough Prices For more complex pricing layouts, you can use these advanced attributes: * `data-pd-original-price-display`: Shows a "compare at" or strikethrough price (never discounted, but can be localized). * `data-pd-rel`: Groups related price elements so they update together (e.g., main price and strikethrough). **Example:** ```html theme={null}

Pro Plan

``` You can assign the same `data-pd-rel` value to all elements that should update together. *** # API Reference (Advanced) All SDK functions are asynchronous and return a `Promise`. None of the below finctions inherit the configuration options set in the `init` function. You need to pass the options for each function call. ## `getUpdatedPrice` Calculate and return the updated price for a given base price (does not update the DOM): ```js theme={null} const price = 99.99; const options = { localizePricing: true }; PDPromotionUI.getUpdatedPrice(price, options) .then(result => { console.log('Updated price object:', result); }); ``` ## `updatePriceElement` Update a specific DOM element's price: ```js theme={null} const priceElement = document.querySelector('#basic-price'); const options = { showDecimal: false }; PDPromotionUI.updatePriceElement(priceElement, options) .then(result => { console.log('Price element updated successfully.'); }); ``` ## `updatePrice` Bulk update multiple price elements with custom templates: ```js theme={null} const priceUpdates = [ { element: document.querySelector('#price-1'), price: 10, options: { localizePricing: true }, template: '
{{formattedPrice}}
' }, { element: document.querySelector('#price-2'), price: 20, options: { isOriginalDisplay: true }, template: '{{currencySymbol}}{{integerPart}}' } ]; PDPromotionUI.updatePrice(priceUpdates) .then(results => { console.log('All prices updated:', results); }); ``` *** # Support Need help or have questions? Reach out to us anytime at **[hi@paritydeals.com](mailto:hi@paritydeals.com)**. # React Promotions UI Source: https://docs.paritydeals.com/frontend-integration/react-promotions-ui A React SDK for integrating ParityDeals dynamic pricing and discounts directly into your React application. ## Installation Install the package using npm: ```bash theme={null} npm install @paritydeals/react-promotions-ui ``` ## Getting Started To start using the SDK, wrap your app with the `ParityDealsProvider` at the root level. This sets up the necessary context. You can copy your product ID from the listing or promotion details page: ```tsx theme={null} import { ParityDealsProvider } from '@paritydeals/react-promotions-ui'; function App() { return ( // Replace with your product ID of the promotion {/* Your app components */} ); } ``` ## Attributes: You can use the following attributes to customize the behavior of the components. | Attribute | Type | Default | Description | | -------------------- | ------ | ------- | ------------------------------------------------------------------------------------------------------------------------- | | `productId` | string | '' | The product ID to display | | `baseCurrencyCode` | string | USD | If you use any base currency other than USD, you must provide this. Currency conversion will be done using this code. | | `baseCurrencySymbol` | string | \$ | If you use any base currency other than USD, you must provide this. Only for the displaying purpose, but still important. | *** ## Components Use these ready-made UI components to easily show location-aware pricing and promotional content. ### `PDBanner` Displays a location-aware discount banner. You can style and position it as needed. ```tsx theme={null} import { PDBanner } from '@paritydeals/react-promotions-ui'; console.log('Banner closed')} /> ``` *** ### PDPriceFormatted Simplified component to display discounted and original prices dynamically based on the user’s location. #### Display Discounted Price Use this to show the localized or discounted price. The price is automatically formatted based on the user's location, including currency symbols, decimal separators, and digit grouping — for example, ₹9,999.99 for India, ¥10,000 for Japan, and 9.999,99 € for Italy where the currency symbol appears on the right. ```tsx theme={null} ``` ##### Configuration Options | Option | Type | Default | Description | | ---------------------- | -------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `localizePricing` | boolean | true | Convert to local currency | | `price` (required) | number | 0 | The price of the product. | | `className` | string | '' | custom class name for the component | | `currencyDisplay` | `symbol\|code\|name` | symbol | The currency display format. This only works on the `data-pd-price-formatted` element. | | `showDecimal` | boolean | false | Whether to show decimals | | `minimumDecimalDigits` | number | 0 | The minimum number of decimal digits | | `maximumDecimalDigits` | number | 2 | The maximum number of decimal digits. Maximum is 2. | | `isOriginalDisplay` | boolean | false | Used to show the original price when there’s a discount, typically for comparison (e.g., strikethrough price). This price is not modified by discounts but may still be affected by currency conversions. | | `displayPrice` | number | 0 | The price to display. If not provided, the original price will be displayed. | #### Display Original Price (Strikethrough) Optionally show the original price with a strikethrough effect: ```tsx theme={null} ``` #### Example Usage Combine both for a side-by-side comparison: ```tsx theme={null}
``` *** ## Granular Price Components Use these components individually to build custom price formats with full styling control. ### PDPriceInteger Displays just the integer part of the price. ```tsx theme={null} ``` ##### Configuration Options | Option | Type | Default | Description | | ------------------ | ------- | ------- | ----------------------------------- | | `localizePricing` | boolean | true | Convert to local currency | | `price` (required) | number | 0 | The price of the product. | | `className` | string | '' | custom class name for the component | *** ### PDPriceDecimal Displays just the decimal portion. ```tsx theme={null} ``` ##### Configuration Options | Option | Type | Default | Description | | ---------------------- | ------- | ------- | --------------------------------------------------- | | `localizePricing` | boolean | true | Convert to local currency | | `price` (required) | number | 0 | The price of the product. | | `className` | string | '' | custom class name for the component | | `minimumDecimalDigits` | number | 0 | The minimum number of decimal digits | | `maximumDecimalDigits` | number | 2 | The maximum number of decimal digits. Maximum is 2. | *** ### PDPriceCurrencySymbol Renders the currency symbol (like \$, ₹, €). ```tsx theme={null} ``` ##### Configuration Options | Option | Type | Default | Description | | ----------------- | ------- | ------- | ----------------------------------- | | `localizePricing` | boolean | true | Convert to local currency | | `className` | string | '' | custom class name for the component | *** ### `PDPriceCurrencyCode` Renders the full currency code (like USD, INR, EUR). ```tsx theme={null} ``` ##### Configuration Options | Option | Type | Default | Description | | ----------------- | ------- | ------- | ----------------------------------- | | `localizePricing` | boolean | true | Convert to local currency | | `className` | string | '' | custom class name for the component | *** ### PDPriceDecimalSeparator Renders the decimal separator based on the user's location (e.g., "."). ```tsx theme={null} ``` ##### Configuration Options | Option | Type | Default | Description | | ------------------ | ------- | ------- | ----------------------------------- | | `localizePricing` | boolean | true | Convert to local currency | | `price` (required) | number | 0 | The price of the product. | | `className` | string | '' | custom class name for the component | ### Custom Display Example Example using all components to create a custom layout: ```tsx theme={null}
``` *** ## Support Need help or have questions? Reach out to us anytime at **[hi@paritydeals.com](mailto:hi@paritydeals.com)**. # Introduction to ParityDeals Source: https://docs.paritydeals.com/getstarted/introduction-to-paritydeals This guide covers how to configure and manage location-based pricing promotions in ParityDeals. You’ll learn both the recommended integrated workflow (with payment platforms) and the manual setup for custom needs. ## What is ParityDeals **ParityDeals** helps you implement purchasing power parity (PPP) pricing so you can offer fair, localized prices to customers worldwide. Instead of charging the same price globally, ParityDeals automatically adjusts pricing based on a visitor’s local economic conditions. This makes your SaaS products, online courses, newsletters, and digital goods more accessible in emerging markets — helping you increase conversions, grow revenue, and expand into new regions without manually managing regional pricing. By detecting a visitor’s location in real time, ParityDeals applies optimized, location-based discounts that reflect local purchasing power — building trust, reducing piracy, and improving global sales performance. Promotions empty state with globe illustration *** ## How Promotions Work in ParityDeals Setting up a promotion is quick and straightforward: ### 1. Platform Integration Connect your existing payment provider directly inside the Promotions Hub. ParityDeals supports native integrations with Stripe, Lemon Squeezy, Paddle, Chargebee, Dodo Payments, and more. ### 2. Automated Coupon Management After selecting the products you want to discount, ParityDeals automatically generates and manages localized coupons directly in your payment provider’s backend — no manual setup required. ### 3. Dynamic Banner Display Add a lightweight one-line script to your site (or specific routes like `/pricing`). ParityDeals dynamically renders a top or bottom banner tailored to eligible visitors based on their location. ### 4. Built-In Fraud Protection ParityDeals includes built-in safeguards such as: * Auto-refreshing coupons * VPN, proxy, and Tor detection/blocking This ensures discounts are applied only to genuinely eligible customers. *** With ParityDeals, you can launch global PPP pricing in minutes — without building complex geo-pricing infrastructure from scratch. # Customization & Settings Source: https://docs.paritydeals.com/quickstart/configuration Manage banner appearance, security, and display rules. ## After Creation: Configuring Your Promotion After creating a promotion using either method, you will land on its detail page and see a success message. This page contains multiple tabs for powerful post-creation configurations. Promotion detail page with success message and tabs This tab allows you to customize the promotional banner that will be displayed on your site and provides the code to make it live. #### Banner Styling Customize the banner's appearance to match your website's theme using the no-code style editor: * **Background color, Font color, Border radius, Font size** #### Banner Copy Toggle on **"Banner copy"** to customize the text displayed. You can use dynamic variables to make the banner more personalized: * `{country_flag}` - The visitor's country flag emoji. * `{country}` - The visitor's country name. * `{coupon_code}` - The specific coupon code for the visitor's region. * `{discount_percentage}` - The discount percentage. * **Example Copy:** `Hello {country_flag}! It looks like you're from {country}. We support Parity Purchasing Power. Use the code {coupon_code} to get {discount_percentage}% off your subscription at checkout.` #### Banner Placement * **Position:** Choose to display the banner at the **Top** or **Bottom** of the viewport. * **Banner Container:** Enter the HTML container selector where you want the banner to be placed (e.g., `#container`, `.main-content`, `body`). Banner customization and placement controls This tab allows you to configure security and display rules for your promotion. #### Security Enable or disable security features to protect your promotion from unauthorized access based on your product and target audience. * **VPN protection:** Safeguards against users masking their location with VPNs to exploit geo-pricing. * **Tor browser protection:** Prevents anonymous Browse that bypasses regional pricing. * **Proxy servers protection:** Blocks access from IP-hiding proxies to ensure fair purchasing power parity pricing. Security tab with VPN, Tor, and Proxy toggles #### Promotion Display Control Connect your website and define the specific pages where your promotional banner should appear. 1. **Enter your website URL:** Enter the full URL, including `http://` or `https://` (e.g., `https://www.example.com`). Do not add anything after the main website URL. Promotion display control website URL input 2. **Target a specific page:** Enter the path of a specific page to target (e.g., `/pricing` or `/products/new`). Do not include your domain. Add multiple page paths by clicking **"Add Page Path"** after each entry. 3. Click the **"Save"** button to apply your display rules. *** # Dashboard Setup Source: https://docs.paritydeals.com/quickstart/dashboard-setup Step-by-step guide to creating your first promotion. ## Getting Started: Two Paths for Promotion Setup There are two primary workflows for setting up location-based discounts: Connect to your existing payment platform (e.g., Stripe, Paddle). ParityDeals fetches your products and automatically creates the necessary discount coupons for you. This is the fastest and most streamlined method. Use this method if you do not use one of our integrated platforms or if you need to manage coupon codes manually. You will define the discounts in ParityDeals, then create corresponding coupons in your payment provider and paste the codes back into ParityDeals. *** ## Setting Up Promotions via Integrated Platforms This is the recommended workflow if you sell your product via a supported payment platform. ### Step 1: Connect to Your Payment Platform 1. From the main sidebar, navigate to **Promotions**. 2. Click the **"+ Create promotion"** button. 3. In the "Choose your platform" modal, select the platform you use. Supported integrations include: * **Stripe** * **Lemon Squeezy** * **Paddle** * **Chargebee** * **Dodo Payments** * **Polar** * **Gumroad** * **Whop** Choose your platform modal with payment logos 4. If connecting for the first time, an authentication modal will appear. Enter the required credentials (e.g., Vendor ID, Auth code/API key) to connect your account. Authenticate with Paddle modal ### Step 2: Select Your Product After authenticating, the two-step promotion creation flow begins. 1. **Select Product:** A list of products fetched from your connected platform account (e.g., Stripe) is displayed. 2. Choose the product for which you want to set up discounts and click **"Continue"**. Select product screen ### Step 3: Set Discounts You will now see the "Set up discounts" screen, which displays countries grouped by their purchasing power parity factor. 1. **Review Discounts:** Review the predefined discount percentages for each PPP group and update them as needed. If you do not want to offer a deal for a specific group, leave the discount box empty. ParityDeals will automatically create the necessary discount coupons on your integrated platform based on the percentage values you set here. 2. **(Optional) Override Group Discounts:** To set a different discount for a specific country that overrides its group's default discount, click the **"+ Create country-specific discount"** button. * In the modal that appears, select a country from the dropdown, enter the `Override discount %`, and optionally a specific `Coupon code` if you want to use a pre-existing one. * Click **"+ Add more"** to specify overrides for multiple countries. * Click **"Create"** to save your overrides. Country-specific discount overrides modal ### Step 4: Create the Promotion 1. Once you are satisfied with your discount settings, click the **"Create promotion"** button at the bottom-right of the page. *** ## Setting Up Custom Promotions (Manual) Use this method if you do not use one of our integrated platforms or prefer to manage coupon codes manually. ### Step 1: Initiate Custom Setup 1. Navigate to **Promotions** from the sidebar and click **"+ Create promotion"**. 2. Select **"Custom setup"** from the platform choice modal. Choose platform custom setup modal ### Step 2: Define Product and Set Discounts This action takes you to the "Create Promotion" page. 1. **Product Setup:** In the "Product setup" section, enter your **Product name** manually. Product name input field 2. **Set Up Coupons:** This section displays countries grouped by purchasing power parity. * **Review Discounts:** Review the predefined discount percentages for each group and update them as needed. * **Enter Coupon Codes:** You must first manually create the corresponding discount coupons in your payment provider's platform. Then, paste each coupon code into the respective **"Coupon code"** field in ParityDeals. 3. **(Optional) Override Group Discounts:** * Click the **"+ Create country-specific discount"** button. * In the modal, select a country, set the `Override discount %`, and paste the specific `Coupon code` you created for it. * Click **"+ Add more"** for additional country-specific overrides. * Click **"Create"** to save your overrides. ### Step 3: Create the Promotion 1. Once all discounts and coupon codes are set, click the **"Create promotion"** button at the bottom-right corner. *** # App Integration Source: https://docs.paritydeals.com/quickstart/integrate-with-your-app Technical guides for adding ParityDeals to your frontend. ## Integrate into your app Adding ParityDeals to your app is simple. You can: * Show a banner based on the user’s location * Directly update the price We support both plain JavaScript and React. Pick what fits your stack: * [JavaScript Integration Guide](/frontend-integration/js-promotions-ui) * [React Integration Guide](/frontend-integration/react-promotions-ui) *** ## Managing Promotions You can edit a promotion at any time after it has been created. 1. Navigate to the **Promotions** list page. 2. Click the **three-dot menu** on the promotion you wish to edit and select the **"Edit"** option from the dropdown. (Alternatively, you can navigate to the promotion's detail page and find an "Edit" option there). Edit promotion three-dot menu 3. This action takes you back into the promotion editing flow where you update the details. 4. Click **"Update promo"** (or a similar button) to save your changes. Your updates will be reflected live for your users. *** ## Best Practices * Always test your promotion setup on a staging environment before going live. * Use clear, descriptive names for each promotion and discount rule. * Regularly review and update your discount percentages to match market conditions. * Use country overrides sparingly and only when necessary. * Never expose secret identifiers in public code. *** ## Troubleshooting **Discount not applied?** * Check your product selection and country rules. * Ensure the user is eligible for a discount based on your rules. * For integrated platforms, verify your payment provider connection is active. **Banner not showing?** * Ensure your domain is whitelisted in the promotion settings. * Make sure your API integration uses the correct identifier and parameters. ***