【问题标题】:React (frontend) + Express (backend) + Stripe integrationReact(前端)+ Express(后端)+ Stripe 集成
【发布时间】:2022-10-24 07:14:37
【问题描述】:

我正在尝试在我的网络应用程序中实现条带化。我已经集成了条带结帐并且它可以工作,但是我需要在前端处理一些逻辑。我已经使用以前版本的 Stripe 完成了它,但现在似乎已弃用。

基本上我需要的是如果付款成功,做其他事情不要做。(我知道如何实现这个逻辑)

我不知道付款成功后如何从后端向前端发送响应。

我读过关于网络套接字或类似的东西,但我不太熟悉,而且我的时间有限。如果可能的话,我宁愿避开它们。

这就是我为已弃用的版本所做的,但现在我无法使用最新的条带结帐版本来做到这一点。

如果不清楚,我是初学者对不起。

谢谢

async function handleToken(token, addresses) {
    const response = await axios.post(
        "https://btycwse.codesandbox.io/checkout",
      { token, product }
    );
    const { status } = response.data;
    
    console.log("Response:", response.data);
    if (status === "success") {
      console.log("Success! Check email for details");
      handleSubmit();
    } else {
      console.log("Something went wrong");
    }
  }

后端(express.js)

// This is your test secret API key.
const stripe = require('stripe')('sk_test');
const express = require('express');
const app = express();

app.use(express.json())

const cors = require("cors")
app.use(
  cors({
    origin: "http://localhost:3000",
    
  })
)

const storeItems = new Map([
  [1, { priceInCents: 10000, name: "JavaScript Tutorial" }],
  [2, { priceInCents: 15000, name: "Ultimate CSS tutorial" }],
])

app.get("/", (req, res) => {
  res.send("Add your Stripe Secret Key to the .require('stripe') statement!");
});

app.post("/checkout", async (req, res) => {
  try {
    // Create a checkout session with Stripe
    const session = await stripe.checkout.sessions.create({
      payment_method_types: ["card"],
      mode: "payment",
      // For each item use the id to get it's details
      // Take that information and convert it to Stripe's format
      line_items: req.body.items.map(({ id, quantity }) => {
        const storeItem = storeItems.get(id)
        return {
            price_data: {
            currency: "usd",
            product_data: {
              name: storeItem.name,
            },
            unit_amount: storeItem.priceInCents,
          },
          quantity: quantity,
        }
      }),
      // Set a success and cancel URL we will send customers to
      // They are complete urls
      success_url: "http://localhost:3000/success.html",
      cancel_url: "http://localhost:3000//cancel.html",
    })

    res.json({ url: session.url })

  } catch (e) {
    // If there is an error send it to the client
    res.status(500).json({ error: e.message })
   
  }
})

const bodyParser = require('body-parser');

app.post('/webhook', bodyParser.raw({type: 'application/json'}), (request, response) => {
  const event = request.body;

  // Handle the event
  switch (event.type) {
    case 'payment_intent.succeeded':
      const paymentIntent = event.data.object;
      // Then define and call a method to handle the successful payment intent.
      // handlePaymentIntentSucceeded(paymentIntent);
      break;
    case 'payment_method.attached':
      const paymentMethod = event.data.object;
      // Then define and call a method to handle the successful attachment of a PaymentMethod.
      // handlePaymentMethodAttached(paymentMethod);
      break;
    // ... handle other event types
    default:
      console.log(`Unhandled event type ${event.type}`);
  }

  // Return a response to acknowledge receipt of the event
  response.json({received: true});
});


app.listen(4242, () => console.log('Running on port 4242'));

前端(ReactJS)

import React from "react";
import "./App.css";


export default function App() {



const handleCheckout = () => {
  fetch("http://localhost:4242/checkout", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    // Send along all the information about the items
    body: JSON.stringify({
      items: [
        {
          id: 1,
          quantity: 5,
        },
        {
          id: 2,
          quantity: 2,
        },
      ],
    }),
  })
   .then(res => {
      if (res.ok) return res.json()
      // If there is an error then make sure we catch that
      return res.json().then(json => Promise.reject
        (json))
    })
    .then(({ url }) => {
    
      // On success redirect the customer to the returned URL
      window.location = url
    })
    .catch(e => {
      console.log(e.error)
      
    })
  }

  return (
    <>
    
     <button type="submit" onClick={handleCheckout}>Checkout</button>
 
    </>

  );
}

【问题讨论】:

    标签: javascript node.js reactjs express stripe-payments


    【解决方案1】:

    我的建议是实现一个 webhook here

    在php中

    switch($payload){
      case 'invoice.paid':
    
      $a = $event->data->object;
        // do stuff e.g. 'talk' to your db, emails
      break;
      default:
           $body['eventDefaulted'] = 'Received unknown event type ' . $event->type;
      break;
     }
    

    添加(以确保它不会超时,并且条带将在脚本的开头抛出错误)

    // respond to stripe otherwise timeout
    // Buffer all upcoming output...
    
    // Send your response.
    
    echo "recieved $event->type";
    
    // // Get the size of the output.
    
    $size = ob_get_length();
    
    // // // Disable compression (in case content length is compressed).
    
    header("Content-Encoding: none");
    
    // // Set the content length of the response.
    
    header("Content-Length: {$size}");
    header($_SERVER["SERVER_PROTOCOL"] . " 200 OK");
    header("HTTP/1.1 200 OK");
    http_response_code(200);
    
    // // Close the connection.
    
    header("Connection: close");
    
    // // // Flush all output.
    
    ob_end_flush();
    ob_flush();
    flush();
    

    api docs

    然后使用 api 与您联系数据库以获取发票详细信息

    【讨论】:

    • 谢谢!我无法让它工作。对我来说有点复杂
    【解决方案2】:

    根据您的假设,除非您使用某些 WebSocket,否则无法从后端向前端发送请求。最封闭的方法是:

    1. 实施 webhook 以侦听来自 Stripe 的最新事件(您已经在这样做)并将它们保存到您的数据库中。
    2. 在您的重定向成功 url (http://localhost:3000/success.html) 中,从前端向后端发送 AJAX 请求,并在步骤 1 中从您的数据库中检索最新数据。

    【讨论】:

    • 惊人的 !谢谢!因为我刚刚创建了这个帐户,所以我无法投票,但谢谢
    猜你喜欢
    • 2020-12-03
    • 2020-07-15
    • 2018-05-16
    • 2018-11-14
    • 2017-09-24
    • 2021-10-22
    • 2023-03-15
    • 1970-01-01
    • 2019-04-15
    相关资源
    最近更新 更多