Razorpay Android SDK月度订阅集成求助:步骤及核心疑问解答
我要在Android应用中集成Razorpay月度订阅功能,但官方Android SDK文档混乱、缺少关键服务信息,也没有完整Demo参考,目前卡在实现上。已经完成了初始化对象、控制台创建Plan、创建Subscription、用subscription_id完成结账这些步骤,但还有很多疑问。
核心困惑点解答
1. 结账后的subscription status
结账完成后,订阅状态随支付结果自动更新:
active:首次支付成功,订阅正常生效pending:首次支付未完成,等待用户补款cancelled:订阅被主动取消或多次支付失败后终止
建议通过Razorpay后台配置Webhook接收状态变更通知,或调用GET /subscriptions/{subscription_id}API获取实时状态,避免客户端轮询。
2. 订阅的next Due(下次到期时间)
该字段由Razorpay自动计算返回,无需手动设置。可从Subscription对象的current_end字段获取当前周期结束时间(即下次扣款触发时间)。若设置了start_at,首次扣款会在指定时间执行,后续周期按Plan间隔自动顺延。
3. 如何renew(续费)订阅
- 自动续费:若Plan开启自动扣款,Razorpay会在到期日自动尝试从用户绑定的支付方式扣款,成功后订阅保持
active状态,周期顺延。 - 手动续费:当订阅处于
pending或expired状态时,可调用POST /subscriptions/{subscription_id}/renewAPI触发续费,或让用户通过客户端再次发起结账流程(使用原subscription_id)。
4. entity参数的取舍
entity是Razorpay返回对象的标识字段,客户端无需手动传入,仅需在接收结果时用于日志或忽略即可,不需要作为请求参数传递。
5. start_at和end_at是否需要手动添加
start_at:可选参数。设置后首次扣款会在指定时间触发;不设置则立即执行首次扣款。你的代码中calendar.timeInMillis / 1000的秒级时间戳格式是正确的。end_at:无需手动添加,Razorpay会根据Plan周期和total_count自动计算结束时间。若total_count设为0(无限期订阅),则无end_at字段。
6. 是否可以创建10分钟时长的测试订阅
可以。在测试环境中,前往Razorpay控制台创建Plan时,将周期设置为10 minutes,再用该Plan创建订阅即可生成10分钟的测试订阅,测试环境不会产生真实扣款。
完整集成步骤梳理
初始化Razorpay客户端
在Application或Activity中使用API密钥初始化实例:val razorpay = Razorpay(API_KEY, API_SECRET)控制台创建Plan
根据业务需求设置周期(月度/10分钟测试)、金额、币种、总周期数(total_count,0表示无限期)。创建Subscription
调用API创建订阅,关键参数包括plan_id、total_count、quantity,可选start_at和自定义notes。发起结账流程
使用生成的subscription_id调用Razorpay Checkout,用户完成首次支付后订阅进入active状态。配置Webhook监听
在Razorpay后台配置Webhook,监听subscription.created、subscription.charged、subscription.cancelled等事件,实时同步服务器端订阅状态,避免客户端状态不一致。
你的代码优化建议
创建订阅代码优化
- 若需月度循环订阅,将
total_count设为对应周期数(比如12表示一年),而非1(仅单次扣款) - 传入用户真实邮箱,便于Razorpay发送支付通知
// Calender API ( to set future date after 3 days) val calendar = Calendar.getInstance() calendar[Calendar.HOUR] = 0 calendar[Calendar.MINUTE] = 0 calendar[Calendar.SECOND] = 0 calendar.add(Calendar.DATE, 3) Log.d(TAG, "calendar: " + calendar.time) val requestJSON = JSONObject() requestJSON.put("plan_id", keyPlan) requestJSON.put("total_count", 12) // 改为一年月度订阅示例 requestJSON.put("quantity", 1) requestJSON.put("start_at", calendar.timeInMillis / 1000) val notesJSON = JSONObject() notesJSON.put( "name", activity.resources.getString(com.razorpay.R.string.app_name) ) notesJSON.put("email", userEmail) // 传入用户真实邮箱 requestJSON.put("notes", notesJSON) val subscription: Subscription = razorpayClient.subscriptions.create(requestJSON) subscriptionResponse = Gson().fromJson(subscription.toString(), SubscriptionResponse::class.java) editor.putString("_id", subscriptionResponse.id) editor.commit()
结账代码优化
- 增加支付结果监听,处理成功/失败场景
- 确保
subscription_id非空,避免结账失败
val subscriptionId = sharePref.getString("_id", "") if (subscriptionId.isNullOrEmpty()) { // 处理订阅ID为空的异常情况 return } val options = JSONObject() options.put( "name", activity.resources.getString(com.razorpay.R.string.app_name) ) options.put("description", "1 Month Subscription") options.put("subscription_id", subscriptionId) val prefill = JSONObject() prefill.put("email", userEmail) // 传入用户真实邮箱 options.put("prefill", prefill) val readOnly = JSONObject() readOnly.put("email", true) options.put("readonly", readOnly) options.put("image", "") options.put("theme.color", "#080637") val retryObj = JSONObject() retryObj.put("enabled", true) retryObj.put("max_count", 3) options.put("retry", retryObj) // 添加支付结果监听 checkout.setListener(object : PaymentResultListener { override fun onPaymentSuccess(paymentId: String) { // 支付成功,可调用API获取订阅最新状态并更新本地数据 } override fun onPaymentError(errorCode: Int, errorDescription: String) { // 支付失败,提示用户并处理异常 } }) activity.runOnUiThread { checkout.open(activity, options) }
内容的提问来源于stack exchange,提问作者Priyanka Vadodariya

