{"id":20974319,"url":"https://github.com/thirdweb-example/shopify-discount-codes","last_synced_at":"2025-05-14T12:31:41.788Z","repository":{"id":107808493,"uuid":"545757284","full_name":"thirdweb-example/shopify-discount-codes","owner":"thirdweb-example","description":"Grant users who hold an NFT from your collection a discount code they can use in your Shopify store!","archived":false,"fork":false,"pushed_at":"2023-05-02T13:00:41.000Z","size":25,"stargazers_count":13,"open_issues_count":0,"forks_count":10,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-02T18:23:03.700Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thirdweb-example.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-04T23:36:42.000Z","updated_at":"2024-03-11T22:09:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"a716217c-8714-4dd5-a116-6f05ef406f85","html_url":"https://github.com/thirdweb-example/shopify-discount-codes","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdweb-example%2Fshopify-discount-codes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdweb-example%2Fshopify-discount-codes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdweb-example%2Fshopify-discount-codes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdweb-example%2Fshopify-discount-codes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thirdweb-example","download_url":"https://codeload.github.com/thirdweb-example/shopify-discount-codes/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254142349,"owners_count":22021508,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-19T04:28:05.932Z","updated_at":"2025-05-14T12:31:41.782Z","avatar_url":"https://github.com/thirdweb-example.png","language":"TypeScript","readme":"# Shopify Discount Codes for NFT Holders\n\nThis template allows you to generate discount codes for your Shopify store to holders of your NFT Collection using [Auth](https://portal.thirdweb.com/auth).\n\n## Using This Repo\n\nTo create your own version of this template, you can use the following steps:\n\nRun this command from the terminal to clone this project and install the required dependencies:\n\n```bash\nnpx thirdweb create --template shopify-discount-codes\n```\n\nCreate a copy of the `.env.example` file and rename it to `.env`. Then, fill in the values for the following environment variables:\n\n```text\nADMIN_PRIVATE_KEY=xxx\nNFT_COLLECTION_ADDRESS=xxx\nSHOPIFY_SECRET_KEY=xxx\nSHOPIFY_SITE_URL=xxx\nSHOPIFY_ACCESS_TOKEN=xxx\n```\n\n## Guide\n\nThis section explores the core elements of the code.\n\n### Auth\n\nFirst, we setup thirdweb Auth by configuring our `ThirdwebProvider` in the `_app.tsx` file:\n\n```tsx\n// This is the chain your dApp will work on.\nconst activeChain = \"polygon\";\n\nfunction MyApp({ Component, pageProps }: AppProps) {\n  return (\n    \u003cThirdwebProvider\n      activeChain={activeChain}\n      authConfig={{\n        authUrl: \"/api/auth\",\n        domain: \"example.com\",\n      }}\n    \u003e\n      \u003cComponent {...pageProps} /\u003e\n    \u003c/ThirdwebProvider\u003e\n  );\n}\n\nexport default MyApp;\n```\n\nWe also create an API route at `/api/auth/[...thirdweb].ts` that exports the `ThirdwebAuthHandler`:\n\n```tsx\nimport { ThirdwebAuth } from \"@thirdweb-dev/auth/next\";\n\nexport const { ThirdwebAuthHandler, getUser } = ThirdwebAuth({\n  // Using environment variables to secure your private key is a security vulnerability.\n  // Learn how to store your private key securely:\n  // https://portal.thirdweb.com/sdk/set-up-the-sdk/securing-your-private-key\n  privateKey: process.env.ADMIN_PRIVATE_KEY || \"\",\n  // Set this to your domain to prevent signature malleability attacks.\n  domain: \"example.com\",\n});\n\n// Export the handler to setup all your endpoints\nexport default ThirdwebAuthHandler();\n```\n\nNow, on the homepage at `index.tsx`, users can connect their wallet and sign a message that proves their identity using the `ConnectWallet` button:\n\n```tsx\nconst Home: NextPage = () =\u003e {\n  return (\n    \u003cConnectWallet\n      auth={{\n        loginOptional: false,\n      }}\n      accentColor=\"#5204BF\"\n    /\u003e\n  );\n};\n\nexport default Home;\n```\n\n### Generating Discount Codes\n\nOn the client, we make a request to the `api/generate-discount.ts` API route in a `useEffect` block whenever the user signs in to the application:\n\n```tsx\nconst Home: NextPage = () =\u003e {\n  const user = useUser();\n\n  const [generatedDiscount, setGeneratedDiscount] = useState\u003cstring\u003e(\"\");\n\n  async function generateDiscount() {\n    try {\n      const response = await fetch(\"/api/generate-discount\", {\n        method: \"POST\",\n        headers: {\n          \"Content-Type\": \"application/json\",\n        },\n      });\n\n      const { discountCode } = await response.json();\n\n      setGeneratedDiscount(discountCode);\n    } catch (error) {\n      console.error(error);\n      setGeneratedDiscount(\"Not eligible for discount\");\n    }\n  }\n\n  // Whenever the `user` is available, call the generateDiscount function.\n  useEffect(() =\u003e {\n    if (user.user?.address) {\n      generateDiscount();\n    }\n  }, [user.user?.address]);\n};\n```\n\nThis API route interacts with the Shopify API to generate a discount code for the user after checking their NFT balance.\n\nFirst, we're going to ensure the user has signed in with their wallet:\n\n```tsx\n// Load environment variables\nconst {\n  SHOPIFY_SITE_URL,\n  SHOPIFY_ACCESS_TOKEN,\n  NFT_COLLECTION_ADDRESS,\n  SHOPIFY_DISCOUNT_ID,\n} = process.env;\n\n// Grab the current thirdweb auth user (wallet address)\nconst thirdwebUser = await getUser(req);\n// If there is no user, return an error\nif (!thirdwebUser) {\n  return res.status(401).json({ error: \"Unauthorized\" });\n}\n```\n\nNext, we'll connect to the thirdweb SDK and check the balance of the authenticated wallet:\n\n```js\n  // Initialize the SDK to check the user's balance\n  const sdk = new ThirdwebSDK(\"goerli\");\n\n  // Check the user's balance\n  const edition = await sdk.getEdition(NFT_COLLECTION_ADDRESS!);\n  // Here, we're checking token ID 0 specifically, just as an example.\n  const balance = await edition.balanceOf(thirdwebUser.address, 0);\n\n  // If the user doesn't own any NFTs, return an error\n  if (balance.eq(0)) {\n    return res.status(401).json({ error: \"Unauthorized\" });\n  }\n```\n\nIf they aren't authenticated or don't own any NFTs from the collection, we send them a `401 unauthorized response` and don't generate a discount code for them.\n\nFinally, if they _do_ own an NFT, we can make a `POST` request to Shopify to generate a discount code for them:\n\n```js\n  // Create a new client for the specified shop.\n  const client = new Shopify.Clients.Rest(\n    SHOPIFY_SITE_URL!,\n    SHOPIFY_ACCESS_TOKEN!\n  );\n\n  // Create a new discount code with the Shopify API\n  const response = await client.post({\n    type: DataType.JSON,\n    path: `/admin/api/2022-10/price_rules/${SHOPIFY_DISCOUNT_ID}/discount_codes.json`,\n    data: {\n      discount_code: {\n        code: thirdwebUser.address,\n        usage_count: 1,\n      },\n    },\n  });\n\n  res\n    .status(200)\n    .json({ discountCode: response.body.discount_code.code as string });\n```\n\n## Join our Discord!\n\nFor any questions or suggestions, join our discord at [https://discord.gg/thirdweb](https://discord.gg/thirdweb).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthirdweb-example%2Fshopify-discount-codes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthirdweb-example%2Fshopify-discount-codes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthirdweb-example%2Fshopify-discount-codes/lists"}