stripe Element 如何使用

在这里插入图片描述
这里要准备好几个东西:

一个支付成功过后的回调

还有一个下单的接口

一旦进入这个下单界面,就要去调下单的接口的,用 post,

这个 接口你自己写,可以写在后端中,也可以放到 nextjs 的 api 中。

首先说的是这个下单接口

可以这样写:

import { NextRequest, NextResponse } from "next/server";
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);

export async function POST(request: NextRequest) {
  try {
    const { amount } = await request.json();

    const paymentIntent = await stripe.paymentIntents.create({
      amount: amount,
      currency: "usd",
      automatic_payment_methods: { enabled: true },
    });

    return NextResponse.json({ clientSecret: paymentIntent.client_secret });
  } catch (error) {
    console.error("Internal Error:", error);
    // Handle other errors (e.g., network issues, parsing errors)
    return NextResponse.json(
      { error: `Internal Server Error: ${error}` },
      { status: 500 }
    );
  }
}

这个东西一般是放后端,因为有个 secrets key,原则 nextjs 的 api 也算是后端。

要传入的参数呢,只有一个是金额,一个是 secret key ,

返回的信息是给前端用的,一个 client secret key.

可以理解为一个通用凭证。

前端怎么利用这个 key 。

    const { error } = await stripe.confirmPayment({
      elements,
      clientSecret,
      confirmParams: {
        return_url: `http://www.localhost:3000/payment-success?amount=${amount}`,
      },
    });

这个 elements 是 stripe 自带的,要利用到里面的一些组件,比如你开了 wechat 就要自动显示。

而不是自己写页面。

clientSecret 这个 client key 就是从后端返回的。

大约就是这样简单,最后这个 return url 中的。

我不太清楚,这样的话,还需要 webhook 吗,还需要去验证。

整个表单的代码我放一下:

"use client";

import React, { useEffect, useState } from "react";
import {
  useStripe,
  useElements,
  PaymentElement,
} from "@stripe/react-stripe-js";
import convertToSubcurrency from "@/lib/convertToSubcurrency";

const CheckoutPage = ({ amount }: { amount: number }) => {
  const stripe = useStripe();
  const elements = useElements();
  const [errorMessage, setErrorMessage] = useState<string>();
  const [clientSecret, setClientSecret] = useState("");
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    fetch("/api/create-payment-intent", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ amount: convertToSubcurrency(amount) }),
    })
      .then((res) => res.json())
      .then((data) => setClientSecret(data.clientSecret));
  }, [amount]);

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setLoading(true);

    if (!stripe || !elements) {
      return;
    }

    const { error: submitError } = await elements.submit();

    if (submitError) {
      setErrorMessage(submitError.message);
      setLoading(false);
      return;
    }

    const { error } = await stripe.confirmPayment({
      elements,
      clientSecret,
      confirmParams: {
        return_url: `http://www.localhost:3000/payment-success?amount=${amount}`,
      },
    });

    if (error) {
      // This point is only reached if there's an immediate error when
      // confirming the payment. Show the error to your customer (for example, payment details incomplete)
      setErrorMessage(error.message);
    } else {
      // The payment UI automatically closes with a success animation.
      // Your customer is redirected to your `return_url`.
    }

    setLoading(false);
  };

  if (!clientSecret || !stripe || !elements) {
    return (
      <div className="flex items-center justify-center">
        <div
          className="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-e-transparent align-[-0.125em] text-surface motion-reduce:animate-[spin_1.5s_linear_infinite] dark:text-white"
          role="status"
        >
          <span className="!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]">
            Loading...
          </span>
        </div>
      </div>
    );
  }

  return (
    <form onSubmit={handleSubmit} className="bg-white p-2 rounded-md">
      {clientSecret && <PaymentElement />}

      {errorMessage && <div>{errorMessage}</div>}

      <button
        disabled={!stripe || loading}
        className="text-white w-full p-5 bg-black mt-2 rounded-md font-bold disabled:opacity-50 disabled:animate-pulse"
      >
        {!loading ? `Pay $${amount}` : "Processing..."}
      </button>
    </form>
  );
};

export default CheckoutPage;

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
如何实现表格分页和排序功能? 很高兴回答这个问题!在Vue2.0中使用Element UI实现表格分页和排序功能非常简单。首先,我们需要引入Element UI组件和相关的样式文件。然后,在Vue组件的template中使用el-table标签来创建表格,同时指定数据的来源和表格列的定义。为了启用分页和排序功能,我们可以在el-table组件上使用属性,例如: :columns="tableColumns" //指定表格列的定义 :data="tableData" //指定数据的来源 :height="tableHeight" //设置表格的高度 :stripe="true" //开启斑马纹 :border="true" //添加表格边框 :pagination="true" //启用分页功能 :page-size="pageSize" //设置每页显示的记录数 :current-page="currentPage" //设置当前页码 :sort-by="sortKey" //设置排序的字段 :sort-order="sortOrder" //设置排序的顺序 在Vue组件的script中,我们需要定义tableColumns和tableData变量,分别用来指定表格列的定义和数据的来源。我们还需要定义pageSize、currentPage、sortKey和sortOrder变量,分别用来设置每页显示的记录数、当前页码、排序的字段和排序的顺序。最后,我们可以使用methods选项来定义相关的函数,例如: handleSortChange(column){ if(column.order === "ascending"){ this.sortOrder = "asc"; }else if(column.order === "descending"){ this.sortOrder = "desc"; }else{ this.sortOrder = ""; } this.sortKey = column.prop; this.fetchData(); //重新获取数据 }, handleCurrentChange(currentPage){ this.currentPage = currentPage; this.fetchData(); //重新获取数据 } 以上是一些简单的示例代码,用来演示如何使用Vue2.0和Element UI实现表格分页和排序功能。希望能够对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员随风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值