由于 API 密钥无效,Stripe 付款表无法打开:com.stripe.android.core.exception.AuthenticationException:提供的 API 密钥无效:

问题描述 投票:0回答:1

我正在尝试在我的 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,
)

我期待着付款单打开。

android kotlin stripe-payments project payment-gateway
1个回答
0
投票

您应该将临时密钥秘密传递给

PaymentSheet.CustomerConfiguration
,而不是临时密钥 ID。

ephemeral = res.body()!!.id
更改为
ephemeral = res.body()!!.secret
,然后重试。

© www.soinside.com 2019 - 2024. All rights reserved.