Next.js 13.4.1集成Paddle.js调用checkout.open时出现CORS错误
Next.js 13.4.1集成Paddle.js调用checkout.open时出现CORS错误
看起来你遇到的CORS错误其实是请求路径错误导致404的次生问题——先看报错里的请求URL,product/undefined这部分说明Paddle在生成结账请求时,没有拿到有效的价格ID,导致请求了一个不存在的资源,而Paddle的404响应没有携带跨域允许的头,才触发了浏览器的CORS报错。咱们一步步来排查解决:
第一步:先确认price_id的有效性
你调用openCheckout(offer.price_id)时,offer.price_id可能是undefined或者无效值,这是核心问题。先在代码里加日志验证:
const openCheckout = (price_id: string) => { console.log("当前传入的price_id:", price_id); if (!price_id) { console.error("price_id为空或未定义!"); return; } paddle.Checkout.open({ settings: { theme: 'dark' }, items: [ { price_id, quantity: 1 } ] }) }
检查控制台输出:
- 要确保
price_id是Paddle沙箱后台生成的有效格式(比如pri_xxxxxxxxxxxx) - 沙箱环境的price_id和生产环境不通用,别搞混了
第二步:确保Paddle完全初始化后再调用结账
Next.js的Script组件加载是异步的,可能存在你点击按钮时Paddle还没完成初始化的情况。可以给Provider加个加载状态,避免提前调用:
修改PaddleProvider:
'use client' import { createContext, useState } from 'react' import Script from 'next/script' import { getNodeEnv } from '@/utils/getNodeEnv' import { vendor_id } from '@/helpers/APIs/paddle/config' type PaddleContext = { paddle: any | null; isLoaded: boolean; } const PaddleContext = createContext<PaddleContext>({ paddle: null, isLoaded: false }) type Props = { children: React.ReactNode } const PaddleProvider: React.FC<Props> = ({ children }) => { const [paddle, setPaddle] = useState<any>(null) const [isLoaded, setIsLoaded] = useState(false) const initializePaddle = () => { if (getNodeEnv() !== 'prod') Paddle.Environment.set("sandbox") Paddle.Setup({ vendor: Number(vendor_id), }) setPaddle(Paddle) setIsLoaded(true) } return ( <PaddleContext.Provider value={{ paddle, isLoaded }}> <Script src="https://cdn.paddle.com/paddle/paddle.js" onLoad={initializePaddle} /> { children } </PaddleContext.Provider> ) } export { PaddleProvider, PaddleContext }
然后在OfferOption组件里,只有加载完成才渲染可点击的按钮:
const OfferOption: React.FC<Props> = ({ offer }) => { const { paddle, isLoaded } = usePaddleContext() const openCheckout = (price_id: string) => { if (!price_id || !paddle) return; paddle.Checkout.open({ settings: { theme: 'dark' }, items: [ { price_id, quantity: 1 } ] }) } if (!isLoaded) { return <button disabled>加载中...</button>; } return ( <button type='button' onClick={() => openCheckout(offer.price_id)} {/* 其他样式属性 */} > 打开结账页面 </button> ) }
第三步:验证vendor_id和环境匹配
确认vendor_id是沙箱环境的ID——登录Paddle沙箱后台查看你的vendor ID,别用生产环境的ID在沙箱里测试,否则也会出现资源找不到的问题。
关于你问的几个额外问题:
- 要不要给Next.js加请求头? 不需要,因为请求是Paddle的脚本发起的,不是你的Next.js服务器发起的,配置Next.js的CORS头对这个场景没用。
- 代理有用吗? 没用,同样因为请求不是你的前端或服务器发起的,代理解决不了Paddle内部请求的问题。
只要解决了price_id无效或Paddle未初始化完成的问题,那个CORS报错会自动消失——毕竟它只是404带来的附属问题。
备注:内容来源于stack exchange,提问作者kroflic
相关产品推荐
相关产品推荐

