├── .gitattributes
├── .npmignore
├── index.js
├── react-native.config.js
├── android
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── tech
│ │ └── bam
│ │ └── RNBraintreeDropIn
│ │ ├── RNBraintreeDropInPackage.java
│ │ └── RNBraintreeDropInModule.java
└── build.gradle
├── ios
├── RNBraintreeDropIn.xcworkspace
│ └── contents.xcworkspacedata
├── RNBraintreeDropIn.h
├── RNBraintreeDropIn.podspec
├── RNBraintreeDropIn.m
└── RNBraintreeDropIn.xcodeproj
│ └── project.pbxproj
├── index.js.flow
├── .gitignore
├── package.json
├── LICENSE
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj -text
2 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | *.test.js
2 | __snapshots/**
3 | .babelrc
4 | .eslintrc
5 | .eslintignore
6 | .flowconfig
7 | .yarn.lock
8 | .gitattributes
9 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import { NativeModules } from 'react-native';
2 |
3 | const { RNBraintreeDropIn } = NativeModules;
4 |
5 | export default RNBraintreeDropIn;
6 |
--------------------------------------------------------------------------------
/react-native.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | project: {
3 | ios: {
4 | podspecPath: './ios/RNBraintreeDropIn.podspec'
5 | },
6 | android: {},
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ios/RNBraintreeDropIn.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 |
3 |
5 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/index.js.flow:
--------------------------------------------------------------------------------
1 | type ShowOptions = {|
2 | clientToken: string,
3 | threeDSecure?: {|
4 | amount: number,
5 | |},
6 | |};
7 |
8 | type ShowResult = {|
9 | nonce: string,
10 | description: string,
11 | type: string,
12 | isDefault: boolean,
13 | |};
14 |
15 | declare module.exports: {
16 | show: (options: ShowOptions) => Promise,
17 | };
18 |
--------------------------------------------------------------------------------
/ios/RNBraintreeDropIn.h:
--------------------------------------------------------------------------------
1 | #if __has_include("RCTBridgeModule.h")
2 | #import "RCTBridgeModule.h"
3 | #else
4 | #import
5 | #endif
6 |
7 | #import "BraintreeCore.h"
8 | #import "BraintreeDropIn.h"
9 | #import "BTCardNonce.h"
10 |
11 | @interface RNBraintreeDropIn : NSObject
12 |
13 | @property (nonatomic, strong) UIViewController* _Nonnull reactRoot;
14 |
15 | + (void)resolvePayment:(BTDropInResult* _Nullable)result resolver:(RCTPromiseResolveBlock _Nonnull)resolve;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # node.js
6 | #
7 | node_modules/
8 | npm-debug.log
9 | yarn-error.log
10 |
11 |
12 | # Xcode
13 | #
14 | build/
15 | *.pbxuser
16 | !default.pbxuser
17 | *.mode1v3
18 | !default.mode1v3
19 | *.mode2v3
20 | !default.mode2v3
21 | *.perspectivev3
22 | !default.perspectivev3
23 | xcuserdata
24 | *.xccheckout
25 | *.moved-aside
26 | DerivedData
27 | *.hmap
28 | *.ipa
29 | *.xcuserstate
30 | project.xcworkspace
31 |
32 |
33 | # Android/IntelliJ
34 | #
35 | build/
36 | .idea
37 | .gradle
38 | local.properties
39 | *.iml
40 |
41 | # BUCK
42 | buck-out/
43 | \.buckd/
44 | *.keystore
45 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-braintree-payments-drop-in",
3 | "version": "1.2.0",
4 | "description": "React Native integration of Braintree Drop-in",
5 | "main": "index.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "git@github.com:bamlab/react-native-braintree-payments-drop-in.git"
9 | },
10 | "scripts": {
11 | "test": "echo \"Error: no test specified\" && exit 1"
12 | },
13 | "keywords": [
14 | "react-native",
15 | "braintree",
16 | "payments",
17 | "drop-in"
18 | ],
19 | "author": {
20 | "name": "Louis Lagrange",
21 | "email": "lagrange.louis@gmail.com",
22 | "url": "https://github.com/Minishlink"
23 | },
24 | "license": "MIT",
25 | "peerDependencies": {
26 | "react-native": "*"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ios/RNBraintreeDropIn.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "RNBraintreeDropIn"
3 | s.version = "1.0.0"
4 | s.summary = "RNBraintreeDropIn"
5 | s.description = <<-DESC
6 | RNBraintreeDropIn
7 | DESC
8 | s.homepage = "https://github.com/bamlab/react-native-braintree-payments-drop-in"
9 | s.license = "MIT"
10 | # s.license = { :type => "MIT", :file => "../LICENSE" }
11 | s.author = { "author" => "lagrange.louis@gmail.com" }
12 | s.platform = :ios, "9.0"
13 | s.source = { :git => "https://github.com/bamlab/react-native-braintree-payments-drop-in.git", :tag => "master" }
14 | s.source_files = "*.{h,m}"
15 | s.requires_arc = true
16 |
17 | s.dependency "React"
18 | s.dependency "BraintreeDropIn", '~> 7.4'
19 | end
20 |
--------------------------------------------------------------------------------
/android/src/main/java/tech/bam/RNBraintreeDropIn/RNBraintreeDropInPackage.java:
--------------------------------------------------------------------------------
1 | package tech.bam.RNBraintreeDropIn;
2 |
3 | import java.util.Arrays;
4 | import java.util.Collections;
5 | import java.util.List;
6 |
7 | import com.facebook.react.ReactPackage;
8 | import com.facebook.react.bridge.NativeModule;
9 | import com.facebook.react.bridge.ReactApplicationContext;
10 | import com.facebook.react.uimanager.ViewManager;
11 | import com.facebook.react.bridge.JavaScriptModule;
12 | public class RNBraintreeDropInPackage implements ReactPackage {
13 | @Override
14 | public List createNativeModules(ReactApplicationContext reactContext) {
15 | return Arrays.asList(new RNBraintreeDropInModule(reactContext));
16 | }
17 |
18 | // Deprecated from RN 0.47
19 | public List> createJSModules() {
20 | return Collections.emptyList();
21 | }
22 |
23 | @Override
24 | public List createViewManagers(ReactApplicationContext reactContext) {
25 | return Collections.emptyList();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Louis Lagrange
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | jcenter()
4 | google()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:3.2.1'
9 | }
10 | }
11 |
12 | apply plugin: 'com.android.library'
13 |
14 | android {
15 | compileSdkVersion 28
16 | buildToolsVersion "28.0.3"
17 |
18 | defaultConfig {
19 | minSdkVersion 21
20 | targetSdkVersion 28
21 | versionCode 1
22 | versionName "1.0"
23 | }
24 | lintOptions {
25 | abortOnError false
26 | }
27 | }
28 |
29 | repositories {
30 | mavenCentral()
31 | google()
32 | }
33 |
34 | dependencies {
35 | implementation 'com.braintreepayments.api:drop-in:4.+'
36 | implementation 'com.facebook.react:react-native:+'
37 | }
38 |
39 | // https://developers.braintreepayments.com/guides/3d-secure/migration/android/v3
40 | rootProject.allprojects {
41 | repositories {
42 | maven {
43 | url "https://cardinalcommerce.bintray.com/android"
44 | credentials {
45 | username 'braintree-team-sdk@cardinalcommerce'
46 | password '220cc9476025679c4e5c843666c27d97cfb0f951'
47 | }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/ios/RNBraintreeDropIn.m:
--------------------------------------------------------------------------------
1 | #import "RNBraintreeDropIn.h"
2 |
3 | @implementation RNBraintreeDropIn
4 |
5 | - (dispatch_queue_t)methodQueue
6 | {
7 | return dispatch_get_main_queue();
8 | }
9 | RCT_EXPORT_MODULE()
10 |
11 | RCT_REMAP_METHOD(show,
12 | showWithOptions:(NSDictionary*)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
13 | {
14 | NSString* clientToken = options[@"clientToken"];
15 | if (!clientToken) {
16 | reject(@"NO_CLIENT_TOKEN", @"You must provide a client token", nil);
17 | return;
18 | }
19 |
20 | BTDropInRequest *request = [[BTDropInRequest alloc] init];
21 |
22 | NSDictionary* threeDSecureOptions = options[@"threeDSecure"];
23 | if (threeDSecureOptions) {
24 | NSNumber* threeDSecureAmount = threeDSecureOptions[@"amount"];
25 | if (!threeDSecureAmount) {
26 | reject(@"NO_3DS_AMOUNT", @"You must provide an amount for 3D Secure", nil);
27 | return;
28 | }
29 |
30 | request.threeDSecureVerification = YES;
31 | request.amount = [threeDSecureAmount stringValue];
32 | }
33 |
34 | BTDropInController *dropIn = [[BTDropInController alloc] initWithAuthorization:clientToken request:request handler:^(BTDropInController * _Nonnull controller, BTDropInResult * _Nullable result, NSError * _Nullable error) {
35 | [self.reactRoot dismissViewControllerAnimated:YES completion:nil];
36 |
37 | if (error != nil) {
38 | reject(error.localizedDescription, error.localizedDescription, error);
39 | } else if (result.cancelled) {
40 | reject(@"USER_CANCELLATION", @"The user cancelled", nil);
41 | } else {
42 | if (threeDSecureOptions && [result.paymentMethod isKindOfClass:[BTCardNonce class]]) {
43 | BTCardNonce *cardNonce = (BTCardNonce *)result.paymentMethod;
44 | if (!cardNonce.threeDSecureInfo.liabilityShiftPossible && cardNonce.threeDSecureInfo.wasVerified) {
45 | reject(@"3DSECURE_NOT_ABLE_TO_SHIFT_LIABILITY", @"3D Secure liability cannot be shifted", nil);
46 | } else if (!cardNonce.threeDSecureInfo.liabilityShifted && cardNonce.threeDSecureInfo.wasVerified) {
47 | reject(@"3DSECURE_LIABILITY_NOT_SHIFTED", @"3D Secure liability was not shifted", nil);
48 | } else {
49 | [[self class] resolvePayment :result resolver:resolve];
50 | }
51 | } else {
52 | [[self class] resolvePayment :result resolver:resolve];
53 | }
54 | }
55 | }];
56 |
57 | if (dropIn != nil) {
58 | [self.reactRoot presentViewController:dropIn animated:YES completion:nil];
59 | } else {
60 | reject(@"INVALID_CLIENT_TOKEN", @"The client token seems invalid", nil);
61 | }
62 | }
63 |
64 | + (void)resolvePayment:(BTDropInResult* _Nullable)result resolver:(RCTPromiseResolveBlock _Nonnull)resolve {
65 | NSMutableDictionary* jsResult = [NSMutableDictionary new];
66 | [jsResult setObject:result.paymentMethod.nonce forKey:@"nonce"];
67 | [jsResult setObject:result.paymentMethod.type forKey:@"type"];
68 | [jsResult setObject:result.paymentDescription forKey:@"description"];
69 | [jsResult setObject:[NSNumber numberWithBool:result.paymentMethod.isDefault] forKey:@"isDefault"];
70 | resolve(jsResult);
71 | }
72 |
73 | - (UIViewController*)reactRoot {
74 | UIViewController *root = [UIApplication sharedApplication].keyWindow.rootViewController;
75 | UIViewController *maybeModal = root.presentedViewController;
76 |
77 | UIViewController *modalRoot = root;
78 |
79 | if (maybeModal != nil) {
80 | modalRoot = maybeModal;
81 | }
82 |
83 | return modalRoot;
84 | }
85 |
86 | @end
87 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-braintree-payments-drop-in
2 |
3 | > React Native integration of Braintree Drop-in
4 |
5 | ## Getting started
6 |
7 | ```bash
8 | yarn add react-native-braintree-payments-drop-in
9 | ```
10 |
11 | ### Mostly automatic installation
12 |
13 | ```bash
14 | # Run this only if you are on RN < 0.60
15 | react-native link react-native-braintree-payments-drop-in
16 | ```
17 |
18 | #### iOS specific
19 |
20 | You must have a iOS deployment target >= 9.0.
21 |
22 | If you don't have a Podfile or are unsure on how to proceed, see the [CocoaPods](http://guides.cocoapods.org/using/using-cocoapods.html) usage guide.
23 |
24 | In your `Podfile`, add:
25 |
26 | ```
27 | # uncomment the next line if you are on RN < 0.60
28 | #pod 'BraintreeDropIn', '~> 6.0'
29 |
30 | # uncomment the next line to support credit card scanning
31 | # pod 'CardIO'
32 | ```
33 |
34 | Then:
35 |
36 | ```bash
37 | cd ios
38 | bundle exec pod repo update # optional and can be very long
39 | bundle exec pod install
40 | ```
41 |
42 | #### Android specific
43 |
44 | If you want to add card scanning, add in your `app/build.gradle`:
45 |
46 | ```
47 | dependencies {
48 | ...
49 | implementation "io.card:android-sdk:5.+"
50 | ```
51 |
52 | ### Configuration
53 |
54 | For more configuration options, see Braintree's documentation ([iOS](https://github.com/braintree/braintree-ios-drop-in) | [Android](https://github.com/braintree/braintree-android-drop-in)).
55 |
56 | #### 3D Secure
57 |
58 | If you plan on using 3D Secure, you have to do the following.
59 |
60 | ##### iOS
61 |
62 | ###### Configure a new URL scheme
63 |
64 | Add a bundle url scheme `{BUNDLE_IDENTIFIER}.payments` in your app Info via XCode or manually in the `Info.plist`.
65 | In your `Info.plist`, you should have something like:
66 |
67 | ```xml
68 | CFBundleURLTypes
69 |
70 |
71 | CFBundleTypeRole
72 | Editor
73 | CFBundleURLName
74 | com.myapp
75 | CFBundleURLSchemes
76 |
77 | com.myapp.payments
78 |
79 |
80 |
81 | ```
82 |
83 | ###### Update your code
84 |
85 | In your `AppDelegate.m`:
86 |
87 | ```objective-c
88 | #import "BraintreeCore.h"
89 |
90 | ...
91 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
92 | {
93 | ...
94 | [BTAppSwitch setReturnURLScheme:self.paymentsURLScheme];
95 | }
96 |
97 | - (BOOL)application:(UIApplication *)application
98 | openURL:(NSURL *)url
99 | options:(NSDictionary *)options {
100 |
101 | if ([url.scheme localizedCaseInsensitiveCompare:self.paymentsURLScheme] == NSOrderedSame) {
102 | return [BTAppSwitch handleOpenURL:url options:options];
103 | }
104 |
105 | return [RCTLinkingManager application:application openURL:url options:options];
106 | }
107 |
108 | - (NSString *)paymentsURLScheme {
109 | NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
110 | return [NSString stringWithFormat:@"%@.%@", bundleIdentifier, @"payments"];
111 | }
112 | ```
113 |
114 | ##### Android
115 |
116 | Setup [browser switch](https://developers.braintreepayments.com/guides/client-sdk/setup/android/v2#browser-switch-setup).
117 |
118 |
119 | ## Usage
120 |
121 | For the API, see the [Flow typings](./index.js.flow).
122 |
123 | ### Basic
124 |
125 | ```javascript
126 | import BraintreeDropIn from 'react-native-braintree-payments-drop-in';
127 |
128 | BraintreeDropIn.show({
129 | clientToken: 'token',
130 | })
131 | .then(result => console.log(result))
132 | .catch((error) => {
133 | if (error.code === 'USER_CANCELLATION') {
134 | // update your UI to handle cancellation
135 | } else {
136 | // update your UI to handle other errors
137 | }
138 | });
139 | ```
140 |
141 | ### 3D Secure
142 |
143 | ```javascript
144 | import BraintreeDropIn from 'react-native-braintree-payments-drop-in';
145 |
146 | BraintreeDropIn.show({
147 | clientToken: 'token',
148 | threeDSecure: {
149 | amount: 1.0,
150 | },
151 | })
152 | .then(result => console.log(result))
153 | .catch((error) => {
154 | if (error.code === 'USER_CANCELLATION') {
155 | // update your UI to handle cancellation
156 | } else {
157 | // update your UI to handle other errors
158 | // for 3D secure, there are two other specific error codes: 3DSECURE_NOT_ABLE_TO_SHIFT_LIABILITY and 3DSECURE_LIABILITY_NOT_SHIFTED
159 | }
160 | });
161 | ```
162 |
--------------------------------------------------------------------------------
/android/src/main/java/tech/bam/RNBraintreeDropIn/RNBraintreeDropInModule.java:
--------------------------------------------------------------------------------
1 | package tech.bam.RNBraintreeDropIn;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import com.facebook.react.bridge.ReactApplicationContext;
6 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
7 | import com.facebook.react.bridge.ReactMethod;
8 | import com.facebook.react.bridge.ReadableMap;
9 | import com.facebook.react.bridge.Arguments;
10 | import com.facebook.react.bridge.WritableMap;
11 | import com.facebook.react.bridge.ActivityEventListener;
12 | import com.facebook.react.bridge.BaseActivityEventListener;
13 | import com.facebook.react.bridge.Promise;
14 | import com.braintreepayments.api.dropin.DropInActivity;
15 | import com.braintreepayments.api.dropin.DropInRequest;
16 | import com.braintreepayments.api.dropin.DropInResult;
17 | import com.braintreepayments.api.models.PaymentMethodNonce;
18 | import com.braintreepayments.api.models.CardNonce;
19 | import com.braintreepayments.api.models.ThreeDSecureInfo;
20 |
21 | public class RNBraintreeDropInModule extends ReactContextBaseJavaModule {
22 |
23 | private Promise mPromise;
24 | private static final int DROP_IN_REQUEST = 0x444;
25 |
26 | private boolean isVerifyingThreeDSecure = false;
27 |
28 | public RNBraintreeDropInModule(ReactApplicationContext reactContext) {
29 | super(reactContext);
30 | reactContext.addActivityEventListener(mActivityListener);
31 | }
32 |
33 | @ReactMethod
34 | public void show(final ReadableMap options, final Promise promise) {
35 | isVerifyingThreeDSecure = false;
36 |
37 | if (!options.hasKey("clientToken")) {
38 | promise.reject("NO_CLIENT_TOKEN", "You must provide a client token");
39 | return;
40 | }
41 |
42 | Activity currentActivity = getCurrentActivity();
43 | if (currentActivity == null) {
44 | promise.reject("NO_ACTIVITY", "There is no current activity");
45 | return;
46 | }
47 |
48 | DropInRequest dropInRequest = new DropInRequest().clientToken(options.getString("clientToken"));
49 |
50 | if (options.hasKey("threeDSecure")) {
51 | final ReadableMap threeDSecureOptions = options.getMap("threeDSecure");
52 | if (!threeDSecureOptions.hasKey("amount")) {
53 | promise.reject("NO_3DS_AMOUNT", "You must provide an amount for 3D Secure");
54 | return;
55 | }
56 |
57 | isVerifyingThreeDSecure = true;
58 |
59 | dropInRequest
60 | .amount(String.valueOf(threeDSecureOptions.getDouble("amount")))
61 | .requestThreeDSecureVerification(true);
62 | }
63 |
64 | mPromise = promise;
65 | currentActivity.startActivityForResult(dropInRequest.getIntent(currentActivity), DROP_IN_REQUEST);
66 | }
67 |
68 | private final ActivityEventListener mActivityListener = new BaseActivityEventListener() {
69 | @Override
70 | public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
71 | super.onActivityResult(requestCode, resultCode, data);
72 |
73 | if (requestCode != DROP_IN_REQUEST || mPromise == null) {
74 | return;
75 | }
76 |
77 | if (resultCode == Activity.RESULT_OK) {
78 | DropInResult result = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT);
79 | PaymentMethodNonce paymentMethodNonce = result.getPaymentMethodNonce();
80 |
81 | if (isVerifyingThreeDSecure && paymentMethodNonce instanceof CardNonce) {
82 | CardNonce cardNonce = (CardNonce) paymentMethodNonce;
83 | ThreeDSecureInfo threeDSecureInfo = cardNonce.getThreeDSecureInfo();
84 | if (!threeDSecureInfo.isLiabilityShiftPossible()) {
85 | mPromise.reject("3DSECURE_NOT_ABLE_TO_SHIFT_LIABILITY", "3D Secure liability cannot be shifted");
86 | } else if (!threeDSecureInfo.isLiabilityShifted()) {
87 | mPromise.reject("3DSECURE_LIABILITY_NOT_SHIFTED", "3D Secure liability was not shifted");
88 | } else {
89 | resolvePayment(paymentMethodNonce);
90 | }
91 | } else {
92 | resolvePayment(paymentMethodNonce);
93 | }
94 | } else if (resultCode == Activity.RESULT_CANCELED) {
95 | mPromise.reject("USER_CANCELLATION", "The user cancelled");
96 | } else {
97 | Exception exception = (Exception) data.getSerializableExtra(DropInActivity.EXTRA_ERROR);
98 | mPromise.reject(exception.getMessage(), exception.getMessage());
99 | }
100 |
101 | mPromise = null;
102 | }
103 | };
104 |
105 | private final void resolvePayment(PaymentMethodNonce paymentMethodNonce) {
106 | WritableMap jsResult = Arguments.createMap();
107 | jsResult.putString("nonce", paymentMethodNonce.getNonce());
108 | jsResult.putString("type", paymentMethodNonce.getTypeLabel());
109 | jsResult.putString("description", paymentMethodNonce.getDescription());
110 | jsResult.putBoolean("isDefault", paymentMethodNonce.isDefault());
111 |
112 | mPromise.resolve(jsResult);
113 | }
114 |
115 | @Override
116 | public String getName() {
117 | return "RNBraintreeDropIn";
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/ios/RNBraintreeDropIn.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | B3E7B58A1CC2AC0600A0062D /* RNBraintreeDropIn.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNBraintreeDropIn.m */; };
11 | /* End PBXBuildFile section */
12 |
13 | /* Begin PBXCopyFilesBuildPhase section */
14 | 58B511D91A9E6C8500147676 /* CopyFiles */ = {
15 | isa = PBXCopyFilesBuildPhase;
16 | buildActionMask = 2147483647;
17 | dstPath = "include/$(PRODUCT_NAME)";
18 | dstSubfolderSpec = 16;
19 | files = (
20 | );
21 | runOnlyForDeploymentPostprocessing = 0;
22 | };
23 | /* End PBXCopyFilesBuildPhase section */
24 |
25 | /* Begin PBXFileReference section */
26 | 134814201AA4EA6300B7C361 /* libRNBraintreeDropIn.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNBraintreeDropIn.a; sourceTree = BUILT_PRODUCTS_DIR; };
27 | B3E7B5881CC2AC0600A0062D /* RNBraintreeDropIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBraintreeDropIn.h; sourceTree = ""; };
28 | B3E7B5891CC2AC0600A0062D /* RNBraintreeDropIn.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNBraintreeDropIn.m; sourceTree = ""; };
29 | /* End PBXFileReference section */
30 |
31 | /* Begin PBXFrameworksBuildPhase section */
32 | 58B511D81A9E6C8500147676 /* Frameworks */ = {
33 | isa = PBXFrameworksBuildPhase;
34 | buildActionMask = 2147483647;
35 | files = (
36 | );
37 | runOnlyForDeploymentPostprocessing = 0;
38 | };
39 | /* End PBXFrameworksBuildPhase section */
40 |
41 | /* Begin PBXGroup section */
42 | 134814211AA4EA7D00B7C361 /* Products */ = {
43 | isa = PBXGroup;
44 | children = (
45 | 134814201AA4EA6300B7C361 /* libRNBraintreeDropIn.a */,
46 | );
47 | name = Products;
48 | sourceTree = "";
49 | };
50 | 58B511D21A9E6C8500147676 = {
51 | isa = PBXGroup;
52 | children = (
53 | B3E7B5881CC2AC0600A0062D /* RNBraintreeDropIn.h */,
54 | B3E7B5891CC2AC0600A0062D /* RNBraintreeDropIn.m */,
55 | 134814211AA4EA7D00B7C361 /* Products */,
56 | );
57 | sourceTree = "";
58 | };
59 | /* End PBXGroup section */
60 |
61 | /* Begin PBXNativeTarget section */
62 | 58B511DA1A9E6C8500147676 /* RNBraintreeDropIn */ = {
63 | isa = PBXNativeTarget;
64 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNBraintreeDropIn" */;
65 | buildPhases = (
66 | 58B511D71A9E6C8500147676 /* Sources */,
67 | 58B511D81A9E6C8500147676 /* Frameworks */,
68 | 58B511D91A9E6C8500147676 /* CopyFiles */,
69 | );
70 | buildRules = (
71 | );
72 | dependencies = (
73 | );
74 | name = RNBraintreeDropIn;
75 | productName = RCTDataManager;
76 | productReference = 134814201AA4EA6300B7C361 /* libRNBraintreeDropIn.a */;
77 | productType = "com.apple.product-type.library.static";
78 | };
79 | /* End PBXNativeTarget section */
80 |
81 | /* Begin PBXProject section */
82 | 58B511D31A9E6C8500147676 /* Project object */ = {
83 | isa = PBXProject;
84 | attributes = {
85 | LastUpgradeCheck = 0830;
86 | ORGANIZATIONNAME = Facebook;
87 | TargetAttributes = {
88 | 58B511DA1A9E6C8500147676 = {
89 | CreatedOnToolsVersion = 6.1.1;
90 | };
91 | };
92 | };
93 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNBraintreeDropIn" */;
94 | compatibilityVersion = "Xcode 3.2";
95 | developmentRegion = English;
96 | hasScannedForEncodings = 0;
97 | knownRegions = (
98 | en,
99 | );
100 | mainGroup = 58B511D21A9E6C8500147676;
101 | productRefGroup = 58B511D21A9E6C8500147676;
102 | projectDirPath = "";
103 | projectRoot = "";
104 | targets = (
105 | 58B511DA1A9E6C8500147676 /* RNBraintreeDropIn */,
106 | );
107 | };
108 | /* End PBXProject section */
109 |
110 | /* Begin PBXSourcesBuildPhase section */
111 | 58B511D71A9E6C8500147676 /* Sources */ = {
112 | isa = PBXSourcesBuildPhase;
113 | buildActionMask = 2147483647;
114 | files = (
115 | B3E7B58A1CC2AC0600A0062D /* RNBraintreeDropIn.m in Sources */,
116 | );
117 | runOnlyForDeploymentPostprocessing = 0;
118 | };
119 | /* End PBXSourcesBuildPhase section */
120 |
121 | /* Begin XCBuildConfiguration section */
122 | 58B511ED1A9E6C8500147676 /* Debug */ = {
123 | isa = XCBuildConfiguration;
124 | buildSettings = {
125 | ALWAYS_SEARCH_USER_PATHS = NO;
126 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
127 | CLANG_CXX_LIBRARY = "libc++";
128 | CLANG_ENABLE_MODULES = YES;
129 | CLANG_ENABLE_OBJC_ARC = YES;
130 | CLANG_WARN_BOOL_CONVERSION = YES;
131 | CLANG_WARN_CONSTANT_CONVERSION = YES;
132 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
133 | CLANG_WARN_EMPTY_BODY = YES;
134 | CLANG_WARN_ENUM_CONVERSION = YES;
135 | CLANG_WARN_INFINITE_RECURSION = YES;
136 | CLANG_WARN_INT_CONVERSION = YES;
137 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
138 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
139 | CLANG_WARN_UNREACHABLE_CODE = YES;
140 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
141 | COPY_PHASE_STRIP = NO;
142 | ENABLE_STRICT_OBJC_MSGSEND = YES;
143 | ENABLE_TESTABILITY = YES;
144 | GCC_C_LANGUAGE_STANDARD = gnu99;
145 | GCC_DYNAMIC_NO_PIC = NO;
146 | GCC_NO_COMMON_BLOCKS = YES;
147 | GCC_OPTIMIZATION_LEVEL = 0;
148 | GCC_PREPROCESSOR_DEFINITIONS = (
149 | "DEBUG=1",
150 | "$(inherited)",
151 | );
152 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
153 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
154 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
155 | GCC_WARN_UNDECLARED_SELECTOR = YES;
156 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
157 | GCC_WARN_UNUSED_FUNCTION = YES;
158 | GCC_WARN_UNUSED_VARIABLE = YES;
159 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
160 | MTL_ENABLE_DEBUG_INFO = YES;
161 | ONLY_ACTIVE_ARCH = YES;
162 | SDKROOT = iphoneos;
163 | };
164 | name = Debug;
165 | };
166 | 58B511EE1A9E6C8500147676 /* Release */ = {
167 | isa = XCBuildConfiguration;
168 | buildSettings = {
169 | ALWAYS_SEARCH_USER_PATHS = NO;
170 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
171 | CLANG_CXX_LIBRARY = "libc++";
172 | CLANG_ENABLE_MODULES = YES;
173 | CLANG_ENABLE_OBJC_ARC = YES;
174 | CLANG_WARN_BOOL_CONVERSION = YES;
175 | CLANG_WARN_CONSTANT_CONVERSION = YES;
176 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
177 | CLANG_WARN_EMPTY_BODY = YES;
178 | CLANG_WARN_ENUM_CONVERSION = YES;
179 | CLANG_WARN_INFINITE_RECURSION = YES;
180 | CLANG_WARN_INT_CONVERSION = YES;
181 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
182 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
183 | CLANG_WARN_UNREACHABLE_CODE = YES;
184 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
185 | COPY_PHASE_STRIP = YES;
186 | ENABLE_NS_ASSERTIONS = NO;
187 | ENABLE_STRICT_OBJC_MSGSEND = YES;
188 | GCC_C_LANGUAGE_STANDARD = gnu99;
189 | GCC_NO_COMMON_BLOCKS = YES;
190 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
191 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
192 | GCC_WARN_UNDECLARED_SELECTOR = YES;
193 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
194 | GCC_WARN_UNUSED_FUNCTION = YES;
195 | GCC_WARN_UNUSED_VARIABLE = YES;
196 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
197 | MTL_ENABLE_DEBUG_INFO = NO;
198 | SDKROOT = iphoneos;
199 | VALIDATE_PRODUCT = YES;
200 | };
201 | name = Release;
202 | };
203 | 58B511F01A9E6C8500147676 /* Debug */ = {
204 | isa = XCBuildConfiguration;
205 | buildSettings = {
206 | FRAMEWORK_SEARCH_PATHS = (
207 | "$(inherited)",
208 | "$(PODS_ROOT)/Braintree/**",
209 | "$(PODS_ROOT)/BraintreeDropIn/**",
210 | );
211 | HEADER_SEARCH_PATHS = (
212 | "$(inherited)",
213 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
214 | "$(SRCROOT)/../../../React/**",
215 | "$(SRCROOT)/../../react-native/React/**",
216 | "$(PODS_ROOT)/Braintree/**",
217 | "$(PODS_ROOT)/BraintreeDropIn/**",
218 | );
219 | LIBRARY_SEARCH_PATHS = "$(inherited)";
220 | OTHER_LDFLAGS = "-ObjC";
221 | PODS_ROOT = "${SRCROOT}/../../../ios/Pods";
222 | PRODUCT_NAME = RNBraintreeDropIn;
223 | SKIP_INSTALL = YES;
224 | };
225 | name = Debug;
226 | };
227 | 58B511F11A9E6C8500147676 /* Release */ = {
228 | isa = XCBuildConfiguration;
229 | buildSettings = {
230 | FRAMEWORK_SEARCH_PATHS = (
231 | "$(inherited)",
232 | "$(PODS_ROOT)/Braintree/**",
233 | "$(PODS_ROOT)/BraintreeDropIn/**",
234 | );
235 | HEADER_SEARCH_PATHS = (
236 | "$(inherited)",
237 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
238 | "$(SRCROOT)/../../../React/**",
239 | "$(SRCROOT)/../../react-native/React/**",
240 | "$(PODS_ROOT)/Braintree/**",
241 | "$(PODS_ROOT)/BraintreeDropIn/**",
242 | );
243 | LIBRARY_SEARCH_PATHS = "$(inherited)";
244 | OTHER_LDFLAGS = "-ObjC";
245 | PODS_ROOT = "${SRCROOT}/../../../ios/Pods";
246 | PRODUCT_NAME = RNBraintreeDropIn;
247 | SKIP_INSTALL = YES;
248 | };
249 | name = Release;
250 | };
251 | /* End XCBuildConfiguration section */
252 |
253 | /* Begin XCConfigurationList section */
254 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNBraintreeDropIn" */ = {
255 | isa = XCConfigurationList;
256 | buildConfigurations = (
257 | 58B511ED1A9E6C8500147676 /* Debug */,
258 | 58B511EE1A9E6C8500147676 /* Release */,
259 | );
260 | defaultConfigurationIsVisible = 0;
261 | defaultConfigurationName = Release;
262 | };
263 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNBraintreeDropIn" */ = {
264 | isa = XCConfigurationList;
265 | buildConfigurations = (
266 | 58B511F01A9E6C8500147676 /* Debug */,
267 | 58B511F11A9E6C8500147676 /* Release */,
268 | );
269 | defaultConfigurationIsVisible = 0;
270 | defaultConfigurationName = Release;
271 | };
272 | /* End XCConfigurationList section */
273 | };
274 | rootObject = 58B511D31A9E6C8500147676 /* Project object */;
275 | }
276 |
--------------------------------------------------------------------------------