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

通过Java创建Stripe订阅时遇400错误:缺失customer参数

问题排查:Stripe订阅创建提示customer参数缺失

问题重现

代码中已设置customer参数,但调用Stripe API创建订阅时返回400错误,提示参数缺失:

实现代码

HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(apiTestKey);
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

CreateSubscriptionRequest createSubscriptionRequest = CreateSubscriptionRequest.builder()
        .customer("cus_P5ZkW678nZi3d0K")
        .object("customer")
        .items(ItemsRequest.builder()
                .data(List.of(DatumRequest.builder()
                        .id(String.valueOf(1))
                        .build()))
                .build())
        .build();

final HttpEntity<String> entity = new HttpEntity<>(objectMapper.writeValueAsString(createSubscriptionRequest), headers);

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<CreateSubscriptionRequest> response
        = restTemplate.exchange(baseUrl + "subscriptions", HttpMethod.POST, entity, CreateSubscriptionRequest.class);

错误日志

org.springframework.web.client.HttpClientErrorException$BadRequest: 400 Bad Request: "{<EOL>  "error": {<EOL>    "code": "parameter_missing",<EOL>    "doc_url": "stripe.com/docs/error-codes/parameter-missing",<EOL>    "message": "Missing required param: customer.",<EOL>    "param": "customer",<EOL>    "request_log_url": "dashboard.stripe.com/test/logs/req_jyjNoqopJFlkH3?t=1701167766",<EOL>    "type": "invalid_request_error"<EOL>  }<EOL>}<EOL>"
    at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:103)

问题根源

请求的Content-Type设置与实际发送的数据格式不匹配:

  • 代码声明Content-Type为APPLICATION_FORM_URLENCODED(表单编码),但实际通过objectMapper把对象序列化成了JSON字符串。
  • Stripe API接收表单编码请求时,仅识别key=value格式的参数,无法解析JSON请求体,因此读取不到customer参数。

另外代码存在两个额外错误:

  1. .object("customer")设置错误:创建订阅时该字段应为"subscription",或直接省略(Stripe会自动处理)。
  2. DatumRequest.id设为1错误:该字段需要传入Stripe平台的价格ID(格式为price_xxx),而非自定义数字。

修复方案

方案1:改用JSON格式发送请求(推荐)

将Content-Type改为JSON,让Stripe正确解析请求体:

HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(apiTestKey);
// 修改Content-Type为JSON格式
headers.setContentType(MediaType.APPLICATION_JSON);

CreateSubscriptionRequest createSubscriptionRequest = CreateSubscriptionRequest.builder()
        .customer("cus_P5ZkW678nZi3d0K")
        // 移除错误的object字段,或改为.object("subscription")
        .items(ItemsRequest.builder()
                .data(List.of(DatumRequest.builder()
                        // 替换为实际的Stripe价格ID
                        .id("price_your_plan_id")
                        .build()))
                .build())
        .build();

// 直接传递请求对象,RestTemplate会自动序列化为JSON
final HttpEntity<CreateSubscriptionRequest> entity = new HttpEntity<>(createSubscriptionRequest, headers);

RestTemplate restTemplate = new RestTemplate();
// 建议用专门的响应对象接收返回结果,而非请求对象
ResponseEntity<CreateSubscriptionResponse> response
        = restTemplate.exchange(baseUrl + "subscriptions", HttpMethod.POST, entity, CreateSubscriptionResponse.class);

方案2:改用表单编码格式发送请求

如果坚持使用表单编码,需将参数转换为MultiValueMap:

HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(apiTestKey);
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("customer", "cus_P5ZkW678nZi3d0K");
// 订阅项需按表单嵌套格式传递
params.add("items[0][price]", "price_your_plan_id");

final HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(params, headers);

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<CreateSubscriptionResponse> response
        = restTemplate.exchange(baseUrl + "subscriptions", HttpMethod.POST, entity, CreateSubscriptionResponse.class);

内容的提问来源于stack exchange,提问作者Nunyet Calçada

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:52:36