Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
Mountain View desk11 min

Building a Full-Stack E-Commerce Site with Google OAuth, APIs, and Real-World Problem Solving

A practical build sequence for a full-stack e-commerce site: Google sign-in and scopes, server-side order state, verified checkout webhooks, and the failures to expect.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A full-stack e-commerce site is more than a page that lists products. It is a storefront, a server-side API, a product and order database, a sign-in system that knows who each shopper is, and a checkout that hands card entry to a payment provider and then waits for the server to confirm the result. The hard part is not any single piece. It is making the pieces agree on what was bought, by whom, and whether payment actually succeeded.

This guide follows that system in the order you need it: the data and cart model, Google sign-in (authentication and optional API access), payment confirmation, security responsibilities, and the failures that show up in production. The title does not fix a framework, host, or payment provider, so the examples assume a React storefront with a Node.js, Express, and PostgreSQL backend. That is the stack of one public example project that combines Google OAuth with Stripe Checkout and webhooks. Other frameworks change the code, not the order of decisions. This article does not independently test that project. Its README is useful mainly because it openly documents the kinds of gaps real builds have.

As an Amazon Associate I earn from qualifying purchases.

The six parts and what each one owns

Each part has a clear job. Most production problems come from one part quietly taking on another part’s job, usually because it was the quickest place to put the logic.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Part Owns What goes wrong when it is weak
Storefront (React in the example) Browsing, cart display, redirects into sign-in and checkout Prices or order status are trusted from the browser
API and server (Express in the example) Pricing, cart validation, order creation, webhook handling Business rules live in client code, so any caller can change them
Database (PostgreSQL in the example) Products, carts, orders, order history, user records Orders have no status history, and retried requests create duplicates
Identity and session Who the person is and whether their browser is signed in Tokens end up in the browser or in URLs
Cart and order state The path from cart to pending to paid to fulfilled An order is marked paid because the browser reached a success page
Checkout and payment provider Card entry, the charge, and the result event The server acts on a result it never verified

Build the parts in this order

Each step below has a visible result you can check before moving on. Skipping ahead to checkout before the order model is stable is the most common reason builds need rework.

  1. Schema and product browsing. Done when product list and detail pages render from PostgreSQL, and a price changed in the database changes what the storefront shows but not what a past order recorded.
  2. Server-side cart. Done when adding a product through the API returns a total the server calculated, and a price sent in the request body is ignored.
  3. Order creation. Done when a POST that creates an order returns a pending order ID before any payment is attempted.
  4. Sign-in and session. Done when a signed-in browser can call a protected endpoint and an anonymous request receives a 401 response.
  5. Checkout session. Done when the server creates the provider’s checkout session with the order ID attached, and the browser is sent to the provider’s hosted page.
  6. Webhook confirmation. Done when an order moves from pending to paid only after a verified webhook, and a replayed event changes nothing.
  7. Hardening and documentation. Done when HTTPS is enforced, every admin route has a role check, and the API documentation matches the routes that are actually live.

Model money, carts, and orders on the server

The order model decides whether the rest of the system can be trusted, so settle these rules before any login or payment code exists.

  • Store money as integer minor units such as cents. Floating-point dollar amounts produce rounding errors that surface as mismatched totals.
  • The browser sends only a product ID and a quantity. The server looks up the price at cart and order time.
  • Copy the product name and price into each order line at purchase time. Later catalog edits must not change past orders.
  • Give orders explicit states such as pending, paid, failed, and fulfilled, and allow only the transitions you define, for example pending to paid and paid to fulfilled.
  • Keep guest carts tied to a session. When a shopper signs in, merge the guest cart into the account cart rather than discarding it.

Google sign-in: authentication first, API access only when needed

Authentication answers who the person is. Authorization answers what your app may do with a Google API on that person’s behalf. A plain sign-in needs only identity. Reading or writing data in a Google service needs a scope the user approves. Keep these two decisions separate in code, because each has its own failure path.

Register a Web application client with exact redirect URIs

Google’s OAuth 2.0 documentation asks you to select the client type that fits the app. A storefront with a server component is a web application, so create a Web application client in the Google Cloud console, in the OAuth client area of Google Auth Platform. Google has renamed these screens over time, so follow the labels you actually see.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

Register the exact callback URI for each environment. For example, a development callback might be http://localhost:3000/auth/google/callback and a production callback https://shop.example.com/auth/google/callback. The callback path in your code must match the registered string character for character. Google requires valid secure origins and redirect URIs, and production must use HTTPS. Keep the client ID and client secret in environment variables, not in source code.

The server-side flow, step by step

  1. The browser requests a sign-in route such as /auth/google. The server creates a random state value, stores it in a short-lived session record, and redirects the browser to Google with the client ID, redirect URI, requested scopes, and response type code. Add offline access only when a feature must call Google APIs while the user is away.
  2. The user consents on Google’s page. Google redirects the browser back to your callback with an authorization code and the state value.
  3. The callback compares the returned state with the stored value and rejects the request if they differ. This check blocks forged callbacks.
  4. The server exchanges the code for tokens in a server-to-server request that includes the client secret. Use an OAuth library for this step.
  5. The server verifies the ID token with the library and reads Google’s stable user identifier, the sub claim. Match users on sub, not on email address, because email addresses can change.
  6. The server creates its own session for the browser: an HTTP-only, Secure, SameSite cookie that references a server-side session record. Google’s tokens stay on the server.
  7. When a feature needs a Google API, the server loads the stored access token, makes the call, and refreshes the token if it has expired.

Handle tokens as credentials

  • Keep tokens out of URLs. Query parameters can end up in server logs, proxy logs, and browser history.
  • Store refresh tokens server-side, encrypted at rest. Do not place them in localStorage or in a cookie the browser can read.
  • Do not log token values, including inside error handlers, where they often appear by accident.
  • Use an established OAuth library rather than hand-built request code.

Google’s OAuth 2.0 documentation puts the library point directly: “Given the security implications of getting the implementation correct, we strongly encourage you to use OAuth 2.0 libraries when interacting with Google’s OAuth 2.0 endpoints.”

Ask for scopes in context and plan for refusal

Request only sign-in at first. Ask for an additional scope when the shopper selects the feature that needs it, and explain the feature in your own interface before the Google consent screen appears. Google’s guidance is to request new authorization only when the user expresses intent to use the feature, and to justify it clearly. A scope the user refuses should disable the feature that depends on it, not trigger repeated calls that will fail.

Refresh tokens can also stop working. A user may revoke access, or Google may invalidate the token. Never assume a stored token works indefinitely.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Situation What the app should do
Signed in, no extra scope requested Create the app session. Google-dependent features stay hidden or unavailable.
User declines an optional scope Disable only the dependent feature, explain why it is unavailable, and offer to ask again if the user chooses that feature later.
User retries the feature after declining Start consent again because the user initiated it. Do not silently retry the API call.
Stored refresh token is rejected (Google returns invalid_grant) Delete the stored token, mark the connection as disconnected, and show a Reconnect control that restarts the authorization flow.

Checkout: send card entry to the provider and confirm on the server

Use a hosted payment page as the default for a small team

Google Cloud’s architecture guidance for card payments describes a redirect-to-processor flow. The shopper enters card details on the processor’s page, and the merchant then verifies the resulting transaction. Because the card form is served by the processor, your application does not handle raw card numbers in that flow. The trade-off is less control over how the payment page looks and behaves, and a redirect the shopper must complete before the order finishes.

A return to your site is not proof of payment

When the provider sends the shopper back to your success page, you know the shopper came back. You do not know that money moved. Confirm the result with the provider’s webhook. The example project verifies the webhook signature and handles the checkout completion event. In Stripe’s event naming, that event is checkout.session.completed. A minimal handler looks like this:

Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
app.post('/webhooks/stripe', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['stripe-signature'];
  let event;
  try {
    event = stripe.webhooks.constructEvent(req.body, signature, process.env.STRIPE_WEBHOOK_SECRET);
  } catch (err) {
    return res.status(400).send('Invalid signature');
  }
  if (event.type === 'checkout.session.completed') {
    const session = event.data.object;
    // Find the order by session.metadata.orderId.
    // Continue only if session.payment_status === 'paid'
    // and session.amount_total matches the stored order total.
    // Update the order only if it is still pending.
  }
  res.json({ received: true });
});

Several details in that handler matter more than the code itself:

  • Verify the signature against the raw request body. If the body is parsed as JSON first, the bytes change and verification fails. Apply raw-body parsing only to the webhook route.
  • Each webhook endpoint has its own signing secret, and test mode and live mode use different ones. A secret from the wrong mode produces signature errors that look like a code bug.
  • Check payment_status before fulfilling. Some payment methods complete a checkout session while payment is still pending.
  • Compare the amount and currency with the stored order. The event type alone does not prove the right amount was paid.
  • Make the update conditional on the order still being pending. Providers can redeliver events, and a repeated event should change nothing.

The example project’s payment verification runs in test mode with test card values. That shows the wiring works. It does not show live-mode behavior, refunds, or how failed payments are handled.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Security duties a hosted checkout does not remove

A hosted payment page reduces the card data your systems touch. It does not make the site PCI compliant. Google Cloud’s guidance keeps the merchant’s application and the systems it runs within the merchant’s responsibility. The PCI Security Standards Council’s e-commerce guidance, a document dated January 2013, makes the same general point: outsourcing payment does not transfer the merchant’s responsibility for securing its site. Treat that document as the principle, not as current requirements. For the PCI DSS requirements that apply to your implementation, read the current standard and your provider’s responsibility documentation.

Duties that stay with the merchant in any hosted-checkout build:

  • HTTPS on every page that handles sign-in, cart data, or checkout, with secure cookies.
  • Server-side authorization on every route, including admin routes.
  • Protection of OAuth client secrets and stored tokens, and logs that never contain them.
  • Patching of dependencies, the server operating system, and the hosting environment.

Problems you will hit, and what fixes them

Symptom Likely cause Fix
Google rejects sign-in with redirect_uri_mismatch The callback sent differs from the registered URI in scheme, host, port, path, or trailing slash Register the exact callback for each environment, and build the URI from an environment variable rather than a hard-coded string
Checkout succeeds but the order stays pending The webhook is not reaching the server, or signature verification is failing Check the endpoint’s delivery log in the provider dashboard, and confirm the signing secret matches the environment (test or live)
Every webhook fails with a signature error The body was parsed as JSON before verification Use raw-body parsing only on the webhook route
A feature errors after the user declined a scope The app calls the API without checking which scopes were granted Check granted scopes before each call, and show the feature as unavailable when a scope is missing
Any signed-in customer can open admin pages The route checks login but not role Add a role check to each admin route, default to deny, and read the role from the server’s own user record rather than a client-supplied value
Developers call routes that are missing from the API docs The OpenAPI description lags newly added OAuth and payment routes, as the example project’s README acknowledges Update the spec in the same change that adds or alters a route, and check the spec against live routes in continuous integration

Custom build or commerce platform

A custom stack gives you control of the data model and checkout logic, and it teaches you every layer. A commerce platform supplies commerce primitives such as products, carts, and checkout, in exchange for working within its APIs and data model. Neither is the right answer in general. Choose based on which work you want to own.

Axis Custom build Commerce platform
Data model You design products, orders, and order states The platform defines core objects, and you extend them through its APIs
Sign-in and account access You implement OAuth, sessions, and role checks yourself The platform provides account access through its own APIs and authorization model
Payment integration You integrate a payment provider and own the webhook logic Checkout runs through the platform’s integration boundary
Operational duties Application, hosting, dependencies, and payment integration are yours Part of the infrastructure is shared with the platform; the division is set out in its documentation

Shopify’s API set as a platform example

Shopify’s developer documentation describes several APIs, each for a different job. Map the job first, then pick the API.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
API Used for Status for new apps
GraphQL Admin API Managing store data from your backend, using scopes the merchant grants Current
Storefront API Buyer-facing storefronts and carts Current
Customer Account API Logged-in buyer account data; supports public clients using PKCE Current
REST Admin API Store data through the older REST interface Legacy; Shopify identifies it as legacy for new apps

What this guide does not settle

Google’s OAuth policies, its console labels, and Shopify’s API set all change over time. Confirm the current versions in Google’s OAuth documentation and Shopify’s developer documentation before you build. Tax, shipping, returns, and consumer-protection rules vary by country and sit outside this stack. Those rules need separate guidance for the market you sell in.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.