如何通过Shopify Checkout Extensions在感谢页获取订单ID或结账令牌
我正在使用Shopify Checkout UI Extensions和React在结账感谢页添加「您是如何了解到我们的」表单,已实现表单渲染及提交值获取,但需要将表单响应与订单ID或结账ID/令牌关联。已知结账扩展运行在Web Worker中,无法访问checkout_token本地存储或订单数据,请问如何获取这些数据,并将其存储到自有数据库或理想情况下的订单元字段中?
import { reactExtension, BlockStack, View, Heading, Text, ChoiceList, Choice, Button, useStorage, TextField, useStorageState, // 注意:原代码未导入此hook,需补充 } from '@shopify/ui-extensions-react/checkout'; import {useCallback, useEffect, useState} from 'react'; // 允许归因调查显示在感谢页 const thankYouBlock = reactExtension("purchase.thank-you.block.render", () => <Attribution />); export { thankYouBlock }; const orderDetailsBlock = reactExtension("customer-account.order-status.block.render", () => <ProductReview />); export { orderDetailsBlock }; function Attribution() { const [attribution, setAttribution] = useState(''); const [loading, setLoading] = useState(false); // 存储用户是否已提交归因调查 const [attributionSubmitted, setAttributionSubmitted] = useStorageState('attribution-submitted') async function handleSubmit() { // 模拟服务器请求 setLoading(true); return new Promise((resolve) => { setTimeout(() => { console.log('Submitted:', attribution); setLoading(false); setAttributionSubmitted(true) resolve(); }, 750)}); } // 如果已提交,隐藏调查 if (attributionSubmitted.loading || attributionSubmitted.data === true) { return null; } return ( <Survey title="How did you hear about us ?" onSubmit={handleSubmit} loading={loading}> <TextField name="sale-attribution" value={attribution} onChange={setAttribution} /> </Survey> ); }
一、获取订单/结账ID
Shopify Checkout UI Extensions提供了内置的useExtensionApi hook,可直接在感谢页扩展中获取订单和结账的核心数据,无需依赖本地存储:
- 首先导入
useExtensionApi:
import { useExtensionApi } from '@shopify/ui-extensions-react/checkout';
- 在
Attribution组件中调用该hook获取数据:
function Attribution() { // 获取扩展API实例 const api = useExtensionApi(); // 获取订单ID和结账ID(使用可选链避免加载时的空值报错) const orderId = api.order?.id; const checkoutId = api.checkout?.id; // 原有状态和逻辑... }
api.order对象包含订单的完整信息(如id、number等),api.checkout包含结账会话的相关数据,完全满足关联需求。
二、关联存储数据
1. 存储到自有数据库
在提交表单时,将归因数据与orderId/checkoutId一起发送到你的后端接口即可:
修改handleSubmit函数:
async function handleSubmit() { if (!orderId) return; // 确保订单ID已加载 setLoading(true); try { // 发送数据到自有后端 await fetch('https://your-backend-url.com/save-attribution', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ attribution, orderId, checkoutId }), }); setAttributionSubmitted(true); } catch (error) { console.error('提交失败:', error); // 可添加错误提示逻辑 } finally { setLoading(false); } }
后端接收到数据后,直接将attribution与orderId关联存储到数据库即可。
2. 存储到Shopify订单元字段
若要将数据直接写入Shopify订单的元字段,需要通过你的后端中转(前端扩展无权限直接调用Admin API):
步骤1:后端配置Shopify API权限
确保你的后端拥有Shopify Admin API的write_orders权限,可通过Shopify Partner后台创建私有应用或自定义应用获取API密钥和密码。
步骤2:前端发送数据到后端
同上述自有数据库的提交逻辑,将attribution和orderId发送到后端。
步骤3:后端调用Shopify Admin API更新订单
后端使用Shopify Admin API的更新订单接口,为订单添加自定义元字段:
// 后端Node.js示例(使用@shopify/shopify-api库) async function updateOrderAttribution(orderId, attribution) { const session = await shopifyAPI.session.loadCurrentSession(); const client = new shopifyAPI.clients.Rest({session}); await client.put({ path: `orders/${orderId}/metafields`, data: { metafield: { namespace: 'custom', // 自定义命名空间 key: 'attribution_source', // 元字段键名 value: attribution, value_type: 'string' } } }); }
三、额外注意事项
- 确保在
api.order加载完成后再允许提交表单,可通过条件渲染禁用提交按钮:
<Button disabled={!attribution || !orderId || loading} onPress={handleSubmit}> 提交 </Button>
useStorageState用于标记用户是否已提交,避免重复显示表单,需确保正确导入该hook(原代码中缺失导入)。
内容的提问来源于stack exchange,提问作者Daelan

