如何在 Android 中集成和使用 ATOM payment SDK?
结论
接入 ATOM payment SDK 时,不要急着编写支付页面。先向 ATOM 获取与你的商户账户匹配的 Android SDK、接入文档、测试凭据和示例工程。不同产品和版本使用的 SDK 类名、初始化参数、签名算法及回调字段可能不同,无法通过通用教程确定。
支付流程通常如下:
- Android 应用向业务后端申请创建订单。
- 业务后端调用 ATOM 支付接口,完成签名或加密。
- Android 应用使用后端返回的交易参数启动 ATOM SDK。
- SDK 返回初步支付结果。
- 业务后端通过 ATOM 查询接口或服务端通知确认最终状态。
- Android 应用从业务后端获取订单结果。
商户密钥不能保存在 APK 中,订单也不能仅凭客户端回调标记为支付成功。
接入前需要准备什么
联系 ATOM 的商务或技术支持,确认并获取以下资料:
- Android SDK,通常是
.aar、.jar或私有 Maven 依赖 - 与 SDK 版本对应的集成文档和示例工程
- 测试环境地址及测试账号
- 商户编号、产品编号等公开配置
- 服务端签名或加密规范
- 支付结果查询接口
- 服务端异步通知规范
- 正式环境开通及应用包名配置要求
- 是否需要配置签名证书指纹、回调地址或 URL Scheme
如果现有资料只有网页支付接口,没有 Android SDK,需要询问 ATOM 是否建议通过 Hosted Payment Page、WebView 或外部浏览器完成支付。不要自行将网页接口当作 SDK 接口使用。
添加 SDK 依赖
依赖的添加方式以 ATOM 提供的文件为准。
如果 ATOM 提供了 Maven 坐标,可在模块级 build.gradle 中添加:
dependencies {
implementation "ATOM_PROVIDED_GROUP:ATOM_PROVIDED_ARTIFACT:ATOM_PROVIDED_VERSION"
}
如果提供的是本地 .aar 文件,可将文件放入应用模块的 libs 目录,再进行配置:
repositories {
flatDir {
dirs "libs"
}
}
dependencies {
implementation(name: "atom-payment-sdk", ext: "aar")
}
使用 Kotlin DSL 时:
repositories {
flatDir {
dirs("libs")
}
}
dependencies {
implementation(files("libs/atom-payment-sdk.aar"))
}
atom-payment-sdk.aar 只是示例文件名,需要替换成 ATOM 实际提供的名称。有些 AAR 不会自动引入其依赖的第三方库,这些依赖需要按照官方文档另行添加。
配置 AndroidManifest.xml
支付功能通常需要网络权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
如果文档要求注册 Activity、Service、Provider、URL Scheme 或 <queries>,必须填写 SDK 给出的真实组件名称。下面的代码只用于说明配置位置,不能直接作为实际组件使用:
<application
...>
<!-- 按 ATOM 文档注册真实组件,不要使用示例类名 -->
<!--
<activity
android:name="ATOM_SDK_ACTIVITY_CLASS"
android:exported="false" />
-->
</application>
在 Android 12 及以上版本中,带有 <intent-filter> 的组件必须明确设置 android:exported。具体值应根据 ATOM 文档和组件用途确定。
由业务后端创建交易
商户密钥、加密密钥和签名逻辑必须留在服务端。Android 应用只提交业务订单信息:
data class CreatePaymentRequest(
val orderId: String
)
data class CreatePaymentResponse(
val transactionId: String,
val sdkPayload: String
)
示例调用:
suspend fun preparePayment(orderId: String): CreatePaymentResponse {
return paymentApi.createPayment(
CreatePaymentRequest(orderId = orderId)
)
}
业务后端需要:
- 根据数据库中的订单计算实际支付金额。
- 生成不可重复的商户订单号。
- 使用服务端保存的密钥生成签名或密文。
- 调用 ATOM 的创建交易接口。
- 将 SDK 所需的非敏感参数返回给 Android 应用。
- 保存 ATOM 交易号与业务订单号的对应关系。
不能直接信任客户端传来的金额。服务端应结合商品、优惠和订单状态重新计算。
启动 ATOM SDK
这里必须使用当前 SDK 文档提供的真实入口类和参数。由于现有信息中没有 SDK 版本和 API 定义,无法安全地给出确定的 ATOM 类名。
建议封装第三方 SDK,避免支付调用分散在各个页面中:
interface PaymentLauncher {
fun launch(
transactionId: String,
sdkPayload: String
)
}
接入 SDK 后,在实现类中调用官方入口:
class AtomPaymentLauncher(
private val activity: Activity
) : PaymentLauncher {
override fun launch(
transactionId: String,
sdkPayload: String
) {
// 在这里调用 ATOM 文档提供的真实初始化和支付 API。
// 不要根据其他版本的示例猜测类名、字段或参数顺序。
}
}
页面中的调用可以保持简洁:
lifecycleScope.launch {
try {
val payment = preparePayment(orderId)
paymentLauncher.launch(
transactionId = payment.transactionId,
sdkPayload = payment.sdkPayload
)
} catch (e: Exception) {
showPaymentError("暂时无法发起支付,请稍后重试")
}
}
如果 SDK 仍使用 startActivityForResult(),应完全按照其文档处理。如果支持 AndroidX Activity Result API,则优先采用 SDK 推荐的方式,不要自行修改回调协议。
正确处理支付结果
SDK 返回“成功”,通常只表示客户端收到了一次成功响应,不一定代表资金已得到最终确认。收到回调后,客户端应请求后端查询交易状态:
private fun handlePaymentCallback(orderId: String) {
lifecycleScope.launch {
when (paymentRepository.refreshOrderStatus(orderId)) {
PaymentStatus.PAID -> showPaymentSuccess()
PaymentStatus.PENDING -> showPaymentPending()
PaymentStatus.FAILED -> showPaymentFailure()
}
}
}
业务状态可以明确定义为:
enum class PaymentStatus {
PAID,
PENDING,
FAILED
}
后端还应处理 ATOM 的异步通知,并验证以下内容:
- 通知签名是否有效
- 商户订单号是否存在
- 商户编号是否匹配
- 支付金额和币种是否匹配
- 交易是否已处理
- ATOM 返回的最终状态是否允许入账
更新订单时必须保证幂等。重复回调不能引起重复发货、充值或记账。
环境切换
测试环境和正式环境应使用不同的配置,正式密钥只能保存在服务端。如果 Android 端需要配置非敏感的环境参数,可以通过构建类型管理:
android {
buildTypes {
debug {
buildConfigField "String", "PAYMENT_ENV", "\"sandbox\""
}
release {
buildConfigField "String", "PAYMENT_ENV", "\"production\""
}
}
}
客户端能否选择环境、环境参数叫什么,以及测试和正式环境的地址,都以 ATOM 文档为准。正式包发布前,还需要确认包名、签名证书和后台登记信息完全一致。
常见问题
SDK 类无法找到
检查 .aar 是否放在正确的模块中、Gradle 依赖是否已生效,以及 SDK 是否依赖其他库。同时确认示例代码与 SDK 文件来自同一版本。
支付页无法打开
可以依次检查:
- 是否用测试凭据调用了正式环境,或用正式凭据调用了测试环境
- 创建交易是否成功
- 交易参数是否完整
- 订单号是否重复
- Manifest 中的组件是否正确注册
- 应用包名或签名证书是否已在 ATOM 后台登记
- 是否启用了混淆,却没有加入 SDK 要求的规则
Release 包失败,Debug 包正常
常见原因包括 R8/ProGuard、签名证书、包名或网络安全配置。应添加 ATOM 文档提供的混淆规则,不要直接使用范围过大的全局 -keep。
回调显示成功,但订单仍未支付
订单状态应以后端查询结果或经过验签的服务端通知为准。网络中断、页面关闭或重复回调,都可能导致客户端状态与实际交易状态暂时不同。
安全注意事项
- 不要将商户密钥、签名私钥或解密密钥写入 Android 代码、资源文件或
BuildConfig。 - 不要在日志中输出完整卡号、CVV、密钥、支付令牌或未经脱敏的响应。
- 不要由客户端决定最终支付金额。
- 不要只校验客户端回调。
- 不要在 WebView 中绕过证书校验,也不要启用不必要的 JavaScript 接口。
- 不要因为接入失败就允许所有明文 HTTP 流量。
- 支付按钮应避免连续点击,但后端仍需保证订单和通知处理的幂等性。
- 对
PENDING状态提供重新查询入口,不要直接显示支付成功或失败。
如果目前还没有 SDK 文件、版本号和官方接入文档,应先向 ATOM 索取与你的商户产品对应的完整 integration kit。拿到 SDK 后,先运行官方示例工程,确认测试交易可用,再将相关调用封装到自己的应用中。
备注:内容仅供参考。