Technical Documentation
GOALS: The Definition of Determination — Website
Overview
Deployment Steps
Maintenance
Payment & Commerce
Section 01
The GOALS website is a static site — HTML, CSS, JavaScript, and images. No backend server is required. The AWS stack below delivers it globally at high speed with HTTPS, for a few dollars per month.
Request Flow
| AWS Service | Purpose | Estimated Cost |
|---|---|---|
| Amazon S3 | Stores and serves all HTML, CSS, JS, and image files | ~$0.02/mo |
| Amazon CloudFront | Global CDN — caches files at 400+ edge locations worldwide | ~$1–5/mo |
| AWS Certificate Manager | Free SSL/TLS certificate for HTTPS on your custom domain | Free |
| Amazon Route 53 | DNS management — connects your domain to CloudFront | ~$0.50/mo |
Total estimated cost: $2–6/month for a fully hosted, global, HTTPS-enabled website with enterprise-grade CDN delivery.
Section 02
Before deploying, confirm you have the following ready.
aws.amazon.com. An IAM user with S3, CloudFront, ACM, and Route 53 permissions is recommended over root account access.goalsbook.com) registered and accessible. Can be managed in Route 53 or an external registrar (GoDaddy, Namecheap, etc.).index.html, book.html, author.html, contact.html, order.html, css/, images/, and aws-deployment-guide.html.aws.amazon.com/cli.console.aws.amazon.com.Important: SSL certificates for CloudFront must be created in the US East (N. Virginia) — us-east-1 region. This is an AWS requirement regardless of where your bucket is located. Set your region to us-east-1 before creating the certificate.
Step 01
S3 is where all your website files live. Think of it as a cloud folder that AWS serves to visitors.
Go to console.aws.amazon.com and sign in
Search for S3 in the top search bar and click it
Click the orange "Create bucket" button
Bucket name: Enter your exact domain name (e.g. goalsbook.com). The bucket name must match your domain exactly.
AWS Region: Choose your preferred region (e.g. us-east-1 — N. Virginia is fastest for US visitors)
Block Public Access: Uncheck "Block all public access" — check the acknowledgment box that appears. This allows CloudFront to access your files.
Leave all other settings as default and click "Create bucket"
After creating the bucket, go to Permissions → Bucket Policy and paste the following:
Bucket Policy JSON
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::YOUR-BUCKET-NAME/*" } ] }
Replace YOUR-BUCKET-NAME with your actual bucket name (e.g. goalsbook.com) before saving.
Step 02
Upload all project files into the S3 bucket exactly as they are structured — maintaining the same folder hierarchy.
Files to Upload
# Your complete file structure: index.html ← Home page book.html ← The Book page author.html ← Author page contact.html ← Contact page order.html ← Order page aws-deployment-guide.html ← This document (optional) css/ style.css ← All styles images/ goals-book-cover.png ← Transparent book cover goals-book-cover.jpg ← Original (keep as fallback) sharif-dyson-headshot.jpg ← Author photo goals-logo.png ← GOALS logo
Open your S3 bucket and click "Upload"
Click "Add files" and select all .html files from your project folder
Click "Add folder" and upload the css folder, then repeat for images
Click "Upload" at the bottom — wait for the green success confirmation
From your terminal, navigate to your project folder and run:
Terminal Command
# Sync entire project folder to S3 (replace bucket name) aws s3 sync . s3://YOUR-BUCKET-NAME --delete # Example with real bucket name: aws s3 sync . s3://goalsbook.com --delete
Pro tip: Use the CLI sync command every time you update the website. The --delete flag removes old files that no longer exist in your local folder.
Step 03
Tell S3 to serve your files as a website and which file to use as the homepage.
In your S3 bucket, click the "Properties" tab
Scroll to the bottom — find "Static website hosting" and click "Edit"
Select "Enable"
Set Index document: index.html
Set Error document: index.html (sends all 404s back to homepage)
Click "Save changes"
After saving, AWS shows you a Bucket website endpoint URL — copy and save this. It looks like: http://goalsbook.com.s3-website-us-east-1.amazonaws.com. You'll need it in the CloudFront step.
Step 04
AWS Certificate Manager (ACM) provides free SSL certificates. Your site must use HTTPS — this is required for CloudFront and expected by visitors.
Critical: You MUST create this certificate in the us-east-1 (N. Virginia) region. Switch your AWS region to US East (N. Virginia) before proceeding, even if your S3 bucket is in a different region.
Switch region to US East (N. Virginia) — us-east-1 using the region dropdown in the top right of AWS Console
Search for "Certificate Manager" and open it
Click "Request a certificate" → select "Request a public certificate" → click Next
In "Fully qualified domain name" enter your domain: goalsbook.com
Click "Add another name" and add: www.goalsbook.com
Validation method: Select "DNS validation" (recommended) → click "Request"
After requesting, click into the certificate — you'll see a CNAME record AWS needs you to add to your domain's DNS
If using Route 53: Click "Create records in Route 53" — AWS does it automatically
If using another registrar (GoDaddy, Namecheap): Copy the CNAME Name and CNAME Value shown, log into your registrar, and add it manually as a CNAME DNS record
Wait 5–30 minutes for the certificate status to change from Pending validation to Issued
Step 05
CloudFront is AWS's global CDN. It caches your files at 400+ locations worldwide so visitors load the site from the nearest server — fast, everywhere.
Search for "CloudFront" in the AWS Console and open it
Click "Create distribution"
Origin domain: Paste your S3 website endpoint URL (from Step 3) — do NOT use the S3 bucket dropdown, paste the full URL manually
Protocol: Select "HTTP only" for the origin (S3 website endpoints use HTTP — CloudFront adds HTTPS for visitors)
Viewer protocol policy: Select "Redirect HTTP to HTTPS"
Allowed HTTP methods: GET, HEAD
Alternate domain names (CNAMEs): Add goalsbook.com and www.goalsbook.com
Custom SSL certificate: Select the certificate you created in Step 4 from the dropdown
Default root object: Type index.html
Click "Create distribution" — deployment takes 5–15 minutes
Once created, copy your CloudFront Domain Name — it looks like d1234abcdef.cloudfront.net. You'll use this in the next step to connect your domain.
Step 06
Point your domain at the CloudFront distribution so visitors reach your site when they type your domain name.
Open Route 53 → Hosted zones → click your domain
Click "Create record"
Record name: leave blank (for root domain goalsbook.com)
Record type: A
Toggle "Alias" ON → Choose "Alias to CloudFront distribution" → select your distribution
Click "Create records"
Repeat for www: Create another A record with name www, same alias to CloudFront
Log into your domain registrar's DNS management panel
Add a CNAME record: Name = www, Value = your CloudFront domain (d1234abcdef.cloudfront.net)
For the root domain (goalsbook.com): Add an ALIAS or ANAME record pointing to the CloudFront domain. If your registrar doesn't support ALIAS, use a redirect from root to www.
DNS propagation typically takes 15 minutes to 48 hours depending on your registrar. During this time the site may not be accessible via your custom domain — this is normal.
Step 07
Confirm everything is working correctly before sharing the site publicly.
https://goalsbook.com — homepage loads correctly with book cover image visiblehttps://www.goalsbook.com — both root and www workhttp://goalsbook.com (no HTTPS) — should redirect automatically to HTTPSAll checks passing? Your site is live on AWS. Share your domain with confidence.
Section 10
When you make changes to the site, follow this process to push updates live.
Upload only the files that changed via the AWS Console, or use the CLI sync command:
CLI Sync Command
aws s3 sync . s3://goalsbook.com --delete
CloudFront caches files for fast delivery. After uploading new files, you must clear the cache so visitors see the updated version.
CLI Invalidation
aws cloudfront create-invalidation \ --distribution-id YOUR_DISTRIBUTION_ID \ --paths "/*"
Or via Console: CloudFront → your distribution → Invalidations tab → Create invalidation → enter /* → click Create.
Invalidations typically take 1–3 minutes to propagate globally. The first 1,000 invalidation paths per month are free.
Section 11
Based on typical traffic for a book launch site. All costs are in USD per month.
| Service | What You Pay For | Est. Monthly Cost |
|---|---|---|
| S3 Storage | Storing ~5MB of HTML, CSS, images | < $0.01 |
| S3 Requests | File reads when CloudFront cache misses | < $0.05 |
| CloudFront | 1,000–10,000 visitors/month, ~100KB per page | $1–5 |
| Route 53 Hosted Zone | 1 hosted zone for your domain | $0.50 |
| Route 53 Queries | DNS lookups | < $0.50 |
| ACM Certificate | SSL certificate for HTTPS | Free |
Total: approximately $2–6/month for a fully hosted, HTTPS, globally distributed website. Scales automatically with traffic — no server to manage, no downtime risk.
Section 12
Common issues and how to resolve them.
Check S3 bucket policy is correctly set (Step 3). Confirm Block all public access is turned off.
Confirm index.html is set as the default root object in CloudFront settings.
Create a CloudFront invalidation for /* (see Step 10). Wait 1–3 minutes, then hard refresh your browser (Ctrl + Shift + R or Cmd + Shift + R).
Confirm the ACM certificate was created in us-east-1 (N. Virginia) — not another region.
Confirm the certificate status is Issued (not Pending) before attaching to CloudFront.
Confirm your domain's CNAME validation record is correctly added in DNS.
DNS changes can take up to 48 hours. Use dig goalsbook.com or dnschecker.org to verify propagation status.
Confirm the CloudFront distribution alternate domain names include both goalsbook.com and www.goalsbook.com.
Need help? AWS Support is available at console.aws.amazon.com/support. The AWS free tier includes basic support. The AWS documentation for each service is also detailed and searchable at docs.aws.amazon.com.
Accept real payments · Deposit to bank · Track every transaction
Why Square? Square charges 2.6% + $0.10 per transaction (card present) or 2.9% + $0.30 per online transaction. There are no monthly fees, no setup fees, and no contract. Funds are deposited to your bank account next business day. For a $19.99 paperback sale, Square keeps ~$0.88 — you receive ~$19.11.
Go to developer.squareup.com and sign in (or create a free account).
Click + New Application → Name it "GOALS Book Website".
In your app dashboard, go to Credentials tab. You will see:
# Square Credentials (copy these — you'll need them) Application ID: sq0idb-XXXXXXXXXXXXXXXXXXXXXXXX ← used in browser JS (public) Access Token: EAAAl-XXXXXXXXXXXXXXXXXXXXXXXX ← used in Lambda ONLY (secret!) Location ID: LXXXXXXXXXXXXXXXXX ← found in Locations tab
CRITICAL SECURITY RULE: The Access Token is your secret key — it can charge any amount and access all your Square data. It must NEVER appear in your HTML, CSS, or JavaScript files. It lives ONLY inside your AWS Lambda environment variable. The Application ID is safe to put in the browser.
Open order.html and find the configuration block at the top of the <script> section.
Replace the placeholder values:
// In order.html — CONFIGURATION block const SQUARE_APP_ID = 'sq0idb-YOUR_ACTUAL_APP_ID'; ← from Square Dashboard const SQUARE_LOCATION_ID = 'LXXXXXXXXXXXXXXXXX'; ← from Locations tab const LAMBDA_ENDPOINT = 'https://abc123.execute-api.us-east-1.amazonaws.com/process-payment'; ← your API Gateway URL (Step D)
Switch the Square SDK script from sandbox to production when going live:
<!-- SANDBOX (testing — current): --> <script src="https://sandbox.web.squarecdn.com/v1/square.js"></script> <!-- PRODUCTION (switch to this when live): --> <script src="https://web.squarecdn.com/v1/square.js"></script>
Delete the <div class="sandbox-notice"> block from order.html when going live.
On your local machine, create a folder and install the Square Node.js SDK:
mkdir goals-payment-lambda && cd goals-payment-lambda cp /path/to/lambda/process-payment.js ./index.js npm init -y npm install square zip -r function.zip index.js node_modules/
In AWS Console → Lambda → Create function:
# Lambda settings Function name: goals-process-payment Runtime: Node.js 20.x Architecture: x86_64 Memory: 256 MB Timeout: 15 seconds Handler: index.handler
Upload function.zip via the Lambda console (Code tab → Upload from → .zip file).
Go to Configuration → Environment variables and add:
# Lambda Environment Variables SQUARE_ACCESS_TOKEN = EAAAl-YOUR_SECRET_ACCESS_TOKEN SQUARE_LOCATION_ID = LXXXXXXXXXXXXXXXXX SQUARE_ENVIRONMENT = sandbox ← change to 'production' when live ALLOWED_ORIGIN = https://yourdomain.com ← your website domain (CORS)
In AWS Console → API Gateway → Create API → Choose HTTP API (not REST API — HTTP is simpler and cheaper).
Click Add Integration → Lambda → select goals-process-payment.
Configure route: POST /process-payment.
Configure CORS (required so your website can call the API):
# API Gateway CORS Configuration Allow origins: https://yourdomain.com ← your domain exactly Allow methods: POST, OPTIONS Allow headers: Content-Type Max age: 300
Deploy the stage → Copy the Invoke URL — this is your LAMBDA_ENDPOINT to paste into order.html:
# Example API Gateway endpoint https://abc1defg23.execute-api.us-east-1.amazonaws.com/process-payment
With sandbox credentials in place, go to your order.html page.
Fill out a test order and use Square's sandbox test card:
# Square Sandbox Test Cards Visa (success): 4111 1111 1111 1111 Exp: any future · CVV: any 3 digits Mastercard (success): 5105 1051 0510 5100 Exp: any future · CVV: any 3 digits Card declined: 4000 0000 0000 0002 (tests declined card flow) Insufficient funds: 4000 0000 0000 9995 (tests insufficient funds)
Verify the payment appears in your Square Developer Dashboard → Sandbox → Transactions.
Verify the order record saves in your Admin Dashboard at admin.html.
In Square Developer Dashboard → switch your app to Production mode. Copy the production Access Token and Application ID.
Update Lambda environment variables: set SQUARE_ACCESS_TOKEN = production token, SQUARE_ENVIRONMENT = production.
In order.html: update SQUARE_APP_ID to production app ID, switch SDK script to web.squarecdn.com, remove sandbox notice div.
Re-upload updated order.html to S3 and invalidate CloudFront cache:
aws s3 cp order.html s3://your-bucket-name/order.html aws cloudfront create-invalidation --distribution-id YOUR_CF_ID --paths "/order.html"
Run a live test with a real card for a small amount ($1.00) to confirm end-to-end flow. Verify payout in Square Dashboard → Transactions.
Bank Deposits: Square deposits your funds to your linked bank account the next business day (or same-day for eligible Square accounts). Set up your bank account in Square Dashboard → Account & Settings → Bank Accounts. You will receive an email each time a deposit is made with a breakdown of all transactions.
See every order · Buyer info · Revenue · Fulfillment status
Every time a buyer completes a purchase on order.html, their full order record is automatically saved to the GOALS order database (via the RESTful Table API). The Admin Dashboard at admin.html gives you a live view of all orders, buyers, revenue, and fulfillment status — all in one place, accessible from any browser.
| Feature | What It Shows |
|---|---|
| Overview Dashboard | Total revenue, books sold, total orders, average order value — updated live |
| Sales by Format | Visual bar graph of Hardcover vs Paperback copies sold |
| All Orders Table | Full order list with search, filter by status/format, sortable columns |
| Order Detail Modal | Full buyer info, shipping address, Square payment ID, receipt link, fulfillment notes |
| Fulfillment Tools | Update order status, add tracking number, log fulfillment notes — all in-app |
| Customer Records | Every buyer: name, email, phone, total orders, books purchased, total spent, ship city |
| CSV Export | Download all order data as a spreadsheet — for accounting, shipping labels, or records |
# Every order record stores:
order_number → GOALS-123456 (auto-generated)
first_name → Buyer's first name
last_name → Buyer's last name
email → Buyer's email (receipt sent here)
phone → Buyer's phone (optional)
format → Hardcover or Paperback
quantity → Number of copies
unit_price → Price per copy ($19.99 or $34.99)
total_amount → Total charged (unit × qty)
signed_copy → none / signed / personalized
personalization → Inscription text (if personalized)
order_notes → Buyer's additional notes
address_line1 → Street address
address_city → City
address_state → State / Province
address_zip → ZIP / Postal code
address_country → Country
status → pending / paid / processing / shipped / delivered / cancelled
payment_status → pending / completed / failed / refunded
square_payment_id → Square transaction ID (e.g. RY9XXXXXXX)
square_receipt_url → Link to buyer's Square receipt
tracking_number → Shipping tracking (added by you after shipping)
fulfillment_notes → Internal notes
shipped_at → Timestamp when marked shipped
created_at → Order placed timestamp
Navigate to https://yourdomain.com/admin.html — this page is password protected.
Password updated to Goals2026!SD — already changed in admin.html and uploaded to S3. ✅
For production security, do NOT expose admin.html publicly. Either:
# Option A: Restrict admin.html via CloudFront signed URLs aws cloudfront create-invalidation ... ← use signed URLs / cookies # Option B: IP whitelist via S3 bucket policy # Block all IPs except your own from accessing admin.html { "Condition": { "NotIpAddress": { "aws:SourceIp": ["YOUR.PUBLIC.IP.ADDRESS/32"] } } } # Option C (best): Move admin behind AWS Cognito authentication # Use Amplify or Cognito User Pools for secure login
CSV Export: Click "Export CSV" in the Admin Dashboard to download every order record as a spreadsheet. This file includes buyer name, email, address, format, quantity, total paid, payment ID, tracking number, and status. Use it for your accountant, shipping labels, or Square reconciliation.
AWS infrastructure + Square payment fees combined
| Service | Cost | Notes |
|---|---|---|
| S3 Storage | ~$0.03/mo | Site files (~5MB) at $0.023/GB |
| CloudFront CDN | ~$0.50–$2/mo | First 1TB free (Free Tier), then $0.085/GB |
| Route 53 DNS | $0.50/mo | Per hosted zone |
| ACM SSL Certificate | FREE | Free with CloudFront |
| Lambda (payment processor) | ~FREE | First 1M requests/mo free. 1,000 orders = ~$0.002 |
| API Gateway | ~FREE | First 1M calls/mo free (HTTP API) |
| AWS Total / Month | ~$1–$3 | At low to moderate traffic levels |
| Square — Paperback ($19.99) | ~$0.88/sale | 2.9% + $0.30 = $0.88 → you keep $19.11 |
| Square — Hardcover ($34.99) | ~$1.31/sale | 2.9% + $0.30 = $1.31 → you keep $33.68 |
| 100 Paperback Sales | $1,911 to you | $1,999 revenue − $88 Square fees |
Bottom line: Your entire website infrastructure costs approximately $1–$3 per month. Square takes a small per-transaction fee (no monthly cost). For every 100 paperbacks sold at $19.99, you deposit $1,911 to your bank account after all fees. No Amazon cut. No Barnes & Noble cut. No middlemen.
Complete every item before going live
Square account created — developer.squareup.com, app created, credentials copied
Bank account linked in Square Dashboard → Account & Settings → Bank Accounts
Lambda deployed with production Square Access Token in environment variables
API Gateway configured — CORS enabled, endpoint URL copied
order.html updated — production Square App ID, production SDK URL, Lambda endpoint, sandbox notice removed
S3 bucket created and all site files uploaded (including images/ folder)
CloudFront distribution live — HTTPS working, correct origin
Custom domain connected via Route 53 — SSL certificate active
Admin password updated — changed to Goals2026!SD in admin.html ✅
Test purchase completed — real card, real charge, order appears in admin.html, Square Dashboard, bank pending
All pages tested — Home, Book, Author, Contact, Order on both desktop and mobile
Email confirmed — Square sends receipt to buyer email automatically after successful charge
You're ready. Once every item above is checked, the GOALS website is live, payments are processing, and every order is tracked automatically. Funds deposit to your bank the next business day. Check admin.html daily during launch week to monitor orders and mark shipments as you fulfill them.
Need help? AWS Support: console.aws.amazon.com/support · Square Support: squareup.com/help · AWS Docs: docs.aws.amazon.com · Square Docs: developer.squareup.com/docs