Stripe中没有return_url参数如何显示支付成功

Mik*_*995 5 stripe-payments

我在将 Stripe 集成到我的 React 应用程序中时遇到一个问题。我使用 Stripe 官方文档中的代码。它按预期工作。我的问题是如何在不使用 return_url 的情况下检查付款是否成功?我需要使用返回网址吗?我在 Stripe 文档中找到了重定向:“if_required”选项,但这没有任何作用。如果我将此对象放入confirmPayment 方法中,我只会在控制台中出现错误问题。我希望场景是付款成功,客户端导航到某个确认页面并成功获取消息付款。

\n

应用程序.jsx

\n
import { loadStripe } from "@stripe/stripe-js";\nimport { Elements } from "@stripe/react-stripe-js";\n\nimport CheckoutForm from "./CheckoutForm";\nimport "./App.css";\n\n// Make sure to call loadStripe outside of a component\xe2\x80\x99s render to avoid\n// recreating the Stripe object on every render.\n// This is your test publishable API key.\nconst stripePromise = loadStripe("pk_test_51LmE9VAoYs2flpvClDqeh0f1vhaDUkBM0bRGaJgThjtaMd3PiPUGQOHjn9f7XW1HGgSQBvTq3xoLy9PovlWLPUnR0031srjgyb");\n\nexport default function App() {\n  const [clientSecret, setClientSecret] = useState("");\n\n  useEffect(() => {\n    // Create PaymentIntent as soon as the page loads\n    fetch("/create-payment-intent", {\n      method: "POST",\n      headers: { "Content-Type": "application/json" },\n      body: JSON.stringify({ items: [{ id: "xl-tshirt" }] }),\n    })\n      .then((res) => res.json())\n      .then((data) => setClientSecret(data.clientSecret));\n  }, []);\n\n  const appearance = {\n    theme: 'stripe',\n  };\n  const options = {\n    clientSecret,\n    appearance,\n  };\n\n  return (\n    <div className="App">\n      {clientSecret && (\n        <Elements options={options} stripe={stripePromise}>\n          <CheckoutForm />\n        </Elements>\n      )}\n    </div>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n

结账表格.jsx

\n
import {\n  PaymentElement,\n  useStripe,\n  useElements\n} from "@stripe/react-stripe-js";\n\nexport default function CheckoutForm() {\n  const stripe = useStripe();\n  const elements = useElements();\n\n  const [message, setMessage] = useState(null);\n  const [isLoading, setIsLoading] = useState(false);\n\n  useEffect(() => {\n    if (!stripe) {\n      return;\n    }\n\n    const clientSecret = new URLSearchParams(window.location.search).get(\n      "payment_intent_client_secret"\n    );\n\n    if (!clientSecret) {\n      return;\n    }\n\n    stripe.retrievePaymentIntent(clientSecret).then(({ paymentIntent }) => {\n      switch (paymentIntent.status) {\n        case "succeeded":\n          setMessage("Payment succeeded!");\n          break;\n        case "processing":\n          setMessage("Your payment is processing.");\n          break;\n        case "requires_payment_method":\n          setMessage("Your payment was not successful, please try again.");\n          break;\n        default:\n          setMessage("Something went wrong.");\n          break;\n      }\n    });\n  }, [stripe]);\n\n  const handleSubmit = async (e) => {\n    e.preventDefault();\n\n    if (!stripe || !elements) {\n      // Stripe.js has not yet loaded.\n      // Make sure to disable form submission until Stripe.js has loaded.\n      return;\n    }\n\n    setIsLoading(true);\n\n    const { error } = await stripe.confirmPayment({\n      elements,\n      confirmParams: {\n        // Make sure to change this to your payment completion page\n        return_url: "http://localhost:3000",\n      },\n    });\n\n    // This point will only be reached if there is an immediate error when\n    // confirming the payment. Otherwise, your customer will be redirected to\n    // your `return_url`. For some payment methods like iDEAL, your customer will\n    // be redirected to an intermediate site first to authorize the payment, then\n    // redirected to the `return_url`.\n    if (error.type === "card_error" || error.type === "validation_error") {\n      setMessage(error.message);\n    } else {\n      setMessage("An unexpected error occurred.");\n    }\n\n    setIsLoading(false);\n  };\n\n  return (\n    <form id="payment-form" onSubmit={handleSubmit}>\n      <PaymentElement id="payment-element" />\n      <button disabled={isLoading || !stripe || !elements} id="submit">\n        <span id="button-text">\n          {isLoading ? <div className="spinner" id="spinner"></div> : "Pay now"}\n        </span>\n      </button>\n      {/* Show any error or success messages */}\n      {message && <div id="payment-message">{message}</div>}\n    </form>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n

小智 6

当使用 时redirect: 'if_required',return_url 属性就变得不需要了。

如果不需要重定向,则需要等待方法的确认stripe.confirmPayment并检查响应中是否有错误。

为此,您可以调整CheckoutForm.jsx文件并调整函数handleSubmit,如下所示:


setIsLoading(true);

const response = await stripe.confirmPayment({
 elements,
 confirmParams: {
  },
 redirect: 'if_required'
});

if (response.error) {
 showMessage(response.error.message);
} else {
 showMessage(`Payment Succeeded: ${response.paymentIntent.id}`);
}

setIsLoading(false);

Run Code Online (Sandbox Code Playgroud)

此外,如果您想在付款成功时收到后端通知,您可以设置一个 webhook[1] 并监听此 Stripe 事件payment_intent.succeeded[2]

[1] https://stripe.com/docs/webhooks

[2] https://stripe.com/docs/api/events/types#event_types- payment_intent.succeeded