Android(Java)集成Stripe PaymentSheet时触发java.lang.NullPointerException问题求助
解决Stripe PaymentSheet的"Parameter specified as non-null is null"错误
从你的错误日志可以直接定位问题:你传给PaymentSheet.CustomerConfiguration的customerId参数是null。因为Stripe的SDK底层用Kotlin实现,非空参数不允许传入null,所以触发了这个空指针异常。
结合你的代码和问题描述(之前正常现在偶尔出错),我整理了以下排查和修复步骤:
1. 先确认后端返回的参数完整性
这个问题大概率出在后端接口BACKEND_URL + "payment-sheet"的返回值上:
- 检查接口返回的JSON是否始终包含
customer、ephemeralKey、paymentIntent三个字段,且没有null值 - 你当前用
optString("customer")获取客户ID,如果后端返回的customer字段是null或者压根没返回这个字段,optString会返回空字符串,而空字符串传给Stripe的非空参数也会触发校验失败
2. 在客户端添加参数校验逻辑
调用presentPaymentSheet()之前,必须先验证三个核心参数的有效性,避免传入空值:
private void presentPaymentSheet() { // 先检查所有必要参数是否有效 if (TextUtils.isEmpty(paymentIntentClientSecret) || TextUtils.isEmpty(customerId) || TextUtils.isEmpty(ephemeralKeySecret)) { // 提示用户并重新获取支付参数 Toast.makeText(this, "支付初始化失败,请重试", Toast.LENGTH_SHORT).show(); fetchInitData(); return; } // 参数有效再拉起支付表单 paymentSheet.presentWithPaymentIntent( paymentIntentClientSecret, new PaymentSheet.Configuration( "Scarlett Saturdays", new PaymentSheet.CustomerConfiguration( customerId, ephemeralKeySecret ) ) ); }
3. 优化数据解析的容错机制
替换当前的optString解析方式,提前发现参数缺失问题:
// 修改fetchInitData里的解析逻辑 @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { if (!response.isSuccessful()) { // Handle failure runOnUiThread(() -> Toast.makeText(StripePayment.this, "服务器请求失败", Toast.LENGTH_SHORT).show()); return; } final JSONObject responseJson = parseResponse(response.body()); // 逐一校验字段是否存在且非空 if (!responseJson.has("paymentIntent") || responseJson.isNull("paymentIntent")) { runOnUiThread(() -> Toast.makeText(StripePayment.this, "支付意图参数缺失", Toast.LENGTH_SHORT).show()); return; } if (!responseJson.has("customer") || responseJson.isNull("customer")) { runOnUiThread(() -> Toast.makeText(StripePayment.this, "客户信息缺失", Toast.LENGTH_SHORT).show()); return; } if (!responseJson.has("ephemeralKey") || responseJson.isNull("ephemeralKey")) { runOnUiThread(() -> Toast.makeText(StripePayment.this, "临时密钥缺失", Toast.LENGTH_SHORT).show()); return; } // 赋值有效参数 paymentIntentClientSecret = responseJson.getString("paymentIntent"); customerId = responseJson.getString("customer"); ephemeralKeySecret = responseJson.getString("ephemeralKey"); runOnUiThread(() -> buyButton.setEnabled(true)); }
4. 排查后端逻辑问题
因为之前功能正常,突然出现异常,重点检查后端的以下逻辑:
- 是否在某些场景下没有正确创建Stripe Customer对象,导致返回的
customer字段为null - 生成Ephemeral Key时是否关联了正确的Customer ID
- 查看后端日志,确认接口返回的JSON数据是否符合预期
5. 清理冗余代码
你在onCreate里重复调用了PaymentConfiguration.init,可以去掉其中一次,保持代码整洁:
// 保留一次初始化即可 PaymentConfiguration.init(getApplicationContext(), STRIPE_PUBLISHABLE_KEY);
内容的提问来源于stack exchange,提问作者Kevin Ngoh
相关产品推荐
相关产品推荐

