微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法在 MERN 应用程序中集成 Stripe 支付

如何解决无法在 MERN 应用程序中集成 Stripe 支付

我正在学习按照官方文档将 Stripe 支付集成到 MERN 应用中。

登录到我的帐户。然后,在 Shop 页面中,当我单击 checkout 按钮时,我向 POST 发出 /api/payment/checkout-session 请求。我还在 Bearer token 标头中提供了 Authorization。但是,我收到以下错误

enter image description here

错误

{"message":"You did not provide an API key. You need to provide your API key in the Authorization header,using Bearer auth (e.g. 'Authorization: Bearer YOUR_SECRET_KEY'). See https://stripe.com/docs/api#authentication for details,or we can help at https://support.stripe.com/.","stack":"Error: You did not provide an API key. You need to provide your API key in the Authorization header,or we can help at https://support.stripe.com/.\n    at IncomingMessage.<anonymous> (D:\\FINISHED CODING PROJECTS\\STRIPE-PAYMENT\\node_modules\\stripe\\lib\\StripeResource.js:174:21)\n    at Object.onceWrapper (events.js:421:28)\n    at IncomingMessage.emit (events.js:327:22)\n    at endReadableNT (internal/streams/readable.js:1327:12)\n    at processticksAndRejections (internal/process/task_queues.js:80:21)"}

我做错了什么? 注意:我使用 Redux Toolkit 进行状态管理。 代码片段如下:

client/src/components/Shopping.js

import React from "react";

const Shopping = ({ handleCheckoutClick }) => {
  return (
    <div className="card bg-light col-8 col-sm-6 col-md-4 mx-auto buy-book">
      <img
        className="card-img-top"
        src="/images/vase.jpg"
        alt="Card image cap"
      />
      <h3 className="card-title text-center">SCANDINAVIAN VASE</h3>
      <button
        type="button"
        id="checkout-button"
        role="link"
        onClick={handleCheckoutClick}
        className="btn btn-warning btn-lg"
      >
        Checkout
      </button>
    </div>
  );
};

export default Shopping;

client/src/App.js

import React,{ useState } from "react";

import Header from "./components/Header";
import Shopping from "./components/Shopping";
import RegisterForm from "./components/RegisterForm";
import LoginForm from "./components/LoginForm";
import { Route,Switch } from "react-router-dom";
import { usedispatch,useSelector } from "react-redux";
import { fetchCheckoutSession } from "./components/stateSlices/paymentSlice";

import { loadStripe } from "@stripe/stripe-js";
const stripePromise = loadStripe(
  "pk_test_51I29jDKK144e4HAvKFfcQEjfPm3PWRDDS5fa1fWXM7bdBlpz92vROkIA04yoJbKYB5FEe42sOLOKu6D4TiDRDy0e0059Iop568"
);

const App = () => {
  const [menuOpen,setMenuOpen] = useState(false);

  const handleMenuClick = () => {
    setMenuOpen(!menuOpen);
  };

  const handleOverlayClick = () => {
    setMenuOpen(!menuOpen);
  };

  const handleSidedrawerNavbarLinkClick = () => {
    setMenuOpen(!menuOpen);
  };

  const dispatch = usedispatch();
  const { user } = useSelector((state) => state.login);

  const handleCheckoutClick = async (e) => {
    e.preventDefault();
    // const stripe = await stripePromise;

    // const response = await fetch("/api/payment/create-checkout-session",{
    //   method: "POST",// });

    // const session = await response.json();
    dispatch(fetchCheckoutSession({ token: user.token }));

    // When the customer clicks on the button,redirect them to Checkout.
    // const result = await stripe.redirecttocheckout({
    //   sessionId: session.id,// });
  };

  return (
    <>
      <Header
        menuOpen={menuOpen}
        onMenuClick={handleMenuClick}
        onSidedrawerNavbarLinkClick={handleSidedrawerNavbarLinkClick}
        onOverlayClick={handleOverlayClick}
      />
      <Switch>
        <Route
          path="/buy"
          render={(props) => (
            <Shopping {...props} handleCheckoutClick={handleCheckoutClick} />
          )}
        />
        <Route path="/registerLogin" component={LoginForm} />
        <Route path="/register" component={RegisterForm} />
      </Switch>
    </>
  );
};

export default App;

client/src/components/stateSlices/paymentSlice.js

import { createSlice,createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";

const initialState = {
  status: "idle",session: null,error: null,};

export const fetchCheckoutSession = createAsyncThunk(
  "payment/fetchCheckoutSession",async (token,{ rejectWithValue }) => {
    const config = {
      headers: {
        "Content-Type": "application/json",Authorization: `Bearer ${token}`,},};

    try {
      const { data } = await axios.post(
        "/api/payment/checkout-session",config
      );
      return data;
    } catch (err) {
      return rejectWithValue(err.response.data);
    }
  }
);

export const paymentSlice = createSlice({
  name: "payment",initialState,reducers: {},extraReducers: {
    [fetchCheckoutSession.pending]: (state,action) => {
      state.status = "loading";
    },[fetchCheckoutSession.fulfilled]: (state,action) => {
      state.status = "succeeded";
      state.session = action.payload;
    },[fetchCheckoutSession.rejected]: (state,action) => {
      state.status = "Failed";
      state.error = action.payload.message;
    },});

export default paymentSlice.reducer;

server/routes/paymentRoutes.js

const express = require("express");
const asyncHandler = require("express-async-handler");
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);

const router = express.Router();

const YOUR_DOMAIN = "http://localhost:3000/";

router.post(
  "/checkout-session",asyncHandler(async (req,res,next) => {
    const session = await stripe.checkout.sessions.create({
      payment_method_types: ["card"],line_items: [
        {
          price_data: {
            currency: "INR",product_data: {
              name: "Vase",images: ["https://i.imgur.com/EHyR2nP.png"],unit_amount: 70000,quantity: 1,],mode: "payment",success_url: `${YOUR_DOMAIN}?success=true`,cancel_url: `${YOUR_DOMAIN}?canceled=true`,});
    res.json({ id: session.id });
  })
);

module.exports = router;

GITHUB 仓库:https://github.com/sundaray/stripe-payment

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。