用 PaymentSheet 类将 Stripe 的预构建支付 UI 集成到您的 Android 应用程序的结账流程。
设置 Stripe 首先,您需要有 Stripe 账户。立即注册 。
Server-side 该集成要求您的服务器上的端点与 Stripe API 通讯。请用官方库从您的服务器访问 Stripe API:
Client-side Stripe Android SDK 是开源的,且有完整的文档 。
安装 SDK 时,将 stripe-android
添加到您的 app/build.gradle 文件的 dependencies
块中:
plugins {
id ( "com.android.application" )
}
android { .. . }
dependencies {
implementation ( "com.stripe:stripe-android:21.19.0" )
implementation ( "com.stripe:financial-connections:21.19.0" )
}
注意 有关最新 SDK 发布及过往版本的详细信息,请查看 GitHub 上的发布 页面。要想在新版本发布时接收通知,请查看仓库的发布情况 。
该集成使用三个 Stripe API 对象:
PaymentIntent :Stripe 用它来表示您从客户收款的意图,跟踪您的扣款尝试及整个过程中付款状态的变化情况。
(可选)Customer :要为将来的付款设置支付方式,就必须将它绑定到 Customer 。当客户在您的公司创建账户时,创建 Customer 对象。如果您的客户以访客身份付款,则可以在付款前创建个 Customer 对象,然后再将它关联到您自己内部的客户账户表示。
(可选)Customer Ephemeral Key:Customer 对象的信息属于敏感信息,无法直接从应用中检索。临时密钥授予 SDK 对客户的临时访问权限。
注意 如果您从不将银行卡保存到客户,并且不允许回头客重复使用已保存的银行卡,则可以从集成中省略 Customer 和 Customer Ephemeral Key 对象。
出于安全原因,您的应用无法创建这些对象。相反,在服务器上会添加一个端点,其功能如下:
检索 Customer,或新建一个。 为 Customer 创建一个 Ephemeral Key。 创建 PaymentIntent,设置好 amount 、currency 和 customer 。您还可以选择包含 automatic_ payment_ methods
参数。默认情况下,Stripe 会在最新版的 API 中启用其功能。 将 Payment Intent 的客户端私钥 、Ephemeral Key 的 secret
以及 Customer 的 id 和您的公钥 返回到您的应用程序。 在结账过程中显示给客户的支付方式也包含在 PaymentIntent 中。您可以让 Stripe 从管理平台设置中提取支付方式,也可以手动列出它们。无论选择哪种方式,都要知道在 PaymentIntent 中传递的货币会过滤显示给客户的支付方式。例如,如果您在 PaymentIntent 中传递 eur
,并且在管理平台中启用了 OXXO,则不会向客户显示 OXXO,因为 OXXO 不支持 eur
支付。
除非您的集成需要基于代码的选项来提供支付方式,否则 Stripe 建议使用自动选项。这是因为 Stripe 会评估货币、支付方式限制和其他参数,以确定支持的支付方式列表。优先显示可提高转化率且与货币和客户所在地最相关的支付方式。
您可以从管理平台 管理支付方式。Stripe 根据交易金额、货币和支付流程等因素处理符合条件的支付方式的退货。PaymentIntent 是用您在管理平台中配置的支付方式创建的。如不想使用管理平台或想手动指定支付方式,可通过 payment_ method_ types
属性将其列出。
curl https://api.stripe.com/v1/customers \
-u sk_test_BQokikJOvBiI2HlWgH4olfQ2
: \
-X "POST"
curl https://api.stripe.com/v1/ephemeral_keys \
-u sk_test_BQokikJOvBiI2HlWgH4olfQ2
: \
-H "Stripe-Version: 2025-05-28.basil" \
-X "POST" \
-d "customer" = "{{CUSTOMER_ID}}" \
curl https://api.stripe.com/v1/payment_intents \
-u sk_test_BQokikJOvBiI2HlWgH4olfQ2
: \
-X "POST" \
-d "customer" = "{{CUSTOMER_ID}}" \
-d "amount" = 1099 \
-d "currency" = "eur" \
-d "automatic_payment_methods[enabled]" = true \
收集付款详情 显示移动端 Payment Element 前,您的结账页面应:
初始化 您的结账活动的 onCreate
内的一个 PaymentSheet
实例,从而传递一个支付方式来处理结果。
import androidx . compose . runtime . Composable
import androidx . compose . runtime . remember
import com . stripe . android . paymentsheet . PaymentSheet
import com . stripe . android . paymentsheet . PaymentSheetResult
@Composable
fun App ( ) {
val paymentSheet = remember { PaymentSheet . Builder ( :: onPaymentSheetResult ) } . build ( )
}
private fun onPaymentSheetResult ( paymentSheetResult : PaymentSheetResult ) {
}
然后,从您在上一步中创建的端点获取 PaymentIntent 客户端私钥、Ephemeral Key 密钥、Customer ID 以及您的公钥。用 PaymentConfiguration
设置该公钥,然后存储另外几项,供您显示 PaymentSheet 时使用。
import androidx . compose . runtime . Composable
import androidx . compose . runtime . remember
import androidx . compose . runtime . LaunchedEffect
import androidx . compose . runtime . getValue
import androidx . compose . runtime . mutableStateOf
import androidx . compose . runtime . setValue
import androidx . compose . ui . platform . LocalContext
import com . github . kittinunf . fuel . httpPost
import com . github . kittinunf . fuel . json . responseJson
import com . stripe . android . PaymentConfiguration
import com . stripe . android . paymentsheet . PaymentSheet
import com . stripe . android . paymentsheet . PaymentSheetResult
import com . github . kittinunf . result . Result
@Composable
fun App ( ) {
val paymentSheet = remember { PaymentSheet . Builder ( :: onPaymentSheetResult ) } . build ( )
val context = LocalContext . current
var customerConfig by remember { mutableStateOf < PaymentSheet . CustomerConfiguration ? > ( null ) }
var paymentIntentClientSecret by remember { mutableStateOf < String ? > ( null ) }
LaunchedEffect ( context ) {
"Your backend endpoint/payment-sheet" . httpPost ( ) . responseJson { _ , _ , result ->
if ( result is Result . Success ) {
val responseJson = result . get ( ) . obj ( )
paymentIntentClientSecret = responseJson . getString ( "paymentIntent" )
customerConfig = PaymentSheet . CustomerConfiguration (
id = responseJson . getString ( "customer" ) ,
ephemeralKeySecret = responseJson . getString ( "ephemeralKey" )
)
val publishableKey = responseJson . getString ( "publishableKey" )
PaymentConfiguration . init ( context , publishableKey )
}
}
}
}
private fun onPaymentSheetResult ( paymentSheetResult : PaymentSheetResult ) {
}
当客户点击您的结账按钮时,调用 presentWithPaymentIntent 来显示支付表单。客户完成付款后,表单将消失,然后 PaymentSheetResult 将调用 PaymentSheetResultCallback 。
import androidx . compose . material . Button
import androidx . compose . material . Text
import androidx . compose . runtime . Composable
import androidx . compose . runtime . LaunchedEffect
import androidx . compose . runtime . getValue
import androidx . compose . runtime . mutableStateOf
import androidx . compose . runtime . remember
import androidx . compose . runtime . setValue
import androidx . compose . ui . platform . LocalContext
import com . github . kittinunf . fuel . httpPost
import com . github . kittinunf . fuel . json . responseJson
import com . stripe . android . PaymentConfiguration
import com . stripe . android . paymentsheet . PaymentSheet
import com . stripe . android . paymentsheet . PaymentSheetResult
import com . github . kittinunf . result . Result
@OptIn ( ExperimentalCustomerSessionApi :: class )
@Composable
fun App ( ) {
val paymentSheet = remember { PaymentSheet . Builder ( :: onPaymentSheetResult ) } . build ( )
val context = LocalContext . current
var customerConfig by remember { mutableStateOf < PaymentSheet . CustomerConfiguration ? > ( null ) }
var paymentIntentClientSecret by remember { mutableStateOf < String ? > ( null ) }
LaunchedEffect ( context ) {
"Your backend endpoint/payment-sheet" . httpPost ( ) . responseJson { _ , _ , result ->
if ( result is Result . Success ) {
val responseJson = result . get ( ) . obj ( )
paymentIntentClientSecret = responseJson . getString ( "paymentIntent" )
customerConfig = PaymentSheet . CustomerConfiguration (
id = responseJson . getString ( "customer" ) ,
ephemeralKeySecret = responseJson . getString ( "ephemeralKey" )
)
val publishableKey = responseJson . getString ( "publishableKey" )
PaymentConfiguration . init ( context , publishableKey )
}
}
}
Button (
onClick = {
val currentConfig = customerConfig
val currentClientSecret = paymentIntentClientSecret
if ( currentConfig != null && currentClientSecret != null ) {
presentPaymentSheet ( paymentSheet , currentConfig , currentClientSecret )
}
}
) {
Text ( "Checkout" )
}
}
private fun presentPaymentSheet (
paymentSheet : PaymentSheet ,
customerConfig : PaymentSheet . CustomerConfiguration ,
paymentIntentClientSecret : String
) {
paymentSheet . presentWithPaymentIntent (
paymentIntentClientSecret ,
PaymentSheet . Configuration . Builder ( merchantDisplayName = "My merchant name" )
. customer ( customerConfig )
. allowsDelayedPaymentMethods ( true )
. build ( )
)
}
private fun onPaymentSheetResult ( paymentSheetResult : PaymentSheetResult ) {
when ( paymentSheetResult ) {
is PaymentSheetResult . Canceled -> {
print ( "Canceled" )
}
is PaymentSheetResult . Failed -> {
print ( "Error: ${ paymentSheetResult . error } " )
}
is PaymentSheetResult . Completed -> {
print ( "Completed" )
}
}
}
将 allowsDelayedPaymentMethods
设置为 true,以允许延迟通知型 支付方式,例如美国银行账户。对于这些支付方式,只有当 PaymentSheet
完成后才能知道最终的付款状态是成功还是失败。如果您支持这些类型的支付方式,请告知客户他们的订单已被确认,并且仅在付款成功时履行订单(例如,为他们安排发货)。
测试集成
卡号 场景 如何测试 4242 4242 4242 4242 该卡付款成功,不需要验证。 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。 4000 0025 0000 3155 该卡付款时需要验证 。 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。 4000 0000 0000 9995 该卡被拒绝,显示拒付代码,例如 insufficient_ funds
。 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。 6205 5000 0000 0000 004 银联卡的长度为 13-19 位。 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。
有关测试您的集成的更多信息,请参阅测试 部分。