好的。所以。我正在使用 Next.js(版本 13.4)和 React 构建一个简单的电子商务网站;我正在使用应用程序路由器和服务器操作。
我已成功集成 PayPal SDK 进行支付。现在,我使用react-paypal-js 在前端渲染按钮,并在
actions
文件夹中定义 createOrder 和 onApprove 函数(因此它们是服务器操作,而不是路由)。我的想法是,根据 Next.js,在服务器或服务器组件中获取/发布数据,这样可以使敏感数据(如 API 密钥)远离浏览器。
但是,
PayPalScriptProvider
必须在客户端组件中使用,而且我必须传递初始选项; clientId 包含在这些选项中。这本质上暴露了我的 Paypal_Client_Id
环境变量
理想情况下,我想对浏览器保密
Paypal_Client_Id
,但我不确定这是否可行。我尝试在服务器组件中定义我的initialOptions并将其作为道具传递给客户端组件,但客户端中的控制台日志仍然显示Paypal_Client_Id
。因此,我希望对这两件事中的任何一件事有想法:
暴露 PayPal 客户 ID 有多重要?就像,有人有了身份证,现在我的生活将被完全毁了,或者更像是有人只是想用我的身份证进入酒吧?
关于如何防止我的客户 ID 在前端暴露有什么想法吗?也许是一个route.ts 文件?但即使在这种情况下,PayPalScriptProvider 也必须在客户端组件中使用,并且它需要这些初始选项。
这是我的文件,供参考,但我不确定您是否需要查看它们来解决问题。到目前为止,这只是简单的框架,目前有很多控制台日志记录错误:
app>cart>page.tsx:...就像我说的,我尝试将环境变量从 SC 传递到客户端组件,所以这是服务器组件
import CartPay from "./CartPay";
export default function Cart() {
const client = process.env.PAYPAL_CLIENT_ID || "";
console.log(client) //logs on the server, not on the client
const initialOptions = {
clientId: client,
currency: "USD",
intent: "capture",
};
return (
<CartPay initialOptions={initialOptions}/>
);
}
这是 CartPay.tsx:
'use client'
import React from 'react'
import { useCart } from "../components/CartContext";
import Product from "../products/[id]/Product";
import { PayPalButtons, PayPalScriptProvider } from '@paypal/react-paypal-js';
import { createOrder, payOrder } from '../actions';
interface CartPayProps {
initialOptions: {
clientId: string,
currency: string,
intent: string
}
}
const CartPay = ({initialOptions} : CartPayProps) => {
console.log(initialOptions) //logs the client id and other information in browser
const {state} = useCart();
const {cart} = state
return (
<PayPalScriptProvider options={initialOptions}>
<div>
{cart.map((item) => (
<Product key={item.id} product={item} />
))}
</div>
<div>
<PayPalButtons
createOrder={async (data, actions) => {
let response = await createOrder();
if (response.success === "true") {
return response.orderId; //success
} else {
// error from createOrder function
console.error("Error creating order:", response.error);
return undefined; // undefined if createOrder failed
}
}}
onApprove={async (data, actions) => {
let response = await payOrder(data.orderID);
if (response && response.success === "true") {
console.log("Payment successful");
} else {
console.error("Payment failed:", response.error);
}
}}
/>
</div>
</PayPalScriptProvider>
);
}
export default CartPay
所有 PayPal JS SDK 集成都使用 client-id 作为必需参数。
没有客户端 ID 就无法集成它们。也没有理由。
浏览器中应保留的值是 REST 应用程序的
secret
。