@@ -14,6 +14,7 @@ import kotlinx.coroutines.Dispatchers
1414import kotlinx.coroutines.launch
1515import org.json.JSONException
1616import org.json.JSONObject
17+ import kotlin.coroutines.cancellation.CancellationException
1718
1819/* *
1920 * Used to tokenize credit or debit cards using a [Card]. For more information see the
@@ -43,21 +44,13 @@ class CardClient internal constructor(
4344 /* *
4445 * Create a [CardNonce].
4546 *
46- *
4747 * The tokenization result is returned via a [CardTokenizeCallback] callback.
4848 *
49- *
50- *
5149 * On success, the [CardTokenizeCallback.onCardResult] method will be
5250 * invoked with a [CardResult.Success] including a nonce.
5351 *
54- *
55- *
5652 * If creation fails validation, the [CardTokenizeCallback.onCardResult]
57- * method will be invoked with a [CardResult.Failure] including an
58- * [ErrorWithResponse] exception.
59- *
60- *
53+ * method will be invoked with a [CardResult.Failure] including an exception.
6154 *
6255 * If an error not due to validation (server error, network issue, etc.) occurs, the
6356 * [CardTokenizeCallback.onCardResult] method will be invoked with a
@@ -67,79 +60,58 @@ class CardClient internal constructor(
6760 * @param callback [CardTokenizeCallback]
6861 */
6962 fun tokenize (card : Card , callback : CardTokenizeCallback ) {
63+ coroutineScope.launch {
64+ val result = tokenize(card)
65+ callback.onCardResult(result)
66+ }
67+ }
68+
69+ private suspend fun tokenize (card : Card ): CardResult {
7070 analyticsParamRepository.reset()
7171 braintreeClient.sendAnalyticsEvent(CardAnalytics .CARD_TOKENIZE_STARTED )
72- coroutineScope.launch {
73- try {
74- val configuration = braintreeClient.getConfiguration()
75- val shouldTokenizeViaGraphQL =
76- configuration.isGraphQLFeatureEnabled(
77- GraphQLConstants .Features .TOKENIZE_CREDIT_CARDS
78- )
79- if (shouldTokenizeViaGraphQL) {
80- card.sessionId = analyticsParamRepository.sessionId
81- try {
82- val tokenizePayload = card.buildJSONForGraphQL()
83- coroutineScope.launch {
84- try {
85- val tokenizationResponse =
86- apiClient.tokenizeGraphQL(tokenizePayload)
87- handleTokenizeResponse(tokenizationResponse, null , callback)
88- } catch (e: Exception ) {
89- handleTokenizeResponse(null , e, callback)
90- }
91- }
92- } catch (e: JSONException ) {
93- callbackFailure(callback, CardResult .Failure (e))
94- }
95- } else {
96- coroutineScope.launch {
97- try {
98- val tokenizationResponse = apiClient.tokenizeREST(card)
99- handleTokenizeResponse(tokenizationResponse, null , callback)
100- } catch (e: Exception ) {
101- handleTokenizeResponse(null , e, callback)
102- }
103- }
104- }
105- } catch (e: Exception ) {
106- callbackFailure(callback, CardResult .Failure (e))
72+ return try {
73+ val configuration = braintreeClient.getConfiguration()
74+ val shouldTokenizeViaGraphQL =
75+ configuration.isGraphQLFeatureEnabled(
76+ GraphQLConstants .Features .TOKENIZE_CREDIT_CARDS
77+ )
78+
79+ val tokenizationResponse = if (shouldTokenizeViaGraphQL) {
80+ card.sessionId = analyticsParamRepository.sessionId
81+ val tokenizePayload = card.buildJSONForGraphQL()
82+ apiClient.tokenizeGraphQL(tokenizePayload)
83+ } else {
84+ apiClient.tokenizeREST(card)
10785 }
86+
87+ handleTokenizeResponse(tokenizationResponse)
88+ } catch (e: Exception ) {
89+ if (e is CancellationException ) throw e
90+ tokenizeFailure(e)
10891 }
10992 }
11093
111- private fun handleTokenizeResponse (
112- tokenizationResponse : JSONObject ? , exception : Exception ? ,
113- callback : CardTokenizeCallback
114- ) {
115- if (tokenizationResponse != null ) {
116- if (tokenizationResponse.has(" errors" ) &&
117- tokenizationResponse.getJSONArray(GraphQLConstants .Keys .ERRORS ).length() > 0
118- ) {
119- callbackFailure(callback, CardResult .Failure (BraintreeException (tokenizationResponse.toString())))
120- return
121- }
94+ private fun handleTokenizeResponse (tokenizationResponse : JSONObject ): CardResult {
95+ return if (tokenizationResponse.has(" errors" ) &&
96+ tokenizationResponse.getJSONArray(GraphQLConstants .Keys .ERRORS ).length() > 0
97+ ) {
98+ tokenizeFailure(BraintreeException (tokenizationResponse.toString()))
99+ } else {
122100 try {
123101 val cardNonce = fromJSON(tokenizationResponse)
124- callbackSuccess(callback, CardResult .Success (cardNonce))
102+ braintreeClient.sendAnalyticsEvent(CardAnalytics .CARD_TOKENIZE_SUCCEEDED )
103+ CardResult .Success (cardNonce)
125104 } catch (e: JSONException ) {
126- callbackFailure(callback, CardResult . Failure (e) )
105+ tokenizeFailure(e )
127106 }
128- } else if (exception != null ) {
129- callbackFailure(callback, CardResult .Failure (exception))
130107 }
131108 }
132109
133- private fun callbackFailure ( callback : CardTokenizeCallback , cardResult : CardResult .Failure ) {
110+ private fun tokenizeFailure ( error : Exception ) : CardResult .Failure {
134111 braintreeClient.sendAnalyticsEvent(
135112 CardAnalytics .CARD_TOKENIZE_FAILED ,
136- AnalyticsEventParams (errorDescription = cardResult. error.message)
113+ AnalyticsEventParams (errorDescription = error.message)
137114 )
138- callback.onCardResult(cardResult)
139- }
140-
141- private fun callbackSuccess (callback : CardTokenizeCallback , cardResult : CardResult .Success ) {
142- braintreeClient.sendAnalyticsEvent(CardAnalytics .CARD_TOKENIZE_SUCCEEDED )
143- callback.onCardResult(cardResult)
115+ return CardResult .Failure (error)
144116 }
145117}
0 commit comments