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

Android Studio集成Razorpay支付成功后插入数据库报错

Razorpay支付回调中写入数据库失败修复

问题场景

在Android Studio集成Razorpay支付SDK时,需要在支付成功后将订单业务数据写入数据库。在onPaymentSuccess回调中调用自定义save()方法执行入库逻辑时抛出错误,无法完成数据写入,原有问题代码如下:

//@Override
public void onPaymentSuccess(String s, PaymentData paymentData) {
    paymentData.getData();
    razorpay_payment_id=  paymentData.getPaymentId();
    save(paymentData);
}

public void save(PaymentData  paymentData)
{
    userid=user_id;
    property_type = ptype1.getText().toString().trim();
    from_date = txtchkin.getText().toString().trim();
    to_date = txtchkout.getText().toString().trim();
    no_of_adults = no_of_adult.getText().toString().trim();
    no_of_childrens = no_of_children.getText().toString().trim();
    price=amount.getText().toString().trim();
    razorpay_payment_id=paymentData.getPaymentId();
    razorpay_order_id=paymentData.getOrderId();

    payment_status="success";
    status="Active";
    isAllFieldsChecked = validate();
    if (isAllFieldsChecked) {
        StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                Toast.makeText(getApplicationContext(), "Data Inserted Successfully", Toast.LENGTH_LONG).show();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(getApplicationContext(), error.toString().trim(), Toast.LENGTH_LONG).show();
            }
        })
    }
}

报错核心原因

  • Razorpay的onPaymentSuccess回调默认运行在子工作线程,直接在该线程内调用getText()访问UI控件、弹Toast,会触发Android的非主线程禁止操作UI的崩溃
  • 现有Volley请求代码不完整:既没有重写getParams()方法传递POST入库参数,也没有将构建好的请求加入Volley请求队列,请求根本不会实际发送
  • 直接在长时间运行的网络请求逻辑里持有Activity控件引用,支付过程中如果页面旋转、Activity销毁,会触发空指针异常

修复代码

  1. 回调触发后先切到主线程,提前取出所有需要的表单值,避免子线程访问UI
  2. 补全Volley请求的参数传递、入队逻辑
  3. 避免在网络请求层直接持有控件引用
@Override
public void onPaymentSuccess(String s, PaymentData paymentData) {
    // 先在子线程取支付相关的非UI数据
    final String payId = paymentData.getPaymentId();
    final String orderId = paymentData.getOrderId();
    // 切主线程取UI表单值、做校验
    runOnUiThread(() -> {
        String propertyType = ptype1.getText().toString().trim();
        String fromDate = txtchkin.getText().toString().trim();
        String toDate = txtchkout.getText().toString().trim();
        String adultCount = no_of_adult.getText().toString().trim();
        String childCount = no_of_children.getText().toString().trim();
        String payAmount = amount.getText().toString().trim();

        if (validate()) {
            submitOrderToServer(payId, orderId, propertyType, fromDate, toDate, adultCount, childCount, payAmount);
        }
    });
}

private void submitOrderToServer(String razorpayPayId, String razorpayOrderId, String propertyType,
                                 String fromDate, String toDate, String adultCount, String childCount, String price) {
    StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
            response -> Toast.makeText(YourActivity.this, "订单入库成功", Toast.LENGTH_LONG).show(),
            error -> {
                String errTip = error.getMessage() == null ? "订单入库失败,请稍后重试" : error.getMessage();
                Toast.makeText(YourActivity.this, errTip, Toast.LENGTH_LONG).show();
            }) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> orderParams = new HashMap<>();
            orderParams.put("userid", String.valueOf(user_id));
            orderParams.put("property_type", propertyType);
            orderParams.put("from_date", fromDate);
            orderParams.put("to_date", toDate);
            orderParams.put("no_of_adults", adultCount);
            orderParams.put("no_of_childrens", childCount);
            orderParams.put("price", price);
            orderParams.put("razorpay_payment_id", razorpayPayId);
            orderParams.put("razorpay_order_id", razorpayOrderId);
            orderParams.put("payment_status", "success");
            orderParams.put("status", "Active");
            return orderParams;
        }
    };
    // 必须将请求加入队列,否则请求不会发送
    Volley.newRequestQueue(this).add(stringRequest);
}

额外优化建议

  • 发起支付前就把用户填写的表单数据暂存到ViewModel或者本地变量中,不要等到支付成功回调里再去控件取值,避免支付过程中页面销毁导致空指针
  • 支付成功后建议先在本地做支付状态标记,再上传服务器,避免网络波动导致用户付了钱但订单没记录的问题
  • 服务器端必须做支付签名校验,不要完全信任客户端传的支付成功状态,避免伪造请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 08:18:17