You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Stripe支付网关测试邮编咨询及incomplete_zip错误解决求助

Stripe incomplete_zip 错误解决及测试邮政编码

一、官方测试邮政编码

Stripe提供的测试邮政编码覆盖不同地区,常用的有:

  • 美国:90210、12345
  • 加拿大:A1A 1A1
  • 英国:SW1A 1AA
  • 澳大利亚:2000

这些邮编在测试环境下均可通过Stripe验证,不会触发incomplete_zip错误。

二、incomplete_zip 错误解决方法

1. 补充支付方法的账单地址信息

你的代码调用stripe.confirmCardPayment时,仅传入了card元素,部分地区的支付验证需要邮编等账单地址信息。需在payment_method中添加billing_details:

修改handleSubmit中的confirmCardPayment片段:

const result = await stripe.confirmCardPayment(clientSecret, {
  payment_method: {
    card: elements.getElement(CardElement),
    billing_details: {
      address: {
        postal_code: "90210" // 测试环境用上述测试邮编,生产环境替换为用户输入值
      }
    }
  },
});

2. 添加用户输入的邮编字段

若需用户自行提供邮编,可在表单中添加输入框,收集后传入验证逻辑:

// 组件内新增状态管理邮编
const [postalCode, setPostalCode] = useState("");

// 表单中添加邮编输入框
<input
  type="text"
  value={postalCode}
  onChange={(e) => setPostalCode(e.target.value)}
  placeholder="邮政编码"
  className="mt-3 p-2 border rounded-lg w-full"
/>

// 验证时使用用户输入的邮编
billing_details: {
  address: {
    postal_code: postalCode
  }
}

3. 启用CardElement的邮编收集功能

如果希望CardElement自动包含邮编输入框,可修改配置:

const DARK_CARD_OPTIONS = {
  iconStyle: "solid",
  style: { /* 原有样式配置 */ },
  fields: {
    postalCode: "always" // 强制显示邮编输入区域
  }
};

4. 修正原代码的变量错误

原代码中await processPayment(paymentIntent.id)存在未定义变量问题,paymentIntent并未声明,应改为使用返回的data.id:

// 支付成功后的处理
await processPayment(data.id);

三、修改后的完整组件片段

import React, { useState } from "react";
import { CardElement, useStripe, useElements } from "@stripe/react-stripe-js";
import axios from "axios";

function Payment({ planDetails }) {
  const { price } = planDetails;
  const stripe = useStripe();
  const elements = useElements();
  const [loading, setLoading] = useState(false);
  const [postalCode, setPostalCode] = useState("");

  const handleSubmit = async (e) => {
    e.preventDefault();

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

    setLoading(true);

    try {
      const data = await createPaymentIntent();
      const clientSecret = data.client_secret;

      const result = await stripe.confirmCardPayment(clientSecret, {
        payment_method: {
          card: elements.getElement(CardElement),
          billing_details: {
            address: {
              postal_code: postalCode
            }
          }
        },
      });

      if (result.error) {
        console.error(result.error);
        setLoading(false);
      } else {
        await processPayment(data.id);
        // 支付成功后的跳转或提示逻辑
      }
    } catch (error) {
      console.error(error);
      setLoading(false);
    }
  };

  const createPaymentIntent = async () => {
    try {
      const response = await axios.post("/member/create-payment-intent", {
        amount: price,
      });

      if (response.data.paymentIntent) {
        return response.data.paymentIntent;
      } else {
        throw new Error("PaymentIntent not found in the response");
      }
    } catch (error) {
      console.error("Error creating payment intent:", error);
      throw error;
    }
  };

  const processPayment = async (paymentIntentId) => {
    try {
      const response = await axios.post("/member/process-payment", {
        paymentIntentId,
      });

      return response.data;
    } catch (error) {
      throw error;
    }
  };

  const DARK_CARD_OPTIONS = {
    iconStyle: "solid",
    style: {
      base: {
        iconColor: "#6D28D9",
        color: "black",
        fontWeight: "500",
        fontFamily: "Roboto, Open Sans, Segoe UI, sans-serif",
        fontSize: "16px",
        fontSmoothing: "antialiased",
        ":-webkit-autofill": {
          color: "#fce883",
        },
        "::placeholder": {
          color: "#D1D5DB",
        },
      },
      invalid: {
        iconColor: "#ef2961",
        color: "#ef2961",
      },
    },
  };

  return (
    <div className="container mt-5 rounded-lg mx-auto my-auto h-screen">
      <div className="p-4 rounded-lg border border-gray-800 dark:border-gray-600 focus:border-purple-700">
        <form onSubmit={handleSubmit}>
          <CardElement options={DARK_CARD_OPTIONS} />
          <input
            type="text"
            value={postalCode}
            onChange={(e) => setPostalCode(e.target.value)}
            placeholder="请输入邮政编码"
            className="mt-3 p-2 border rounded-lg w-full"
          />
          <div className="mt-2 d-block">
            <button
              type="submit"
              disabled={loading}
              className="bg-theme-orange block w-full text-white border rounded-lg p-5"
            >
              {loading ? "Processing..." : "Pay Now"}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}

export default Payment;

内容的提问来源于stack exchange,提问作者Hassan Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 21:24:57