我正在尝试在我的 andorid 应用程序中使用 stripe 实现支付集成网关。我正在使用正确的 SECRET 密钥和 PUBLISHABLE 密钥。 Stripe 服务器发送对我的请求的响应,但当它发送 ephermal_key 时,付款表不会打开。我参考了本教程的实现:https://www.youtube.com/watch?v=dZI9HnRABKw&t=1196s.
当我单击付款按钮时,付款表会快速打开然后关闭。在我记录 paymentsheet.failure 后,我得到了这个 -> com.stripe.android.core.exception.AuthenticationException:提供的 API 密钥无效:ephkey_1******************** JPG .
StripePaymentGateway.kt
package com.example.gps_kotlin.Registration.Stripe
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import com.example.gps_kotlin.R
import com.example.gps_kotlin.Registration.Stripe.Utils.PUBLISHBLE_KEY
import com.example.gps_kotlin.Registration.Stripe.models.Customermodel
import com.stripe.android.PaymentConfiguration
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.PaymentSheetResult
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import retrofit2.Response
class StripePaymentGateway : AppCompatActivity() {
lateinit var paymentSheet : PaymentSheet
lateinit var customerId : String
lateinit var ephemeral : String
lateinit var clientSecret : String
private var isClientSecretInitialized = false
private var isCustomerIdInitialized = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_stripe_payment_gateway)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
val button = findViewById<Button>(R.id.button)
System.setProperty("stripe.android.debug", "true")
PaymentConfiguration.init(this, PUBLISHBLE_KEY)
paymentSheet = PaymentSheet(this, ::onPaymentSheetResult)
getCustomerID()
button.setOnClickListener {
if (isCustomerIdInitialized && isClientSecretInitialized) {
paymentFlow()
} else {
button.isEnabled = false
// Handle case where customerId or clientSecret is not initialized yet
// You can show a loading indicator or disable the button temporarily
Toast.makeText(this, "Please wait while we initialize payment details", Toast.LENGTH_SHORT).show()
}
}
}
private fun paymentFlow() {
Log.d("API KEYS", "$customerId, $ephemeral")
paymentSheet.presentWithPaymentIntent(
clientSecret,
PaymentSheet.Configuration("Tejas",
PaymentSheet.CustomerConfiguration(
customerId, ephemeral
)
)
)
}
private var apiInterface = Api_utilities.getApiInterface()
private fun getCustomerID() {
lifecycleScope.launch(Dispatchers.IO) {
val res = apiInterface.getCustomer()
withContext(Dispatchers.Main){
if (res.isSuccessful && res.body() != null) {
customerId = res.body()!!.id
getEphermaralKey(customerId)
isCustomerIdInitialized = true // Mark customerId as initialized
}
}
}
}
private fun getEphermaralKey(customerId : String) {
lifecycleScope.launch(Dispatchers.IO) {
val res = apiInterface.getEphermal(customerId)
withContext(Dispatchers.Main){
if(res.isSuccessful && res.body() != null)
{
ephemeral = res.body()!!.id
getPaymentIntent(customerId,ephemeral )
// Access customerModel here
}
}
}
}
private fun getPaymentIntent(customerId: String, ephemeral: String) {
lifecycleScope.launch(Dispatchers.IO) {
val res = apiInterface.getPaymentIntent(customerId)
withContext(Dispatchers.Main) {
if (res.isSuccessful && res.body() != null) {
clientSecret = res.body()!!.client_secret
isClientSecretInitialized = true // Mark clientSecret as initialized
Toast.makeText(this@StripePaymentGateway, "Proceed for Payment", Toast.LENGTH_LONG).show()
Log.d("Client", "c : $clientSecret")
}
}
}
}
fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {
when(paymentSheetResult) {
is PaymentSheetResult.Canceled -> {
Toast.makeText(this, "Canceled", Toast.LENGTH_LONG).show()
}
is PaymentSheetResult.Failed -> {
Toast.makeText(this, "Error: ${paymentSheetResult.error}", Toast.LENGTH_LONG).show()
Log.d("error", "${paymentSheetResult.error}")
}
is PaymentSheetResult.Completed -> {
// Display for example, an order confirmation screen
Toast.makeText(this, "Completed", Toast.LENGTH_LONG).show()
}
}
}
}
API_接口.kt
package com.example.gps_kotlin.Registration.Stripe
import com.example.gps_kotlin.Registration.Stripe.Utils.SECRET_KEY
import com.example.gps_kotlin.Registration.Stripe.models.PaymentIntentModel
import com.example.gps_kotlin.Registration.Stripe.models.Customermodel
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Headers
import retrofit2.http.POST
import retrofit2.http.Query
import retrofit2.Response
interface API_interface {
@Headers("Authorization: Bearer $SECRET_KEY")
@POST("v1/customers")
suspend fun getCustomer() : Response<Customermodel>
@Headers("Authorization: Bearer $SECRET_KEY","Stripe-Version: 2023-10-16")
@POST("v1/ephemeral_keys")
suspend fun getEphermal(
@Query("customer") customer : String
) : Response<Customermodel>
@Headers("Authorization: Bearer $SECRET_KEY")
@POST("v1/payment_intents")
suspend fun getPaymentIntent(@Query("customer") customer : String,
@Query("amount") amount : String = "100",
@Query("currency") currency : String = "inr",
@Query("automatic_payment_methods[enabled]") automatepay: Boolean = true
) : Response<PaymentIntentModel>
}
utlis.kt
package com.example.gps_kotlin.Registration.Stripe
object Utils {
const val PUBLISHBLE_KEY =
"pk_test_51P2zTTSCjUy49T37Pt64bus4H7zv4HU8pI1gozsvcnfSiCrUBrRS080d5EyL7PBAIsRBbphBzZE7QE1CEUScHWPu007a7krJWs"
const val SECRET_KEY =
"sk_test_51P2zTTSCjUy49T37fCezjCLMdzhhb5dtgS0gSaT2Oa4DAl2VH3zzHg6fu5PWbw7p66YpLqYJQHy4RThyn7tqz1QY00BJ2JAxI1"
}
api_utilitis.kt
package com.example.gps_kotlin.Registration.Stripe
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object Api_utilities {
fun getApiInterface() : API_interface {
return Retrofit.Builder().baseUrl("https://api.stripe.com/").addConverterFactory(GsonConverterFactory.create()).build().create(API_interface::class.java)
}
}
客户模型.kt
package com.example.gps_kotlin.Registration.Stripe.models
data class Customermodel(
val id : String,
)
支付意图模型.kt
package com.example.gps_kotlin.Registration.Stripe.models
data class PaymentIntentModel(
val id : String,
val client_secret : String,
)
我期待着付款单打开。
您应该将临时密钥秘密传递给
PaymentSheet.CustomerConfiguration
,而不是临时密钥 ID。
将
ephemeral = res.body()!!.id
更改为 ephemeral = res.body()!!.secret
,然后重试。