react-amwal-pay 0.1.2 → 0.1.3
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/android/build.gradle +93 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/reactamwalpay/ReactAmwalPayModule.kt +115 -0
- package/android/src/main/java/com/reactamwalpay/ReactAmwalPayPackage.kt +33 -0
- package/ios/ReactAmwalPay.h +14 -0
- package/ios/ReactAmwalPay.mm +141 -0
- package/package.json +3 -1
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
ext.getExtOrDefault = {name ->
|
|
3
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['ReactAmwalPay_' + name]
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
repositories {
|
|
7
|
+
google()
|
|
8
|
+
mavenCentral()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
dependencies {
|
|
12
|
+
classpath "com.android.tools.build:gradle:8.7.3"
|
|
13
|
+
// noinspection DifferentKotlinGradleVersion
|
|
14
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
apply plugin: "com.android.library"
|
|
20
|
+
apply plugin: "kotlin-android"
|
|
21
|
+
|
|
22
|
+
apply plugin: "com.facebook.react"
|
|
23
|
+
|
|
24
|
+
def getExtOrIntegerDefault(name) {
|
|
25
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["ReactAmwalPay_" + name]).toInteger()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
android {
|
|
29
|
+
namespace "com.reactamwalpay"
|
|
30
|
+
|
|
31
|
+
compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
|
|
32
|
+
|
|
33
|
+
defaultConfig {
|
|
34
|
+
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
|
|
35
|
+
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
buildFeatures {
|
|
39
|
+
buildConfig true
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
buildTypes {
|
|
43
|
+
release {
|
|
44
|
+
minifyEnabled false
|
|
45
|
+
shrinkResources false
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
lintOptions {
|
|
50
|
+
disable "GradleCompatible"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
compileOptions {
|
|
54
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
55
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
sourceSets {
|
|
59
|
+
main {
|
|
60
|
+
java.srcDirs += [
|
|
61
|
+
"generated/java",
|
|
62
|
+
"generated/jni"
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
repositories {
|
|
69
|
+
mavenCentral()
|
|
70
|
+
google()
|
|
71
|
+
}
|
|
72
|
+
rootProject.allprojects { Project subproject ->
|
|
73
|
+
subproject.repositories {
|
|
74
|
+
maven { url = uri("https://storage.googleapis.com/download.flutter.io") }
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
def kotlin_version = getExtOrDefault("kotlinVersion")
|
|
78
|
+
|
|
79
|
+
dependencies {
|
|
80
|
+
implementation "com.facebook.react:react-android"
|
|
81
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
82
|
+
implementation("com.amwal-pay:amwal_sdk:+"){
|
|
83
|
+
exclude group: 'com.android.support', module: 'support-v4'
|
|
84
|
+
exclude group: 'com.android.support', module: 'design'
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
react {
|
|
90
|
+
jsRootDir = file("../src/")
|
|
91
|
+
libraryName = "ReactAmwalPay"
|
|
92
|
+
codegenJavaPackageName = "com.reactamwalpay"
|
|
93
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
package com.reactamwalpay
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import com.facebook.react.bridge.*
|
|
5
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
6
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
7
|
+
import com.anwalpay.sdk.AmwalSDK
|
|
8
|
+
import org.json.JSONObject
|
|
9
|
+
|
|
10
|
+
@ReactModule(name = ReactAmwalPayModule.NAME)
|
|
11
|
+
class ReactAmwalPayModule(reactContext: ReactApplicationContext) :
|
|
12
|
+
NativeReactAmwalPaySpec(reactContext) {
|
|
13
|
+
|
|
14
|
+
private val amwalSDK = AmwalSDK()
|
|
15
|
+
|
|
16
|
+
override fun getName(): String {
|
|
17
|
+
return NAME
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
private fun sendEvent(eventName: String, params: WritableMap?) {
|
|
23
|
+
reactApplicationContext
|
|
24
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
25
|
+
.emit(eventName, params)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
override fun initiate(config: ReadableMap) {
|
|
29
|
+
Log.d(NAME, "initiate called")
|
|
30
|
+
val activity = reactApplicationContext.currentActivity
|
|
31
|
+
if (activity == null) {
|
|
32
|
+
// Since we can't use Promise here (method signature must match the spec),
|
|
33
|
+
// we'll send an error event
|
|
34
|
+
val params = Arguments.createMap()
|
|
35
|
+
params.putString("type", "onResponse")
|
|
36
|
+
val errorData = Arguments.createMap()
|
|
37
|
+
errorData.putString("status", "ERROR")
|
|
38
|
+
errorData.putString("message", "Activity context is not available")
|
|
39
|
+
params.putMap("data", errorData)
|
|
40
|
+
sendEvent("AmwalPayEvent", params)
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
Log.d(NAME, "initiate got here")
|
|
45
|
+
try {
|
|
46
|
+
val sdkConfig = AmwalSDK.Config(
|
|
47
|
+
environment = AmwalSDK.Config.Environment.valueOf(config.getString("environment") ?: ""),
|
|
48
|
+
sessionToken = config.getString("sessionToken") ?: "",
|
|
49
|
+
currency = AmwalSDK.Config.Currency.valueOf(config.getString("currency") ?: ""),
|
|
50
|
+
amount = config.getString("amount") ?: "",
|
|
51
|
+
merchantId = config.getString("merchantId") ?: "",
|
|
52
|
+
terminalId = config.getString("terminalId") ?: "",
|
|
53
|
+
locale = java.util.Locale(config.getString("locale") ?: "en"),
|
|
54
|
+
customerId = if (config.hasKey("customerId")) config.getString("customerId") else null,
|
|
55
|
+
transactionType = AmwalSDK.Config.TransactionType.valueOf(config.getString("transactionType") ?: "")
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
// Ensure this runs on the UI thread
|
|
59
|
+
(reactApplicationContext.currentActivity ?: return).runOnUiThread {
|
|
60
|
+
amwalSDK.start(
|
|
61
|
+
activity,
|
|
62
|
+
sdkConfig,
|
|
63
|
+
onResponse = {
|
|
64
|
+
Log.d(NAME, "onResponse called")
|
|
65
|
+
val params = Arguments.createMap()
|
|
66
|
+
try {
|
|
67
|
+
val json = JSONObject(it.toString())
|
|
68
|
+
val dataMap = jsonToWritableMap(json)
|
|
69
|
+
params.putMap("data", dataMap)
|
|
70
|
+
} catch (e: Exception) {
|
|
71
|
+
params.putString("data", it.toString())
|
|
72
|
+
}
|
|
73
|
+
emitOnResponse(params)
|
|
74
|
+
},
|
|
75
|
+
onCustomerId = {
|
|
76
|
+
Log.d(NAME, "onCustomerId called")
|
|
77
|
+
emitOnCustomerId(it)
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
} catch (e: Exception) {
|
|
82
|
+
Log.e(NAME, "Error initializing AmwalSDK", e)
|
|
83
|
+
val params = Arguments.createMap()
|
|
84
|
+
params.putString("type", "onResponse")
|
|
85
|
+
val errorData = Arguments.createMap()
|
|
86
|
+
errorData.putString("status", "ERROR")
|
|
87
|
+
errorData.putString("message", e.message ?: "Unknown error")
|
|
88
|
+
params.putMap("data", errorData)
|
|
89
|
+
sendEvent("AmwalPayEvent", params)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Helper function to convert JSONObject to WritableMap
|
|
94
|
+
private fun jsonToWritableMap(jsonObject: JSONObject): WritableMap {
|
|
95
|
+
val map = Arguments.createMap()
|
|
96
|
+
val keys = jsonObject.keys()
|
|
97
|
+
while (keys.hasNext()) {
|
|
98
|
+
val key = keys.next()
|
|
99
|
+
val value = jsonObject.get(key)
|
|
100
|
+
when (value) {
|
|
101
|
+
is JSONObject -> map.putMap(key, jsonToWritableMap(value))
|
|
102
|
+
is Boolean -> map.putBoolean(key, value)
|
|
103
|
+
is Int -> map.putInt(key, value)
|
|
104
|
+
is Double -> map.putDouble(key, value)
|
|
105
|
+
is String -> map.putString(key, value)
|
|
106
|
+
else -> map.putString(key, value.toString())
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return map
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
companion object {
|
|
113
|
+
const val NAME = "ReactAmwalPay"
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
package com.reactamwalpay
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.BaseReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.module.model.ReactModuleInfo
|
|
7
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
8
|
+
import java.util.HashMap
|
|
9
|
+
|
|
10
|
+
class ReactAmwalPayPackage : BaseReactPackage() {
|
|
11
|
+
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
|
|
12
|
+
return if (name == ReactAmwalPayModule.NAME) {
|
|
13
|
+
ReactAmwalPayModule(reactContext)
|
|
14
|
+
} else {
|
|
15
|
+
null
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
|
|
20
|
+
return ReactModuleInfoProvider {
|
|
21
|
+
val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
|
|
22
|
+
moduleInfos[ReactAmwalPayModule.NAME] = ReactModuleInfo(
|
|
23
|
+
ReactAmwalPayModule.NAME,
|
|
24
|
+
ReactAmwalPayModule.NAME,
|
|
25
|
+
false, // canOverrideExistingModule
|
|
26
|
+
false, // needsEagerInit
|
|
27
|
+
false, // isCxxModule
|
|
28
|
+
true // isTurboModule
|
|
29
|
+
)
|
|
30
|
+
moduleInfos
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#import <ReactAmwalPaySpec/ReactAmwalPaySpec.h>
|
|
2
|
+
#import <React/RCTEventEmitter.h>
|
|
3
|
+
#import <amwalsdk/amwalsdk.h>
|
|
4
|
+
|
|
5
|
+
@interface ReactAmwalPay : RCTEventEmitter <NativeReactAmwalPaySpec>
|
|
6
|
+
|
|
7
|
+
- (AmwalEnvironment)getEnvironmentFromString:(NSString *)env;
|
|
8
|
+
- (AmwalLocale)getLocaleFromString:(NSString *)locale;
|
|
9
|
+
- (AmwalTransactionType)getTransactionTypeFromString:(NSString *)type;
|
|
10
|
+
- (void)sendResponseEvent:(NSDictionary *)response;
|
|
11
|
+
- (void)sendCustomerIdEvent:(NSString *)customerId;
|
|
12
|
+
- (void)sendErrorEvent:(NSString *)errorMessage;
|
|
13
|
+
|
|
14
|
+
@end
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#import "ReactAmwalPay.h"
|
|
2
|
+
#import <React/RCTBridgeModule.h>
|
|
3
|
+
#import <React/RCTEventEmitter.h>
|
|
4
|
+
#import <React/RCTUtils.h>
|
|
5
|
+
#import <amwalsdk/amwalsdk.h>
|
|
6
|
+
|
|
7
|
+
@implementation ReactAmwalPay
|
|
8
|
+
RCT_EXPORT_MODULE()
|
|
9
|
+
|
|
10
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
11
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
12
|
+
{
|
|
13
|
+
return std::make_shared<facebook::react::NativeReactAmwalPaySpecJSI>(params);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
- (AmwalEnvironment)getEnvironmentFromString:(NSString *)env {
|
|
17
|
+
if ([env isEqualToString:@"PROD"]) {
|
|
18
|
+
return AmwalEnvironmentPROD;
|
|
19
|
+
} else if ([env isEqualToString:@"UAT"]) {
|
|
20
|
+
return AmwalEnvironmentUAT;
|
|
21
|
+
}
|
|
22
|
+
return AmwalEnvironmentSIT;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
- (AmwalLocale)getLocaleFromString:(NSString *)locale {
|
|
26
|
+
if ([locale isEqualToString:@"ar"]) {
|
|
27
|
+
return AmwalLocaleAr;
|
|
28
|
+
}
|
|
29
|
+
return AmwalLocaleEn;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
- (AmwalTransactionType)getTransactionTypeFromString:(NSString *)type {
|
|
33
|
+
if ([type isEqualToString:@"NFC"]) {
|
|
34
|
+
return AmwalTransactionTypeNFC;
|
|
35
|
+
} else if ([type isEqualToString:@"APPLE_PAY"]) {
|
|
36
|
+
return AmwalTransactionTypeApplePay;
|
|
37
|
+
}
|
|
38
|
+
return AmwalTransactionTypeCardWallet;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
- (void)initiate:(JS::NativeReactAmwalPay::AmwalPayNativeConfig &)config {
|
|
42
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
43
|
+
UIViewController *rootViewController = RCTPresentedViewController();
|
|
44
|
+
if (!rootViewController) {
|
|
45
|
+
[self sendErrorEvent:@"Activity context is not available"];
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@try {
|
|
50
|
+
// Get values using method calls
|
|
51
|
+
NSString *sessionToken = config.sessionToken();
|
|
52
|
+
NSString *amount = config.amount();
|
|
53
|
+
NSString *merchantId = config.merchantId();
|
|
54
|
+
NSString *terminalId = config.terminalId();
|
|
55
|
+
NSString *customerId = config.customerId();
|
|
56
|
+
NSString *environment = config.environment();
|
|
57
|
+
NSString *locale = config.locale();
|
|
58
|
+
NSString *transactionType = config.transactionType();
|
|
59
|
+
|
|
60
|
+
// Create config object with all required parameters
|
|
61
|
+
Config *sdkConfig = [[Config alloc] initWithEnvironment:[self getEnvironmentFromString:environment]
|
|
62
|
+
sessionToken:sessionToken
|
|
63
|
+
currency:AmwalCurrencyOMR
|
|
64
|
+
amount:amount
|
|
65
|
+
merchantId:merchantId
|
|
66
|
+
terminalId:terminalId
|
|
67
|
+
customerId:customerId
|
|
68
|
+
locale:[self getLocaleFromString:locale]
|
|
69
|
+
transactionType:[self getTransactionTypeFromString:transactionType]];
|
|
70
|
+
|
|
71
|
+
// Initialize AmwalSDK
|
|
72
|
+
AmwalSDK *amwalSDK = [[AmwalSDK alloc] init];
|
|
73
|
+
|
|
74
|
+
// Create and present the payment view controller
|
|
75
|
+
NSError *error = nil;
|
|
76
|
+
UIViewController *paymentVC = [amwalSDK createViewControllerWithConfig:sdkConfig
|
|
77
|
+
onResponse:^(NSString * _Nullable response) {
|
|
78
|
+
if (response) {
|
|
79
|
+
[self sendResponseEvent:@{@"response": response}];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
onCustomerId:^(NSString *customerId) {
|
|
83
|
+
[self sendCustomerIdEvent:customerId];
|
|
84
|
+
}
|
|
85
|
+
error:&error];
|
|
86
|
+
|
|
87
|
+
if (error) {
|
|
88
|
+
[self sendErrorEvent:error.localizedDescription];
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (paymentVC) {
|
|
93
|
+
[rootViewController presentViewController:paymentVC animated:YES completion:nil];
|
|
94
|
+
} else {
|
|
95
|
+
[self sendErrorEvent:@"Failed to create payment view controller"];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
} @catch (NSException *exception) {
|
|
99
|
+
[self sendErrorEvent:exception.reason];
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
#pragma mark - Helper Methods
|
|
105
|
+
|
|
106
|
+
- (void)sendResponseEvent:(NSDictionary *)response {
|
|
107
|
+
NSMutableDictionary *params = [NSMutableDictionary dictionary];
|
|
108
|
+
params[@"type"] = @"onResponse";
|
|
109
|
+
params[@"data"] = response;
|
|
110
|
+
|
|
111
|
+
[self sendEventWithName:@"AmwalPayEvent" body:params];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
- (void)sendCustomerIdEvent:(NSString *)customerId {
|
|
115
|
+
NSMutableDictionary *params = [NSMutableDictionary dictionary];
|
|
116
|
+
params[@"type"] = @"onCustomerId";
|
|
117
|
+
params[@"data"] = customerId;
|
|
118
|
+
|
|
119
|
+
[self sendEventWithName:@"AmwalPayEvent" body:params];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
- (void)sendErrorEvent:(NSString *)errorMessage {
|
|
123
|
+
NSMutableDictionary *params = [NSMutableDictionary dictionary];
|
|
124
|
+
params[@"type"] = @"onResponse";
|
|
125
|
+
|
|
126
|
+
NSMutableDictionary *errorData = [NSMutableDictionary dictionary];
|
|
127
|
+
errorData[@"status"] = @"ERROR";
|
|
128
|
+
errorData[@"message"] = errorMessage;
|
|
129
|
+
|
|
130
|
+
params[@"data"] = errorData;
|
|
131
|
+
|
|
132
|
+
[self sendEventWithName:@"AmwalPayEvent" body:params];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Add this to ensure the module is properly initialized
|
|
136
|
+
+ (BOOL)requiresMainQueueSetup
|
|
137
|
+
{
|
|
138
|
+
return YES;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@end
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-amwal-pay",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "amwal pay",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"src",
|
|
17
|
+
"android",
|
|
18
|
+
"ios",
|
|
17
19
|
"lib",
|
|
18
20
|
"cpp",
|
|
19
21
|
"*.podspec",
|