@xbenjii/react-native-braintree-dropin-ui 2.5.0 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,366 +1,366 @@
1
- package com.xbenjii.RNBraintreeDropIn;
2
-
3
- import android.app.Activity;
4
-
5
- import androidx.annotation.NonNull;
6
- import androidx.fragment.app.FragmentActivity;
7
-
8
- import com.braintreepayments.api.BraintreeClient;
9
- import com.braintreepayments.api.DataCollector;
10
- import com.braintreepayments.api.Card;
11
- import com.braintreepayments.api.CardClient;
12
- import com.braintreepayments.api.DropInClient;
13
- import com.braintreepayments.api.DropInListener;
14
- import com.braintreepayments.api.DropInPaymentMethod;
15
- import com.braintreepayments.api.ThreeDSecureRequest;
16
- import com.braintreepayments.api.ThreeDSecureAdditionalInformation;
17
- import com.braintreepayments.api.ThreeDSecurePostalAddress;
18
- import com.braintreepayments.api.UserCanceledException;
19
- import com.braintreepayments.api.PayPalAccountNonce;
20
- import com.braintreepayments.api.GooglePayCardNonce;
21
- import com.braintreepayments.api.PostalAddress;
22
- import com.facebook.react.bridge.ReactApplicationContext;
23
- import com.facebook.react.bridge.ReactContextBaseJavaModule;
24
- import com.facebook.react.bridge.ReactMethod;
25
- import com.facebook.react.bridge.ReadableMap;
26
- import com.facebook.react.bridge.Arguments;
27
- import com.facebook.react.bridge.WritableMap;
28
- import com.facebook.react.bridge.Promise;
29
- import com.braintreepayments.api.DropInRequest;
30
- import com.braintreepayments.api.DropInResult;
31
- import com.braintreepayments.api.PaymentMethodNonce;
32
- import com.braintreepayments.api.CardNonce;
33
- import com.braintreepayments.api.ThreeDSecureInfo;
34
- import com.braintreepayments.api.GooglePayRequest;
35
- import com.google.android.gms.wallet.TransactionInfo;
36
- import com.google.android.gms.wallet.WalletConstants;
37
-
38
- import java.util.Objects;
39
-
40
- public class RNBraintreeDropInModule extends ReactContextBaseJavaModule {
41
- private boolean isVerifyingThreeDSecure = false;
42
- private static DropInClient dropInClient = null;
43
- private static String clientToken = null;
44
- public static final int GPAY_BILLING_ADDRESS_FORMAT_FULL = 1;
45
-
46
- public static void initDropInClient(FragmentActivity activity) {
47
- dropInClient = new DropInClient(activity, callback -> {
48
- if (clientToken != null) {
49
- callback.onSuccess(clientToken);
50
- } else {
51
- callback.onFailure(new Exception("Client token is null"));
52
- }
53
- });
54
- }
55
-
56
- public RNBraintreeDropInModule(ReactApplicationContext reactContext) {
57
- super(reactContext);
58
- }
59
-
60
- @ReactMethod
61
- public void show(final ReadableMap options, final Promise promise) {
62
- isVerifyingThreeDSecure = false;
63
-
64
- if (!options.hasKey("clientToken")) {
65
- promise.reject("NO_CLIENT_TOKEN", "You must provide a client token");
66
- return;
67
- }
68
-
69
- FragmentActivity currentActivity = (FragmentActivity) getCurrentActivity();
70
- if (currentActivity == null) {
71
- promise.reject("NO_ACTIVITY", "There is no current activity");
72
- return;
73
- }
74
-
75
- DropInRequest dropInRequest = new DropInRequest();
76
-
77
- if(options.hasKey("vaultManager")) {
78
- dropInRequest.setVaultManagerEnabled(options.getBoolean("vaultManager"));
79
- }
80
-
81
- if(options.hasKey("googlePay") && options.getBoolean("googlePay")){
82
- GooglePayRequest googlePayRequest = new GooglePayRequest();
83
- googlePayRequest.setTransactionInfo(TransactionInfo.newBuilder()
84
- .setTotalPrice(Objects.requireNonNull(options.getString("orderTotal")))
85
- .setTotalPriceStatus(WalletConstants.TOTAL_PRICE_STATUS_FINAL)
86
- .setCurrencyCode(Objects.requireNonNull(options.getString("currencyCode")))
87
- .build());
88
- googlePayRequest.setBillingAddressRequired(true);
89
- googlePayRequest.setEmailRequired(true);
90
- googlePayRequest.setBillingAddressFormat(GPAY_BILLING_ADDRESS_FORMAT_FULL);
91
- googlePayRequest.setGoogleMerchantId(options.getString("googlePayMerchantId"));
92
-
93
- dropInRequest.setGooglePayDisabled(false);
94
- dropInRequest.setGooglePayRequest(googlePayRequest);
95
- }else{
96
- dropInRequest.setGooglePayDisabled(true);
97
- }
98
-
99
- if(options.hasKey("cardDisabled")) {
100
- dropInRequest.setCardDisabled(options.getBoolean("cardDisabled"));
101
- }
102
-
103
- if (options.hasKey("threeDSecure")) {
104
- final ReadableMap threeDSecureOptions = options.getMap("threeDSecure");
105
- if (threeDSecureOptions == null || !threeDSecureOptions.hasKey("amount")) {
106
- promise.reject("NO_3DS_AMOUNT", "You must provide an amount for 3D Secure");
107
- return;
108
- }
109
-
110
- isVerifyingThreeDSecure = true;
111
-
112
- String amount = String.valueOf(threeDSecureOptions.getDouble("amount"));
113
-
114
- ThreeDSecureRequest threeDSecureRequest = new ThreeDSecureRequest();
115
- threeDSecureRequest.setAmount(threeDSecureOptions.getString("amount"));
116
- threeDSecureRequest.setVersionRequested(ThreeDSecureRequest.VERSION_2);
117
-
118
- if (threeDSecureOptions.hasKey("email")) {
119
- threeDSecureRequest.setEmail(threeDSecureOptions.getString("email"));
120
- }
121
-
122
- if(threeDSecureOptions.hasKey("billingAddress")) {
123
- final ReadableMap threeDSecureBillingAddress = threeDSecureOptions.getMap("billingAddress");
124
- ThreeDSecurePostalAddress billingAddress = new ThreeDSecurePostalAddress();
125
-
126
- if(threeDSecureBillingAddress.hasKey("givenName")) {
127
- billingAddress.setGivenName(threeDSecureBillingAddress.getString("givenName"));
128
- }
129
-
130
- if(threeDSecureBillingAddress.hasKey("surname")) {
131
- billingAddress.setGivenName(threeDSecureBillingAddress.getString("surname"));
132
- }
133
-
134
- if(threeDSecureBillingAddress.hasKey("streetAddress")) {
135
- billingAddress.setGivenName(threeDSecureBillingAddress.getString("streetAddress"));
136
- }
137
-
138
- if(threeDSecureBillingAddress.hasKey("extendedAddress")) {
139
- billingAddress.setGivenName(threeDSecureBillingAddress.getString("extendedAddress"));
140
- }
141
-
142
- if(threeDSecureBillingAddress.hasKey("locality")) {
143
- billingAddress.setGivenName(threeDSecureBillingAddress.getString("locality"));
144
- }
145
-
146
- if(threeDSecureBillingAddress.hasKey("region")) {
147
- billingAddress.setGivenName(threeDSecureBillingAddress.getString("region"));
148
- }
149
-
150
- if(threeDSecureBillingAddress.hasKey("countryCodeAlpha2")) {
151
- billingAddress.setGivenName(threeDSecureBillingAddress.getString("countryCodeAlpha2"));
152
- }
153
-
154
- if(threeDSecureBillingAddress.hasKey("postalCode")) {
155
- billingAddress.setGivenName(threeDSecureBillingAddress.getString("postalCode"));
156
- }
157
-
158
- threeDSecureRequest.setBillingAddress(billingAddress);
159
- }
160
-
161
- dropInRequest.setThreeDSecureRequest(threeDSecureRequest);
162
- }
163
-
164
- dropInRequest.setPayPalDisabled(!options.hasKey("payPal") || !options.getBoolean("payPal"));
165
-
166
- clientToken = options.getString("clientToken");
167
-
168
- if (dropInClient == null) {
169
- promise.reject(
170
- "DROP_IN_CLIENT_UNINITIALIZED",
171
- "Did you forget to call RNBraintreeDropInModule.initDropInClient(this) in MainActivity.onCreate?"
172
- );
173
- return;
174
- }
175
- dropInClient.setListener(new DropInListener() {
176
- @Override
177
- public void onDropInSuccess(@NonNull DropInResult dropInResult) {
178
- PaymentMethodNonce paymentMethodNonce = dropInResult.getPaymentMethodNonce();
179
-
180
- if (isVerifyingThreeDSecure && paymentMethodNonce instanceof CardNonce) {
181
- CardNonce cardNonce = (CardNonce) paymentMethodNonce;
182
- ThreeDSecureInfo threeDSecureInfo = cardNonce.getThreeDSecureInfo();
183
- if (!threeDSecureInfo.isLiabilityShiftPossible()) {
184
- promise.reject("3DSECURE_NOT_ABLE_TO_SHIFT_LIABILITY", "3D Secure liability cannot be shifted");
185
- } else if (!threeDSecureInfo.isLiabilityShifted()) {
186
- promise.reject("3DSECURE_LIABILITY_NOT_SHIFTED", "3D Secure liability was not shifted");
187
- } else {
188
- resolvePayment(dropInResult, promise);
189
- }
190
- } else {
191
- resolvePayment(dropInResult, promise);
192
- }
193
- }
194
-
195
- @Override
196
- public void onDropInFailure(@NonNull Exception exception) {
197
- if (exception instanceof UserCanceledException) {
198
- promise.reject("USER_CANCELLATION", "The user cancelled");
199
- } else {
200
- promise.reject(exception.getMessage(), exception.getMessage());
201
- }
202
- }
203
- });
204
- dropInClient.launchDropIn(dropInRequest);
205
- }
206
-
207
- @ReactMethod
208
- public void getDeviceData(final String clientToken, final Promise promise) {
209
- BraintreeClient braintreeClient = new BraintreeClient(getCurrentActivity(), clientToken);
210
- DataCollector dataCollector = new DataCollector(braintreeClient);
211
- dataCollector.collectDeviceData(getCurrentActivity(), (deviceData, error) -> {
212
- if (error != null) {
213
- promise.reject("ERROR", "Error collecting device data");
214
- } else {
215
- promise.resolve(deviceData);
216
- }
217
- });
218
- }
219
-
220
- @ReactMethod
221
- public void fetchMostRecentPaymentMethod(final String clientToken, final Promise promise) {
222
- FragmentActivity currentActivity = (FragmentActivity) getCurrentActivity();
223
-
224
- if (currentActivity == null) {
225
- promise.reject("NO_ACTIVITY", "There is no current activity");
226
- return;
227
- }
228
-
229
- if (dropInClient == null) {
230
- promise.reject(
231
- "DROP_IN_CLIENT_UNINITIALIZED",
232
- "Did you forget to call RNBraintreeDropInModule.initDropInClient(this) in MainActivity.onCreate?"
233
- );
234
- return;
235
- }
236
-
237
- RNBraintreeDropInModule.clientToken = clientToken;
238
-
239
- dropInClient.fetchMostRecentPaymentMethod(currentActivity, (dropInResult, error) -> {
240
- if (error != null) {
241
- promise.reject(error.getMessage(), error.getMessage());
242
- } else if (dropInResult == null) {
243
- promise.reject("NO_DROP_IN_RESULT", "dropInResult is null");
244
- } else {
245
- resolvePayment(dropInResult, promise);
246
- }
247
- });
248
- }
249
-
250
- @ReactMethod
251
- public void tokenizeCard(final String clientToken, final ReadableMap cardInfo, final Promise promise) {
252
- if (clientToken == null) {
253
- promise.reject("NO_CLIENT_TOKEN", "You must provide a client token");
254
- return;
255
- }
256
-
257
- if (
258
- !cardInfo.hasKey("number") ||
259
- !cardInfo.hasKey("expirationMonth") ||
260
- !cardInfo.hasKey("expirationYear") ||
261
- !cardInfo.hasKey("cvv") ||
262
- !cardInfo.hasKey("postalCode")
263
- ) {
264
- promise.reject("INVALID_CARD_INFO", "Invalid card info");
265
- return;
266
- }
267
-
268
- Activity currentActivity = getCurrentActivity();
269
-
270
- if (currentActivity == null) {
271
- promise.reject("NO_ACTIVITY", "There is no current activity");
272
- return;
273
- }
274
-
275
- BraintreeClient braintreeClient = new BraintreeClient(getCurrentActivity(), clientToken);
276
- CardClient cardClient = new CardClient(braintreeClient);
277
-
278
- Card card = new Card();
279
- card.setNumber(cardInfo.getString("number"));
280
- card.setExpirationMonth(cardInfo.getString("expirationMonth"));
281
- card.setExpirationYear(cardInfo.getString("expirationYear"));
282
- card.setCvv(cardInfo.getString("cvv"));
283
- card.setPostalCode(cardInfo.getString("postalCode"));
284
-
285
- cardClient.tokenize(card, (cardNonce, error) -> {
286
- if (error != null) {
287
- promise.reject(error.getMessage(), error.getMessage());
288
- } else if (cardNonce == null) {
289
- promise.reject("NO_CARD_NONCE", "Card nonce is null");
290
- } else {
291
- promise.resolve(cardNonce.getString());
292
- }
293
- });
294
- }
295
-
296
- private void resolvePayment(DropInResult dropInResult, Promise promise) {
297
- String deviceData = dropInResult.getDeviceData();
298
- PaymentMethodNonce paymentMethodNonce = dropInResult.getPaymentMethodNonce();
299
-
300
- WritableMap jsResult = Arguments.createMap();
301
-
302
- if (paymentMethodNonce == null) {
303
- promise.resolve(null);
304
- return;
305
- }
306
-
307
- Activity currentActivity = getCurrentActivity();
308
- if (currentActivity == null) {
309
- promise.reject("NO_ACTIVITY", "There is no current activity");
310
- return;
311
- }
312
-
313
- DropInPaymentMethod dropInPaymentMethod = dropInResult.getPaymentMethodType();
314
- if (dropInPaymentMethod == null) {
315
- promise.reject("NO_PAYMENT_METHOD", "There is no payment method");
316
- return;
317
- }
318
-
319
- PostalAddress billingAddress = null;
320
- if(paymentMethodNonce instanceof PayPalAccountNonce) {
321
- PayPalAccountNonce payPalAccountNonce = (PayPalAccountNonce) paymentMethodNonce;
322
- jsResult.putString("firstName", payPalAccountNonce.getFirstName());
323
- jsResult.putString("lastName", payPalAccountNonce.getLastName());
324
- jsResult.putString("email", payPalAccountNonce.getEmail());
325
- billingAddress = payPalAccountNonce.getBillingAddress();
326
- } else if (paymentMethodNonce instanceof GooglePayCardNonce) {
327
- GooglePayCardNonce googlePayCardNonce = (GooglePayCardNonce) paymentMethodNonce;
328
- billingAddress = googlePayCardNonce.getBillingAddress();
329
- jsResult.putString("email", googlePayCardNonce.getEmail());
330
- if(billingAddress != null) {
331
- String name = billingAddress.getRecipientName();
332
- if(!name.equals("")) {
333
- short lastIndexOfSpace = (short) name.lastIndexOf(" ");
334
- if(lastIndexOfSpace == -1) {
335
- jsResult.putString("firstName", name.trim());
336
- } else {
337
- jsResult.putString("firstName", name.substring(0, lastIndexOfSpace));
338
- jsResult.putString("lastName", name.substring(lastIndexOfSpace));
339
- }
340
- }
341
- }
342
- }
343
- if(billingAddress != null) {
344
- jsResult.putString("addressLine1", billingAddress.getStreetAddress());
345
- jsResult.putString("addressLine2", billingAddress.getExtendedAddress());
346
- jsResult.putString("city", billingAddress.getLocality());
347
- jsResult.putString("state", billingAddress.getRegion());
348
- jsResult.putString("country", billingAddress.getCountryCodeAlpha2());
349
- jsResult.putString("zip1", billingAddress.getPostalCode());
350
- }
351
-
352
- jsResult.putString("nonce", paymentMethodNonce.getString());
353
- jsResult.putString("type", currentActivity.getString(dropInPaymentMethod.getLocalizedName()));
354
- jsResult.putString("description", dropInResult.getPaymentDescription());
355
- jsResult.putBoolean("isDefault", paymentMethodNonce.isDefault());
356
- jsResult.putString("deviceData", deviceData);
357
-
358
- promise.resolve(jsResult);
359
- }
360
-
361
- @NonNull
362
- @Override
363
- public String getName() {
364
- return "RNBraintreeDropIn";
365
- }
366
- }
1
+ package com.xbenjii.RNBraintreeDropIn;
2
+
3
+ import android.app.Activity;
4
+
5
+ import androidx.annotation.NonNull;
6
+ import androidx.fragment.app.FragmentActivity;
7
+
8
+ import com.braintreepayments.api.BraintreeClient;
9
+ import com.braintreepayments.api.DataCollector;
10
+ import com.braintreepayments.api.Card;
11
+ import com.braintreepayments.api.CardClient;
12
+ import com.braintreepayments.api.DropInClient;
13
+ import com.braintreepayments.api.DropInListener;
14
+ import com.braintreepayments.api.DropInPaymentMethod;
15
+ import com.braintreepayments.api.ThreeDSecureRequest;
16
+ import com.braintreepayments.api.ThreeDSecureAdditionalInformation;
17
+ import com.braintreepayments.api.ThreeDSecurePostalAddress;
18
+ import com.braintreepayments.api.UserCanceledException;
19
+ import com.braintreepayments.api.PayPalAccountNonce;
20
+ import com.braintreepayments.api.GooglePayCardNonce;
21
+ import com.braintreepayments.api.PostalAddress;
22
+ import com.facebook.react.bridge.ReactApplicationContext;
23
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
24
+ import com.facebook.react.bridge.ReactMethod;
25
+ import com.facebook.react.bridge.ReadableMap;
26
+ import com.facebook.react.bridge.Arguments;
27
+ import com.facebook.react.bridge.WritableMap;
28
+ import com.facebook.react.bridge.Promise;
29
+ import com.braintreepayments.api.DropInRequest;
30
+ import com.braintreepayments.api.DropInResult;
31
+ import com.braintreepayments.api.PaymentMethodNonce;
32
+ import com.braintreepayments.api.CardNonce;
33
+ import com.braintreepayments.api.ThreeDSecureInfo;
34
+ import com.braintreepayments.api.GooglePayRequest;
35
+ import com.google.android.gms.wallet.TransactionInfo;
36
+ import com.google.android.gms.wallet.WalletConstants;
37
+
38
+ import java.util.Objects;
39
+
40
+ public class RNBraintreeDropInModule extends ReactContextBaseJavaModule {
41
+ private boolean isVerifyingThreeDSecure = false;
42
+ private static DropInClient dropInClient = null;
43
+ private static String clientToken = null;
44
+ public static final int GPAY_BILLING_ADDRESS_FORMAT_FULL = 1;
45
+
46
+ public static void initDropInClient(FragmentActivity activity) {
47
+ dropInClient = new DropInClient(activity, callback -> {
48
+ if (clientToken != null) {
49
+ callback.onSuccess(clientToken);
50
+ } else {
51
+ callback.onFailure(new Exception("Client token is null"));
52
+ }
53
+ });
54
+ }
55
+
56
+ public RNBraintreeDropInModule(ReactApplicationContext reactContext) {
57
+ super(reactContext);
58
+ }
59
+
60
+ @ReactMethod
61
+ public void show(final ReadableMap options, final Promise promise) {
62
+ isVerifyingThreeDSecure = false;
63
+
64
+ if (!options.hasKey("clientToken")) {
65
+ promise.reject("NO_CLIENT_TOKEN", "You must provide a client token");
66
+ return;
67
+ }
68
+
69
+ FragmentActivity currentActivity = (FragmentActivity) getCurrentActivity();
70
+ if (currentActivity == null) {
71
+ promise.reject("NO_ACTIVITY", "There is no current activity");
72
+ return;
73
+ }
74
+
75
+ DropInRequest dropInRequest = new DropInRequest();
76
+
77
+ if(options.hasKey("vaultManager")) {
78
+ dropInRequest.setVaultManagerEnabled(options.getBoolean("vaultManager"));
79
+ }
80
+
81
+ if(options.hasKey("googlePay") && options.getBoolean("googlePay")){
82
+ GooglePayRequest googlePayRequest = new GooglePayRequest();
83
+ googlePayRequest.setTransactionInfo(TransactionInfo.newBuilder()
84
+ .setTotalPrice(Objects.requireNonNull(options.getString("orderTotal")))
85
+ .setTotalPriceStatus(WalletConstants.TOTAL_PRICE_STATUS_FINAL)
86
+ .setCurrencyCode(Objects.requireNonNull(options.getString("currencyCode")))
87
+ .build());
88
+ googlePayRequest.setBillingAddressRequired(true);
89
+ googlePayRequest.setEmailRequired(true);
90
+ googlePayRequest.setBillingAddressFormat(GPAY_BILLING_ADDRESS_FORMAT_FULL);
91
+ googlePayRequest.setGoogleMerchantId(options.getString("googlePayMerchantId"));
92
+
93
+ dropInRequest.setGooglePayDisabled(false);
94
+ dropInRequest.setGooglePayRequest(googlePayRequest);
95
+ }else{
96
+ dropInRequest.setGooglePayDisabled(true);
97
+ }
98
+
99
+ if(options.hasKey("cardDisabled")) {
100
+ dropInRequest.setCardDisabled(options.getBoolean("cardDisabled"));
101
+ }
102
+
103
+ if (options.hasKey("threeDSecure")) {
104
+ final ReadableMap threeDSecureOptions = options.getMap("threeDSecure");
105
+ if (threeDSecureOptions == null || !threeDSecureOptions.hasKey("amount")) {
106
+ promise.reject("NO_3DS_AMOUNT", "You must provide an amount for 3D Secure");
107
+ return;
108
+ }
109
+
110
+ isVerifyingThreeDSecure = true;
111
+
112
+ String amount = String.valueOf(threeDSecureOptions.getDouble("amount"));
113
+
114
+ ThreeDSecureRequest threeDSecureRequest = new ThreeDSecureRequest();
115
+ threeDSecureRequest.setAmount(amount);
116
+ threeDSecureRequest.setVersionRequested(ThreeDSecureRequest.VERSION_2);
117
+
118
+ if (threeDSecureOptions.hasKey("email")) {
119
+ threeDSecureRequest.setEmail(threeDSecureOptions.getString("email"));
120
+ }
121
+
122
+ if(threeDSecureOptions.hasKey("billingAddress")) {
123
+ final ReadableMap threeDSecureBillingAddress = threeDSecureOptions.getMap("billingAddress");
124
+ ThreeDSecurePostalAddress billingAddress = new ThreeDSecurePostalAddress();
125
+
126
+ if(threeDSecureBillingAddress.hasKey("givenName")) {
127
+ billingAddress.setGivenName(threeDSecureBillingAddress.getString("givenName"));
128
+ }
129
+
130
+ if(threeDSecureBillingAddress.hasKey("surname")) {
131
+ billingAddress.setGivenName(threeDSecureBillingAddress.getString("surname"));
132
+ }
133
+
134
+ if(threeDSecureBillingAddress.hasKey("streetAddress")) {
135
+ billingAddress.setGivenName(threeDSecureBillingAddress.getString("streetAddress"));
136
+ }
137
+
138
+ if(threeDSecureBillingAddress.hasKey("extendedAddress")) {
139
+ billingAddress.setGivenName(threeDSecureBillingAddress.getString("extendedAddress"));
140
+ }
141
+
142
+ if(threeDSecureBillingAddress.hasKey("locality")) {
143
+ billingAddress.setGivenName(threeDSecureBillingAddress.getString("locality"));
144
+ }
145
+
146
+ if(threeDSecureBillingAddress.hasKey("region")) {
147
+ billingAddress.setGivenName(threeDSecureBillingAddress.getString("region"));
148
+ }
149
+
150
+ if(threeDSecureBillingAddress.hasKey("countryCodeAlpha2")) {
151
+ billingAddress.setGivenName(threeDSecureBillingAddress.getString("countryCodeAlpha2"));
152
+ }
153
+
154
+ if(threeDSecureBillingAddress.hasKey("postalCode")) {
155
+ billingAddress.setGivenName(threeDSecureBillingAddress.getString("postalCode"));
156
+ }
157
+
158
+ threeDSecureRequest.setBillingAddress(billingAddress);
159
+ }
160
+
161
+ dropInRequest.setThreeDSecureRequest(threeDSecureRequest);
162
+ }
163
+
164
+ dropInRequest.setPayPalDisabled(!options.hasKey("payPal") || !options.getBoolean("payPal"));
165
+
166
+ clientToken = options.getString("clientToken");
167
+
168
+ if (dropInClient == null) {
169
+ promise.reject(
170
+ "DROP_IN_CLIENT_UNINITIALIZED",
171
+ "Did you forget to call RNBraintreeDropInModule.initDropInClient(this) in MainActivity.onCreate?"
172
+ );
173
+ return;
174
+ }
175
+ dropInClient.setListener(new DropInListener() {
176
+ @Override
177
+ public void onDropInSuccess(@NonNull DropInResult dropInResult) {
178
+ PaymentMethodNonce paymentMethodNonce = dropInResult.getPaymentMethodNonce();
179
+
180
+ if (isVerifyingThreeDSecure && paymentMethodNonce instanceof CardNonce) {
181
+ CardNonce cardNonce = (CardNonce) paymentMethodNonce;
182
+ ThreeDSecureInfo threeDSecureInfo = cardNonce.getThreeDSecureInfo();
183
+ if (!threeDSecureInfo.isLiabilityShiftPossible()) {
184
+ promise.reject("3DSECURE_NOT_ABLE_TO_SHIFT_LIABILITY", "3D Secure liability cannot be shifted");
185
+ } else if (!threeDSecureInfo.isLiabilityShifted()) {
186
+ promise.reject("3DSECURE_LIABILITY_NOT_SHIFTED", "3D Secure liability was not shifted");
187
+ } else {
188
+ resolvePayment(dropInResult, promise);
189
+ }
190
+ } else {
191
+ resolvePayment(dropInResult, promise);
192
+ }
193
+ }
194
+
195
+ @Override
196
+ public void onDropInFailure(@NonNull Exception exception) {
197
+ if (exception instanceof UserCanceledException) {
198
+ promise.reject("USER_CANCELLATION", "The user cancelled");
199
+ } else {
200
+ promise.reject(exception.getMessage(), exception.getMessage());
201
+ }
202
+ }
203
+ });
204
+ dropInClient.launchDropIn(dropInRequest);
205
+ }
206
+
207
+ @ReactMethod
208
+ public void getDeviceData(final String clientToken, final Promise promise) {
209
+ BraintreeClient braintreeClient = new BraintreeClient(getCurrentActivity(), clientToken);
210
+ DataCollector dataCollector = new DataCollector(braintreeClient);
211
+ dataCollector.collectDeviceData(getCurrentActivity(), (deviceData, error) -> {
212
+ if (error != null) {
213
+ promise.reject("ERROR", "Error collecting device data");
214
+ } else {
215
+ promise.resolve(deviceData);
216
+ }
217
+ });
218
+ }
219
+
220
+ @ReactMethod
221
+ public void fetchMostRecentPaymentMethod(final String clientToken, final Promise promise) {
222
+ FragmentActivity currentActivity = (FragmentActivity) getCurrentActivity();
223
+
224
+ if (currentActivity == null) {
225
+ promise.reject("NO_ACTIVITY", "There is no current activity");
226
+ return;
227
+ }
228
+
229
+ if (dropInClient == null) {
230
+ promise.reject(
231
+ "DROP_IN_CLIENT_UNINITIALIZED",
232
+ "Did you forget to call RNBraintreeDropInModule.initDropInClient(this) in MainActivity.onCreate?"
233
+ );
234
+ return;
235
+ }
236
+
237
+ RNBraintreeDropInModule.clientToken = clientToken;
238
+
239
+ dropInClient.fetchMostRecentPaymentMethod(currentActivity, (dropInResult, error) -> {
240
+ if (error != null) {
241
+ promise.reject(error.getMessage(), error.getMessage());
242
+ } else if (dropInResult == null) {
243
+ promise.reject("NO_DROP_IN_RESULT", "dropInResult is null");
244
+ } else {
245
+ resolvePayment(dropInResult, promise);
246
+ }
247
+ });
248
+ }
249
+
250
+ @ReactMethod
251
+ public void tokenizeCard(final String clientToken, final ReadableMap cardInfo, final Promise promise) {
252
+ if (clientToken == null) {
253
+ promise.reject("NO_CLIENT_TOKEN", "You must provide a client token");
254
+ return;
255
+ }
256
+
257
+ if (
258
+ !cardInfo.hasKey("number") ||
259
+ !cardInfo.hasKey("expirationMonth") ||
260
+ !cardInfo.hasKey("expirationYear") ||
261
+ !cardInfo.hasKey("cvv") ||
262
+ !cardInfo.hasKey("postalCode")
263
+ ) {
264
+ promise.reject("INVALID_CARD_INFO", "Invalid card info");
265
+ return;
266
+ }
267
+
268
+ Activity currentActivity = getCurrentActivity();
269
+
270
+ if (currentActivity == null) {
271
+ promise.reject("NO_ACTIVITY", "There is no current activity");
272
+ return;
273
+ }
274
+
275
+ BraintreeClient braintreeClient = new BraintreeClient(getCurrentActivity(), clientToken);
276
+ CardClient cardClient = new CardClient(braintreeClient);
277
+
278
+ Card card = new Card();
279
+ card.setNumber(cardInfo.getString("number"));
280
+ card.setExpirationMonth(cardInfo.getString("expirationMonth"));
281
+ card.setExpirationYear(cardInfo.getString("expirationYear"));
282
+ card.setCvv(cardInfo.getString("cvv"));
283
+ card.setPostalCode(cardInfo.getString("postalCode"));
284
+
285
+ cardClient.tokenize(card, (cardNonce, error) -> {
286
+ if (error != null) {
287
+ promise.reject(error.getMessage(), error.getMessage());
288
+ } else if (cardNonce == null) {
289
+ promise.reject("NO_CARD_NONCE", "Card nonce is null");
290
+ } else {
291
+ promise.resolve(cardNonce.getString());
292
+ }
293
+ });
294
+ }
295
+
296
+ private void resolvePayment(DropInResult dropInResult, Promise promise) {
297
+ String deviceData = dropInResult.getDeviceData();
298
+ PaymentMethodNonce paymentMethodNonce = dropInResult.getPaymentMethodNonce();
299
+
300
+ WritableMap jsResult = Arguments.createMap();
301
+
302
+ if (paymentMethodNonce == null) {
303
+ promise.resolve(null);
304
+ return;
305
+ }
306
+
307
+ Activity currentActivity = getCurrentActivity();
308
+ if (currentActivity == null) {
309
+ promise.reject("NO_ACTIVITY", "There is no current activity");
310
+ return;
311
+ }
312
+
313
+ DropInPaymentMethod dropInPaymentMethod = dropInResult.getPaymentMethodType();
314
+ if (dropInPaymentMethod == null) {
315
+ promise.reject("NO_PAYMENT_METHOD", "There is no payment method");
316
+ return;
317
+ }
318
+
319
+ PostalAddress billingAddress = null;
320
+ if(paymentMethodNonce instanceof PayPalAccountNonce) {
321
+ PayPalAccountNonce payPalAccountNonce = (PayPalAccountNonce) paymentMethodNonce;
322
+ jsResult.putString("firstName", payPalAccountNonce.getFirstName());
323
+ jsResult.putString("lastName", payPalAccountNonce.getLastName());
324
+ jsResult.putString("email", payPalAccountNonce.getEmail());
325
+ billingAddress = payPalAccountNonce.getBillingAddress();
326
+ } else if (paymentMethodNonce instanceof GooglePayCardNonce) {
327
+ GooglePayCardNonce googlePayCardNonce = (GooglePayCardNonce) paymentMethodNonce;
328
+ billingAddress = googlePayCardNonce.getBillingAddress();
329
+ jsResult.putString("email", googlePayCardNonce.getEmail());
330
+ if(billingAddress != null) {
331
+ String name = billingAddress.getRecipientName();
332
+ if(!name.equals("")) {
333
+ short lastIndexOfSpace = (short) name.lastIndexOf(" ");
334
+ if(lastIndexOfSpace == -1) {
335
+ jsResult.putString("firstName", name.trim());
336
+ } else {
337
+ jsResult.putString("firstName", name.substring(0, lastIndexOfSpace));
338
+ jsResult.putString("lastName", name.substring(lastIndexOfSpace));
339
+ }
340
+ }
341
+ }
342
+ }
343
+ if(billingAddress != null) {
344
+ jsResult.putString("addressLine1", billingAddress.getStreetAddress());
345
+ jsResult.putString("addressLine2", billingAddress.getExtendedAddress());
346
+ jsResult.putString("city", billingAddress.getLocality());
347
+ jsResult.putString("state", billingAddress.getRegion());
348
+ jsResult.putString("country", billingAddress.getCountryCodeAlpha2());
349
+ jsResult.putString("zip1", billingAddress.getPostalCode());
350
+ }
351
+
352
+ jsResult.putString("nonce", paymentMethodNonce.getString());
353
+ jsResult.putString("type", currentActivity.getString(dropInPaymentMethod.getLocalizedName()));
354
+ jsResult.putString("description", dropInResult.getPaymentDescription());
355
+ jsResult.putBoolean("isDefault", paymentMethodNonce.isDefault());
356
+ jsResult.putString("deviceData", deviceData);
357
+
358
+ promise.resolve(jsResult);
359
+ }
360
+
361
+ @NonNull
362
+ @Override
363
+ public String getName() {
364
+ return "RNBraintreeDropIn";
365
+ }
366
+ }