You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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 拼写错误,要改成const
  • paymentDataRequest.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 18:44:54