Android Kotlin Retrofit手机充值API调用失败问题求助
Android Kotlin+Retrofit调用POST API失败排查
作为编程新手,在Android平台使用Kotlin+Retrofit开发手机充值功能时,调用POST类型API出现异常,代码无法正常运行。以下是相关信息及问题排查:
1. 相关代码片段
PHP API查询语句
query('select mt.translationID,mt.mobile,mt.amount, mt.operatorCodeTimestamp as rechargedate, mt.status from mst_translation mt join agent_users mu on mu.agent_id=mt.userID where mu.mobile="'.$userID.'" and mu.domainName="'.$domain.'"')->result();
Retrofit接口定义
interface ApiEndPoint { @POST("api/Recharge/make") fun rechargeMobile( @Query("userId") userId: String, @Query("domain") domain: String, @Body request: RechargeRequest ): Call<RechargeResponce?>? }
Main Activity代码
class MoneyTransfer : AppCompatActivity() { val binding by lazy{ ActivityMoneyTransferBinding.inflate(layoutInflater) } private lateinit var apiEndPoint : ApiEndPoint override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(binding.root) initBlock() binding.proceed.setOnClickListener { dataSetup() } } fun dataSetup(){ val mobileRechargeRequest = RechargeRequest( operatorCode = binding.operatorCode.text.toString(), userID = "2050", userpin = "1234", amount = binding.mobileNumber.text.toString(), servicenumber = binding.mobileNumber.text.toString(), domain = "www.pay2kart.com", servicetype = "MOBILE" ) val response = apiEndPoint.rechargeMobile("2050", "www.pay2kart.com",mobileRechargeRequest) response!!.enqueue(object : Callback<RechargeResponce?> { override fun onResponse( call: Call<RechargeResponce?>, response: Response<RechargeResponce?> ) { try { if (response != null) { Log.e("message", response.message().toString()) Toast.makeText( this@MoneyTransfer, response.message().toString(), Toast.LENGTH_LONG ).show() } } catch (e: Exception) { Toast.makeText( this@MoneyTransfer, "Some NetWork Error Has been found ... ", Toast.LENGTH_LONG ).show() } } override fun onFailure(call: Call<RechargeResponce?>, t: Throwable) { Toast.makeText(this@MoneyTransfer, "Failed ...", Toast.LENGTH_LONG).show() } }) } private fun initBlock() { var retrofit = ServerConnection.getConnection() if (retrofit != null) { apiEndPoint = retrofit.create(ApiEndPoint::class.java) } } }
2. API信息
API地址:https://www.pay2kart.com/pay2kart_api_testing/Services/index.php/api/Recharge/make
3. Postman测试成功的请求体
{ "operatorCode":"102", "userID":"2050", "userpin":"1234", "servicenumber":"8878840990", "domain":"www.pay2kart.com", "servicetype":"MOBILE" }
问题排查与修正
核心错误点
- 参数传递方式不匹配:Postman测试时所有参数都放在请求Body中,但你的Retrofit接口把
userId和domain作为URL Query参数传递,与API期望的接收方式不符,API会从Body读取参数,忽略Query参数导致校验失败。 - 请求体结构冗余:
RechargeRequest中已经包含userID和domain,却额外通过@Query传递,造成参数重复;同时你给amount赋值了手机号输入框的内容,而Postman成功请求里并不存在amount字段,导致请求体结构不匹配。 - 空安全风险:使用
response!!强制非空,一旦接口返回null会触发空指针异常。
修正方案
- 修改Retrofit接口:移除
@Query参数,仅保留@Body传递完整请求体:
interface ApiEndPoint { @POST("api/Recharge/make") fun rechargeMobile( @Body request: RechargeRequest ): Call<RechargeResponce?> }
调整
RechargeRequest类:删除多余的amount字段,确保所有字段名、大小写与Postman成功请求的JSON完全一致。修正API调用逻辑:仅传递
RechargeRequest对象,去掉冗余的Query参数:
val response = apiEndPoint.rechargeMobile(mobileRechargeRequest)
- 优化空安全与调试信息:
response?.enqueue(object : Callback<RechargeResponce?> { override fun onResponse(call: Call<RechargeResponce?>, response: Response<RechargeResponce?>) { Log.e("API Code", response.code().toString()) Log.e("API Body", response.body().toString()) Toast.makeText(this@MoneyTransfer, "Code: ${response.code()}, Msg: ${response.message()}", Toast.LENGTH_LONG).show() } override fun onFailure(call: Call<RechargeResponce?>, t: Throwable) { Log.e("API Error", t.message.toString()) Toast.makeText(this@MoneyTransfer, "Error: ${t.message}", Toast.LENGTH_LONG).show() } })
- 检查Retrofit配置:确保初始化时添加了JSON转换器(如
GsonConverterFactory),否则无法正确序列化请求体:
Retrofit.Builder() .baseUrl("https://www.pay2kart.com/pay2kart_api_testing/Services/index.php/") .addConverterFactory(GsonConverterFactory.create()) .build()
内容的提问来源于stack exchange,提问作者Sabuj Ahmed
相关产品推荐
相关产品推荐

