0

I am following this tutorial on cloning Amazon and I have the exact same code as in the video but keep getting an error. I created new keys (Firebase and Stripe) and even changed the Shipping Rates in Stripe. The error is shown in the screenshot below. screenshot The code is in this GitHub repo. This is the component where I'm calling the secret key:

const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);

export default async (req, res) => {
  const { items, email } = req.body;

  const transformedItems = items.map((item) => ({
    price_data: {
      currency: "gbp",
      unit_amount: item.price * 100,
      product_data: {
        name: item.title,
        images: [item.image],
        description: item.description,
      },
    },
    quantity: 1,
  }));

  const session = await stripe.checkout.sessions.create({
    payment_method_types: ["card"],
    shipping_options: [
      {
        shipping_rates: ["shr_1M97piHPvZNNoU6bvw5ut7Oy"],
      },
    ],
    shipping_address_collection: {
      allowed_countries: ["GB", "US", "CA"],
    },
    line_items: transformedItems,
    mode: "payment",
    success_url: `${process.env.HOST}/success`,
    cancel_url: `${process.env.HOST}/checkout`,
    metadata: {
      email,
      images: JSON.stringify(items.map((item) => item.image)),
    },
  });
  res.status(200).json({ id: session.id });
};

This is the checkout component:

import Image from "next/image";
import React from "react";
import { useSelector } from "react-redux";
import CheckoutProduct from "../components/CheckoutProduct";
import Header from "../components/Header";
import { selectItems, selectTotal } from "../slices/basketSlice";
import Currency from "react-currency-formatter";
import { useSession } from "next-auth/client";
import { loadStripe } from "@stripe/stripe-js";
import axios from "axios";

const stripePromise = loadStripe(process.env.stripe_public_key);

function Checkout() {
  const items = useSelector(selectItems);
  const total = useSelector(selectTotal);
  const [session] = useSession();

  const createCheckoutSession = async () => {
    const stripe = await stripePromise;

    // Call the backend to create a checkout session
    const checkoutSession = await axios.post("/api/create-checkout-session", {
      items: items,
      email: session.user.email,
    });

    // Redirect customer to Stripe checkout
    const result = await stripe.redirectToCheckout({
      sessionId: checkoutSession.data.id,
    });

    if (result.error) {
      alert(result.error.message);
    }
  };

  return (
    <div className="bg-gray-100">
      <Header />

      <main className="lg:flex max-w-screen-2xl mx-auto">
        {/* Left side */}
        <div className="flex-grow m-5 shadow-sm">
          <Image
            src="https://links.papareact.com/ikj"
            width={1020}
            height={250}
            objectFit="contain"
          />

          <div className="flex flex-col p-5 space-y-10 bg-white">
            <h1 className="text-3xl border-b pb-4">
              {items.length === 0
                ? "Your Amazon Basket is empty."
                : "Shopping Basket"}
            </h1>

            {items.map((item, i) => (
              <CheckoutProduct
                key={i}
                id={item.id}
                title={item.title}
                rating={item.rating}
                price={item.price}
                description={item.description}
                category={item.category}
                image={item.image}
                hasPrime={item.hasPrime}
              />
            ))}
          </div>
        </div>

        {/* Right side */}
        <div className="flex flex-col bg-white p-10 shadow-md">
          {items.length > 0 && (
            <>
              <h2 className="whitespace-nowrap">
                Subtotal ({items.length} items):{" "}
                <span className="font-bold">
                  <Currency quantity={total} currency="GBP" />
                </span>
              </h2>

              <button
                role="link"
                onClick={createCheckoutSession}
                disabled={!session}
                className={`button mt-2 ${
                  !session &&
                  "from-gray-300 to-gray-500 border-gray-200 text-gray-300 cursor-not-allowed"
                }`}
              >
                {!session ? "Sign in to checkout" : "Proceed to checkout"}
              </button>
            </>
          )}
        </div>
      </main>
    </div>
  );
}

export default Checkout;

This is shown in the VS Codes terimanl: StripePermissionError: This API call cannot be made with a publishable API key. Please use a secret API key. You can find a list of your API keys at https://dashboard.stripe.com/account/apikeys. at res.toJSON.then.StripeAPIError.message (/Users/joanskenderi/Amazon-Clone/node_modules/stripe/lib/StripeResource.js:216:23) at runMicrotasks (<anonymous>) at processTicksAndRejections (node:internal/process/task_queues:96:5) { type: 'StripePermissionError', raw: { code: 'secret_key_required', doc_url: 'https://stripe.com/docs/error-codes/secret-key-required', message: 'This API call cannot be made with a publishable API key. Please use a secret API key. You can find a list of your API keys at https://dashboard.stripe.com/account/apikeys.', request_log_url: 'https://dashboard.stripe.com/test/logs/req_duLaUMVrQ3aelr?t=1669643878', type: 'invalid_request_error', headers: { server: 'nginx', date: 'Mon, 28 Nov 2022 13:57:58 GMT', 'content-type': 'application/json', 'content-length': '453', connection: 'keep-alive', 'access-control-allow-credentials': 'true', 'access-control-allow-methods': 'GET, POST, HEAD, OPTIONS, DELETE', 'access-control-allow-origin': '*', 'access-control-expose-headers': 'Request-Id, Stripe-Manage-Version, X-Stripe-External-Auth-Required, X-Stripe-Privileged-Session-Required', 'access-control-max-age': '300', 'cache-control': 'no-cache, no-store', 'idempotency-key': 'd678ecb5-f3a6-428c-90b8-60f6d58a5398', 'original-request': 'req_duLaUMVrQ3aelr', 'request-id': 'req_duLaUMVrQ3aelr', 'stripe-version': '2022-11-15', 'strict-transport-security': 'max-age=63072000; includeSubDomains; preload' }, statusCode: 403, requestId: 'req_duLaUMVrQ3aelr' }, rawType: 'invalid_request_error', code: 'secret_key_required', doc_url: 'https://stripe.com/docs/error-codes/secret-key-required', param: undefined, detail: undefined, headers: { server: 'nginx', date: 'Mon, 28 Nov 2022 13:57:58 GMT', 'content-type': 'application/json', 'content-length': '453', connection: 'keep-alive', 'access-control-allow-credentials': 'true', 'access-control-allow-methods': 'GET, POST, HEAD, OPTIONS, DELETE', 'access-control-allow-origin': '*', 'access-control-expose-headers': 'Request-Id, Stripe-Manage-Version, X-Stripe-External-Auth-Required, X-Stripe-Privileged-Session-Required', 'access-control-max-age': '300', 'cache-control': 'no-cache, no-store', 'idempotency-key': 'd678ecb5-f3a6-428c-90b8-60f6d58a5398', 'original-request': 'req_duLaUMVrQ3aelr', 'request-id': 'req_duLaUMVrQ3aelr', 'stripe-version': '2022-11-15', 'strict-transport-security': 'max-age=63072000; includeSubDomains; preload' }, requestId: 'req_duLaUMVrQ3aelr', statusCode: 403, charge: undefined, decline_code: undefined, payment_intent: undefined, payment_method: undefined, payment_method_type: undefined, setup_intent: undefined, source: undefined }

8
  • Please share more details, like the code involved and your attempts to resolve the problem Commented Nov 28, 2022 at 14:00
  • This API call cannot be made with a publishable API key. Please use a secret API key - did you try anything like that in your code? Commented Nov 28, 2022 at 14:00
  • It says you need to have an API key from stripe , just create one for yourself and use the same Commented Nov 28, 2022 at 14:05
  • @NicoHaase the code is the exact same one I have on my GitHub repo, i just have the .env.local file which obviously i can't publish. il looks like this: ``` # Authentication GOOGLE_ID=key_goes_here GOOGLE_SECRET=key_goes_here NEXTAUTH_URL=localhost:3000 # Stripe STRIPE_PUBLIC_KEY=key_goes_here STRIPE_SECRET_KEY=key_goes_here HOST=localhost:3000 ``` Commented Nov 28, 2022 at 14:05
  • @NicoHaase I also used a secret key and called it. idk why it is throwing this This API call cannot be made with a publishable API key. Please use a secret API key Commented Nov 28, 2022 at 14:06

1 Answer 1

0

When using Stripe, you have two types of keys[1]

  • Publishable Key: Use this key in your web or mobile app’s client-side code.
  • Private/Secret Key: Use this key to authenticate requests on your server when in test mode. By default, you can use this key to perform any API request without restriction.

It looks like you are using your publishable key (STRIPE_SECRET_KEY) instead of using the Secret Key when calling Stripe APIs from your backend server.

You can follow these steps in order to generate an API Secret key for your test mode[2] and use it instead for your tests.

[1] https://stripe.com/docs/keys#obtain-api-keys

[2] https://stripe.com/docs/keys#reveal-an-api-secret-key-for-test-mode

Sign up to request clarification or add additional context in comments.

2 Comments

I did it this way and it gives the error above.
When printing the value of process.env.STRIPE_SECRET_KEY, it starts with pk_test_... or sk_test_... ? you need to make sure that you are using the key starting with sk_test_...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.