Better-auth dynamic products creation
Hi! Can you help me integrate the Polar plugin with Better-Auth? Instead of defining each product statically, I would like to allow administrators to add new products dynamically from my admin panel.
Can you guide me on the correct way to implement this? I checked the documentation and found 
polarClient.products.list, but I’m running into type issues when trying to use it.
Here’s the default code I want to modify:
import { betterAuth } from "better-auth";
import { polar, checkout } from "@polar-sh/better-auth";
import { admin } from "better-auth/plugins";
import { nextCookies } from "better-auth/next-js";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { db } from "@/db/drizzle";
import { Polar } from "@polar-sh/sdk";
const polarClient = new Polar({
  accessToken: process.env.POLAR_ACCESS_TOKEN,
  server: "sandbox",
});
export const auth = betterAuth({
  database: drizzleAdapter(db, {
    provider: "pg",
  }),
  emailAndPassword: {
    enabled: true,
    requireEmailVerification: false,
  },
  session: {
    cookieCache: {
      enabled: true,
      maxAge: 10 * 60,
    },
  },
  plugins: [
    polar({
      client: polarClient,
      createCustomerOnSignUp: true,
      use: [
        checkout({
          products: [
            {
              productId: "(productId)",
              slug: "(productSlug)",
            },
          ],
          successUrl: process.env.POLAR_SUCCESS_URL,
          authenticatedUsersOnly: true,
        }),
      ],
    }),
    admin(),
    nextCookies(),
  ],
});
import { betterAuth } from "better-auth";
import { polar, checkout } from "@polar-sh/better-auth";
import { admin } from "better-auth/plugins";
import { nextCookies } from "better-auth/next-js";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { db } from "@/db/drizzle";
import { Polar } from "@polar-sh/sdk";
const polarClient = new Polar({
  accessToken: process.env.POLAR_ACCESS_TOKEN,
  server: "sandbox",
});
export const auth = betterAuth({
  database: drizzleAdapter(db, {
    provider: "pg",
  }),
  emailAndPassword: {
    enabled: true,
    requireEmailVerification: false,
  },
  session: {
    cookieCache: {
      enabled: true,
      maxAge: 10 * 60,
    },
  },
  plugins: [
    polar({
      client: polarClient,
      createCustomerOnSignUp: true,
      use: [
        checkout({
          products: [
            {
              productId: "(productId)",
              slug: "(productSlug)",
            },
          ],
          successUrl: process.env.POLAR_SUCCESS_URL,
          authenticatedUsersOnly: true,
        }),
      ],
    }),
    admin(),
    nextCookies(),
  ],
});
1 Reply
If i set it like that - I'm getting 'Type 'ListResourceProduct' must have a 'Symbol.iterator' method that returns an iterator.ts(2488)' - I feel totally lost
 polar({
      client: polarClient,
      createCustomerOnSignUp: true,
      use: [
        checkout({
          products: async () => {
            try {
              const result = await polarClient.products.list({
                isArchived: false,
              });
              const allProducts = [];
              for await (const page of result) {
                allProducts.push(...page.result);
              }
              return allProducts.map((product) => ({
                productId: product.id,
                slug: product.name
                  ? product.name
                      .toLowerCase()
                      .replace(/\s+/g, "-")
                      .replace(/[^\w-]+/g, "")
                  : `product-${product.id}`,
              }));
            } catch (error) {
              console.error("Error:", error);
              return [];
            }
          },
          successUrl: process.env.POLAR_SUCCESS_URL,
          authenticatedUsersOnly: true,
        }),
      ],
    }),
 polar({
      client: polarClient,
      createCustomerOnSignUp: true,
      use: [
        checkout({
          products: async () => {
            try {
              const result = await polarClient.products.list({
                isArchived: false,
              });
              const allProducts = [];
              for await (const page of result) {
                allProducts.push(...page.result);
              }
              return allProducts.map((product) => ({
                productId: product.id,
                slug: product.name
                  ? product.name
                      .toLowerCase()
                      .replace(/\s+/g, "-")
                      .replace(/[^\w-]+/g, "")
                  : `product-${product.id}`,
              }));
            } catch (error) {
              console.error("Error:", error);
              return [];
            }
          },
          successUrl: process.env.POLAR_SUCCESS_URL,
          authenticatedUsersOnly: true,
        }),
      ],
    }),