### Disclaimer

This template is provided "as-is" and "as available" for informational and educational purposes only, without any express or implied warranties of any kind, including but not limited to warranties of merchantability, fitness for a particular purpose, or non-infringement. The author(s) and contributor(s) assume no responsibility or liability for any errors or omissions in the content of this template, or for any direct, indirect, incidental, consequential, or special damages arising out of or in connection with your use of, or inability to use, this template or information provided, including how this template is used, modified, or deployed by others. Users are solely responsible for ensuring that their use of this template and any resulting application complies with all applicable laws, regulations, and third-party terms of service, including but not limited to financial regulations and data privacy laws. You acknowledge that any reliance on this template or its content is solely at your own risk.

## Get Started!

Download the complete store template and this setup guide to begin building your $PEP-powered store.

Download Template & Guide (.zip)

Welcome! This guide will walk you through setting up your own $PEP-powered online store using this template. Follow these steps carefully to get your store live on Cloudflare Pages.

### 1Create Your Cloudflare Pages Project

First, you'll configure your Cloudflare account and create the necessary services.

1. Log in to your Cloudflare Dashboard: dash.cloudflare.com
2. Navigate to Workers & Pages (left sidebar).
3. Select the Pages tab, then click "Create a project".
4. Choose your deployment method:
   - Connect to Git (Recommended): If you've forked this template's repository on GitHub/GitLab, connect it.
     - Project name: e.g., `my-pep-store` (this becomes part of your URL).
     - Production branch: Typically `main`.
     - Build settings:
       - Framework preset: Select "None".
       - Build command: Leave blank.
       - Build output directory: Enter `/public` (Crucial!)
   - Direct Upload: Choose this if you want to upload the template files manually.
     - Project name: e.g., `my-pep-store`.
     - You'll later upload a ZIP of the `public` folder.
5. Click "Save and Deploy".

### 2Create KV Namespaces

KV (Key-Value) storage is used for orders and session management. You need to create SIX namespaces.

1. In the Cloudflare Dashboard, go to Workers & Pages → KV (under "Storage" on the right).
2. Click "Create a namespace" six times, using these exact names:
   - `SITE_WIDE_LOCK`
   - `USER_ORDER_ATTEMPTS`
   - `USER_PROFILES`
   - `PAID_ORDERS_ARCHIVE`
   - `PROCESSED_TXS_GLOBAL`
   - `DOWNLOAD_ACCESS_TOKENS`
3. After creating each namespace, Cloudflare shows an **ID**. Copy each ID into a temporary text file – you'll need them for `wrangler.jsonc`.

       Example:
       SITE_WIDE_LOCK ID:         [PASTE ID HERE]
       USER_ORDER_ATTEMPTS ID:    [PASTE ID HERE]
       USER_PROFILES ID:          [PASTE ID HERE]
       PAID_ORDERS_ARCHIVE ID:    [PASTE ID HERE]
       PROCESSED_TXS_GLOBAL ID:   [PASTE ID HERE]
       DOWNLOAD_ACCESS_TOKENS ID: [PASTE ID HERE]

### 3Configure Pages Project Settings

Link the KVs and set essential variables for your Pages project.

1. Go to your Pages project in the Cloudflare Dashboard (Workers & Pages → select your project).
2. Go to Settings tab → Functions (in the side menu).
3. Scroll to "KV namespace bindings". Click "Add binding" six times:
   - Binding 1: Variable name: `SITE_WIDE_LOCK` → KV namespace: (Select your `SITE_WIDE_LOCK` KV)
   - Binding 2: Variable name: `USER_ORDER_ATTEMPTS` → KV namespace: (Select your `USER_ORDER_ATTEMPTS` KV)
   - Binding 3: Variable name: `USER_PROFILES` → KV namespace: (Select your `USER_PROFILES` KV)
   - Binding 4: Variable name: `PAID_ORDERS_ARCHIVE` → KV namespace: (Select your `PAID_ORDERS_ARCHIVE` KV)
   - Binding 5: Variable name: `PROCESSED_TXS_GLOBAL` → KV namespace: (Select your `PROCESSED_TXS_GLOBAL` KV)
   - Binding 6: Variable name: `DOWNLOAD_ACCESS_TOKENS` → KV namespace: (Select your `DOWNLOAD_ACCESS_TOKENS` KV)
4. Now go to Settings tab → Environment Variables.
5. Under **"Production"** (and "Preview" if needed), click **"Add variable"** for each:

   Note: The dashboard might require you to add these as "Secrets" if it detects a `wrangler.toml` or assumes it. This is fine; the worker can still access them. If it allows "Text", use Text.

   - Name: `RECEIVING_ADDRESS` → Value: `YOUR_ACTUAL_PEPECOIN_WALLET_ADDRESS`
   - Name: `MIN_CONFIRMATIONS` → Value: `6`
   - Name: `SESSION_LOCK_DURATION_SECONDS` → Value: `1800` (for 30 minutes)
   - Name: `DOWNLOAD_TOKEN_TTL_SECONDS` → Value: `86400` (for 24 hours)
   - Name: `PEPEBLOCKS_API_BASE` → Value: `https://pepeblocks.com/api/v2`
   - Name: `DIGITAL_PRODUCT_FILENAME` → Value: `placeholder_thank_you.zip` (default digital file)
   - Name: `WORKER_USER_AGENT` → Value: `MyCustomPepStore/1.0` (optional)
6. Save all changes. This will likely trigger a new deployment of your Pages project.

## Part 2: Customizing Your Store Content

Edit the template files to personalize your store.

### 1Edit `wrangler.jsonc`

This file tells Cloudflare about your project structure and KV needs.

1. Open `wrangler.jsonc` (in the root of the template folder) in a text editor.
2. Update the project `name` if desired (e.g., to match your Pages project name).
3. Fill in the `id` for each of the 6 `kv_namespaces` entries with the actual IDs you copied from the Cloudflare dashboard.

Example snippet:

    {
      "name": "my-pep-store",
      "compatibility_date": "2024-03-20",
      "pages_build_output_dir": "./public",
      "kv_namespaces": [
        { "binding": "SITE_WIDE_LOCK",       "id": "YOUR_ACTUAL_ID_HERE" },
        // ... add all 6 bindings with their correct IDs ...
      ]
    }

Save the file.

### 2Understanding Key Project Files (Included in Your Download)

The template packet you downloaded contains all the necessary files. You'll primarily edit `public/index.html` for store configuration, but understanding these other files is important.

Your downloaded template (from the ZIP file) is structured with these important files at its root (the main folder you unzipped):

- `public/` folder: This is the heart of your website, containing all files that will be visible to users.
  - `index.html`: The main page of your store. Most of your store-specific configuration (products, prices, text) happens here by editing the `STORE_CONFIG` JavaScript object inside this file.
  - `_worker.js`: The backend Cloudflare Worker logic that handles payments, sessions, and digital downloads. You generally won't need to edit this for basic setup unless you're adding advanced custom features.
  - `setup_guide.html`: (This file) Detailed instructions for setting up and customizing the template.
  - `placeholder_thank_you.zip`: The default file provided for digital downloads. You'll replace this with your actual digital product.
  - `images/` folder: Contains placeholder images like `favicon.png`, `logo.png`, and `pepecoinorgb.png` (or `pepecoinorgw.png`). You should replace these with your own brand images.
  - `carousel/` folder: Place your product showcase images here (e.g., `carousel1.png`, etc.).
- `wrangler.jsonc`: This is a configuration file for Wrangler, Cloudflare's command-line tool.
  - Its main purpose in this template is to list the KV (Key-Value) Namespaces your project uses and tell Wrangler their **IDs** (which you get from the Cloudflare dashboard).
  - It also includes `"pages_build_output_dir": "./public"`, which tells deployment tools that your website files are in the `public/` directory.
  - Your Action: You MUST edit this file to insert the KV Namespace IDs you copied from the Cloudflare dashboard in Part 1, Step 2.
- `package.json`: This is a standard file for Node.js projects, often used to manage project dependencies and define scripts.
  - For this template, its primary role is to define a convenient "deploy" script (`npm run deploy`) and a "dev" script (`npm run dev` for local testing).
  - It also lists `wrangler` as a development tool, which is necessary if you use the npm scripts or run `npx wrangler ...` commands.
  - Your Action: You will likely need to edit the `--project-name` within the "deploy" script in this file to match your actual Cloudflare Pages project name. You can also update the general project `"name"` field at the top for your own records.

Both `wrangler.jsonc` and `package.json` files should be located in the main (root) directory of your project when you unzip the template, with the `public` folder sitting alongside them at the same level.

### 3Edit `wrangler.jsonc` with Your KV IDs

This file links your code's KV binding names to the actual KV Namespaces you created on Cloudflare. It's essential for Wrangler CLI if you use it for local development or certain KV operations.

1. Open `wrangler.jsonc` (located in the root of the template folder) in a text editor.
2. Update the project `"name"` field at the top to match your Cloudflare Pages project name (e.g., `"my-pep-store"`).
3. Fill in the `"id"` field for each of the 6 `kv_namespaces` entries with the actual IDs you copied from the Cloudflare dashboard in "Part 1, Step 2".

The structure should look like this (ensure `pages_build_output_dir` is `"./public"`):

    {
      "name": "my-pep-store",                     // CHANGE THIS to your Pages project name
      "compatibility_date": "2024-03-20",   // Or a more recent date
      "pages_build_output_dir": "./public",
      "kv_namespaces": [
        { "binding": "SITE_WIDE_LOCK",         "id": "REPLACE_WITH_YOUR_SITE_WIDE_LOCK_ID" },
        { "binding": "USER_ORDER_ATTEMPTS",    "id": "REPLACE_WITH_YOUR_USER_ORDER_ATTEMPTS_ID" },
        { "binding": "USER_PROFILES",          "id": "REPLACE_WITH_YOUR_USER_PROFILES_ID" },
        { "binding": "PAID_ORDERS_ARCHIVE",    "id": "REPLACE_WITH_YOUR_PAID_ORDERS_ARCHIVE_ID" },
        { "binding": "PROCESSED_TXS_GLOBAL",   "id": "REPLACE_WITH_YOUR_PROCESSED_TXS_GLOBAL_ID" },
        { "binding": "DOWNLOAD_ACCESS_TOKENS", "id": "REPLACE_WITH_YOUR_DOWNLOAD_ACCESS_TOKENS_ID" }
      ]
    }

Save the `wrangler.jsonc` file.

### 4Edit `public/index.html` (Store Configuration)

This is where you define your products, prices, and general store information displayed to users.

1. Open `public/index.html` in a text editor.
2. Scroll down to the `<script>` tag near the end of the file.
3. Find the `STORE_CONFIG` JavaScript object. This is your main configuration hub:
   - Modify `storeTitle`: Your shop's name (e.g., "Paolo's Pepe Goodies").
   - Modify `storeIntro`: A welcoming message for your store.
   - Update image paths if needed: `pepecoinOrgLogoPath`, `storeLogoPath`, `faviconPath`, `carouselImagePaths`. Ensure these images exist in the specified locations within your `public/` folder (e.g., paths like `images/my_logo.png` or `carousel/image1.jpg`). Paths should be relative to the `public` folder (e.g., use `images/logo.png` not `/images/logo.png` if `index.html` is in `public/` and `logo.png` is in `public/images/`).
   - Edit the `products` array: This is where you list your items for sale.
     - You can add, remove, or modify the example product objects.
     - Each product object needs:
       - `id`: A unique string identifier for the product (e.g., `"my_keychain_glow"`).
       - `name`: The display name of the product (e.g., "Super Glow $PEP Keychain").
       - `price`: The price in **whole $PEP units** (e.g., `60000` for 60,000 $PEP). Do not use commas in the number.
       - `type`: Must be either `"physical"` or `"digital"`.
       - `description`: A short description of the product (optional).
   - `baseShippingFee`: Set your worldwide shipping cost in whole $PEP units. If you only sell digital items, or if shipping is included/free, set this to `0`.
   - `siteReceivingAddress`: CRITICAL! Replace the placeholder `"YOUR_PEP_RECEIVING_ADDRESS_HERE_REPLACE_ME"` with your actual Pepecoin wallet address where you want to receive payments.
   - `formspreeGeneralContactID` & `formspreeShippingFormID`: Replace placeholders with your unique endpoint IDs from formspree.io if you want to use their service for the contact and shipping forms.

Example of editing the `products` array within `STORE_CONFIG`:

    // Inside STORE_CONFIG in public/index.html
    products: [
      { id: "glow_keychain", name: "Super Glow $PEP Keychain", price: 60000, type: "physical", description: "Limited edition! Glows bright." },
      { id: "standard_keychain", name: "Classic $PEP Keychain", price: 40000, type: "physical", description: "High-quality enamel keychain." },
      { id: "pepe_font_pack",  name: "$PEP Exclusive Font Pack",    price: 15000, type: "digital",  description: "Custom fonts for your projects." }
    ],

Save `public/index.html` after making your edits.

#### 5Setting Up Forms (Contact & Shipping)

This template includes HTML for a general contact form and a shipping details form. By default, these forms will not actually send data anywhere unless you configure them using a service like Formspree.io.

1. Go to formspree.io and create a free account (or use any other form handling service).
2. Create two new forms in your Formspree (or equivalent) dashboard:
   - One for your **General Contact** inquiries.
   - One for collecting **Shipping Details** from customers.
3. For each form, the service will provide you with a unique endpoint ID or URL (it usually looks like `https://formspree.io/f/your_unique_id`).
4. Open your `public/index.html` file, find the `STORE_CONFIG` JavaScript object (near the end, inside the `<script>` tag), and update these lines:

       formspreeGeneralContactID: "YOUR_FORMSpree_ENDPOINT_ID_FOR_GENERAL_CONTACT",
       formspreeShippingFormID: "YOUR_FORMSpree_ENDPOINT_ID_FOR_SHIPPING",

   Replace the placeholders with the unique IDs from your form service. The JavaScript in `index.html` will use these to set the `action` attribute of the forms.

Once configured, when users submit these forms, the data will be sent to your email address (or wherever your form service is configured to send it).

If you choose not to use Formspree or these forms, you can remove the entire `...` sections from the HTML body of `public/index.html` or implement your own backend form handling solution by changing the `action` attribute of the forms.

### 6Digital Product File (If Applicable)

If you added any products with `type: "digital"` in your `STORE_CONFIG`:

1. The system is configured by default to look for a file named `placeholder_thank_you.zip` in your `public/` folder to serve as the download for all digital products.
2. Place your desired digital product (it should be a `.zip` file) into the `public/` folder.
3. If you want to use a filename different from `placeholder_thank_you.zip`:
   - Rename your file (e.g., to `my_digital_product.zip`) and ensure it's in the `public/` folder.
   - Go to your Cloudflare Pages project dashboard → Settings → Environment Variables → Production.
   - Edit or Add the variable `DIGITAL_PRODUCT_FILENAME` and set its value to your new ZIP filename (e.g., `my_digital_product.zip`). If this variable isn't set, the worker defaults to "placeholder_thank_you.zip".

### 7Images

Update the placeholder images provided in the template with your own branding and product images.

- Favicon: Replace `public/images/favicon.png`. Update `faviconPath` in `STORE_CONFIG` if you change its name or location.
- Store Logo: Replace `public/images/logo.png`. Update `storeLogoPath` in `STORE_CONFIG`.
- Pepecoin.org Link Image: Located at `public/images/pepecoinorgb.png` (for light backgrounds) or `pepecoinorgw.png` (for dark backgrounds). Update `pepecoinOrgLogoPath` in `STORE_CONFIG` if you use a different one or change its name/location.
- Carousel Images: Place your images in the `public/carousel/` folder. Then, update the `carouselImagePaths` array in `STORE_CONFIG` with the correct relative paths to these images (e.g., `"carousel/image1.jpg"`).

### 8(Optional but Recommended) Edit `package.json`

This file helps manage project dependencies and define useful command-line scripts for deployment and local development.

1. Open `package.json` (located in the root of the template folder).
2. (Optional) Update the general project `"name"` field at the top (e.g., `"my-pep-store-project"`) for your own records.
3. Find the `"scripts"` section, then the `"deploy"` line. Ensure the `--project-name` flag in that command matches your actual Cloudflare Pages project name that you created in Part 1, Step 1. For example:

       // Inside "scripts" in package.json:
       "deploy": "npx wrangler pages deploy ./public --project-name \"YOUR_ACTUAL_PAGES_PROJECT_NAME\"",

4. The `"dev"` script is also configured here for local testing. It includes bindings for all necessary KV stores, assuming they are defined in your `wrangler.jsonc` with their preview IDs or if you set up local KV stores.

Save the file if you make changes. This allows you to use `npm run deploy` from your project's root directory in the terminal, which can be more convenient.

## Part 3: Deploying Your Store

Once all configurations and customizations are done, it's time to deploy your store to Cloudflare.

### 1Using Wrangler CLI (Command Line)

This method requires Node.js and npm (which includes npx) to be installed on your computer.

1. Open your computer's terminal or command prompt.
2. Navigate (using `cd` commands) to your project's main root folder (the one containing `wrangler.jsonc` and `package.json`).
3. Log in to your Cloudflare account via Wrangler (if you haven't recently):

       npx wrangler login

   This will open a browser window for you to authorize Wrangler.
4. Once logged in, deploy your Pages project using one of these commands:
   - If you updated the "deploy" script in `package.json`:

         npm run deploy

   - Or directly:

         npx wrangler pages deploy ./public --project-name "YOUR_PAGES_PROJECT_NAME"

     (Replace `YOUR_PAGES_PROJECT_NAME` with the name you chose in Part 1, Step 1).
5. Wrangler will upload your files and deploy your Worker. It will then provide a URL to your live store!

### 2Using Git-Connected Deployment

If you connected your Pages project to a Git repository (like GitHub or GitLab) in Part 1, Step 1:

1. Commit all your changes to your local Git repository:
   - The entire `public/` folder with your updated `index.html`, images, and digital product.
   - Your updated `wrangler.jsonc` file (with KV IDs).
   - Your updated `package.json` file (if you changed the project name in the deploy script).
2. Push the commits to the production branch (e.g., `main` or `master`) of your connected Git repository.
3. Cloudflare Pages will automatically detect these changes, start a new build, and deploy your site. You can monitor its progress in your Pages project dashboard on Cloudflare.

#### Useful Wrangler CLI Commands (for Pages)

If you're using the command line with Wrangler, here are some helpful commands. Run these from your project's root directory:

- Login to Cloudflare:

      npx wrangler login

- Deploy your `./public` folder:

      npx wrangler pages deploy ./public --project-name "YOUR_PROJECT_NAME"

- List your Pages projects:

      npx wrangler pages project list

- List deployments for a specific project:

      npx wrangler pages deployment list --project-name "YOUR_PROJECT_NAME"

- View live logs from your Worker for a specific deployment:

      npx wrangler pages deployment tail

  (Get the `` from the previous command or the Cloudflare dashboard).
- Create a new KV Namespace (gives you an ID):

      npx wrangler kv namespace create DESIRED_NAMESPACE_NAME

- List all KV Namespaces in your account:

      npx wrangler kv namespace list

## Part 4: Testing Your Live Store

### 1Test All Flows!

Open your deployed website URL and test everything meticulously:

- Product selection, order summary updates.
- Initiating a new order session (entering email).
- Making a small test $PEP payment (within the 30-min window).
- Saving the TXID. Waiting for 6+ confirmations.
- Redeeming the TXID via the "Redeem Your Payment" section.
- If digital: Check if the download link appears and downloads the correct file.
- If physical: Check if the shipping form section appears.
- Test the "View a Previous Paid Order" section with a successfully redeemed TXID.
- Test Formspree forms (if configured).

Tip for Testing Payments: You can temporarily change product prices to very small amounts in the `STORE_CONFIG` section of `public/index.html`, deploy, test with a small $PEP transaction, and then change them back to real prices and re-deploy.

### 2Troubleshooting with Logs

If something isn't working as expected, check the logs from your backend worker:

- Option A (Command Line):
  1. `npx wrangler pages deployment list --project-name "YOUR_PROJECT_NAME"` (to get the latest `Deployment ID`).
  2. `npx wrangler pages deployment tail`
- Option B (Cloudflare Dashboard):
  - Go to your Pages Project → Functions tab → Logs section.

Also, always check your browser's Developer Console (usually F12) for any frontend JavaScript errors.

## Part 5: Go Live & Further Customization

### Congratulations!

Your $PEP-powered store should now be operational. You can further customize the HTML, CSS, and even the `_worker.js` logic if you become more familiar with web development and Cloudflare Workers.

Consider adding more product details, better images, and refining the text to match your brand.

Cloudflare Pages Docs Cloudflare Workers Docs

## Get Started!

Download the complete store template and the setup guide to begin building your $PEP-powered store.

Download Template & Guide (.zip)

### Security Design Principles

This template incorporates several design principles aimed at providing a secure transaction process. However, like any software, absolute 100% security against all possible scenarios cannot be guaranteed. Users should understand these principles and are responsible for the secure operation of their deployed instance.

- Mitigation of TXID Replay/Double Spending: The `PROCESSED_TXS_GLOBAL` KV is designed to prevent any given blockchain transaction ID from being successfully redeemed through your system more than once. This is a critical control against using the same payment for multiple orders.
- Timestamp-Bound Payment Windows: A key feature is the requirement for a blockchain transaction's timestamp to fall within a specific, server-generated 30-minute window (`session_start_ts` to `session_end_ts`) associated with a unique user email and order attempt. This design aims to ensure that the payment claimed was intended for the active session, making it significantly harder to use unrelated transactions.
- Site-Wide Lock During New Order Session Initiation: The `SITE_WIDE_LOCK` is intended to serialize the creation of new payment windows. This helps maintain a clear context for which user and which order attempt is currently in the "awaiting payment" state, reducing potential for data conflicts during this critical phase.
- Specific Order Amount Verification: Each payment is validated against the *exact total amount calculated and recorded for that specific order attempt*, rather than a single fixed price.
- Server-Side Validation: All critical checks (TXID uniqueness, amount, recipient, timestamp window, confirmations) are performed by the Cloudflare Worker on the backend. This is inherently more secure than client-side validation, which can be bypassed.
- Controlled Digital Download Access: For digital products, download tokens are designed to be short-lived and invalidated after first use, reducing the risk of unauthorized link sharing leading to multiple downloads.
- HTTPS: Communication with Cloudflare Pages/Workers is over HTTPS, providing encryption for data in transit.

Important Considerations:

- Correct Configuration is Crucial: The security of your deployed store heavily relies on you correctly setting up all Cloudflare KV namespaces, bindings, and especially environment variables (like your `RECEIVING_ADDRESS` and `MIN_CONFIRMATIONS`). Incorrect configuration can undermine the security measures.
- External API Reliance: The system relies on an external blockchain explorer API (e.g., Pepeblocks) for transaction data. The accuracy and availability of this API are external factors.
- User Responsibility: Users are responsible for making payments to the correct address and for the correct amount. This system verifies payments made; it cannot prevent user error in sending cryptocurrency or protect against phishing if users interact with fraudulent sites.
- No Absolute Guarantees: While these measures provide a robust framework, no system can offer an absolute 100% guarantee against all conceivable security threats or software bugs. Users should operate this template with an understanding of these inherent limitations.