We're excited to introduce a chat widget to the Polar dashboard, making it easier than ever for merchants to get help directly within the product.
## Improved Checkout Flow for Invalid Discount Code
Previously, if you entered an invalid discount code during checkout, you couldn't continue even after removing the code. Now, clearing the discount input lets you proceed smoothly with the checkout process.
## Improved Customer Portal Rate Limits
We've made several improvements to the Customer Portal to handle authentication rate limits more gracefully:
* The portal now clearly shows 401 and 429 errors on the OTP (one-time password) page.
* If you hit a 429 (too many requests), you'll be redirected to a clear `/too-many-requests` page.
We've added detailed cancellation metrics, giving you clearer insights into subscription cancellations and their impact on your business performance.
The payment attempts information is also available on each order.
Besides, we've also added new analytics around checkouts: total number of checkouts, successful checkouts, and conversion rate.
[Better Auth](https://www.better-auth.com/) is an open source authentication framework for
TypeScript that is quickly becoming a favorite amongst developers. Today, we're
thrilled to have shipped a Polar plugin for Better Auth - in collaboration with them.
Checkout our [integration guide](/integrate/sdk/adapters/better-auth).
This is available right now using the [Checkout Session API](/features/checkout/session) and [Checkout Links](/features/checkout/links).
### Depreciations
* Products can no longer have both a monthly and yearly pricing. Existing products still work, but you'll see a warning like this when trying to edit their pricing:
{" "}
### API changes
* The `product_id` and `product_price_id` fields are deprecated in the [Checkout Session API](/api-reference/checkouts/create-session). You should now use the `products` field to specify the products you want to include in the checkout.
* The `type` and `recurring_interval` fields on `ProductPrice` are deprecated. `recurring_interval` is now set directly on `Product`.
**Missing any metrics?** [Let us know so we can add it.](https://github.com/orgs/polarsource/discussions/categories/feature-requests)
### Filters
You can easily slice and dice metrics with the filters below.
### Period
Change the time period in the X-axis to one of:
* Yearly
* Monthly
* Weekly
* Daily
* Hourly
### Timeframe
You can choose a date range to view all metrics for.
### Product
By default metrics reflect the total across all products. However, you can specify individual products or subscription tiers to filter metrics by.
## Metrics
* **Revenue**: How much revenue you've earned before fees.
* **Orders**: How many product sales and subscription payments have been made.
* **Average Order Value (AOV)**: The average earning per order, i.e. revenue / orders.
* **One-Time Products**: Amount of products sold.
* **One-Time Products Revenue**: Amount of revenue earned from products.
* **New Subscriptions**: Amount of new subscriptions.
* **New Subscription Revenue**: Amount of revenue earned from new subscriptions.
* **Renewed Subscriptions**: Amount of renewed subscriptions.
* **Renewed Subscription Revenue**: Amount of revenue earned from renewed subscriptions.
* **Active Subscriptions**: Amount of active subscriptions (new + renewed).
* **Monthly Recurring Revenue (MRR)**: Amount of revenue earned from active subscriptions.
* **Checkouts**: Number of created checkouts.
* **Succeeded Checkouts**: Number of successful checkouts, i.e. checkouts that lead to a new order or subscription.
* **Checkouts Conversion Rate**: The percentage of successful checkouts out of all created checkouts.
## Cost Metrics
* **Costs**: How much costs you've incurred.
* **Cumulative Costs**: How much costs you've incurred over time.
* **Cost Per User**: The average cost per active user.
* **Gross Margin**: The gross margin, i.e. revenue - costs.
* **Gross Margin Percentage**: The gross margin percentage, i.e. gross margin / revenue.
* **Net Cashflow**: The net cashflow, i.e. revenue - costs.
* **Monthly Recurring Cost (MRC)**: The monthly recurring cost, i.e. costs / active subscriptions.
* **Return on Investment (ROI)**: The return on investment, i.e. (revenue - costs) / costs.
# Credits Benefit
Source: https://polar.sh/docs/features/benefits/credits
Create your own Credits benefit
The Credits benefit allows you to credit a customer's Usage Meter balance.
## Crediting Usage Meter Balance
The Credits benefit will credit a customer's Usage Meter balance at different points in time depending on the type of product purchased.
### Subscription Products
The customer will be credited the amount of units specified in the benefit at the beginning of every subscription cycle period โ monthly or yearly.
### One-Time Products
The customer will be credited the amount of units specified in the benefit once at the time of purchase.
## Rollover unused credits
You can choose to rollover unused credits to the next billing cycle. This means that if a customer doesn't use all of their credits in a given billing cycle, the remaining credits will be added to their balance for the next billing cycle. To enable this feature, check the "Rollover unused credits" checkbox when creating or editing the Credits benefit.
Automating Discord server invites and roles for customers or subscribers is super easy and powerful with Polar.
* Fully automated Discord server invitations
* You can even setup multiple Discord servers, or...
* Offer different roles for different subscription tiers or products
## Create Discord Benefit
Click on `Connect your Discord server`. You'll be redirected to Discord where you can grant the Polar App for your desired server.
Next, you'll be prompted to approve the permissions our app requires to function. It needs all of them.
### **Manage Roles**
Access to your Discord roles. You'll be able to select which ones to grant to your customers later.
### **Kick Members**
Ability to kick members who have this benefit and connected Discord with Polar.
### **Create Invite**
Ability to invite members who purchase a product or subscribes to a tier with this benefit.
You're now redirected back to Polar and can finish setting up the Discord benefit on our end.
### **Connected Discord server**
The Discord server you connected cannot be changed. However, you can create multiple benefits and connect more Discord servers if you want.
### **Granted role**
Which Discord role do you want to grant as part of this benefit?
## Adding Benefit to Product
Head over to the product you want to associate this new Discord benefit with. You should be able to toggle the benefit in the bottom of the Edit Product form.
# Automate Customer File Downloads
Source: https://polar.sh/docs/features/benefits/file-downloads
Offer digital file downloads with ease
## Sell Digital Products
You can easily offer customers and subscribers access to downloadable files with Polar.
* Up to 10GB per file
* Upload any type of file - from ebooks to full-fledged applications
* SHA-256 checksum validation throughout for you and your customers (if desired)
* Customers get a signed & personal downloadable URL
## Create Downloadable Benefit
1. Go to `Benefits` in the Dashboard sidebar
2. Click `+ Add Benefit` to create a new benefit
3. Choose `File Downloads` as the `Type`
You can now upload the files you want to offer as downloadables for customers.
1. Drag & drop files to the dropzone (`Feed me some bytes`)
2. Or click on that area to open a file browser
### Change filename
Click on the filename to change it inline.
### Change order of files
You can drag and drop the files in the order you want.
### Review SHA-256 checksum
Click on the contextual menu dots and then `Copy SHA-256 Checksum`
### Delete a file
Click on the contextual menu dots and then `Delete` in the menu.
**Active subscribers & customers will lose access too!**
Deleting a file permanently deletes it from Polar and our S3 buckets except for the metadata. Disable the file instead if you don't want it permanently deleted.
### Disable & Enable Files
You can disable files at any point to prevent new customers getting access to it.
**Existing customers retain their access**
Customers who purchased before the file was disabled will still have access to legacy files. Only new customers will be impacted.
**Enabling or adding files grants access retroactively**
In case you add more files or re-enable existing ones, all current customers and subscribers with the benefit will be granted access.
# Automate Private GitHub Repo(s) Access
Source: https://polar.sh/docs/features/benefits/github-access
Sell premium GitHub repository access with ease
## Sell GitHub Repository Access
With Polar you can seamlessly offer your customers and subscribers automated access to private GitHub repositories.
* Fully automated collaborator invites
* Unlimited repositories (via multiple benefits) from your organization(s)
* Users get access upon subscribing & removed on cancellation
* Or get lifetime access upon paying a one-time price (product)
### **Use cases**
* Sponsorware
* Access to private GitHub discussions & issues for sponsors
* Early access to new feature development before upstream push
* Premium educational materials & code
* Self-hosting products
* Courses, starter kits, open core software & more...
## Create GitHub Repository Benefit
1. Go to `Benefits` in the sidebar
2. Click `+ New Benefit` to create a new benefit
3. Choose `GitHub Repository Access` as the `Type`
You first need to `Connect your GitHub Account` and install a dedicated Polar App for this benefit across the repositories you want to use it with.
* Click `Connect your GitHub Account`
You can easily sell software license keys with Polar without having to deal with sales tax or hosting an API to validate them in real-time. License keys with Polar come with a lot of powerful features built-in.
* Brandable prefixes, e.g `POLAR_*****`
* Automatic expiration after `N` days, months or years
* Limited number of user activations, e.g devices
* Custom validation conditions
* Usage quotas per license key
* Automatic revokation upon cancelled subscriptions
## Create License Key Benefit
1. Go to `Benefits` in the sidebar
2. Click `+ New Benefit` to create a new benefit
3. Choose `License Keys` as the `Type`
### Custom Branding
Make your license keys standout with brandable prefixes, e.g `MYAPP_
You can either copy and paste our code snippet to get up and running in a second or use our JavaScript library for more advanced integrations. Our embedded checkout allows you to provide a seamless purchasing experience without redirecting users away from your site.
## Code Snippet
The code snippet can be used on any website or CMS that allows you to insert HTML.
First, create a [Checkout Link](/features/checkout/links) as described in the previous section. The code snippet can directly be copied from there by clicking on `Copy Embed Code`.
The snippet looks like this:
```typescript theme={null}
Purchase
```
This will display a `Purchase` link which will open an inline checkout when clicked.
You can style the trigger element any way you want, as long as you keep the `data-polar-checkout` attribute.
## Import Library
If you have a more advanced project in JavaScript, like a React app, adding the `
```
Replace `YOUR_AFFONSO_PROGRAM_ID` with the unique program ID provided by Affonso.
This script should be placed on all pages of your website, including:
* Your main marketing website
* Your application domain
* Any subdomains where users might land or make purchases
### 4. Track User Signups (Optional)
For better conversion insights, you can track when users sign up through an affiliate link:
```javascript theme={null}
// After successful registration
window.Affonso.signup(userEmail);
```
### 5. Pass Referral Data to Polar Checkout
To ensure proper commission attribution, pass the referral data when creating checkout sessions:
```javascript theme={null}
// Get the referral ID from the Affonso global variable
const referralId = window.affonso_referral;
// Create checkout session with Polar
const checkout = await polar.checkouts.create({
products: ["your_product_id"],
success_url: "https://your-site.com/success",
metadata: {
affonso_referral: referralId, // Include referral ID from Affonso
}
});
// Redirect to checkout
window.location.href = checkout.url;
```
## How It Works
1. When a user visits your site through an affiliate link, Affonso's script stores a unique identifier in a cookie
2. If you've implemented signup tracking, Affonso records when the user creates an account
3. When the user makes a purchase, the referral ID is passed to Polar as metadata
4. Polar's webhook notifies Affonso about the purchase
5. Affonso attributes the sale to the correct affiliate and calculates the commission
## Benefits of the Integration
* **Automated Tracking**: No manual work required to track affiliate-driven sales
* **Real-Time Analytics**: Both you and your affiliates get immediate insights into performance
* **Seamless User Experience**: The integration works behind the scenes without affecting your checkout flow
* **Flexible Commission Structures**: Set up complex commission rules based on product, subscription duration, etc.
## Getting Help
More details about the integration: [Polar Affiliate Program](https://affonso.io/polar-affiliate-program)
If you need assistance with your Affonso integration, contact Affonso's support team:
* Email: [hello@affonso.io](mailto:hello@affonso.io)
* Live chat: Available directly in the Affonso dashboard
# Polar Integration in Fernand
Source: https://polar.sh/docs/features/integrations/fernand
Learn how to sync customer and payment data from Polar to Fernand.
## What is Fernand?
[Fernand](https://getfernand.com/) is a modern customer support tool designed for SaaS โ itโs fast, calm, and built to reduce the anxiety of answering support requests.
## How it works
After connecting your [Polar](https://polar.sh/) account to Fernand, youโll be able to see customer payment information and product access details directly within each customer conversation.
This enables you to:
* Instantly verify if someone is an active customer
* Prioritize conversations from high-tier plans
* View product purchases and payment history in context
***
## How to connect Fernand with Polar
1. Open [Integrations](https://app.getfernand.com/settings/organization/integrations) in your Fernand organization settings.
2. Click on **Connect Polar**.
3. You'll be redirected to Polar to authorize the connection.
4. Once approved, Fernand will begin syncing customer data automatically.
Thatโs it! Youโll now see Polar customer info directly in Fernand's conversation list and sidebar.
***
## How to automate your inbox with Polar data
Once Polar is connected, you can create automation rules in Fernand based on Polar data.
Letโs walk through a basic example: auto-replying to all customers on your `Pro` plan.
### Create a new rule
### Grant ParityDeals Access (OAuth 2.0)
No need to create API access keys and share them externally. Just connect securely and grant the necessary permissions using Polar OAuth 2.0.
### Choose Products
Now, let's select the Polar products you want to offer deals for.
### Configure Deals
Let's configure our deal settings.
* Enter your website URL (requires your own site vs. Polar storefront)
* Enter a targeted URL path, e.g `/pricing` to only show deals on that page
Now we can configure the deals for different countries. ParityDeals offers great defaults, but you can of course change them.
### Configure Banner
You can then customize the ParityDeals banner to suit your site and design.
### Embed Banner
Finally, we're all setup over at ParityDeals. Just copy the script to their banner and embed it on your site. You're now done ๐๐ผ
## Questions & Help
Checkout the [ParityDeals documentation](https://www.paritydeals.com/docs/) for more guides and information.
# Polar for Raycast
Source: https://polar.sh/docs/features/integrations/raycast
The fastest way to access Polar from your keyboard
## Install Extension
[Head over to Polar on the Raycast Store, and install it from there.](https://www.raycast.com/emilwidlund/polar)
### View Orders
Easily view orders across organizations.

### View Subscriptions
View all active subscriptions across your organizations.

### View Customers
Keep track of all your customers.
# Polar for Zapier
Source: https://polar.sh/docs/features/integrations/zapier
Connect Polar to hundreds of other apps with Zapier
export const ZapierEmbed = () => {
if (typeof document === "undefined") {
return null;
} else {
setTimeout(() => {
const script = document.createElement("script");
script.type = "module";
script.src = "https://cdn.zapier.com/packages/partner-sdk/v0/zapier-elements/zapier-elements.esm.js";
document.head.appendChild(script);
const stylesheet = document.createElement("link");
stylesheet.rel = "stylesheet";
stylesheet.href = "https://cdn.zapier.com/packages/partner-sdk/v0/zapier-elements/zapier-elements.css";
document.head.appendChild(stylesheet);
const element = document.createElement("zapier-workflow");
element.clientId = "Zci4gpfx7Co47mBoFOYm0m8bmnzB5UPcw7eGhpSR";
element.theme = document.querySelector("html").classList.contains("dark") ? "dark" : "light";
element.introCopyDisplay = "hide";
element.manageZapsDisplay = "hide";
element.guessZapDisplay = "hide";
const container = document.querySelector("#zapier-container") || document.body;
container.appendChild(element);
}, 1);
return ;
}
};
[Zapier](https://zapier.com/apps/polar/integrations) lets you connect Polar to 2,000+ other web services. Automated connections called Zaps, set up in minutes with no coding, can automate your day-to-day tasks and build workflows between apps that otherwise wouldn't be possible.
Each Zap has one app as the **Trigger**, where your information comes from and which causes one or more **Actions** in other apps, where your data gets sent automatically.
The sales view shows you all sales in a paginated list.
## Order & Subscription Details
Each sale has metadata attached to it. Common properties like
* Amount
* Tax Amount
* Invoices
* Customer
* Basic Customer Details
* Past Orders
## Checkouts
You can also have an overview of all checkout sessions. You can filter them by customer email, status and product.
A checkout can be in the following states:
* Open: The checkout session is open and waiting for the customer to complete the payment.
* Confirmed: The customer clicked the **Pay** or **Subscribe** button and the payment is being processed.
* Succeeded: The payment was successful and the order was created.
* Expired: The checkout session expired and the customer can no longer complete it. A new checkout session must be created.
If you click on a Checkout, you can have more details on the **payment attempts**, in particular, why a payment has failed or has been declined.
# Products
Source: https://polar.sh/docs/features/products
Create digital products on Polar in minutes
## Create a product
### Name & Description
Starting off with the basic.
* **Name** The title of your product.
* **Description** Markdown is supported here too.
### Pricing
Determine how you want to charge your customers for this product.
Fields are managed from your organization settings, and you can choose which fields to show on a per-product basis, and set if they are required or not. We support the following field types:
* Text
* Number
* Date
* Checkbox
* Select
**Amount**
Specify the amount to refund. By default itโs the full order amount, but you can reduce this to issue a partial refund instead.
## Starting a trial
When a customer checks out a subscription product with a trial period, they will not be charged immediately. Instead, they will have access to the product for the duration of the trial period.
We'll still collect their payment information at checkout, but they won't be charged until the trial period ends. This means that if they decide to cancel before the trial ends, they won't be charged at all.
Once the trial period ends, the customer will be automatically charged for the subscription, and their billing cycle will begin.
## Adding, extending or canceling a trial
For existing subscriptions, you can add, extend or cancel a customer's trial period at any time through the dashboard, from the subscription details page. Click on **Update Subscription**, then click on the **Trial** tab.
To add or extend a trial, set a new trial end date in the future. If the subscription was active, its status will be changed to **trialing**, and the billing will be postponed until the end of the trial.
To cancel a trial, click on the **End trial** button. The subscription will become active immediately, and the customer will be charged immediately for a new billing cycle.
## Preventing trial abuse
To protect your business from customers repeatedly signing up for trials, you can enable the **Prevent trial abuse** feature from your organization's subscription settings.
### How it works
When this feature is enabled, Polar tracks trial redemptions using:
* **Email addresses**: We automatically detect and normalize email aliases (e.g., `user+alias@example.com` is treated as `user@example.com`) to prevent abuse through simple email variations.
* **Payment method fingerprints**: We track the unique fingerprint of payment methods (credit cards) used during checkout to identify returning customers even if they use a different email address.
A customer will be blocked from starting a new trial if they have previously redeemed a trial for any of your products and match either:
* The same unaliased email address, OR
* The same payment method fingerprint
### Enabling the feature
1. Go to your organization's **Settings** page
2. Navigate to the **Subscription** section
3. Toggle on **Prevent trial abuse**
Once enabled, the feature will apply to all future trial checkout attempts across all your products.
### Customer experience
When a customer who has already used a trial attempts to check out again:
1. They will see an error message: "You have already used a trial for this product. Trials can only be used once per customer."
2. The checkout will automatically refresh without the trial period
3. The customer can still complete their purchase and subscribe at the regular price
This approach ensures a smooth experience while protecting your business from trial abuse.
# Billing
Source: https://polar.sh/docs/features/usage-based-billing/billing
How billing works with Usage Based
## Metered Pricing
Metered Pricing is a pricing model where you charge your customers based on the usage of your application.
There are a few different pricing models unique to Usage Based Billing:
* Unit Pricing
* Volume Pricing *(coming soon)*
### Unit Pricing
Unit pricing is a simple pricing model where you charge a fixed amount for each unit of usage.
For example:
| Product Meter | Price per unit |
| ------------------- | -------------- |
| `prompt-tokens` | \$0.10 |
| `completion-tokens` | \$0.18 |
This means that every unit of `prompt-tokens` consumed by a customer will be charged at \$0.10 and every unit of `completion-tokens` will be charged at \$0.18.
It's a linear pricing model, where the price per unit is fixed.
### Volume Pricing *(coming soon)*
Volume pricing is a pricing model where you charge a fixed amount for a certain volume of usage. Volume pricing is not yet available, but will be coming soon.
## Invoicing Customers for Usage
Our Usage Based Billing infrastructure is built to work with Subscription products out of the box.
### Add a metered price to your product
To charge your customers for usage, you need to add a metered price to your product. You'll need the select the **Meter** and the **amount per unit**.
Optionally, you can set a **cap**. The customer will be charged the cap amount if they exceed it, regardless of the usage.
### Monthly Invoicing
If a customer has a subscription with a monthly billing period, usage is aggregated monthly and invoiced at the end of the month with the rest of the subscription.
### Yearly Invoicing
If a customer has a subscription with a yearly billing period, usage is aggregated yearly and invoiced at the end of the year with the rest of the subscription.
### Usage Charges and Subscription Cancellation
When a subscription is canceled, it generally remains active until the end of the current billing period (known as the grace period). During this grace period, all accumulated usage-based charges continue to be tracked. A final invoice will be issued at the end of that period to cover the consumed usage, even if the subscription will not be renewed. This ensures no pending usage charges are lost.
# Credits
Source: https://polar.sh/docs/features/usage-based-billing/credits
Crediting customers for Usage Based Billing
Credits is the way to pre-pay for usage in Polar. It allows you to give your customers the ability to pre-pay for usage instead of risk getting a hefty bill at the end of the month.
## How Credits Work
When you ingest events into a Usage Meter, customers will be charged for the usage based on the product's pricing model.
However, sometimes you may want to give your customers the ability to pre-pay for usage instead of risk getting a hefty bill at the end of the month.
When you issue Credits to a customer, we first deduct the Credits from their Usage Meter balance. If the Usage Meter balance reaches 0, the customer will be charged for the overage.
### Credits-only spending
To avoid any overage charges, don't create any Metered price on your product. This way, billing won't be triggered at all for the meter
## Issuing Credits with the Credits Benefit
The Credits benefit will credit a customer's Usage Meter balance at different points in time depending on the type of product the benefit is attached to.
### Subscription Products
The customer will be credited the amount of units specified in the benefit at the beginning of every subscription cycle period โ monthly or yearly.
### One-Time Products
The customer will be credited the amount of units specified in the benefit once at the time of purchase.
## Tracking customer's balance
In your application, you'll likely need to track the customer's balance for a given meter. The easiest way to do this is to use the [Customer State](/integrate/customer-state), which will give you the overview of the customer, including the balance for each of their active meters.
You can also specifically query the meters balance using the [Customer Meters API](/api-reference/customer-meters/list).
## Filters
A filter is a set of clauses that are combined using conjunctions. They're used to filter events that you've ingested into Polar.
### Clauses
A clause is a condition that an event must meet to be included in the meter.
#### Property
Properties are the properties of the event that you want to filter on.
If you want to match on a metadata field, you can use the metadata key directly. No need to include a `metadata.` prefix.
#### Operator
Operators are the operators that you want to use to filter the events.
* **Equals**
* **Not equals**
* **Greater Than**
* **Greater Than or Equals**
* **Less Than**
* **Less Than or Equals**
* **Contains**
* **Does Not Contain**
#### Value
Values are automatically parsed in the filter builder. They're parsed in the following order:
1. Number โ Tries to parse the value as number
2. Boolean โ Checks if value is "true" or "false"
3. String โ Treats value as string as fallback
### Conjunctions
A conjunction is a logical operator that combines two or more clauses.
* **and** โ All clauses must be true for the event to be included.
* **or** โ At least one clause must be true for the event to be included.
## Aggregation
The aggregation is the function that is used to aggregate the events that match the filter.
For example, if you want to count the number of events that match the filter, you can use the **Count** aggregation. If you want to sum the value of a metadata field, you can use the **Sum** aggregation.
* **Count** โ Counts the number of events that match the filter.
* **Sum** โ Sums the value of a property.
* **Average** โ Computes the average value of a property.
* **Minimum** โ Computes the minimum value of a property.
* **Maximum** โ Computes the maximum value of a property.
* **Unique** โ Counts the number of unique values of a property.
The **Type** field is set to Custom by default (which is what we need).
Your product is successfully created along with the Custom benefit that allows you to share the links automatically to customers after purchase.
### After Purchase
Once the customer completes their purchase, the **Description**, the **Benefit Type** (in this case, **Custom**), and the **rendered Markdown content** from the **Private note** of the **Custom Benefit** are displayed, allowing them to access any links or formatted text youโve added.
### Purchase Confirmation Email
The **Description** and the rendered Markdown content of the **Custom Benefit** also appear in the purchase confirmation email sent to the customer, as shown below.
### Customer Portal
When the customer opens the [Customer Portal](/features/customer-portal) through the link in their confirmation email, the **Custom Benefit** is displayed there as well.
# How to Change Account Email (as a Merchant)
Source: https://polar.sh/docs/guides/change-email-as-merchant
Learn how to change your account email on Polar as a Merchant.
"url" key of the JSON.
```json theme={null}
{
"...": "...",
"url": "https://buy.polar.sh/polar_c_...", // [!code ++]
"...": "..."
}
```
Your product catalogue should now show this product as follows:
* **Advanced version**: We create a monthly subscription product named **Advanced version** with cost \$40.
* **Product Catalogue**: You should be able to see all your products on Product Catalogue.
At this step, you may add a label, success URL and metadata. You may also configure whether discount codes are allowed and whether billing address is required from customers.
Click on **Create Link** after adding your configurations.
Click on your label to see the checkout link.
You can copy this link and share to your customers for them to purchase a variant.
"url" key of the JSON and open it.
```json theme={null}
{
"...": "...",
"...": "...",
"url": "https://buy.polar.sh/polar_cl_..." // [!code ++]
}
```
It looks like below:
"url" key of the JSON and open it.
```json theme={null}
{
"...": "...",
"url": "https://buy.polar.sh/polar_c_...", // [!code ++]
"...": "..."
}
```
It looks like below:
Consider following this guide while using the Polar Sandbox Environment. This will allow you to test your integration without affecting your production data.
## Polar Laravel Example App
We've created a simple example Laravel application that you can use as a reference.
[View Code on GitHub](https://github.com/polarsource/polar-laravel)
## Setting up environment variables
### Polar API Key
To authenticate with Polar, you need to create an access token, and supply it to Laravel using a `POLAR_API_KEY` environment variable.
You can create an organization access token from your organization settings.
## Fetching Polar Products for display
### Creating the Products Controller
Go ahead and add the following entry in your `routes/web.php` file:
```php theme={null}
// routes/web.php
Route::get('/products', [ProductsController::class, 'handle']);
```
Next up, create the `ProductsController` class in the `app/Http/Controllers` directory:
```php theme={null}
// app/Http/Controllers/ProductsController.php
api.polar.sh when ready to go live
// And don't forget to update the .env file with the correct POLAR_ORGANIZATION_ID and POLAR_WEBHOOK_SECRET
$data = Http::get('https://sandbox-api.polar.sh/v1/products', [
'is_archived' => false,
]);
$products = $data->json();
return view('products', ['products' => $products['items']]);
}
}
```
## Displaying Products
Finally, create the `products` view in the `resources/views` directory:
```php theme={null}
// resources/views/products.blade.php
@foreach ($products as $product)
{seatInfo?.available} of {seatInfo?.total} seats available
{/* Assign new seat */}| Status | Role | Actions | |
|---|---|---|---|
| {seat.customer_email} |
|
{seat.seat_metadata?.role} | {seat.status === 'pending' && ( )} {seat.status === 'claimed' && ( )} |
Join {claimInfo?.organization}'s {claimInfo?.product} plan
Email: {claimInfo?.email}
theme=dark to your checkout session URL as obtained earlier. For example, if your checkout session URL is:\
[https://polar.sh/checkout/polar\_c\_ES7DwhlyvlYTPNaLiccKqiwJPda43FIzer](https://polar.sh/checkout/polar_c_ES7DwhlyvlYTPNaLiccKqiwJPda43FIzer)
You should use:\
[https://polar.sh/checkout/polar\_c\_ES7DwhlyvlYTPNaLiccKqiwJPda43FIzer?theme=dark](https://polar.sh/checkout/polar_c_ES7DwhlyvlYTPNaLiccKqiwJPda43FIzer?theme=dark)
The checkout session then looks like below:
theme=light to your checkout session URL.
For example:\
[https://polar.sh/checkout/polar\_c\_ES7DwhlyvlYTPNaLiccKqiwJPda43FIzer?theme=light](https://polar.sh/checkout/polar_c_ES7DwhlyvlYTPNaLiccKqiwJPda43FIzer?theme=light)
The checkout session then looks like below:
theme=dark to your checkout link.
For example, if your checkout link is:\
[https://sandbox-api.polar.sh/v1/checkout-links/polar\_cl\_QHMjrDLsORxLIRfyQlfyqF1TWUR6Cy4afVcd/redirect](https://sandbox-api.polar.sh/v1/checkout-links/polar_cl_QHMjrDLsORxLIRfyQlfyqF1TWUR6Cy4afVcd/redirect)
You should use:\
[https://sandbox-api.polar.sh/v1/checkout-links/polar\_cl\_QHMjrDLsORxLIRfyQlfyqF1TWUR6Cy4afVcd/redirect?theme=dark](https://sandbox-api.polar.sh/v1/checkout-links/polar_cl_QHMjrDLsORxLIRfyQlfyqF1TWUR6Cy4afVcd/redirect?theme=dark)
The checkout session then looks like below:
theme=light to your checkout link.
For example:\
[https://sandbox-api.polar.sh/v1/checkout-links/polar\_cl\_QHMjrDLsORxLIRfyQlfyqF1TWUR6Cy4afVcd/redirect?theme=light](https://sandbox-api.polar.sh/v1/checkout-links/polar_cl_QHMjrDLsORxLIRfyQlfyqF1TWUR6Cy4afVcd/redirect?theme=light)
The checkout session then looks like below:
Supercharge your AI agents with Polar as a Model Context Protocol (MCP) server.
## What is MCP?
MCP is a protocol for integrating tools with AI agents. It can greatly enhance the capabilities of your AI agents by providing them with real-time data and context.
Polar offers a remote MCP server that you can connect to from most AI clients.
## How does it work?
You need a MCP-capable agent environment to use Polar over MCP. A few of them are Claude Desktop and Cursor.
## Connecting to Polar MCP
Polar provides two MCP servers:
* **Production**: `https://mcp.polar.sh/mcp/polar-mcp` - Connect to your live Polar organization
* **Sandbox**: `https://mcp.polar.sh/mcp/polar-sandbox` - Connect to the Polar sandbox environment for testing
When you can specify a MCP URL, use one of the URLs above depending on your environment.
If you have to specify a command, use:
```json theme={null}
{
"mcpServers": {
"Polar": {
"command": "npx",
"args": ["mcp-remote", "https://mcp.polar.sh/mcp/polar-mcp"]
}
}
}
```
For sandbox:
```json theme={null}
{
"mcpServers": {
"Polar Sandbox": {
"command": "npx",
"args": ["mcp-remote", "https://mcp.polar.sh/mcp/polar-sandbox"]
}
}
}
```
### Cursor
In `.cursor/mcp.json`, add:
```json theme={null}
{
"mcpServers": {
"Polar": {
"url": "https://mcp.polar.sh/mcp/polar-mcp"
}
}
}
```
For sandbox:
```json theme={null}
{
"mcpServers": {
"Polar Sandbox": {
"url": "https://mcp.polar.sh/mcp/polar-sandbox"
}
}
}
```
### Windsurf
In `mcp_config.json`, add:
```json theme={null}
{
"mcpServers": {
"Polar": {
"command": "npx",
"args": ["mcp-remote", "https://mcp.polar.sh/mcp/polar-mcp"]
}
}
}
```
For sandbox:
```json theme={null}
{
"mcpServers": {
"Polar Sandbox": {
"command": "npx",
"args": ["mcp-remote", "https://mcp.polar.sh/mcp/polar-sandbox"]
}
}
}
```
### Codex
Add the following to your `~/.codex/config.toml`:
```toml theme={null}
[features]
rmcp_client = true
[mcp_servers.polar]
type = "http"
url = "https://mcp.polar.sh/mcp/polar-mcp"
```
Then run:
```sh theme={null}
codex mcp login polar
```
For sandbox:
```toml theme={null}
[features]
rmcp_client = true
[mcp_servers.polar_sandbox]
type = "http"
url = "https://mcp.polar.sh/mcp/polar-sandbox"
```
Then run:
```sh theme={null}
codex mcp login polar_sandbox
```
### Claude Code
Run the following command:
```
claude mcp add --transport http "Polar" "https://mcp.polar.sh/mcp/polar-mcp"
```
For sandbox:
```
claude mcp add --transport http "Polar Sandbox" "https://mcp.polar.sh/mcp/polar-sandbox"
```
### ChatGPT
MCP is only available for paid users in beta on ChatGPT web, by enabling Developer Mode.
Once Developer Mode is enabled, go to *Settings* โ *Connectors* and add the MCP server using `https://mcp.polar.sh/mcp/polar-mcp`.
For sandbox, use `https://mcp.polar.sh/mcp/polar-sandbox` instead.
### Claude Desktop
Go to *Settings* โ *Connectors* and click *Add custom connector*.
Name it "Polar" and add `https://mcp.polar.sh/mcp/polar-mcp` as the server URL.
For sandbox, use `https://mcp.polar.sh/mcp/polar-sandbox` as the server URL instead.
Save, and click *Connect* to connect to your Polar organization.
# OAuth 2.0 Connect
Source: https://polar.sh/docs/integrate/oauth2/connect
## Authorize
To start the authorization flow you need to redirect the user to the authorization URL. It looks like this:
```
https://polar.sh/oauth2/authorize?
response_type=code
&client_id=CLIENT_ID
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=openid%20email
```
The parameters are the one described in the [OpenID Connect specification](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). The most important ones are:
If they allow it and select an organization, they'll be redirected to your `redirect_uri` with a `code` parameter in the query string. This code is a one-time code that you can exchange for an access token.
To skip the organization selection and get a user-scoped token instead, you can add `sub_type=user` to the authorization URL:
```
https://polar.sh/oauth2/authorize?
response_type=code
&client_id=CLIENT_ID
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=openid%20email
&sub_type=user
```
#### Exchange code token
Once you have the authorization code, you can exchange it for an access token. To do so, you'll need to make a `POST` request to the token endpoint. This call needs to be authenticated with the Client ID and Client Secret you got when creating the OAuth2 client.
Here is an example with cURL:
```bash theme={null}
curl -X POST https://api.polar.sh/v1/oauth2/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=authorization_code&code=AUTHORIZATION_CODE&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&redirect_uri=https://example.com/callback'
```
You should get the following response:
```json theme={null}
{
"token_type": "Bearer",
"access_token": "polar_at_XXX",
"expires_in": 864000,
"refresh_token": "polar_rt_XXX",
"scope": "openid email",
"id_token": "ID_TOKEN"
}
```
The `access_token` will allow you to make authenticated API requests on behalf of the user. The `refresh_token` is a long-lived token that you can use to get new access tokens when the current one expires. The `id_token` is a signed JWT token containing information about the user, as per the [OpenID Connect specification](https://openid.net/specs/openid-connect-core-1_0.html#IDToken).
#### Organization vs User Access Tokens
By default, Polar OAuth2 flow generates **organization-level** access tokens. These tokens are tied to a specific organization rather than a user, allowing requests to operate only on that organization's data, which improves privacy and security.
When using the default flow, the user will be prompted to select one of their organizations before allowing access to their data:
```
https://polar.sh/oauth2/authorize?response_type=code&client_id=polar_ci_j3X95_MgfdSCeCd2qkFnUw&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback&scope=openid%20email
```
To request a **user-scoped** access token instead, you need to explicitly add the parameter `sub_type=user` to the authorization URL:
```
https://polar.sh/oauth2/authorize?response_type=code&client_id=polar_ci_j3X95_MgfdSCeCd2qkFnUw&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback&scope=openid%20email&sub_type=user
```
The rest of the flow remains unchanged. The access token you'll get will be tied to either the selected organization (default) or the user (when explicitly requested).
#### Public Clients
Public clients are clients where the Client Secret can't be kept safe, as it would be accessible by the final user. This is the case for SPA, mobile applications, or any client running on the user's device.
In this case, **and only if the client is configured as a Public Client**, the request to the token endpoint won't require the `client_secret` parameter. However, the [PKCE](https://oauth.net/2/pkce/) method will be required to maximize security.
### Make authenticated requests
Once you have an access token, either from a Personal Access Token or from the OpenID Connect flow, you can make authenticated requests to the API. Here is a simple example with cURL:
```bash theme={null}
curl -X GET https://api.polar.sh/v1/oauth2/userinfo \
-H 'Authorization: Bearer polar_at_XXX'
```
# Introduction
Source: https://polar.sh/docs/integrate/oauth2/introduction
For partners building services and extensions for Polar customers
### OpenID Connect (OAuth2)
Only use our **OpenID Connect** in case you want to act on the behalf of other users via our API, e.g building an app/service for Polar customers. Otherwise, always use an **Organization Access Token (OAT)** to integrate Polar for your own service.
Polar implements the [OpenID Connect specification](https://openid.net/developers/how-connect-works/) to enable third-party authentication. It's a layer on top of the OAuth2 framework aiming at making integration more standard and predictable.
In particular, it comes with a **discovery endpoint** allowing compatible clients to automatically work with the OpenID Connect server. Here is Polar's one:
[OpenID Configuration](https://api.polar.sh/.well-known/openid-configuration)
# Create an OAuth 2.0 Client
Source: https://polar.sh/docs/integrate/oauth2/setup
Before being able to make authentication requests, you'll need an **OAuth2 Client**. It's the entity that'll identify you, as a third-party developer, between Polar and the final user.
You can manage them from your [User Settings](https://polar.sh/settings#oauth)
Here are the required fields:
* *Application Name*: the name of the application that'll be shown to the final users.
* *Client Type*: the type of client you are creating. [Read more](#public-clients)
* *Redirect URIs*: for security reasons, you need to declare your application URL where the users will be redirected after granting access to their data.
| {{ $order->ordered_at->toFormattedDateString() }} | {{ $order->polar_id }} | {{ $order->amount }} | {{ $order->tax_amount }} | {{ $order->refunded_amount }} | {{ $order->refunded_tax_amount }} | {{ $order->currency }} | @endforeach
Once a webhook endpoint is setup you will have access to the delivery overview
page. Here you can:
* See historic deliveries
* Review payload sent
* Trigger redelivery in case of failure
Now, let's integrate our endpoint route to validate, parse & handle incoming webhooks.
## Validate & parse webhooks
You now need to setup a route handler for the endpoint registered on Polar to
receive, validate and parse webhooks before handling them according to your
needs.
### Using our SDKs
Our TypeScript & Python SDKs come with a built-in helper function to easily
validate and parse the webhook event - see full examples below.
If you paste a Discord or Slack Webhook URL, the format will be automatically selected.
## What is Polar?
Turn your software into a business with Polar. Sell digital products, subscriptions, and more without the hassle of traditional payment systems.
Stripe and other Payment Service Providers (PSPs) offer an accessible and convenient abstraction to faciliate transactions on top of underlying credit card networks & banks.
* โ
Powerful, flexibile & low-level APIs to facilitate transactions
* โ
Can be used to power all business- and pricing models under the sun.
* โ You are responsible for all liabilities associated with transactions, e.g international taxes
* โ Low-level APIs require more development even for common use cases
**Merchants of Record (MoRs)**
Merchants of Record offer yet another layer of convenient abstraction to facilitate digital orders on top of the underlying PSPs and transactions. E.g Polar is built on Stripe (+ more PSPs in the future).
* โ
Higher-level Dashboard, APIs & SDKs to better facilitate digital products, services & orders beyond the underlying transactions
* โ
The platform (Polar) handles international taxes by being a reseller of your digital goods & services. Of course, without being in the way of your relationship with your customers.
* โ Less flexibility & control in terms of advanced business- and pricing models.
* โ Higher fees per payment
**What should you choose?**
**Ship with what you feel comfortable with vs. others tell you to**
Just like in programming, abstractions are super helpful to ship faster with fewer low-level concerns, but in exchange for reduced flexibility and higher costs. So what's the right level of abstraction for you? As always, it depends (tm).
**Go with Stripe (PSP) if...**
* You've already integrated it? Just ship already - we salute builders however they ship
* You're comfortable with the Stripe API and prefer absolute control with low-level APIs.
* You're looking for the lowest fees possible.
* You're fine with handling international taxes yourself (you absolutely can).
**Go with Polar (MoR) if...**
* You want product-, customer-, order- and subscription management via an intuitive and easy dashboard
* You want to offer file downloads, license keys, Discord- and/or private GitHub repository invites with ease - with more built-in automations to come.
* You prefer a more high-level API optimized for making monetization easier. We're only getting started here and have some big things coming
* You want us to handle international taxes for you
### Polar MoR
**We take on the liability of international sales taxes globally for you. So you can focus on building your passion. Leaving billing infrastructure and sales tax headaches to us.**
So how does Polar offer a Merchant of Record (MoR) service and handle international sale taxes? All other Merchants of Record simply state they handle it internationally - don't worry about it. We do too.
But we believe in transparency and don't want to scare customers into thinking it's impossible to manage it themselves. So below we'll share how exactly we go about doing this.
#### International Sales Taxes
Most countries, states and jurisdictions globally impose sales taxes on digital goods and services (VAT, GST, US Sales Tax etc). Regardless of whether the merchant (seller) is a resident there or not - they're doing business there.
For example, a \$10/month subscription should cost \$12.5/month for a Swedish (25% VAT) consumer, but \$10/month for a Swedish business with VAT registration (reverse charge).
Merchants are responsible for 1) capturing & 2) remitting sales taxes to the local tax authorities. What does that mean in our example?
1. **Capturing**. Charging the Swedish consumer \$12.5/month and saving \$2.5/month for the Swedish tax authorities. Stripe Tax is an excellent service to automate this and the one Polar uses today.
2. **Remitting**. Filing & paying the captured sales taxes with the tax authorities on time. Stripe Tax does not do this, i.e the merchant is liable to register, file and pay taxes to local tax authorities.
Many jurisdictions, however, don't require this until you reach a certain threshold in terms of sales volume. But others require registration even before the first sale - or after a very low threshold. In addition to having different rates and rules on which goods are taxable and whether they're deductable or not for business customers.
For example, United Kingdom and EU countries require upfront registration for international companies, but Texas (United States) does not until you've sold for more than \$500,000 ๐บ๐ธ๐ฆ
In short: It's complex and hard. Even large and well-known businesses don't do it perfectly. Arguably, it's almost impossible and at least highly impracticle and expensive to comply perfectly upfront. Many companies even delay compliance as a calculated risk, i.e focus on validating & growing their business with the risk of paying back taxes + penalities later.
**PSP (Stripe)**
* โ
Your volume alone is what counts towards international thresholds vs. the MoR platform, i.e customers might not need to pay sales taxes with you, but would via a MoR.
* โ
You can deduct inbound VAT against purchases your business does with VAT
* โ You're liable for capturing & remitting international sales taxes
* โ Stripe Tax is great to monitor & automate capturing, but registration and remittance is up to you.
**MoR (Polar)**
* โ
We are liable for all of the above as your reseller, i.e we have to worry about it vs. you.
* โ
Offer EU VAT for B2B sales (expected and desired within EU for businesses) without having to register, capture and remit it yourself.
* โ Sales taxes would be added for more customers vs. with you selling directly
* โ You cannot leverage inbound VAT towards VAT expense deductions yourself
Merchants of Record (MoR) handles sales taxes, e.g US Sales Tax, EU VAT,
Canadian GST etc. **However, you're always responsible for your own
income/revenue tax** in your country of residency.
#### Polar Coverage
**We support global payments and are liable for all international sales taxes. We continuously monitor and work with our accounting firms to expand registrations as needed on our end.**
**Global Payments & Tax Liabilities**
As your Merchant of Record, Polar is liable for tax compliance globally on all sales internationally via our platform, hosted- or embedded checkoutsfrom payments anywhere in the world.
**Current Polar Tax Registrations**
1. Polar Software Inc. is incorporated as a US Delaware C Corp and will register for US State Sales Taxes upon reaching thresholds
2. EU VAT (Irish OSS VAT)
3. UK VAT
No Merchant of Record (MoR) or business registers upfront in all global jurisdictions. Since it would be 1) unnecessary in case of thresholds & 2) incredibly expensive with uncertain return on investment (ROI) in all markets.
We work with global accounting firms specialized in registering, filing and remitting taxes in all countries. So we can easily scale registrations and remittance as needed. Below is our process and evaluation for expanding registrations.
**Expanding Registrations**
Below are the fees the global acounting firms we work with charge us - on average per market:
* \~\$500 upfront for registration
* \~\$300 per filing and remittance (\~quarterly)
* *Excluding consultations (billed hourly) and our internal efforts and automations to transform Stripe Tax reports into correct output for the accounting firms.*
So on average \$1,700 in year one and \$1,200 therafter for each market at a minimum. Businesses (and you if you handle this yourself) therefore need to ask themselves: Do I anticipate more in sales from a given market vs. costs of operating there?
Let's imagine a country with 20% sales tax.
1. At \$6,000+ the tax liability start outgrowing the accounting costs for you standalone (\$1,200/20%)
2. Polar with a 1.1% premium vs. Stripe would need to help facilitate \$109,090 in sales for the given market in order for it to cover our accounting costs (\$1,200/1.1%)
Our customers are selling mostly in the US, UK & EU. Given US thresholds and our current registrations, it's therefore a non-issue.
In markets we're not registered, we still have the liability and take it on (#1) to assess the potential for our customers and us long-term. In addition to being comfortable betting on markets a lot earlier than it becomes profitable for us (#2).
However, in case of neither we reserve the right to block payments from such countries in the short-term until the opportunity for our customers and us changes in the given market.
**Want to do this yourself?**
Selling a lot and want to handle this yourself, i.e worth the ongoing costs? Feel free to reach out and we'd be happy to introduce you to our contacts at the accounting firms we use.
We consider MoR a key value-add to Polar, but not the sole reason for Polar to exist. Our ambition is to be the easiest way to monetize for developers. However, we're never going to be the right solution for all use cases. But we'll always salute and help anyone who ships software - regardless of billing platform.
## Frequently Asked Questions