基于Braintree Web的Google Pay集成:ShippingOptions回调实现疑问
集成Braintree Google Pay时配置Shipping Options回调的完整步骤
你当前在用Braintree Web库集成Google Pay,想给shippingOptions添加回调函数,已经知道要在paymentDataRequest里加callbackIntents和paymentDataCallbacks配置,但不清楚后续具体操作。下面是完整的实现步骤:
1. 把回调配置正确加入请求参数
直接把你提到的callbackIntents和paymentDataCallbacks放到createPaymentDataRequest的配置对象里,不需要单独追加,示例如下:
const paymentDataRequest = googlePaymentInstance.createPaymentDataRequest({ merchantInfo: { merchantId: 'my-merchant-id-from-google', }, transactionInfo: { currencyCode: 'USD', totalPriceStatus: 'FINAL', totalPrice: '100.00', }, shippingAddressRequired: true, shippingAddressParameters: { // 按需配置地址参数,比如允许的国家 }, shippingOptionRequired: true, shippingOptionParameters: { defaultSelectedOptionId: 'shipping-001', shippingOptions: [ { id: 'shipping-001', label: '$0.00: Free shipping', description: 'Free Shipping delivered in 5 business days.', }, { id: 'shipping-002', label: '$1.99: Standard shipping', description: 'Standard shipping delivered in 3 business days.', }, { id: 'shipping-003', label: '$1000: Express shipping', description: 'Express shipping delivered in 1 business day.', }, ], }, // 新增回调配置 callbackIntents: ['SHIPPING_ADDRESS', 'SHIPPING_OPTION'], paymentDataCallbacks: { onPaymentDataChanged: onPaymentDataChanged, // 如果需要支付授权回调再加onPaymentAuthorized }, });
注意:如果不需要支付阶段的回调,可以去掉
PAYMENT_AUTHORIZATION,只保留地址和配送选项相关的即可。
2. 实现onPaymentDataChanged回调函数
这个函数是核心,负责处理用户修改配送地址或选择不同配送选项时的逻辑,比如重新计算运费、更新订单总价。函数要返回一个Promise,包含更新后的支付数据:
function onPaymentDataChanged(paymentData) { return new Promise((resolve, reject) => { const intent = paymentData.callbackTrigger; let updatedPaymentData = {}; // 处理配送地址变更 if (intent === 'SHIPPING_ADDRESS') { const shippingAddress = paymentData.shippingAddress; // 这里可以根据地址计算可用配送选项和运费 // 比如模拟根据地区调整运费 let newShippingOptions = [...paymentDataRequest.shippingOptionParameters.shippingOptions]; let newTotalPrice = '100.00'; // 假设美国加州需要额外运费 if (shippingAddress.administrativeArea === 'CA') { newShippingOptions = newShippingOptions.map(option => { if (option.id === 'shipping-002') { return { ...option, label: '$2.99: Standard shipping' }; } return option; }); newTotalPrice = '102.99'; } updatedPaymentData = { shippingOptionParameters: { shippingOptions: newShippingOptions, defaultSelectedOptionId: 'shipping-001' }, transactionInfo: { ...paymentDataRequest.transactionInfo, totalPrice: newTotalPrice } }; } // 处理配送选项变更 if (intent === 'SHIPPING_OPTION') { const selectedOptionId = paymentData.shippingOptionData.id; // 根据选中的选项计算总价 let shippingFee = '0.00'; switch(selectedOptionId) { case 'shipping-002': shippingFee = '1.99'; break; case 'shipping-003': shippingFee = '1000.00'; break; } const newTotalPrice = (parseFloat(paymentDataRequest.transactionInfo.totalPrice) + parseFloat(shippingFee)).toFixed(2); updatedPaymentData = { transactionInfo: { ...paymentDataRequest.transactionInfo, totalPrice: newTotalPrice } }; } resolve({ paymentData: updatedPaymentData }); }); }
3. 修正原有代码的语法错误
你的代码里有两个小问题,必须修正否则会报错:
cosnt拼写错误,要改成constpaymentDataRequest.allowedPaymentMethods是数组类型,要取第一个元素才能修改参数,因为Braintree生成的支付方式是数组格式:
// 修正后的代码 const cardPaymentMethod = paymentDataRequest.allowedPaymentMethods[0]; cardPaymentMethod.parameters.billingAddressRequired = true; cardPaymentMethod.parameters.billingAddressParameters = { format: 'FULL', phoneNumberRequired: true, };
4. 可选:实现onPaymentAuthorized回调
如果需要在用户确认支付前做额外验证(比如库存检查),可以实现这个回调:
function onPaymentAuthorized(paymentData) { return new Promise((resolve, reject) => { // 这里调用后端接口验证订单、库存等 const isValid = true; // 模拟验证通过 if (isValid) { resolve({ paymentAuthorizationResult: { state: 'SUCCESS' } }); } else { resolve({ paymentAuthorizationResult: { state: 'FAILURE', error: { reason: 'INVALID_REQUEST', message: '库存不足', intent: 'PAYMENT_AUTHORIZATION' } } }); } }); }
完整整合后的代码
把所有部分整合起来,就是可以直接运行的完整代码:
// 定义回调函数 function onPaymentDataChanged(paymentData) { return new Promise((resolve, reject) => { const intent = paymentData.callbackTrigger; let updatedPaymentData = {}; if (intent === 'SHIPPING_ADDRESS') { const shippingAddress = paymentData.shippingAddress; let newShippingOptions = [...paymentDataRequest.shippingOptionParameters.shippingOptions]; let newTotalPrice = '100.00'; if (shippingAddress.administrativeArea === 'CA') { newShippingOptions = newShippingOptions.map(option => { if (option.id === 'shipping-002') { return { ...option, label: '$2.99: Standard shipping' }; } return option; }); newTotalPrice = '102.99'; } updatedPaymentData = { shippingOptionParameters: { shippingOptions: newShippingOptions, defaultSelectedOptionId: 'shipping-001' }, transactionInfo: { ...paymentDataRequest.transactionInfo, totalPrice: newTotalPrice } }; } if (intent === 'SHIPPING_OPTION') { const selectedOptionId = paymentData.shippingOptionData.id; let shippingFee = '0.00'; switch(selectedOptionId) { case 'shipping-002': shippingFee = '1.99'; break; case 'shipping-003': shippingFee = '1000.00'; break; } const newTotalPrice = (parseFloat(paymentDataRequest.transactionInfo.totalPrice) + parseFloat(shippingFee)).toFixed(2); updatedPaymentData = { transactionInfo: { ...paymentDataRequest.transactionInfo, totalPrice: newTotalPrice } }; } resolve({ paymentData: updatedPaymentData }); }); } // 创建支付请求 const paymentDataRequest = googlePaymentInstance.createPaymentDataRequest({ merchantInfo: { merchantId: 'my-merchant-id-from-google', }, transactionInfo: { currencyCode: 'USD', totalPriceStatus: 'FINAL', totalPrice: '100.00', }, shippingAddressRequired: true, shippingAddressParameters: { // 按需配置,比如allowedCountryCodes: ['US'] }, shippingOptionRequired: true, shippingOptionParameters: { defaultSelectedOptionId: 'shipping-001', shippingOptions: [ { id: 'shipping-001', label: '$0.00: Free shipping', description: 'Free Shipping delivered in 5 business days.', }, { id: 'shipping-002', label: '$1.99: Standard shipping', description: 'Standard shipping delivered in 3 business days.', }, { id: 'shipping-003', label: '$1000: Express shipping', description: 'Express shipping delivered in 1 business day.', }, ], }, callbackIntents: ['SHIPPING_ADDRESS', 'SHIPPING_OPTION'], paymentDataCallbacks: { onPaymentDataChanged: onPaymentDataChanged, }, }); // 修正后的账单地址配置 const cardPaymentMethod = paymentDataRequest.allowedPaymentMethods[0]; cardPaymentMethod.parameters.billingAddressRequired = true; cardPaymentMethod.parameters.billingAddressParameters = { format: 'FULL', phoneNumberRequired: true, }; // 初始化PaymentsClient并加载支付数据 const paymentsClient = new google.payments.api.PaymentsClient({ environment: 'TEST', // 生产环境改成'PRODUCTION' }); paymentsClient.loadPaymentData(paymentDataRequest).then(function (response) { // 用Braintree解析响应并处理支付 const parsedResponse = googlePaymentInstance.parseResponse(response); // 这里调用Braintree的tokenize等方法完成支付流程 });
内容的提问来源于stack exchange,提问作者David R
相关产品推荐
相关产品推荐

