halo-sdk-react-native 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +163 -0
- package/android/build.gradle +89 -0
- package/android/libs/VisaSensoryBranding.aar +0 -0
- package/android/libs/sonic-sdk-release-1.5.0.aar +0 -0
- package/android/settings.gradle +1 -0
- package/android/src/main/AndroidManifest.xml +9 -0
- package/android/src/main/kotlin/za/co/synthesis/halo/sdkreactnativeplugin/AnimationActivity.kt +160 -0
- package/android/src/main/kotlin/za/co/synthesis/halo/sdkreactnativeplugin/Const.kt +15 -0
- package/android/src/main/kotlin/za/co/synthesis/halo/sdkreactnativeplugin/HaloCallbacks.kt +126 -0
- package/android/src/main/kotlin/za/co/synthesis/halo/sdkreactnativeplugin/HaloReactActivity.kt +61 -0
- package/android/src/main/kotlin/za/co/synthesis/halo/sdkreactnativeplugin/HaloSdkImplementation.kt +81 -0
- package/android/src/main/kotlin/za/co/synthesis/halo/sdkreactnativeplugin/HaloSdkModule.kt +71 -0
- package/android/src/main/kotlin/za/co/synthesis/halo/sdkreactnativeplugin/HaloSdkPackage.kt +16 -0
- package/android/src/main/kotlin/za/co/synthesis/halo/sdkreactnativeplugin/UIContext.kt +20 -0
- package/android/src/main/kotlin/za/co/synthesis/halo/sdkreactnativeplugin/Utils.kt +154 -0
- package/android/src/main/res/drawable/amex.png +0 -0
- package/android/src/main/res/raw/amex_confirm.mp3 +0 -0
- package/dist/HaloSdk.d.ts +36 -0
- package/dist/HaloSdk.d.ts.map +1 -0
- package/dist/HaloSdk.js +105 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/types.d.ts +86 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/package.json +33 -0
package/README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# halo-sdk-react-native
|
|
2
|
+
|
|
3
|
+
React Native plugin for the Halo SDK, enabling Android NFC card-present payment transactions.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- React Native 0.73+
|
|
8
|
+
- Android SDK 29+ (minSdkVersion 29)
|
|
9
|
+
- NFC-capable Android device
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
### 1. Install the package
|
|
14
|
+
|
|
15
|
+
Add the package to your project using npm or yarn:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install halo-sdk-react-native
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
yarn add halo-sdk-react-native
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### 2. Configure AWS credentials for the Halo Maven repository
|
|
26
|
+
|
|
27
|
+
The plugin fetches the Halo SDK from an S3-backed Maven repo. Provide credentials in `android/local.properties`:
|
|
28
|
+
|
|
29
|
+
```properties
|
|
30
|
+
aws.accesskey=YOUR_ACCESS_KEY
|
|
31
|
+
aws.secretkey=YOUR_SECRET_KEY
|
|
32
|
+
aws.token=YOUR_SESSION_TOKEN # optional
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Or set environment variables `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN`.
|
|
36
|
+
|
|
37
|
+
### 3. Register the native module
|
|
38
|
+
|
|
39
|
+
In your `MainApplication`, add `HaloSdkPackage` to `getPackages()`:
|
|
40
|
+
|
|
41
|
+
```kotlin
|
|
42
|
+
override fun getPackages(): List<ReactPackage> = listOf(
|
|
43
|
+
MainReactPackage(),
|
|
44
|
+
HaloSdkPackage(),
|
|
45
|
+
)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 4. Extend HaloReactActivity
|
|
49
|
+
|
|
50
|
+
In `MainActivity`, extend `HaloReactActivity` instead of `ReactActivity`:
|
|
51
|
+
|
|
52
|
+
```kotlin
|
|
53
|
+
import za.co.synthesis.halo.sdkreactnativeplugin.HaloReactActivity
|
|
54
|
+
|
|
55
|
+
class MainActivity : HaloReactActivity() {
|
|
56
|
+
override fun getMainComponentName(): String = "YourAppName"
|
|
57
|
+
override fun createReactActivityDelegate() =
|
|
58
|
+
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
This ensures Halo SDK lifecycle management works correctly.
|
|
63
|
+
|
|
64
|
+
## Usage
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import {
|
|
68
|
+
HaloSdk,
|
|
69
|
+
type IHaloCallbacks,
|
|
70
|
+
type HaloInitializationResult,
|
|
71
|
+
type HaloTransactionResult,
|
|
72
|
+
type HaloUIMessage,
|
|
73
|
+
type HaloAttestationHealthResult,
|
|
74
|
+
} from 'halo-sdk-react-native';
|
|
75
|
+
|
|
76
|
+
const callbacks: IHaloCallbacks = {
|
|
77
|
+
onInitializationResult(result: HaloInitializationResult) {
|
|
78
|
+
console.log('Initialized:', result.resultType);
|
|
79
|
+
},
|
|
80
|
+
onHaloTransactionResult(result: HaloTransactionResult) {
|
|
81
|
+
console.log('Transaction:', result.resultType, result.errorCode);
|
|
82
|
+
},
|
|
83
|
+
onHaloUIMessage(message: HaloUIMessage) {
|
|
84
|
+
console.log('UI Message:', message.msgID);
|
|
85
|
+
},
|
|
86
|
+
onAttestationError(details: HaloAttestationHealthResult) {
|
|
87
|
+
console.error('Attestation error:', details.errorCode);
|
|
88
|
+
},
|
|
89
|
+
onRequestJWT(jwtCallback: (jwt: string) => void) {
|
|
90
|
+
const jwt = getJwtFromYourServer();
|
|
91
|
+
jwtCallback(jwt);
|
|
92
|
+
},
|
|
93
|
+
onSecurityError(errorCode: string) {
|
|
94
|
+
console.error('Security error:', errorCode);
|
|
95
|
+
},
|
|
96
|
+
onCameraControlLost() {
|
|
97
|
+
console.warn('Camera control lost');
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// Initialize once (e.g. on app start)
|
|
102
|
+
await HaloSdk.initialize(
|
|
103
|
+
callbacks,
|
|
104
|
+
'com.your.package.name',
|
|
105
|
+
'1.0.0',
|
|
106
|
+
300000, // transaction timeout in ms (optional, default 300000)
|
|
107
|
+
true, // enable scheme animations (optional)
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Start a purchase
|
|
111
|
+
const result = await HaloSdk.startTransaction(10.50, 'REF-001', 'ZAR');
|
|
112
|
+
|
|
113
|
+
// Start a card refund
|
|
114
|
+
const refund = await HaloSdk.cardRefundTransaction(10.50, 'REF-001', 'ZAR');
|
|
115
|
+
|
|
116
|
+
// Cancel current transaction
|
|
117
|
+
await HaloSdk.cancelTransaction();
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## API
|
|
121
|
+
|
|
122
|
+
### `HaloSdk.initialize(callbacks, packageName, version, timeout?, animations?)`
|
|
123
|
+
|
|
124
|
+
Initialises the SDK. Must be called before any transaction methods.
|
|
125
|
+
|
|
126
|
+
| Parameter | Type | Description |
|
|
127
|
+
|-----------|------|-------------|
|
|
128
|
+
| `callbacks` | `IHaloCallbacks` | Event handler object |
|
|
129
|
+
| `applicationPackageName` | `string` | Your app's package name |
|
|
130
|
+
| `applicationVersion` | `string` | Your app's version string |
|
|
131
|
+
| `onStartTransactionTimeOut` | `number?` | Tap timeout in ms (default 300000) |
|
|
132
|
+
| `enableSchemeAnimations` | `boolean?` | Show Visa/Mastercard/Amex animations on approval |
|
|
133
|
+
|
|
134
|
+
### `HaloSdk.startTransaction(amount, reference, currency)`
|
|
135
|
+
|
|
136
|
+
Starts a purchase transaction. Resolves with a `HaloStartTransactionResult` once the card tap is accepted or rejected.
|
|
137
|
+
|
|
138
|
+
### `HaloSdk.cardRefundTransaction(amount, reference, currency)`
|
|
139
|
+
|
|
140
|
+
Starts a card-present refund transaction.
|
|
141
|
+
|
|
142
|
+
### `HaloSdk.cancelTransaction()`
|
|
143
|
+
|
|
144
|
+
Requests cancellation of the current in-progress transaction.
|
|
145
|
+
|
|
146
|
+
## Callbacks (`IHaloCallbacks`)
|
|
147
|
+
|
|
148
|
+
| Callback | Description |
|
|
149
|
+
|----------------------------|-----------------------------------------------------------------------|
|
|
150
|
+
| `onInitializationResult` | SDK initialisation complete or failed |
|
|
151
|
+
| `onHaloTransactionResult` | Final transaction outcome |
|
|
152
|
+
| `onHaloUIMessage` | Prompt to display to the cardholder (e.g. "Present card") |
|
|
153
|
+
| `onRequestJWT` | SDK needs a fresh JWT; call the provided `jwtCallback` with the token |
|
|
154
|
+
| `onAttestationError` | Device attestation failed |
|
|
155
|
+
| `onSecurityError` | Security check failed |
|
|
156
|
+
| `onCameraControlLost` | SDK released camera control |
|
|
157
|
+
|
|
158
|
+
## Building the plugin
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npm install
|
|
162
|
+
npm run build
|
|
163
|
+
```
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
apply plugin: 'com.android.library'
|
|
2
|
+
apply plugin: 'kotlin-android'
|
|
3
|
+
|
|
4
|
+
group 'za.co.synthesis.halo.sdkreactnativeplugin'
|
|
5
|
+
version '1.0-SNAPSHOT'
|
|
6
|
+
|
|
7
|
+
Properties properties = new Properties()
|
|
8
|
+
if (rootProject.file("local.properties").exists()) {
|
|
9
|
+
properties.load(project.rootProject.file("local.properties").newDataInputStream())
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
rootProject.allprojects {
|
|
13
|
+
repositories {
|
|
14
|
+
google()
|
|
15
|
+
mavenCentral()
|
|
16
|
+
maven { url 'https://jitpack.io' }
|
|
17
|
+
|
|
18
|
+
def repos = [
|
|
19
|
+
'releases',
|
|
20
|
+
'snapshots'
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
flatDir {
|
|
24
|
+
dirs project(':halo_sdk_react_native_plugin').file('libs')
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
repos.each { repo ->
|
|
28
|
+
maven {
|
|
29
|
+
name = repo
|
|
30
|
+
url = "s3://synthesis-halo-artifacts/$repo"
|
|
31
|
+
credentials(AwsCredentials) {
|
|
32
|
+
def localAccessKey = properties.getProperty('aws.accesskey')
|
|
33
|
+
def systemEnvAccessKey = System.getenv('AWS_ACCESS_KEY_ID')
|
|
34
|
+
|
|
35
|
+
def localSecretKey = properties.getProperty('aws.secretkey')
|
|
36
|
+
def systemEnvSecretKey = System.getenv('AWS_SECRET_ACCESS_KEY')
|
|
37
|
+
|
|
38
|
+
def localToken = properties.getProperty('aws.token')
|
|
39
|
+
def systemEnvToken = System.getenv('AWS_SESSION_TOKEN')
|
|
40
|
+
|
|
41
|
+
accessKey = localAccessKey != null ? localAccessKey : systemEnvAccessKey
|
|
42
|
+
secretKey = localSecretKey != null ? localSecretKey : systemEnvSecretKey
|
|
43
|
+
|
|
44
|
+
if (systemEnvToken != null) {
|
|
45
|
+
sessionToken = systemEnvToken
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
android {
|
|
54
|
+
compileSdk 35
|
|
55
|
+
namespace 'za.co.synthesis.halo.sdkreactnativeplugin'
|
|
56
|
+
|
|
57
|
+
compileOptions {
|
|
58
|
+
sourceCompatibility JavaVersion.VERSION_17
|
|
59
|
+
targetCompatibility JavaVersion.VERSION_17
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
kotlinOptions {
|
|
63
|
+
jvmTarget = '17'
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
sourceSets {
|
|
67
|
+
main.java.srcDirs += 'src/main/kotlin'
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
defaultConfig {
|
|
71
|
+
minSdkVersion 29
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
def sdkVersion = "4.0.12"
|
|
76
|
+
|
|
77
|
+
dependencies {
|
|
78
|
+
// React Native is provided by the host app — do not bundle it
|
|
79
|
+
compileOnly 'com.facebook.react:react-native:+'
|
|
80
|
+
implementation 'androidx.core:core-ktx:1.9.0'
|
|
81
|
+
implementation 'androidx.appcompat:appcompat:1.6.1'
|
|
82
|
+
|
|
83
|
+
// Halo SDK
|
|
84
|
+
releaseImplementation group: "za.co.synthesis.halo", name: "sdk", version: "$sdkVersion", changing: true
|
|
85
|
+
debugImplementation group: "za.co.synthesis.halo", name: "sdk", version: "$sdkVersion-debug", changing: true
|
|
86
|
+
|
|
87
|
+
implementation(name: 'VisaSensoryBranding', ext: 'aar')
|
|
88
|
+
implementation(name: 'sonic-sdk-release-1.5.0', ext: 'aar')
|
|
89
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rootProject.name = 'halo_sdk_react_native_plugin'
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
package="za.co.synthesis.halo.sdkreactnativeplugin">
|
|
3
|
+
<application>
|
|
4
|
+
<activity
|
|
5
|
+
android:name=".AnimationActivity"
|
|
6
|
+
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
|
|
7
|
+
android:screenOrientation="portrait" />
|
|
8
|
+
</application>
|
|
9
|
+
</manifest>
|
package/android/src/main/kotlin/za/co/synthesis/halo/sdkreactnativeplugin/AnimationActivity.kt
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
package za.co.synthesis.halo.sdkreactnativeplugin
|
|
2
|
+
|
|
3
|
+
import android.graphics.Color
|
|
4
|
+
import android.media.MediaPlayer
|
|
5
|
+
import android.os.Bundle
|
|
6
|
+
import android.os.Handler
|
|
7
|
+
import android.os.Looper
|
|
8
|
+
import android.util.Log
|
|
9
|
+
import android.view.Gravity
|
|
10
|
+
import android.view.HapticFeedbackConstants
|
|
11
|
+
import android.view.ViewGroup
|
|
12
|
+
import android.widget.ImageView
|
|
13
|
+
import android.widget.LinearLayout
|
|
14
|
+
import androidx.appcompat.app.AppCompatActivity
|
|
15
|
+
import com.mastercard.sonic.controller.SonicController
|
|
16
|
+
import com.mastercard.sonic.controller.SonicEnvironment
|
|
17
|
+
import com.mastercard.sonic.controller.SonicType
|
|
18
|
+
import com.mastercard.sonic.listeners.OnCompleteListener
|
|
19
|
+
import com.mastercard.sonic.listeners.OnPrepareListener
|
|
20
|
+
import com.mastercard.sonic.model.SonicMerchant
|
|
21
|
+
import com.mastercard.sonic.widget.SonicBackground
|
|
22
|
+
import com.mastercard.sonic.widget.SonicView
|
|
23
|
+
import com.visa.SensoryBrandingView
|
|
24
|
+
|
|
25
|
+
class AnimationActivity : AppCompatActivity() {
|
|
26
|
+
private val TAG = "AnimationActivity"
|
|
27
|
+
|
|
28
|
+
private lateinit var sonicView: SonicView
|
|
29
|
+
private var sonicController: SonicController? = null
|
|
30
|
+
private lateinit var amexView: ImageView
|
|
31
|
+
private var mediaPlayer: MediaPlayer? = null
|
|
32
|
+
|
|
33
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
34
|
+
super.onCreate(savedInstanceState)
|
|
35
|
+
supportRequestWindowFeature(android.view.Window.FEATURE_NO_TITLE)
|
|
36
|
+
window.setFlags(
|
|
37
|
+
android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
|
38
|
+
android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
val maskedPAN = intent.getStringExtra(Const.MASKED_PAN)
|
|
42
|
+
val cardAssociation: CardAssociations = try {
|
|
43
|
+
intent.getStringExtra(Const.CARD_ASSOCIATION)?.let {
|
|
44
|
+
CardAssociations.valueOf(it.uppercase())
|
|
45
|
+
}
|
|
46
|
+
} catch (e: Exception) {
|
|
47
|
+
getCardTypeFromPan(maskedPAN)
|
|
48
|
+
} ?: CardAssociations.UNKNOWN
|
|
49
|
+
|
|
50
|
+
when (cardAssociation) {
|
|
51
|
+
CardAssociations.VISA -> {
|
|
52
|
+
val animationView = SensoryBrandingView(this, null).apply {
|
|
53
|
+
layoutParams = ViewGroup.LayoutParams(
|
|
54
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
55
|
+
ViewGroup.LayoutParams.MATCH_PARENT
|
|
56
|
+
)
|
|
57
|
+
gravity = android.view.Gravity.CENTER
|
|
58
|
+
}
|
|
59
|
+
setContentView(animationView)
|
|
60
|
+
animationView.setConstrainedFlags(true)
|
|
61
|
+
animationView.isSoundEnabled = true
|
|
62
|
+
animationView.isHapticFeedbackEnabled = true
|
|
63
|
+
animationView.isCheckMarkShown = true
|
|
64
|
+
animationView.setBackdropColor(Color.parseColor("#FFFFFF"))
|
|
65
|
+
animationView.post {
|
|
66
|
+
animationView.animate { closeAnimation() }
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
CardAssociations.MASTERCARD -> {
|
|
71
|
+
sonicView = SonicView(this).apply {
|
|
72
|
+
layoutParams = ViewGroup.LayoutParams(
|
|
73
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
74
|
+
ViewGroup.LayoutParams.MATCH_PARENT
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
sonicController = SonicController()
|
|
78
|
+
val sonicMerchant = SonicMerchant.Builder()
|
|
79
|
+
.merchantName("Halo")
|
|
80
|
+
.city("Pretoria")
|
|
81
|
+
.merchantCategoryCodes(arrayOf("MCC 5122"))
|
|
82
|
+
.countryCode("RSA")
|
|
83
|
+
.merchantId("halo-merc-1")
|
|
84
|
+
.build()
|
|
85
|
+
sonicController?.prepare(
|
|
86
|
+
sonicType = SonicType.SOUND_AND_ANIMATION,
|
|
87
|
+
sonicCue = "checkout",
|
|
88
|
+
sonicEnvironment = SonicEnvironment.SANDBOX,
|
|
89
|
+
merchant = sonicMerchant,
|
|
90
|
+
isHapticsEnabled = true,
|
|
91
|
+
context = this,
|
|
92
|
+
onPrepareListener = object : OnPrepareListener {
|
|
93
|
+
override fun onPrepared(statusCode: Int) { playSonic() }
|
|
94
|
+
}
|
|
95
|
+
)
|
|
96
|
+
sonicView.background = SonicBackground.WHITE
|
|
97
|
+
setContentView(sonicView)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
CardAssociations.AMEX -> {
|
|
101
|
+
val layout = LinearLayout(this).apply {
|
|
102
|
+
orientation = LinearLayout.VERTICAL
|
|
103
|
+
gravity = Gravity.CENTER
|
|
104
|
+
}
|
|
105
|
+
amexView = ImageView(this).apply {
|
|
106
|
+
layoutParams = LinearLayout.LayoutParams(500, 500)
|
|
107
|
+
setImageResource(R.drawable.amex)
|
|
108
|
+
}
|
|
109
|
+
layout.addView(amexView)
|
|
110
|
+
setContentView(layout)
|
|
111
|
+
mediaPlayer = MediaPlayer.create(this, R.raw.amex_confirm)
|
|
112
|
+
mediaPlayer?.isLooping = false
|
|
113
|
+
mediaPlayer?.start()
|
|
114
|
+
mediaPlayer?.setOnCompletionListener {
|
|
115
|
+
mediaPlayer?.release()
|
|
116
|
+
amexView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
|
|
117
|
+
closeAnimation()
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
else -> finish()
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private fun playSonic() {
|
|
126
|
+
sonicController?.play(sonicView, object : OnCompleteListener {
|
|
127
|
+
override fun onComplete(statusCode: Int) { closeAnimation() }
|
|
128
|
+
})
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private fun closeAnimation() {
|
|
132
|
+
Handler(Looper.getMainLooper()).postDelayed({ finish() }, 3000)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private fun getCardTypeFromPan(maskedPan: String?): CardAssociations {
|
|
136
|
+
return if (maskedPan != null) {
|
|
137
|
+
when (maskedPan[0]) {
|
|
138
|
+
'2' -> CardAssociations.MASTERCARD
|
|
139
|
+
'5' -> CardAssociations.MASTERCARD
|
|
140
|
+
'4' -> CardAssociations.VISA
|
|
141
|
+
'3' -> CardAssociations.AMEX
|
|
142
|
+
else -> CardAssociations.UNKNOWN
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
CardAssociations.UNKNOWN
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
@Deprecated("Use onBackPressedDispatcher")
|
|
150
|
+
override fun onBackPressed() {
|
|
151
|
+
// Prevent back press during animation
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
enum class CardAssociations(val association: String) {
|
|
156
|
+
VISA("VISA"),
|
|
157
|
+
MASTERCARD("MASTERCARD"),
|
|
158
|
+
AMEX("AMERICAN EXPRESS"),
|
|
159
|
+
UNKNOWN("UNKNOWN ASSOCIATION")
|
|
160
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
package za.co.synthesis.halo.sdkreactnativeplugin
|
|
2
|
+
|
|
3
|
+
object Const {
|
|
4
|
+
const val APPLICATION_PACKAGE_NAME = "applicationPackageName"
|
|
5
|
+
const val APPLICATION_VERSION = "applicationVersion"
|
|
6
|
+
const val ON_START_TRANSACTION_TIME_OUT = "onStartTransactionTimeOut"
|
|
7
|
+
const val ENABLE_SCHEME_ANIMATIONS = "enableSchemeAnimations"
|
|
8
|
+
|
|
9
|
+
const val TRANSACTION_AMOUNT = "transactionAmount"
|
|
10
|
+
const val MERCHANT_TRANSACTION_REFERENCE = "merchantTransactionReference"
|
|
11
|
+
const val TRANSACTION_CURRENCY = "transactionCurrency"
|
|
12
|
+
|
|
13
|
+
const val CARD_ASSOCIATION = "cardAssociation"
|
|
14
|
+
const val MASKED_PAN = "maskedPAN"
|
|
15
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
package za.co.synthesis.halo.sdkreactnativeplugin
|
|
2
|
+
|
|
3
|
+
import android.content.Intent
|
|
4
|
+
import android.os.Looper
|
|
5
|
+
import android.util.Log
|
|
6
|
+
import com.facebook.react.bridge.Arguments
|
|
7
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
8
|
+
import com.facebook.react.bridge.WritableMap
|
|
9
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
10
|
+
import za.co.synthesis.halo.haloCommonInterface.HaloErrorCode
|
|
11
|
+
import za.co.synthesis.halo.haloCommonInterface.HaloTransactionResult
|
|
12
|
+
import za.co.synthesis.halo.haloCommonInterface.HaloTransactionResultType
|
|
13
|
+
import za.co.synthesis.halo.sdk.model.HaloAttestationHealthResult
|
|
14
|
+
import za.co.synthesis.halo.sdk.model.HaloInitializationResult
|
|
15
|
+
import za.co.synthesis.halo.sdk.model.HaloUIMessage
|
|
16
|
+
import za.co.synthesis.halo.sdk.model.IHaloCallbacks
|
|
17
|
+
|
|
18
|
+
const val HALO_SDK_EVENT = "haloSdkEvent"
|
|
19
|
+
|
|
20
|
+
class HaloCallbacks(
|
|
21
|
+
private val reactContext: ReactApplicationContext
|
|
22
|
+
) : IHaloCallbacks() {
|
|
23
|
+
private val TAG = "HaloCallbacks"
|
|
24
|
+
private val handler = android.os.Handler(Looper.getMainLooper())
|
|
25
|
+
private var _jwtCallback: ((String) -> Unit)? = null
|
|
26
|
+
|
|
27
|
+
private fun sendEvent(params: WritableMap) {
|
|
28
|
+
handler.post {
|
|
29
|
+
if (reactContext.hasActiveCatalystInstance()) {
|
|
30
|
+
reactContext
|
|
31
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
32
|
+
.emit(HALO_SDK_EVENT, params)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
override fun onAttestationError(details: HaloAttestationHealthResult) {
|
|
38
|
+
Log.d(TAG, "onAttestationError: $details")
|
|
39
|
+
val params = Arguments.createMap().apply {
|
|
40
|
+
putString("eventType", "attestation")
|
|
41
|
+
putMap("data", makeWritableMap(details))
|
|
42
|
+
}
|
|
43
|
+
sendEvent(params)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
override fun onHaloTransactionResult(result: HaloTransactionResult) {
|
|
47
|
+
Log.d(TAG, "onHaloTransactionResult: $result")
|
|
48
|
+
val association = "${result.receipt?.association}"
|
|
49
|
+
val maskedPAN = "${result.receipt?.maskedPAN}"
|
|
50
|
+
val transactionApproved = result.resultType == HaloTransactionResultType.Approved
|
|
51
|
+
|
|
52
|
+
val params = Arguments.createMap().apply {
|
|
53
|
+
putString("eventType", "transaction")
|
|
54
|
+
putMap("data", makeWritableMap(result))
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
handler.post {
|
|
58
|
+
val context = UIContext.getActivity()
|
|
59
|
+
val showSchemeAnimations = UIContext.areSchemeAnimationsEnabled()
|
|
60
|
+
if (context != null && transactionApproved && showSchemeAnimations) {
|
|
61
|
+
val intent = Intent(context, AnimationActivity::class.java)
|
|
62
|
+
intent.putExtra(Const.CARD_ASSOCIATION, association)
|
|
63
|
+
intent.putExtra(Const.MASKED_PAN, maskedPAN)
|
|
64
|
+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
65
|
+
context.startActivity(intent)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (reactContext.hasActiveCatalystInstance()) {
|
|
69
|
+
reactContext
|
|
70
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
71
|
+
.emit(HALO_SDK_EVENT, params)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
override fun onHaloUIMessage(message: HaloUIMessage) {
|
|
77
|
+
Log.d(TAG, "onHaloUIMessage: $message")
|
|
78
|
+
val params = Arguments.createMap().apply {
|
|
79
|
+
putString("eventType", "ui")
|
|
80
|
+
putMap("data", makeWritableMap(message))
|
|
81
|
+
}
|
|
82
|
+
sendEvent(params)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
override fun onInitializationResult(result: HaloInitializationResult) {
|
|
86
|
+
Log.d(TAG, "onInitializationResult resultType: ${result.resultType}")
|
|
87
|
+
Log.d(TAG, "onInitializationResult errorCode: ${result.errorCode}")
|
|
88
|
+
|
|
89
|
+
val params = Arguments.createMap().apply {
|
|
90
|
+
putString("eventType", "initialization")
|
|
91
|
+
putMap("data", makeWritableMap(result))
|
|
92
|
+
}
|
|
93
|
+
sendEvent(params)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
override fun onRequestJWT(callback: (String) -> Unit) {
|
|
97
|
+
Log.d(TAG, "onRequestJWT")
|
|
98
|
+
_jwtCallback = callback
|
|
99
|
+
val params = Arguments.createMap().apply {
|
|
100
|
+
putString("eventType", "onJwtRequest")
|
|
101
|
+
}
|
|
102
|
+
sendEvent(params)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
override fun onSecurityError(errorCode: HaloErrorCode) {
|
|
106
|
+
Log.d(TAG, "onSecurityError: $errorCode")
|
|
107
|
+
val params = Arguments.createMap().apply {
|
|
108
|
+
putString("eventType", "security")
|
|
109
|
+
putString("data", errorCode.name)
|
|
110
|
+
}
|
|
111
|
+
sendEvent(params)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
override fun onCameraControlLost() {
|
|
115
|
+
Log.d(TAG, "onCameraControlLost")
|
|
116
|
+
val params = Arguments.createMap().apply {
|
|
117
|
+
putString("eventType", "camera")
|
|
118
|
+
putString("data", "onCameraControlLost")
|
|
119
|
+
}
|
|
120
|
+
sendEvent(params)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
fun jwtCallback(jwt: String) {
|
|
124
|
+
_jwtCallback?.invoke(jwt)
|
|
125
|
+
}
|
|
126
|
+
}
|
package/android/src/main/kotlin/za/co/synthesis/halo/sdkreactnativeplugin/HaloReactActivity.kt
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
package za.co.synthesis.halo.sdkreactnativeplugin
|
|
2
|
+
|
|
3
|
+
import android.nfc.NfcAdapter
|
|
4
|
+
import android.os.Bundle
|
|
5
|
+
import android.util.Log
|
|
6
|
+
import com.facebook.react.ReactActivity
|
|
7
|
+
import za.co.synthesis.halo.sdk.HaloSDK
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Abstract base activity for React Native apps using Halo SDK.
|
|
11
|
+
*
|
|
12
|
+
* Your app's MainActivity should extend HaloReactActivity instead of ReactActivity:
|
|
13
|
+
*
|
|
14
|
+
* ```kotlin
|
|
15
|
+
* class MainActivity : HaloReactActivity() {
|
|
16
|
+
* override fun getMainComponentName() = "YourAppName"
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* This class handles the full HaloSDK lifecycle (onCreate, onStart, onResume, onPause, onStop),
|
|
21
|
+
* mirroring the Flutter plugin's HaloActivity.
|
|
22
|
+
*/
|
|
23
|
+
abstract class HaloReactActivity : ReactActivity() {
|
|
24
|
+
private val TAG = "HaloReactActivity"
|
|
25
|
+
|
|
26
|
+
private val nfcAdapter: NfcAdapter? by lazy {
|
|
27
|
+
NfcAdapter.getDefaultAdapter(this)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
31
|
+
Log.d(TAG, "onCreate")
|
|
32
|
+
super.onCreate(savedInstanceState)
|
|
33
|
+
if (nfcAdapter?.isEnabled == true) {
|
|
34
|
+
HaloSDK.onCreate(this, this, savedInstanceState, null)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
override fun onStart() {
|
|
39
|
+
Log.d(TAG, "onStart")
|
|
40
|
+
super.onStart()
|
|
41
|
+
HaloSDK.onStart()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
override fun onResume() {
|
|
45
|
+
Log.d(TAG, "onResume")
|
|
46
|
+
super.onResume()
|
|
47
|
+
HaloSDK.onResume()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
override fun onPause() {
|
|
51
|
+
Log.d(TAG, "onPause")
|
|
52
|
+
HaloSDK.onPause()
|
|
53
|
+
super.onPause()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
override fun onStop() {
|
|
57
|
+
Log.d(TAG, "onStop")
|
|
58
|
+
HaloSDK.onStop()
|
|
59
|
+
super.onStop()
|
|
60
|
+
}
|
|
61
|
+
}
|
package/android/src/main/kotlin/za/co/synthesis/halo/sdkreactnativeplugin/HaloSdkImplementation.kt
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
package za.co.synthesis.halo.sdkreactnativeplugin
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import com.facebook.react.bridge.Promise
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import za.co.synthesis.halo.haloCommonInterface.HaloException
|
|
7
|
+
import za.co.synthesis.halo.haloCommonInterface.TransactionType
|
|
8
|
+
import za.co.synthesis.halo.sdk.HaloSDK
|
|
9
|
+
import za.co.synthesis.halo.sdk.model.HaloInitializationParameters
|
|
10
|
+
|
|
11
|
+
class HaloSdkImplementation(reactContext: ReactApplicationContext) {
|
|
12
|
+
private val TAG = "HaloSdkImplementation"
|
|
13
|
+
private val ON_START_TRANSACTION_TIME_OUT = 300000L
|
|
14
|
+
private val haloCallbacks: HaloCallbacks = HaloCallbacks(reactContext)
|
|
15
|
+
|
|
16
|
+
fun initializeHaloSDK(promise: Promise, args: HashMap<String, Any>) {
|
|
17
|
+
Log.d(TAG, "initializeHaloSDK: $args")
|
|
18
|
+
try {
|
|
19
|
+
HaloSDK.initialize(
|
|
20
|
+
HaloInitializationParameters(
|
|
21
|
+
haloCallbacks,
|
|
22
|
+
(args[Const.ON_START_TRANSACTION_TIME_OUT] as? Number)?.toLong()
|
|
23
|
+
?: ON_START_TRANSACTION_TIME_OUT,
|
|
24
|
+
args[Const.APPLICATION_PACKAGE_NAME] as String,
|
|
25
|
+
args[Const.APPLICATION_VERSION] as String
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
UIContext.enableSchemeAnimations(
|
|
29
|
+
(args[Const.ENABLE_SCHEME_ANIMATIONS] as Boolean?) ?: false
|
|
30
|
+
)
|
|
31
|
+
promise.resolve(null)
|
|
32
|
+
} catch (e: Exception) {
|
|
33
|
+
if (e is HaloException) {
|
|
34
|
+
promise.reject("sdkreactnativeplugin error", e.message, e)
|
|
35
|
+
} else {
|
|
36
|
+
promise.reject("sdkreactnativeplugin error", e.message, e)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
fun startTransaction(
|
|
42
|
+
promise: Promise,
|
|
43
|
+
args: HashMap<String, Any>,
|
|
44
|
+
transactionType: TransactionType = TransactionType.Purchase
|
|
45
|
+
) {
|
|
46
|
+
Log.d(TAG, "startTransaction: $args")
|
|
47
|
+
try {
|
|
48
|
+
val extraFields = getRest<String>(
|
|
49
|
+
args,
|
|
50
|
+
listOf(
|
|
51
|
+
Const.TRANSACTION_AMOUNT,
|
|
52
|
+
Const.MERCHANT_TRANSACTION_REFERENCE,
|
|
53
|
+
Const.TRANSACTION_CURRENCY
|
|
54
|
+
)
|
|
55
|
+
)
|
|
56
|
+
val result = HaloSDK.startTransaction(
|
|
57
|
+
(args[Const.TRANSACTION_AMOUNT] as Double).toBigDecimal(),
|
|
58
|
+
args[Const.MERCHANT_TRANSACTION_REFERENCE] as String,
|
|
59
|
+
args[Const.TRANSACTION_CURRENCY] as String,
|
|
60
|
+
extraFields,
|
|
61
|
+
null,
|
|
62
|
+
transactionType
|
|
63
|
+
)
|
|
64
|
+
promise.resolve(makeWritableMap(result))
|
|
65
|
+
} catch (e: Exception) {
|
|
66
|
+
promise.reject("sdkreactnativeplugin error", e.message, e)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
fun cancelTransaction(promise: Promise) {
|
|
71
|
+
Log.d(TAG, "cancelTransaction")
|
|
72
|
+
HaloSDK.requestTransactionCancellation()
|
|
73
|
+
promise.resolve(null)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
fun jwtCallback(promise: Promise, jwt: String) {
|
|
77
|
+
Log.d(TAG, "jwtCallback")
|
|
78
|
+
haloCallbacks.jwtCallback(jwt)
|
|
79
|
+
promise.resolve(null)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
package za.co.synthesis.halo.sdkreactnativeplugin
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import com.facebook.react.bridge.LifecycleEventListener
|
|
5
|
+
import com.facebook.react.bridge.Promise
|
|
6
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
7
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
8
|
+
import com.facebook.react.bridge.ReactMethod
|
|
9
|
+
import com.facebook.react.bridge.ReadableMap
|
|
10
|
+
import za.co.synthesis.halo.haloCommonInterface.TransactionType
|
|
11
|
+
|
|
12
|
+
class HaloSdkModule(reactContext: ReactApplicationContext) :
|
|
13
|
+
ReactContextBaseJavaModule(reactContext),
|
|
14
|
+
LifecycleEventListener {
|
|
15
|
+
|
|
16
|
+
private val TAG = "HaloSdkModule"
|
|
17
|
+
private val haloSdkImplementation: HaloSdkImplementation = HaloSdkImplementation(reactContext)
|
|
18
|
+
|
|
19
|
+
init {
|
|
20
|
+
reactContext.addLifecycleEventListener(this)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
override fun getName(): String = "HaloSdk"
|
|
24
|
+
|
|
25
|
+
@ReactMethod
|
|
26
|
+
fun initializeHaloSDK(args: ReadableMap, promise: Promise) {
|
|
27
|
+
haloSdkImplementation.initializeHaloSDK(promise, args.toHashMap())
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@ReactMethod
|
|
31
|
+
fun startTransaction(args: ReadableMap, promise: Promise) {
|
|
32
|
+
haloSdkImplementation.startTransaction(promise, args.toHashMap())
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@ReactMethod
|
|
36
|
+
fun cardRefundTransaction(args: ReadableMap, promise: Promise) {
|
|
37
|
+
haloSdkImplementation.startTransaction(promise, args.toHashMap(), TransactionType.Refund)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@ReactMethod
|
|
41
|
+
fun jwtCallback(jwt: String, promise: Promise) {
|
|
42
|
+
haloSdkImplementation.jwtCallback(promise, jwt)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@ReactMethod
|
|
46
|
+
fun cancelTransaction(promise: Promise) {
|
|
47
|
+
haloSdkImplementation.cancelTransaction(promise)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Required for RN NativeEventEmitter
|
|
51
|
+
@ReactMethod
|
|
52
|
+
fun addListener(eventName: String) {}
|
|
53
|
+
|
|
54
|
+
@ReactMethod
|
|
55
|
+
fun removeListeners(count: Int) {}
|
|
56
|
+
|
|
57
|
+
// Keep UIContext activity reference up to date
|
|
58
|
+
override fun onHostResume() {
|
|
59
|
+
Log.d(TAG, "onHostResume")
|
|
60
|
+
UIContext.updateActivity(currentActivity)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
override fun onHostPause() {
|
|
64
|
+
Log.d(TAG, "onHostPause")
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
override fun onHostDestroy() {
|
|
68
|
+
Log.d(TAG, "onHostDestroy")
|
|
69
|
+
UIContext.updateActivity(null)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package za.co.synthesis.halo.sdkreactnativeplugin
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
|
|
8
|
+
class HaloSdkPackage : ReactPackage {
|
|
9
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
10
|
+
return listOf(HaloSdkModule(reactContext))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
14
|
+
return emptyList()
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package za.co.synthesis.halo.sdkreactnativeplugin
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import java.lang.ref.WeakReference
|
|
5
|
+
|
|
6
|
+
object UIContext {
|
|
7
|
+
private var activityRef: WeakReference<Activity>? = null
|
|
8
|
+
private var enableSchemeAnimations: Boolean = false
|
|
9
|
+
|
|
10
|
+
fun updateActivity(activity: Activity?) {
|
|
11
|
+
activityRef = activity?.let { WeakReference(it) }
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
fun enableSchemeAnimations(enable: Boolean) {
|
|
15
|
+
enableSchemeAnimations = enable
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
fun getActivity(): Activity? = activityRef?.get()
|
|
19
|
+
fun areSchemeAnimationsEnabled(): Boolean = enableSchemeAnimations
|
|
20
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
package za.co.synthesis.halo.sdkreactnativeplugin
|
|
2
|
+
|
|
3
|
+
import android.util.Base64
|
|
4
|
+
import com.facebook.react.bridge.Arguments
|
|
5
|
+
import com.facebook.react.bridge.WritableArray
|
|
6
|
+
import com.facebook.react.bridge.WritableMap
|
|
7
|
+
import za.co.synthesis.halo.haloCommonInterface.HaloTransactionReceipt
|
|
8
|
+
import za.co.synthesis.halo.haloCommonInterface.HaloTransactionResult
|
|
9
|
+
import za.co.synthesis.halo.sdk.model.HaloAttestationHealthResult
|
|
10
|
+
import za.co.synthesis.halo.sdk.model.HaloCurrencyValue
|
|
11
|
+
import za.co.synthesis.halo.sdk.model.HaloInitializationResult
|
|
12
|
+
import za.co.synthesis.halo.sdk.model.HaloStartTransactionResult
|
|
13
|
+
import za.co.synthesis.halo.sdk.model.HaloUIMessage
|
|
14
|
+
import za.co.synthesis.halo.sdk.model.HaloWarning
|
|
15
|
+
import java.util.Currency
|
|
16
|
+
|
|
17
|
+
internal fun <T> getRest(args: Map<String, Any>, keys: List<String>): Map<String, T> {
|
|
18
|
+
val rest = HashMap<String, T>()
|
|
19
|
+
for (key in args.keys) {
|
|
20
|
+
try {
|
|
21
|
+
if (key !in keys) {
|
|
22
|
+
rest[key] = args[key] as T
|
|
23
|
+
}
|
|
24
|
+
} catch (e: TypeCastException) {
|
|
25
|
+
throw TypeCastException("The value of $key is not of type T")
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return rest
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
internal fun makeWritableMap(data: HaloAttestationHealthResult): WritableMap {
|
|
32
|
+
return Arguments.createMap().apply {
|
|
33
|
+
putString("resultType", data.resultType.name)
|
|
34
|
+
putString("errorCode", data.errorCode.name)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
internal fun makeWritableMap(data: HaloTransactionResult): WritableMap {
|
|
39
|
+
return Arguments.createMap().apply {
|
|
40
|
+
putString("resultType", data.resultType.name)
|
|
41
|
+
putString("merchantTransactionReference", data.merchantTransactionReference)
|
|
42
|
+
putString("haloTransactionReference", data.haloTransactionReference)
|
|
43
|
+
putString("paymentProviderReference", data.paymentProviderReference)
|
|
44
|
+
putString("errorCode", data.errorCode.name)
|
|
45
|
+
putArray("errorDetails", data.errorDetails.toWritableArray())
|
|
46
|
+
putMap("receipt", makeWritableMap(data.receipt))
|
|
47
|
+
putMap("customTags", data.customTags?.toWritableMap())
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
internal fun makeWritableMap(data: HaloTransactionReceipt?): WritableMap? {
|
|
52
|
+
if (data == null) return null
|
|
53
|
+
return Arguments.createMap().apply {
|
|
54
|
+
putString("signature", Base64.encodeToString(data.signature, Base64.NO_WRAP))
|
|
55
|
+
putString("transactionDate", data.transactionDate)
|
|
56
|
+
putString("transactionTime", data.transactionTime)
|
|
57
|
+
putString("aid", data.aid)
|
|
58
|
+
putString("applicationLabel", data.applicationLabel)
|
|
59
|
+
putString("applicationPreferredName", data.applicationPreferredName)
|
|
60
|
+
putString("tvr", data.tvr)
|
|
61
|
+
putString("cvr", data.cvr)
|
|
62
|
+
putString("cryptogramType", data.cryptogramType?.name)
|
|
63
|
+
putString("cryptogram", data.cryptogram)
|
|
64
|
+
putString("maskedPAN", data.maskedPAN)
|
|
65
|
+
putString("authorizationCode", data.authorizationCode)
|
|
66
|
+
putString("ISOResponseCode", data.ISOResponseCode)
|
|
67
|
+
putString("association", data.association)
|
|
68
|
+
putString("expiryDate", data.expiryDate)
|
|
69
|
+
putString("mid", data.mid)
|
|
70
|
+
putString("merchantName", data.merchantName)
|
|
71
|
+
putString("tid", data.tid)
|
|
72
|
+
putString("stan", data.stan)
|
|
73
|
+
putString("panEntry", data.panEntry)
|
|
74
|
+
putString("cardType", data.cardType)
|
|
75
|
+
putString("panSequenceNumber", data.panSequenceNumber)
|
|
76
|
+
putString("effectiveDate", data.effectiveDate)
|
|
77
|
+
putString("disposition", data.disposition)
|
|
78
|
+
putString("currencyCode", data.currencyCode?.toString())
|
|
79
|
+
putString("amountAuthorised", data.amountAuthorised?.toString())
|
|
80
|
+
putString("amountOther", data.amountOther?.toString())
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
internal fun makeWritableMap(data: HaloUIMessage): WritableMap {
|
|
85
|
+
return Arguments.createMap().apply {
|
|
86
|
+
putString("msgID", data.msgID.name)
|
|
87
|
+
putInt("holdTimeMS", data.holdTimeMS)
|
|
88
|
+
putArray("languagePreference", data.languagePreference?.toWritableArray())
|
|
89
|
+
putMap("offlineBalance", makeWritableMap(data.offlineBalance))
|
|
90
|
+
putMap("transactionAmount", makeWritableMap(data.transactionAmount))
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
internal fun makeWritableMap(data: HaloCurrencyValue?): WritableMap? {
|
|
95
|
+
if (data == null) return null
|
|
96
|
+
return Arguments.createMap().apply {
|
|
97
|
+
putMap("currency", makeWritableMap(data.currency))
|
|
98
|
+
putDouble("amount", data.amount.toDouble())
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
internal fun makeWritableMap(data: Currency?): WritableMap? {
|
|
103
|
+
if (data == null) return null
|
|
104
|
+
return Arguments.createMap().apply {
|
|
105
|
+
putString("currencyCode", data.currencyCode)
|
|
106
|
+
putInt("defaultFractionDigits", data.defaultFractionDigits)
|
|
107
|
+
putInt("numericCode", data.numericCode)
|
|
108
|
+
putString("displayName", data.displayName)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
internal fun makeWritableMap(data: HaloInitializationResult): WritableMap {
|
|
113
|
+
return Arguments.createMap().apply {
|
|
114
|
+
putString("resultType", data.resultType.name)
|
|
115
|
+
putMap("terminalCurrency", makeWritableMap(data.terminalCurrency))
|
|
116
|
+
putArray("terminalLanguageCodes", data.terminalLanguageCodes?.toWritableArray())
|
|
117
|
+
putString("terminalCountryCode", data.terminalCountryCode)
|
|
118
|
+
putString("errorCode", data.errorCode.name)
|
|
119
|
+
putArray("warnings", data.warnings.toWritableArray { makeWritableMap(it) })
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
internal fun makeWritableMap(data: HaloWarning): WritableMap {
|
|
124
|
+
return Arguments.createMap().apply {
|
|
125
|
+
putString("errorCode", data.errorCode.name)
|
|
126
|
+
putArray("details", data.details?.toWritableArray())
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
internal fun makeWritableMap(data: HaloStartTransactionResult): WritableMap {
|
|
131
|
+
return Arguments.createMap().apply {
|
|
132
|
+
putString("resultType", data.resultType.name)
|
|
133
|
+
putString("errorCode", data.errorCode.name)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private fun Map<String, String>.toWritableMap(): WritableMap {
|
|
138
|
+
return Arguments.createMap().apply {
|
|
139
|
+
this@toWritableMap.forEach { (key, value) -> putString(key, value) }
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private fun List<String>.toWritableArray(): WritableArray {
|
|
144
|
+
return Arguments.createArray().apply {
|
|
145
|
+
this@toWritableArray.forEach { pushString(it) }
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
private fun <T> List<T>.toWritableArray(transform: (T) -> WritableMap): WritableArray {
|
|
151
|
+
return Arguments.createArray().apply {
|
|
152
|
+
this@toWritableArray.forEach { pushMap(transform(it)) }
|
|
153
|
+
}
|
|
154
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { IHaloCallbacks, HaloStartTransactionResult } from './types';
|
|
2
|
+
export declare const HaloSdk: {
|
|
3
|
+
/**
|
|
4
|
+
* Initialize the Halo SDK. Must be called before any transactions.
|
|
5
|
+
*
|
|
6
|
+
* @param callbacks - Object implementing IHaloCallbacks to receive SDK events.
|
|
7
|
+
* @param applicationPackageName - Your app's package name.
|
|
8
|
+
* @param applicationVersion - Your app's version string.
|
|
9
|
+
* @param onStartTransactionTimeOut - Timeout in ms for starting a transaction (default 300000).
|
|
10
|
+
* @param enableSchemeAnimations - Whether to show Visa/Mastercard/Amex animations on approval.
|
|
11
|
+
*/
|
|
12
|
+
initialize(callbacks: IHaloCallbacks, applicationPackageName: string, applicationVersion: string, onStartTransactionTimeOut?: number, enableSchemeAnimations?: boolean): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Start a purchase transaction.
|
|
15
|
+
*
|
|
16
|
+
* @param transactionAmount - Amount to charge (e.g. 10.50).
|
|
17
|
+
* @param merchantTransactionReference - Unique reference for this transaction.
|
|
18
|
+
* @param transactionCurrency - ISO 4217 currency code (e.g. "ZAR").
|
|
19
|
+
* @returns HaloStartTransactionResult indicating whether the tap was accepted.
|
|
20
|
+
*/
|
|
21
|
+
startTransaction(transactionAmount: number, merchantTransactionReference: string, transactionCurrency: string): Promise<HaloStartTransactionResult>;
|
|
22
|
+
/**
|
|
23
|
+
* Start a card refund transaction.
|
|
24
|
+
*
|
|
25
|
+
* @param transactionAmount - Amount to refund.
|
|
26
|
+
* @param merchantTransactionReference - Unique reference for this transaction.
|
|
27
|
+
* @param transactionCurrency - ISO 4217 currency code (e.g. "ZAR").
|
|
28
|
+
* @returns HaloStartTransactionResult indicating whether the tap was accepted.
|
|
29
|
+
*/
|
|
30
|
+
cardRefundTransaction(transactionAmount: number, merchantTransactionReference: string, transactionCurrency: string): Promise<HaloStartTransactionResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Request cancellation of the current transaction.
|
|
33
|
+
*/
|
|
34
|
+
cancelTransaction(): Promise<void>;
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=HaloSdk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HaloSdk.d.ts","sourceRoot":"","sources":["../src/HaloSdk.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,0BAA0B,EAC3B,MAAM,SAAS,CAAC;AAyDjB,eAAO,MAAM,OAAO;IAClB;;;;;;;;OAQG;0BAEU,cAAc,0BACD,MAAM,sBACV,MAAM,8BACE,MAAM,2BACT,OAAO,GAC/B,OAAO,CAAC,IAAI,CAAC;IAUhB;;;;;;;OAOG;wCAEkB,MAAM,gCACK,MAAM,uBACf,MAAM,GAC1B,OAAO,CAAC,0BAA0B,CAAC;IAQtC;;;;;;;OAOG;6CAEkB,MAAM,gCACK,MAAM,uBACf,MAAM,GAC1B,OAAO,CAAC,0BAA0B,CAAC;IAQtC;;OAEG;yBACkB,OAAO,CAAC,IAAI,CAAC;CAGnC,CAAC"}
|
package/dist/HaloSdk.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HaloSdk = void 0;
|
|
4
|
+
const react_native_1 = require("react-native");
|
|
5
|
+
const LINKING_ERROR = `The package 'halo-sdk-react-native' doesn't seem to be linked. Make sure to: \n\n` +
|
|
6
|
+
`1. Add HaloSdkPackage to your MainApplication's getPackages() list.\n` +
|
|
7
|
+
`2. Extend HaloReactActivity instead of ReactActivity in MainActivity.\n` +
|
|
8
|
+
`3. Copy the Halo AAR libs to your android/libs folder.`;
|
|
9
|
+
const HaloSdkNative = react_native_1.NativeModules.HaloSdk
|
|
10
|
+
? react_native_1.NativeModules.HaloSdk
|
|
11
|
+
: new Proxy({}, {
|
|
12
|
+
get() {
|
|
13
|
+
throw new Error(LINKING_ERROR);
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
const eventEmitter = new react_native_1.NativeEventEmitter(HaloSdkNative);
|
|
17
|
+
const HALO_SDK_EVENT = 'haloSdkEvent';
|
|
18
|
+
let _subscription = null;
|
|
19
|
+
function _setupEventListener(callbacks) {
|
|
20
|
+
_subscription === null || _subscription === void 0 ? void 0 : _subscription.remove();
|
|
21
|
+
_subscription = eventEmitter.addListener(HALO_SDK_EVENT, (event) => {
|
|
22
|
+
switch (event.eventType) {
|
|
23
|
+
case 'attestation':
|
|
24
|
+
callbacks.onAttestationError(event.data);
|
|
25
|
+
break;
|
|
26
|
+
case 'transaction':
|
|
27
|
+
callbacks.onHaloTransactionResult(event.data);
|
|
28
|
+
break;
|
|
29
|
+
case 'ui':
|
|
30
|
+
callbacks.onHaloUIMessage(event.data);
|
|
31
|
+
break;
|
|
32
|
+
case 'initialization':
|
|
33
|
+
callbacks.onInitializationResult(event.data);
|
|
34
|
+
break;
|
|
35
|
+
case 'onJwtRequest':
|
|
36
|
+
callbacks.onRequestJWT(_jwtCallback);
|
|
37
|
+
break;
|
|
38
|
+
case 'security':
|
|
39
|
+
callbacks.onSecurityError(event.data);
|
|
40
|
+
break;
|
|
41
|
+
case 'camera':
|
|
42
|
+
callbacks.onCameraControlLost();
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function _jwtCallback(jwt) {
|
|
48
|
+
HaloSdkNative.jwtCallback(jwt);
|
|
49
|
+
}
|
|
50
|
+
exports.HaloSdk = {
|
|
51
|
+
/**
|
|
52
|
+
* Initialize the Halo SDK. Must be called before any transactions.
|
|
53
|
+
*
|
|
54
|
+
* @param callbacks - Object implementing IHaloCallbacks to receive SDK events.
|
|
55
|
+
* @param applicationPackageName - Your app's package name.
|
|
56
|
+
* @param applicationVersion - Your app's version string.
|
|
57
|
+
* @param onStartTransactionTimeOut - Timeout in ms for starting a transaction (default 300000).
|
|
58
|
+
* @param enableSchemeAnimations - Whether to show Visa/Mastercard/Amex animations on approval.
|
|
59
|
+
*/
|
|
60
|
+
initialize(callbacks, applicationPackageName, applicationVersion, onStartTransactionTimeOut, enableSchemeAnimations) {
|
|
61
|
+
_setupEventListener(callbacks);
|
|
62
|
+
return HaloSdkNative.initializeHaloSDK({
|
|
63
|
+
applicationPackageName,
|
|
64
|
+
applicationVersion,
|
|
65
|
+
onStartTransactionTimeOut: onStartTransactionTimeOut !== null && onStartTransactionTimeOut !== void 0 ? onStartTransactionTimeOut : null,
|
|
66
|
+
enableSchemeAnimations: enableSchemeAnimations !== null && enableSchemeAnimations !== void 0 ? enableSchemeAnimations : false,
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
/**
|
|
70
|
+
* Start a purchase transaction.
|
|
71
|
+
*
|
|
72
|
+
* @param transactionAmount - Amount to charge (e.g. 10.50).
|
|
73
|
+
* @param merchantTransactionReference - Unique reference for this transaction.
|
|
74
|
+
* @param transactionCurrency - ISO 4217 currency code (e.g. "ZAR").
|
|
75
|
+
* @returns HaloStartTransactionResult indicating whether the tap was accepted.
|
|
76
|
+
*/
|
|
77
|
+
startTransaction(transactionAmount, merchantTransactionReference, transactionCurrency) {
|
|
78
|
+
return HaloSdkNative.startTransaction({
|
|
79
|
+
transactionAmount,
|
|
80
|
+
merchantTransactionReference,
|
|
81
|
+
transactionCurrency,
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
/**
|
|
85
|
+
* Start a card refund transaction.
|
|
86
|
+
*
|
|
87
|
+
* @param transactionAmount - Amount to refund.
|
|
88
|
+
* @param merchantTransactionReference - Unique reference for this transaction.
|
|
89
|
+
* @param transactionCurrency - ISO 4217 currency code (e.g. "ZAR").
|
|
90
|
+
* @returns HaloStartTransactionResult indicating whether the tap was accepted.
|
|
91
|
+
*/
|
|
92
|
+
cardRefundTransaction(transactionAmount, merchantTransactionReference, transactionCurrency) {
|
|
93
|
+
return HaloSdkNative.cardRefundTransaction({
|
|
94
|
+
transactionAmount,
|
|
95
|
+
merchantTransactionReference,
|
|
96
|
+
transactionCurrency,
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
/**
|
|
100
|
+
* Request cancellation of the current transaction.
|
|
101
|
+
*/
|
|
102
|
+
cancelTransaction() {
|
|
103
|
+
return HaloSdkNative.cancelTransaction();
|
|
104
|
+
},
|
|
105
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { HaloSdk } from './HaloSdk';
|
|
2
|
+
export type { IHaloCallbacks, HaloStartTransactionResult, HaloAttestationHealthResult, HaloInitializationResult, HaloTransactionResult, HaloTransactionReceipt, HaloUIMessage, HaloCurrencyValue, HaloCurrencyInfo, HaloWarning, } from './types';
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EACV,cAAc,EACd,0BAA0B,EAC1B,2BAA2B,EAC3B,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,GACZ,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export interface HaloStartTransactionResult {
|
|
2
|
+
resultType: string;
|
|
3
|
+
errorCode: string;
|
|
4
|
+
}
|
|
5
|
+
export interface HaloAttestationHealthResult {
|
|
6
|
+
resultType: string;
|
|
7
|
+
errorCode: string;
|
|
8
|
+
}
|
|
9
|
+
export interface HaloCurrencyInfo {
|
|
10
|
+
currencyCode: string;
|
|
11
|
+
defaultFractionDigits: number;
|
|
12
|
+
numericCode: number;
|
|
13
|
+
displayName: string;
|
|
14
|
+
}
|
|
15
|
+
export interface HaloCurrencyValue {
|
|
16
|
+
currency?: HaloCurrencyInfo;
|
|
17
|
+
amount?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface HaloWarning {
|
|
20
|
+
errorCode: string;
|
|
21
|
+
details?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface HaloInitializationResult {
|
|
24
|
+
resultType: string;
|
|
25
|
+
terminalCurrency?: HaloCurrencyInfo;
|
|
26
|
+
terminalLanguageCodes?: string[];
|
|
27
|
+
terminalCountryCode?: string;
|
|
28
|
+
errorCode: string;
|
|
29
|
+
warnings: HaloWarning[];
|
|
30
|
+
}
|
|
31
|
+
export interface HaloTransactionReceipt {
|
|
32
|
+
signature?: string;
|
|
33
|
+
transactionDate?: string;
|
|
34
|
+
transactionTime?: string;
|
|
35
|
+
aid?: string;
|
|
36
|
+
applicationLabel?: string;
|
|
37
|
+
applicationPreferredName?: string;
|
|
38
|
+
tvr?: string;
|
|
39
|
+
cvr?: string;
|
|
40
|
+
cryptogramType?: string;
|
|
41
|
+
cryptogram?: string;
|
|
42
|
+
maskedPAN?: string;
|
|
43
|
+
authorizationCode?: string;
|
|
44
|
+
ISOResponseCode?: string;
|
|
45
|
+
association?: string;
|
|
46
|
+
expiryDate?: string;
|
|
47
|
+
mid?: string;
|
|
48
|
+
merchantName?: string;
|
|
49
|
+
tid?: string;
|
|
50
|
+
stan?: string;
|
|
51
|
+
panEntry?: string;
|
|
52
|
+
cardType?: string;
|
|
53
|
+
panSequenceNumber?: string;
|
|
54
|
+
effectiveDate?: string;
|
|
55
|
+
disposition?: string;
|
|
56
|
+
currencyCode?: string;
|
|
57
|
+
amountAuthorised?: string;
|
|
58
|
+
amountOther?: string;
|
|
59
|
+
}
|
|
60
|
+
export interface HaloTransactionResult {
|
|
61
|
+
resultType: string;
|
|
62
|
+
merchantTransactionReference?: string;
|
|
63
|
+
haloTransactionReference?: string;
|
|
64
|
+
paymentProviderReference?: string;
|
|
65
|
+
errorCode: string;
|
|
66
|
+
errorDetails?: string;
|
|
67
|
+
receipt?: HaloTransactionReceipt;
|
|
68
|
+
customTags?: Record<string, string>;
|
|
69
|
+
}
|
|
70
|
+
export interface HaloUIMessage {
|
|
71
|
+
msgID: string;
|
|
72
|
+
holdTimeMS?: number;
|
|
73
|
+
languagePreference?: string;
|
|
74
|
+
offlineBalance?: HaloCurrencyValue;
|
|
75
|
+
transactionAmount?: HaloCurrencyValue;
|
|
76
|
+
}
|
|
77
|
+
export interface IHaloCallbacks {
|
|
78
|
+
onAttestationError: (details: HaloAttestationHealthResult) => void;
|
|
79
|
+
onHaloTransactionResult: (result: HaloTransactionResult) => void;
|
|
80
|
+
onHaloUIMessage: (message: HaloUIMessage) => void;
|
|
81
|
+
onInitializationResult: (result: HaloInitializationResult) => void;
|
|
82
|
+
onRequestJWT: (jwtCallback: (jwt: string) => void) => void;
|
|
83
|
+
onSecurityError: (errorCode: string) => void;
|
|
84
|
+
onCameraControlLost: () => void;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "halo-sdk-react-native",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "React Native plugin for Halo SDK",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"android/src",
|
|
10
|
+
"android/libs",
|
|
11
|
+
"android/build.gradle",
|
|
12
|
+
"android/settings.gradle",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"halo",
|
|
20
|
+
"sdk",
|
|
21
|
+
"react-native",
|
|
22
|
+
"nfc",
|
|
23
|
+
"payment"
|
|
24
|
+
],
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"react-native": "*"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"typescript": "^5.0.0",
|
|
31
|
+
"@types/react-native": "^0.73.0"
|
|
32
|
+
}
|
|
33
|
+
}
|