在条纹中添加自己的 CardHolder 名称

Adding own CardHolder name in stripe

所以我面临的问题是这样的。在这里,我使用 Stripe 创建了 PaymentForm。因此,当我没有输入 CardHolder 名称的输入值时,当我按下 Purchase 按钮​​时,它应该显示 <h1>Please enter your cardholder name</h1> 但它没有这样做。我已经创建了自己的 CardHolder 名称。我知道 Stripe Elements 没有那个部分。我认为错误位于 CardHolder if Condition of handleSumbit.

import React,{useContext, useEffect, useState} from 'react'
import {CardElement, useStripe, useElements } from"@stripe/react-stripe-js"
import { CartContext } from '../../context/cart'

import {  useHistory, Link } from "react-router-dom";



const PaymentForm = () => {
  const { total} = useContext(CartContext)
  const {cart, cartItems}= useContext(CartContext)
  const history = useHistory()
  const {clearCart} = useContext(CartContext)
  const [nameError, setNameError]=useState(null)
  const [name, setName] = React.useState("");
  const [succeeded, setSucceeded] = useState(false);
  const [error, setError] = useState(null);
  const [processing, setProcessing] = useState('');
  const [disabled, setDisabled] = useState(true);
  const [clientSecret, setClientSecret] = useState('');
  const stripe = useStripe();
  const elements = useElements();
  useEffect(() => {
    // Create PaymentIntent as soon as the page loads
    window
      .fetch("http://localhost:5000/create-payment-intent", {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify({items: [{cart}]})
      })
      .then(res => {
        return res.json();
      })
      .then(data => {
        setClientSecret(data.clientSecret);
      });
  }, [cart]);
  const cardStyle = {
    style: {
      base: {
        color: "#32325d",
        fontFamily: 'Arial, sans-serif',
        fontSmoothing: "antialiased",
        fontSize: "16px",
        "::placeholder": {
          color: "#32325d"
        }
      },
      invalid: {
        color: "#fa755a",
        iconColor: "#fa755a"
      }
    }
  };
  const handleChange = async (event) => {
    setDisabled(event.empty);
    setError(event.error ? event.error.message : "");
  };

  const handleChangeInput = async (event) => {
    const { value } = event.target;
    setDisabled(!value); 
    setNameError(value ? "" : "Please enter a name");
    setName(value)
  };

  const handleSubmit = async ev => {
    ev.preventDefault();
    setProcessing(true);
    const payload = await stripe.confirmCardPayment(clientSecret, {
      payment_method: {
        card: elements.getElement(CardElement),
        billing_details: {
          name: 'Jenny Rosen',
        },
      }
    });
     
    /*cardHolder */
    if (name.length >0 ){
      stripe
      .confirmCardPayment()
    }else{
      setNameError(null)
    }

    if (payload.error) {
      setError(`Payment failed ${payload.error.message}`);
      setProcessing(false);
    } else {
      setError(null);     
      setProcessing(false);
      setSucceeded(true)
      clearCart()
    }
  };  
  useEffect(()=>{
    setTimeout(() => {  
    if(succeeded){
      history.push('/')
    }
    }, 3000);
  },[history, succeeded])
 
console.log(name)
 
  return (
    <form id="payment-form" onSubmit={handleSubmit}>
      <h2>Checkout</h2>
      <div className='payment__cont'>
       <label>Cardholder Name </label>
       <input 
        placeholder='Please enter your Cardholder name'
        type="text"
        id="name"
        value={name}
        onChange={handleChangeInput}
         />
      </div>
      <div className="stripe-input">
          <label htmlFor="card-element">
            Credit or Debit Card
            </label>
          <p className="stripe-info">
            Test using this credit card : <span>4242 4242 4242 4242</span>
            <br />
            enter any 5 digits for the zip code
            <br />
            enter any 3 digits for the CVC
          </p>
        </div>
        
    <CardElement id="card-element" options={cardStyle} onChange={handleChange} />

      <div className='review__order'>
      <h2>Review Order</h2>
      <h4>Total amount to pay ${total}</h4>
      <h4>Total amount of items {cartItems}</h4>
      <button
        className='purchase__button'
        disabled={processing || disabled || succeeded}
        id="submit"
      >     
        <span id="button-text">
          {processing ? (
            <div className="spinner" id="spinner"></div>
          ) : (
            "Complete purchase"
          )}
        </span>
      </button>
      <button className='edit__button'onClick={()=> {history.push('/cart')}}>Edit Items</button>
      </div>
      {error && (
        <div className="card-error" role="alert">
          {error}
        </div>
      )}
     {nameError && (
        <div className="card-error" role="alert">
          <h1>Please enter a card holder name</h1>
        </div>
      )}
      <p className={succeeded  ? "result-message" : "result-message hidden"}>
        Payment succeeded        
          {''}
          <h1>Redirecting you yo the home</h1>
      </p>
  
    </form>
  );
}



export default PaymentForm

您需要检查 name 状态是否已设置,如果已设置,则继续付款。现在,您的 handleSubmit() 函数根本不检查 name,或者在 confirmCardPayment() Stripe API 调用中传递它。

您的 handleSubmit() 函数应如下所示:

const handleSubmit = async ev => {
    ev.preventDefault();
    setProcessing(true);
     
    /* check for `name` being set */
    if (name.length > 0 ) {
     // if name is set, call `confirmCardPayment()` and pass `name`
      
      const payload = await stripe.confirmCardPayment(clientSecret, {
        payment_method: {
          card: elements.getElement(CardElement),
          billing_details: {
            name: name,
          },
        }
      });

      // check `payload` for PaymentIntent status, or error
    }
    else {
      setNameError("please enter a card holder name")
    }

    // ... everything else
  };