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

Google Apps Script Web App向Stripe提交嵌套对象失败问题

问题背景

我用Google Apps Script(GAS)开发Web App,监听Stripe Webhook事件并回传数据。提交顶层属性时一切正常,示例代码如下:

const data = await postCustomer(customerId, {
        name: 'Name',
        email: 'email@example.com'
    }
  )
async function postCustomer(id, args) {
  const data = await postStripeData(id, args, ['customers'])
  return data
}

async function postStripeData(id, args, path1, path2) {
  const fullPath = makeFullPath(id, path1, path2)
  const data = await post(getStripeApiUrl() + fullPath + '?key=' + getKey(), args)
  return data
}

async function post(url, args) {
  const response = await UrlFetchApp.fetch(url, {
    'method': 'post',
    'payload': args
  })
    if (await response.getResponseCode() === 200) {
      const data = await JSON.parse(response)
    return data
  } else {
    throw new Error("I couldn't post to this url: " + url)
  }
}
问题描述

但提交嵌套对象时请求失败(使用真实地址信息测试):

const data = await postCustomer(customerId, {
    address: {
      country: 'US',
      state: 'CA',
      city: 'City',
      postal_code: '00000',
      line1: 'Line 1',
      line2: 'Line 2'
    }
  })

报错提示address是无效对象,Stripe日志显示接收的格式为:

{
"address": 
"{line2=Line 2, state=CA, country=US, postal_code=00000, line1=Line 1, city=City}",
}

Stripe官方文档有Node.js示例,但无GAS相关内容:

const stripe = require('stripe')('sk_test_51PoHIuFYLeju0XxwXR4z3EHW3oaSqtTlD2Kr2xvUPRzhORHsjssb35rLfw1kbdQsVYdkHiYZ7vmKgWrXic30Y2XN00bvs1FZaO');
const customer = await stripe.customers.update(
  'cus_NffrFeUfNV2Hib',
  {
    metadata: {
      order_id: '6735',
    },
  }
);
已尝试方案
  • 对address使用JSON.stringify():仍报错,Stripe日志显示:
{
"address": "{\"country\":\"US\"}"
}
  • 在post()中对整个payload使用JSON.stringify():返回200响应,但客户信息未更新。
  • 将address作为Blob发送:格式错误,Stripe期望application/x-www-form-urlencoded格式,这也是UrlFetchApp.fetch()的默认格式。
解决方案

问题根源是GAS的UrlFetchApp默认会把嵌套对象直接转成字符串,而Stripe API需要的是表单编码的嵌套格式(比如address[country]=US&address[state]=CA)。

解决步骤:

  1. 添加工具函数,将嵌套对象转换为符合规范的扁平结构:
function flattenObject(obj, parentKey = '') {
  let result = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      const newKey = parentKey ? `${parentKey}[${key}]` : key;
      if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
        Object.assign(result, flattenObject(obj[key], newKey));
      } else {
        result[newKey] = obj[key];
      }
    }
  }
  return result;
}
  1. 修改post()函数,发送前用工具函数处理payload,同时修正原代码中错误的await使用:
async function post(url, args) {
  // 扁平化嵌套对象
  const flattenedPayload = flattenObject(args);
  const response = UrlFetchApp.fetch(url, {
    'method': 'post',
    'payload': flattenedPayload,
    'contentType': 'application/x-www-form-urlencoded'
  });
  
  if (response.getResponseCode() === 200) {
    const data = JSON.parse(response.getContentText());
    return data;
  } else {
    throw new Error(`请求失败,URL: ${url},响应码: ${response.getResponseCode()}`);
  }
}

修改后,提交嵌套对象时,Stripe会接收到address[country]=US&address[state]=CA这类正确格式的参数,即可正常更新客户信息。

内容的提问来源于stack exchange,提问作者Alex Cap

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 23:45:16