上传文件至 /

This commit is contained in:
2026-02-13 07:17:40 +00:00
commit dd42dc04ce
5 changed files with 780 additions and 0 deletions

39
CHANGELOG.md Normal file
View File

@@ -0,0 +1,39 @@
# Changelog
All notable changes to this project will be documented in this file.
## [1.0.0] - 2024-01-XX
### Added
- Initial release with Turbo Modules support
- Swift implementation for iOS
- Kotlin implementation for Android
- Support for latest Braintree SDK versions:
- iOS: Braintree 6.0, BraintreeDropIn 9.0
- Android: Drop-In 6.16.0, Card 4.45.0
- Apple Pay support (iOS)
- Google Pay support (Android)
- Venmo payment support
- PayPal payment support
- 3D Secure authentication
- Direct card tokenization
- Device data collection for fraud detection
- Vault manager support
- Dark theme support (iOS)
- Custom font support (iOS)
- TypeScript definitions
- Comprehensive documentation and examples
### Features
- Full React Native New Architecture compatibility
- Backward compatible with old architecture
- Promise-based API
- Detailed error handling
- Latest payment methods support
### Technical
- Built with React Native 0.73 compatibility
- Minimum iOS version: 13.0
- Minimum Android SDK: 21
- Swift 5.0
- Kotlin 1.8.21

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 [Your Name]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

402
MIGRATION.md Normal file
View File

@@ -0,0 +1,402 @@
# Migration Guide
## Migrating from Old Braintree Drop-In Implementation
This guide helps you migrate from the legacy Braintree implementation to the new Turbo Module version.
## Key Differences
### Architecture
- **Old**: Bridge-based module
- **New**: Turbo Module with full New Architecture support
### SDK Versions
- **iOS**: Upgraded to Braintree 6.0, BraintreeDropIn 9.0
- **Android**: Upgraded to Drop-In 6.16.0, Card 4.45.0
### Language
- **iOS**: Migrated from Objective-C to Swift
- **Android**: Migrated from Java to Kotlin
## Breaking Changes
### 1. Import Statement
**Old:**
```javascript
import RNBraintreeDropIn from 'react-native-braintree-dropin';
```
**New:**
```typescript
import BraintreeDropIn from 'react-native-braintree-dropin-turbo';
```
### 2. Method Calls
**Old:**
```javascript
RNBraintreeDropIn.show(options)
.then(result => {
console.log(result.nonce);
})
.catch(error => {
console.error(error);
});
```
**New:**
```typescript
try {
const result = await BraintreeDropIn.show(options);
console.log(result.nonce);
} catch (error) {
console.error(error);
}
```
### 3. Options Structure
Most options remain the same, but there are some changes:
**Old:**
```javascript
{
clientToken: 'token',
darkTheme: true,
merchantIdentifier: 'merchant.id', // iOS
// ...
}
```
**New (unchanged, but TypeScript-typed):**
```typescript
{
clientToken: 'token',
darkTheme: true,
merchantIdentifier: 'merchant.id',
// ...
}: DropInOptions
```
### 4. Android Setup Changes
**Old:**
```java
// No special initialization needed
```
**New:**
```kotlin
import com.braintreedroptinturbo.RNBraintreeDropInModule
class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
RNBraintreeDropInModule.initDropInClient(this)
}
}
```
**Important:** MainActivity must now extend `FragmentActivity` instead of `ReactActivity`.
### 5. Package Name Changes
**Old (AndroidManifest.xml):**
```xml
<!-- Old package name -->
```
**New:**
```kotlin
package com.braintreedroptinturbo
```
### 6. iOS Podspec
**Old:**
```ruby
pod 'RNBraintreeDropIn', :path => '../node_modules/react-native-braintree-dropin'
```
**New (auto-linked):**
```ruby
# No manual podspec needed - auto-linked
# Or if manual:
pod 'react-native-braintree-dropin-turbo', :path => '../node_modules/react-native-braintree-dropin-turbo'
```
## Step-by-Step Migration
### Step 1: Uninstall Old Package
```bash
npm uninstall react-native-braintree-dropin
# or
yarn remove react-native-braintree-dropin
```
### Step 2: Clean iOS Pods
```bash
cd ios
rm -rf Pods Podfile.lock
cd ..
```
### Step 3: Install New Package
```bash
npm install react-native-braintree-dropin-turbo
# or
yarn add react-native-braintree-dropin-turbo
```
### Step 4: Update iOS
```bash
cd ios
pod install
cd ..
```
### Step 5: Update Android MainActivity
Update your `MainActivity.kt` (or convert from .java to .kt):
```kotlin
import android.os.Bundle
import androidx.fragment.app.FragmentActivity
import com.braintreedroptinturbo.RNBraintreeDropInModule
class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
RNBraintreeDropInModule.initDropInClient(this)
}
// If you have other ReactActivity methods, you may need to adjust them
}
```
### Step 6: Update Import Statements
Find and replace in your codebase:
```bash
# Find
import RNBraintreeDropIn from 'react-native-braintree-dropin';
# Replace with
import BraintreeDropIn from 'react-native-braintree-dropin-turbo';
```
### Step 7: Update Method Calls
Convert from promise chains to async/await (recommended):
**Before:**
```javascript
RNBraintreeDropIn.show(options)
.then(result => {
// handle result
})
.catch(error => {
// handle error
});
```
**After:**
```typescript
try {
const result = await BraintreeDropIn.show(options);
// handle result
} catch (error) {
// handle error
}
```
### Step 8: Add TypeScript Types (Optional but Recommended)
If using TypeScript, add proper typing:
```typescript
import BraintreeDropIn, {
type DropInOptions,
type PaymentResult
} from 'react-native-braintree-dropin-turbo';
const options: DropInOptions = {
clientToken: 'your-token',
orderTotal: 10.00,
// ...
};
const result: PaymentResult = await BraintreeDropIn.show(options);
```
### Step 9: Test Thoroughly
Test all payment flows:
- Credit/Debit cards
- Apple Pay (iOS)
- Google Pay (Android)
- Venmo
- PayPal
- 3D Secure
## API Changes
### Unchanged Methods
These methods work the same way:
- `show(options)` - Display Drop-In UI
- `fetchMostRecentPaymentMethod(clientToken)` - Get last payment method
- `tokenizeCard(clientToken, cardInfo)` - Tokenize a card
### New Methods
- `collectDeviceData(clientToken)` - Now available as a standalone method
### Return Types
The return types are now properly typed with TypeScript:
```typescript
interface PaymentResult {
nonce: string;
type: string;
description: string;
isDefault: boolean;
deviceData: string;
}
```
## Compatibility
### React Native Version Support
- **Old**: React Native 0.60+
- **New**: React Native 0.68+ (Turbo Modules support)
If you're on an older React Native version, you'll need to upgrade first.
### New Architecture
The new package supports both:
- Old Architecture (Bridge)
- New Architecture (Turbo Modules)
Enable New Architecture by setting:
- iOS: `ENV['RCT_NEW_ARCH_ENABLED'] = '1'` in Podfile
- Android: `newArchEnabled=true` in gradle.properties
## Common Migration Issues
### Issue 1: MainActivity Compilation Error
**Error:** "MainActivity must extend FragmentActivity"
**Solution:**
```kotlin
// Change from
class MainActivity : ReactActivity()
// To
class MainActivity : FragmentActivity()
```
### Issue 2: Swift Bridging Header
**Error:** "No such module 'BraintreeDropIn'"
**Solution:**
1. Clean and rebuild
2. Check Swift version is 5.0+
3. Run `pod install` again
### Issue 3: Android Build Failures
**Error:** Various Gradle errors
**Solution:**
```bash
cd android
./gradlew clean
cd ..
# Rebuild
```
### Issue 4: Type Errors
**Error:** TypeScript type mismatches
**Solution:** Make sure you're importing types:
```typescript
import type { DropInOptions, PaymentResult } from 'react-native-braintree-dropin-turbo';
```
## Testing After Migration
Create a test checklist:
- [ ] Drop-In UI displays correctly
- [ ] Card payment works
- [ ] Apple Pay works (iOS)
- [ ] Google Pay works (Android)
- [ ] Venmo works
- [ ] PayPal works
- [ ] 3D Secure verification works
- [ ] Error handling works
- [ ] Device data collection works
- [ ] Vault manager works (if used)
## Rollback Plan
If you need to rollback:
```bash
# Uninstall new package
npm uninstall react-native-braintree-dropin-turbo
# Reinstall old package
npm install react-native-braintree-dropin@[old-version]
# Clean iOS
cd ios && rm -rf Pods Podfile.lock && pod install && cd ..
# Revert MainActivity changes
# Rebuild
```
## Benefits of Migration
1.**Performance**: Turbo Modules are faster than the old bridge
2.**Latest SDKs**: Access to latest Braintree features and security updates
3.**Type Safety**: Full TypeScript support
4.**Future-proof**: Compatible with React Native's New Architecture
5.**Better Maintenance**: Modern codebase with Swift and Kotlin
6.**Improved Error Handling**: Better error messages and handling
## Getting Help
If you encounter issues during migration:
1. Check this migration guide
2. Review the [Installation Guide](./INSTALLATION.md)
3. Check closed issues on GitHub
4. Open a new issue with:
- Old package version
- New package version
- React Native version
- Complete error messages
- Migration steps attempted
## Timeline Recommendation
- **Testing Phase**: 1-2 days
- **Migration**: 2-3 hours
- **QA Testing**: 1-2 days
- **Monitoring**: 1 week post-release
Good luck with your migration! 🚀

269
README.md Normal file
View File

@@ -0,0 +1,269 @@
# react-native-braintree-dropin-turbo
Modern Braintree Drop-In UI for React Native with Turbo Modules support.
## Features
- ✅ Turbo Modules support (React Native 0.68+)
- ✅ Latest Braintree SDK versions
- ✅ iOS (Swift) and Android (Kotlin)
- ✅ Apple Pay support (iOS)
- ✅ Google Pay support (Android)
- ✅ Venmo support
- ✅ PayPal support
- ✅ 3D Secure support
- ✅ Card tokenization
- ✅ Device data collection
## Installation
```bash
npm install react-native-braintree-dropin-turbo
# or
yarn add react-native-braintree-dropin-turbo
```
### iOS Setup
1. Install pods:
```bash
cd ios && pod install
```
2. Add to your `Info.plist` for Apple Pay:
```xml
<key>com.apple.developer.in-app-payments</key>
<array>
<string>merchant.your.merchant.identifier</string>
</array>
```
### Android Setup
1. Initialize DropIn client in your `MainActivity.kt`:
```kotlin
import com.braintreedroptinturbo.RNBraintreeDropInModule
class MainActivity : ReactActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
RNBraintreeDropInModule.initDropInClient(this)
}
}
```
2. Make sure your MainActivity extends `FragmentActivity`:
```kotlin
import androidx.fragment.app.FragmentActivity
class MainActivity : FragmentActivity() {
// ...
}
```
## Usage
### Basic Usage
```typescript
import BraintreeDropIn from 'react-native-braintree-dropin-turbo';
try {
const result = await BraintreeDropIn.show({
clientToken: 'YOUR_CLIENT_TOKEN',
orderTotal: 10.0,
currencyCode: 'USD',
});
console.log('Payment nonce:', result.nonce);
console.log('Device data:', result.deviceData);
// Send result.nonce to your server
} catch (error) {
if (error.message === 'USER_CANCELLATION') {
console.log('User cancelled payment');
} else {
console.error('Payment error:', error);
}
}
```
### With Apple Pay (iOS)
```typescript
const result = await BraintreeDropIn.show({
clientToken: 'YOUR_CLIENT_TOKEN',
applePay: true,
merchantIdentifier: 'merchant.your.identifier',
countryCode: 'US',
currencyCode: 'USD',
merchantName: 'Your Store',
orderTotal: 10.0,
});
```
### With Google Pay (Android)
```typescript
const result = await BraintreeDropIn.show({
clientToken: 'YOUR_CLIENT_TOKEN',
googlePay: true,
googlePayMerchantId: 'YOUR_MERCHANT_ID',
orderTotal: 10.0,
currencyCode: 'USD',
});
```
### With 3D Secure
```typescript
const result = await BraintreeDropIn.show({
clientToken: 'YOUR_CLIENT_TOKEN',
threeDSecure: {
amount: 10.0,
},
});
```
### Tokenize Card Directly
```typescript
const result = await BraintreeDropIn.tokenizeCard('YOUR_CLIENT_TOKEN', {
number: '4111111111111111',
expirationMonth: '12',
expirationYear: '2025',
cvv: '123',
postalCode: '12345',
});
```
### Collect Device Data
```typescript
const deviceData = await BraintreeDropIn.collectDeviceData('YOUR_CLIENT_TOKEN');
// Send to your server for fraud detection
```
### Fetch Most Recent Payment Method
```typescript
const paymentMethod =
await BraintreeDropIn.fetchMostRecentPaymentMethod('YOUR_CLIENT_TOKEN');
if (paymentMethod) {
console.log('Last payment:', paymentMethod.description);
}
```
## API Reference
### `show(options: DropInOptions): Promise<PaymentResult>`
Display the Braintree Drop-In UI.
#### Options
| Option | Type | Required | Description |
| --------------------- | ------- | -------- | ---------------------------------------------------- |
| `clientToken` | string | ✅ | Braintree client token |
| `orderTotal` | number | ❌ | Total amount for the transaction |
| `currencyCode` | string | ❌ | Currency code (default: 'USD') |
| `darkTheme` | boolean | ❌ | Use dark theme (iOS only) |
| `fontFamily` | string | ❌ | Custom font family (iOS only) |
| `boldFontFamily` | string | ❌ | Custom bold font family (iOS only) |
| `vaultManager` | boolean | ❌ | Enable vault manager |
| `cardDisabled` | boolean | ❌ | Disable card payments |
| `applePay` | boolean | ❌ | Enable Apple Pay (iOS only) |
| `merchantIdentifier` | string | ❌ | Apple Pay merchant ID (required if applePay is true) |
| `countryCode` | string | ❌ | Country code for Apple Pay |
| `merchantName` | string | ❌ | Merchant name for Apple Pay |
| `venmo` | boolean | ❌ | Enable Venmo |
| `payPal` | boolean | ❌ | Enable PayPal |
| `googlePay` | boolean | ❌ | Enable Google Pay (Android only) |
| `googlePayMerchantId` | string | ❌ | Google Pay merchant ID |
| `threeDSecure` | object | ❌ | 3D Secure configuration |
| `threeDSecure.amount` | number | ❌ | Amount for 3D Secure verification |
#### Returns
```typescript
interface PaymentResult {
nonce: string; // Payment method nonce
type: string; // Payment method type
description: string; // Payment method description
isDefault: boolean; // Is default payment method
deviceData: string; // Device data for fraud detection
}
```
### `tokenizeCard(clientToken: string, cardInfo: CardInfo): Promise<PaymentResult>`
Tokenize a card without showing the UI.
```typescript
interface CardInfo {
number?: string;
expirationMonth?: string;
expirationYear?: string;
cvv: string;
postalCode?: string;
onlyCVV?: boolean; // If true, only CVV is required
}
```
### `collectDeviceData(clientToken: string): Promise<string>`
Collect device data for fraud detection.
### `fetchMostRecentPaymentMethod(clientToken: string): Promise<PaymentResult | null>`
Fetch the most recently used payment method.
## Error Handling
```typescript
try {
const result = await BraintreeDropIn.show(options);
} catch (error) {
switch (error.message) {
case 'USER_CANCELLATION':
// User cancelled the payment flow
break;
case 'NO_CLIENT_TOKEN':
// Client token was not provided
break;
case '3DSECURE_NOT_ABLE_TO_SHIFT_LIABILITY':
// 3D Secure verification failed
break;
default:
// Other errors
console.error(error);
}
}
```
## Braintree SDK Versions
- **iOS**: Braintree ~> 6.0, BraintreeDropIn ~> 9.0
- **Android**: Drop-In 6.16.0, Card 4.45.0, Data Collector 4.45.0
## Requirements
- React Native >= 0.68
- iOS >= 13.0
- Android minSdkVersion >= 21
## New Architecture (Turbo Modules)
This library supports the New Architecture out of the box. No additional configuration needed.
## License
MIT
## Support
For issues and feature requests, please visit the [GitHub repository](https://github.com/aveekshan/react-native-braintree-dropin-turbo).

View File

@@ -0,0 +1,49 @@
require "json"
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
Pod::Spec.new do |s|
s.name = "react-native-braintree-dropin-turbo"
s.version = package["version"]
s.summary = package["description"]
s.homepage = package["homepage"]
s.license = package["license"]
s.authors = package["author"]
s.platforms = { :ios => "13.0" }
s.source = { :git => "https://github.com/aveekshan/react-native-braintree-dropin-turbo.git", :tag => "#{s.version}" }
s.source_files = "ios/**/*.{h,m,mm,swift}"
# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
if respond_to?(:install_modules_dependencies, true)
install_modules_dependencies(s)
else
s.dependency "React-Core"
# Don't install the dependencies when we run `pod install` in the old architecture.
if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
s.pod_target_xcconfig = {
"HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
"OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
}
s.dependency "React-Codegen"
s.dependency "RCT-Folly"
s.dependency "RCTRequired"
s.dependency "RCTTypeSafety"
s.dependency "ReactCommon/turbomodule/core"
end
end
# Braintree Dependencies
# s.dependency 'Braintree', '~> 6.0'
# s.dependency 'BraintreeDropIn', '~> 9.0'
# s.dependency 'Braintree/DataCollector', '~> 6.0'
# s.dependency 'Braintree/ApplePay', '~> 6.0'
# s.dependency 'Braintree/Venmo', '~> 6.0'
s.swift_version = '5.0'
end