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

AWS Lambda Java函数返回空JSON问题求助(Stripe支付场景)

问题排查:AWS Lambda对接Stripe Payment Intents返回空JSON响应

我有一个Angular应用,使用Stripe Payment Intents API实现支付流程。此前通过Spring Boot Rest Controller部署在Elastic Beanstalk时,前后端均能正常工作;切换到AWS Lambda的Java函数后,函数返回空JSON响应,无法获取包含client_secret的预期结果。

相关代码

AWS Lambda Java函数代码

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import com.fasterxml.jackson.jr.ob.JSON;
import com.stripe.Stripe;
import com.stripe.exception.StripeException;
import com.stripe.model.PaymentIntent;

public class CheckoutPayment implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent>{

    @Override
    public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context){
        String paymentStr ="";
        
        try {
            
            PaymentInfo paymentInfo = JSON.std.beanFrom(PaymentInfo.class, input.getBody());
            PaymentIntent paymentIntent = createPaymentIntent(paymentInfo);
            paymentStr = paymentIntent.toJson();


        } catch (Exception ex) {
            ex.printStackTrace();
            return new APIGatewayProxyResponseEvent()
                    .withStatusCode(400)
                    .withBody("Error processing the request");
        }

        APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
        response.withStatusCode(200).withBody(paymentStr);
        return response;
    }

    private PaymentIntent createPaymentIntent(PaymentInfo paymentInfo) throws StripeException {
        
        Stripe.apiKey = "sk_test_5....something";
        
        List<String> paymentMethodeTypes = new ArrayList<>();
        paymentMethodeTypes.add("card");
        Map<String, Object> params = new HashMap<>();
        params.put("amount", paymentInfo.getAmount());
        params.put("currency", paymentInfo.getCurrency());
        params.put("payment_method_types", paymentMethodeTypes);
        return PaymentIntent.create(params);
    }

}

PaymentInfo类代码

public class PaymentInfo {
    private Long amount;
    private String currency;
    
    public PaymentInfo() {}
    
    public PaymentInfo(Long amount, String currency) {
        this.amount = amount;
        this.currency = currency;
    }

    public Long getAmount() {
        return amount;
    }

    public String getCurrency() {
        return currency;
    }

    public void setAmount(Long amount) {
        this.amount = amount;
    }

    public void setCurrency(String currency) {
        this.currency = currency;
    }

    @Override
    public String toString() {
        return "PaymentInfo [amount=" + amount + ", currency=" + currency + "]";
    }

}

预期返回响应格式

{
  "id": "pi_3MQBPOHNXSQZoPBk0KGKrqAV",
  "object": "payment_intent",
  "amount": 2000,
  "amount_capturable": 0,
  "amount_details": {
    "tip": {}
  },
  "amount_received": 0,
  "application": null,
  "application_fee_amount": null,
  "automatic_payment_methods": null,
  "canceled_at": null,
  "cancellation_reason": null,
  "capture_method": "automatic",
  "client_secret": "pi_remo",
  "confirmation_method": "automatic",
  "created": 1673709158,
  "currency": "usd",
  "customer": null,
  "description": null,
  "invoice": null,
  "last_payment_error": null,
  "latest_charge": null,
  "livemode": false,
  "metadata": {},
  "next_action": null,
  "on_behalf_of": null,
  "payment_method": null,
  "payment_method_options": {
    "card": {
      "installments": null,
      "mandate_options": null,
      "network": null,
      "request_three_d_secure": "automatic"
    }
  },
  "payment_method_types": [
    "card"
  ],
  "processing": null,
  "receipt_email": null,
  "review": null,
  "setup_future_usage": null,
  "shipping": null,
  "statement_descriptor": null,
  "statement_descriptor_suffix": null,
  "status": "requires_payment_method",
  "transfer_data": null,
  "transfer_group": null
}

Angular前端onSubmit()函数

onSubmit() {
    // compute payment info
    this.paymentInfo.amount = Math.round(this.totalPrice * 100);
    this.paymentInfo.currency = "CAD";
    if (!this.checkoutFormGroup.invalid && this.displayError.textContent === "") {

      this.checkoutService.createPaymentIntent(this.paymentInfo).subscribe(
        (paymentIntentResponse) => {
          this.stripe.confirmCardPayment(paymentIntentResponse.client_secret,
            {

              payment_method: {
                card: this.cardElement
              }
            }, { handleActions: false })
          .then(function(result) {
            if (result.error) {
              // inform the customer there was an error
              alert(`There was an error: ${result.error.message}`);
            } else {
              // reset cart
              this.resetCart();
            }
          }.bind(this));
        }
      );
    } else {
      this.checkoutFormGroup.markAllAsTouched();
      return;
    }
  }

Angular CheckoutService代码

import { PaymentInfo } from './../common/payment-info';
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class CheckoutService {

  private paymentIntentUrl = 'https://removed real path amazonaws.com/api/payment-intent';

  constructor(private httpClient: HttpClient) { }

  createPaymentIntent(paymentInfo: PaymentInfo): Observable<any>{
    console.log("paymentInfo - ", paymentInfo)
    return this.httpClient.post<PaymentInfo>(this.paymentIntentUrl, paymentInfo);
  }
}

排查关键点

  1. 完善日志记录

    • 原代码中ex.printStackTrace()在Lambda环境下无法输出到CloudWatch日志,需替换为Lambda上下文的日志工具:
      context.getLogger().log("Error message: " + ex.getMessage());
      context.getLogger().log("Stack trace: " + Arrays.toString(ex.getStackTrace()));
      
    • 添加日志打印input.getBody()和paymentIntent.toJson()的内容,确认请求体解析和PaymentIntent创建是否正常。
  2. 验证请求体解析

    • 检查APIGateway代理集成是否传递了原始请求体,确认input.getBody()的内容与前端发送的paymentInfo结构一致。
    • 若Jackson JR解析失败(比如字段大小写不匹配、JSON格式错误),会直接进入catch块返回400,可尝试替换为完整Jackson库测试解析逻辑。
  3. 确认Stripe API调用有效性

    • 检查Stripe密钥是否正确、是否具备创建PaymentIntent的权限。
    • 在createPaymentIntent方法中添加日志,打印生成的PaymentIntent内容,确认Stripe是否返回了包含client_secret的完整对象。
  4. 修复响应格式

    • 原Lambda响应未设置Content-Type为application/json,前端可能无法正确解析JSON,需添加响应头:
      Map<String, String> headers = new HashMap<>();
      headers.put("Content-Type", "application/json");
      response.withHeaders(headers);
      
  5. 检查异常覆盖范围

    • 确认所有可能的异常都被捕获,比如Stripe API调用时的网络异常、权限异常等,避免因未捕获异常导致Lambda返回空响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 15:15:10