高级功能 Android SDK
Android的高级配置和自定义集成。
替代安装方案
基本流程采用自动支付方式显示。如需更多控制选项,请使用以下替代方案:
自定义支付方式选择(startPaymentLite)
startPaymentLite)控制要显示的支付方式:
// 1. Fetch available methods
val methods = fetchPaymentMethods(sessionId)
// 2. Display in your UI
// 3. Start payment with selected method
startPaymentLite(
paymentMethodType = selectedMethod, // "CARD", "PIX", etc.
vaultedToken = null,
showPaymentStatus = true,
callbackOTT = { token ->
token?.let { createPayment(it, checkoutSession) }
}
)简化流程 (startPaymentSeamlessLite)
startPaymentSeamlessLite)与精简版类似,但具备自动创建付款功能:
startPaymentSeamlessLite(
paymentMethodType "CARD",
vaultedToken null,
showPaymentStatus true
)注册(保存卡片)
付款时节省
// When creating payment on backend, include vault_on_success flag
suspend fun createPayment(token: String, checkoutSession: String) {
apiClient.post("/payment/create", mapOf(
"one_time_token" to token,
"checkout_session" to checkoutSession,
"vault_on_success" to true // Save after successful payment
))
}
// Configure SDK to show save checkbox
startCheckout(
callbackPaymentState = { state -> handlePaymentState(state) }
)
// Update with session - SDK will show "Save card" checkbox automatically
updateCheckoutSession(
checkoutSession = session.checkoutSession,
countryCode = "US"
)单独注册
// Create customer session on backend
val customerSession = createCustomerSession("cus_123")
// Start enrollment
initEnrollment(
customerSession = customerSession.id,
countryCode = "US"
)
// Start enrollment flow
startEnrollment(
showEnrollmentStatus = true,
callback = { vaultedToken ->
vaultedToken?.let {
println("Card saved: $it")
}
}
)拱顶Token
startPaymentLite(
paymentMethodType "CARD",
vaultedToken "vtok_saved_card_123",
showPaymentStatus true,
callbackOTT {token >
token?.let { createPayment(it,checkoutSession) }
}
)自定义用户界面(无头集成)
当您需要完全掌控每个用户界面元素、打造高度定制的结账体验,或拥有开发定制界面的资源时,可构建具备完整用户界面控制权的完全定制化支付表单。
import com.yuno.sdk.Yuno
import com.yuno.sdk.api.ApiClientPayment
lifecycleScope.launch {
// 1.Initialize
val apiClient = Yuno.apiClientPayment(
countryCode "US",
checkoutSession "session_id"
)
// 2. 在自定义界面收集卡片数据
valtoken apiClient.generateToken(
checkoutSession "session_id",
paymentMethod = PaymentMethod(
type = "CARD",
card = CardData(
number = "4111111111111111",
expirationMonth = 12,
expirationYear = 25,
securityCode = "123",
holderName = "John Doe",
type = "CREDIT"
)
)
)
// 3. 使用令token
创建支付
createPayment(token.oneTimeToken)
// 4. 处理后续操作(如需)
apiClient.continuePayment(
activity = this@PaymentActivity,
onPaymentResult = { result ->
handlePaymentResult(result)
}
)
}使用拱顶Token
valtoken apiClient.generateToken(
checkoutSession "session_id",
paymentMethod = PaymentMethod(
type = "CARD",
vaultedToken "saved_token_id",
card = CardData(securityCode = "123")
)
)渲染模式集成
在您的自定义视图中显示付款表单。
class PaymentActivity : ComponentActivity(), YunoPaymentRenderListener {
private lateinit var paymentController: YunoPaymentFragmentController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var paymentView by remember { mutableStateOf<View?>(null) }
Column {
Button(onClick = { startRenderMode() }) {
Text("Pay Now")
}
paymentView?.let {
AndroidView(factory = { it })
}
}
}
}
private fun startRenderMode() {
lifecycleScope.launch {
val session = createCheckoutSession()
paymentController = Yuno.startPaymentRender(
activity = this@PaymentActivity,
checkoutSession = session.id,
countryCode = "US",
listener = this@PaymentActivity
)
}
}
override fun onFormView(view: View) {
// Add view to your layout
findViewById<FrameLayout>(R.id.payment_container).addView(view)
}
override fun onSubmitForm() {
// Customer submitted form
}
override fun onPaymentResult(result: PaymentResult) {
if (result.status == PaymentStatus.SUCCEEDED) {
navigateToSuccess()
}
}
}造型设计
通过主题自定义SDK外观。
colors.xml:
<color name="yuno_primary">#007bff</color>
<color name="yuno_background">#ffffff</color>
<color name="yuno_text">#333333</color>
<color name="yuno_error">#dc3545</color>themes.xml:
<style name="YunoSDKTheme" parent="Theme.MaterialComponents">
<item name="colorPrimary">@color/yuno_primary</item>
<item name="colorOnPrimary">@android:color/white</item>
<item name="android:textColor">@color/yuno_text</item>
</style>应用主题:
Yuno.setTheme(R.style.YunoSDK主题)卡片扫描(OCR)
启用摄像头扫码功能。
添加依赖项:
dependencies {
implementation("com.yuno.sdk:card-scan:2.8.1")
}在配置中启用:
Yuno.initialize(
this,
publicApiKey = "your-key",
config =YunoConfig(
cardScanEnabled = true
)
)卡片扫描按钮自动以卡片形式显示。
ClearSale 集成
启用欺诈预防功能。
添加 ClearSale SDK:
dependencies {
implementation("br.com.clearsale:cs-android-sdk:4.0.0")
}Initialize:
import br.com.clearsale.androidsdk.ClearSale
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// Initialize ClearSale
ClearSale.init(this, "your-clearsale-app-key")
// Initialize Yuno
Yuno.initialize(this, "your-public-key", YunoConfig())
}
}ClearSalefingerprint 自动收集并发送。
错误处理
处理支付状态回调和支付处理中的错误:
// Set up error handling in payment state callback
startCheckout(
callbackPaymentState = { state ->
when (state) {
"SUCCEEDED" -> handleSuccess()
"FAIL" -> {
// Handle payment failure
showError("Payment failed")
}
"REJECT" -> {
// Handle payment rejection
showRejectedMessage()
}
"PROCESSING" -> showPendingMessage()
else -> {}
}
}
)
// Update session with error handling
try {
val session = createCheckoutSession()
updateCheckoutSession(
checkoutSession = session.checkoutSession,
countryCode = "US"
)
} catch (e: Exception) {
Log.e("Payment", "Session error: ${e.message}")
showError("Failed to initialize payment")
}
// Handle errors during payment creation
startPayment(
showStatusYuno = true,
callbackOTT = { token ->
lifecycleScope.launch {
try {
createPayment(token, checkoutSession)
} catch (e: Exception) {
Log.e("Payment", "Payment creation error: ${e.message}")
showError("Payment failed: ${e.message}")
}
}
}
)测试与调试
启用日志记录
Yuno.setLogLevel(LogLevel.VERBOSE)测试模式
Yuno.initialize(
this,
publicApiKey = "pk_test_your_key",
config =YunoConfig(testMode = true)
)性能
延迟初始化
val yuno by lazy {
Yuno.initialize(this, "pk_test_key",YunoConfig())
Yuno.getInstance()
}预加载 SDK
lifecycleScope.launch(Dispatchers.IO) {
Yuno.preload(this@MainActivity)
}外部浏览器返回(深度链接)
处理用户在经历外部支付流程(如3DS认证挑战、银行转账重定向、PIX支付以及其他带外部重定向的支付方式)后返回应用的情况。
1. 在结账会话中设置回调网址
包含 callback_url 在后端创建结账会话时:
{
"callback_url": "myapp://return"
}
重要没有
callback_url用户可能会被困在外部浏览器中,无法返回您的应用。
2. 配置深度链接处理
添加一个 intent-filter 在您的活动中 AndroidManifest.xml:
<activity android:name=".YourMainActivity">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="myapp"
android:host="return" />
</intent-filter>
</activity>该计划 (myapp)和主机(return) 必须与您的 callback_url.
3. 处理退货意向
当用户返回时处理深度链接:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Check if app was opened via deep link
intent.data?.let { uri ->
val url = uri.toString()
if (url.contains("myapp://return")) {
handlePaymentReturn(uri)
}
}
}
private fun handlePaymentReturn(uri: Uri) {
val sessionId = uri.getQueryParameter("checkoutSession")
sessionId?.let {
continuePayment(
showPaymentStatus = true,
checkoutSession = it,
countryCode = "US"
) { result ->
result?.let { status ->
Toast.makeText(this, "Payment status: $status", Toast.LENGTH_SHORT).show()
}
}
}
}4. 全面集成示例
class PaymentActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Initialize checkout
startCheckout(
callbackPaymentState = { state ->
handlePaymentState(state)
}
)
// Handle deep link return
if (intent?.data != null) {
handleDeepLinkReturn(intent)
} else {
// Normal payment flow
initializePaymentUI()
}
}
private fun handleDeepLinkReturn(intent: Intent) {
intent.data?.let { uri ->
if (uri.toString().contains("myapp://return")) {
val sessionId = extractCheckoutSession(uri)
sessionId?.let {
continuePayment(
showPaymentStatus = true,
checkoutSession = it,
countryCode = "US"
) { result ->
when (result) {
"SUCCEEDED" -> navigateToSuccess()
"FAILED" -> showError("Payment failed")
else -> showPendingMessage()
}
}
}
}
}
}
private fun extractCheckoutSession(uri: Uri): String? {
return uri.getQueryParameter("checkoutSession")
}
}最佳实践
- 始终包含
callback_url在可能重定向的支付流程中 - 在多种设备和Android版本上测试深度链接处理
- 优雅处理缺失或格式错误的深度链接数据
- 在从外部浏览器返回后,在您的用户界面中更新付款状态
1 天前已更新