react-amwal-pay 0.1.2 → 0.1.4
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 +101 -101
- package/ReactAmwalPay.podspec +21 -21
- 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.m +14 -0
- package/ios/ReactAmwalPay.swift +111 -0
- package/lib/module/AmwalPaySDK.js +8 -8
- package/lib/module/AmwalPaySDK.js.map +1 -1
- package/lib/module/NativeReactAmwalPay.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/network/NetworkClient.js.map +1 -1
- package/lib/module/utils/SecureHashUtil.js.map +1 -1
- package/package.json +173 -166
- package/src/AmwalPaySDK.ts +97 -97
- package/src/network/NetworkClient.ts +83 -83
- package/src/utils/SecureHashUtil.ts +44 -44
- package/lib/AmwalPay.d.ts +0 -47
- package/lib/AmwalPay.js +0 -63
- package/lib/AmwalPay.js.map +0 -1
- package/lib/index.d.ts +0 -4
- package/lib/index.js +0 -4
- package/lib/index.js.map +0 -1
- package/lib/screens/PaymentScreen.d.ts +0 -2
- package/lib/screens/PaymentScreen.js +0 -133
- package/lib/screens/PaymentScreen.js.map +0 -1
- package/lib/services/NetworkClient.d.ts +0 -10
- package/lib/services/NetworkClient.js +0 -65
- package/lib/services/NetworkClient.js.map +0 -1
- package/lib/utils/SecureHashUtil.d.ts +0 -9
- package/lib/utils/SecureHashUtil.js +0 -37
- package/lib/utils/SecureHashUtil.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
# react-amwal-pay
|
|
2
|
-
|
|
3
|
-
A React Native library for integrating Amwal Pay payment gateway into your React Native applications.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```sh
|
|
8
|
-
npm install react-amwal-pay
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage
|
|
12
|
-
|
|
13
|
-
```js
|
|
14
|
-
import {
|
|
15
|
-
AmwalPaySDK,
|
|
16
|
-
Environment,
|
|
17
|
-
Currency,
|
|
18
|
-
TransactionType,
|
|
19
|
-
type AmwalPayConfig,
|
|
20
|
-
type AmwalPayResponse
|
|
21
|
-
} from 'react-amwal-pay';
|
|
22
|
-
|
|
23
|
-
// Configure Amwal Pay
|
|
24
|
-
const config: AmwalPayConfig = {
|
|
25
|
-
environment: Environment.SIT, // or Environment.PRODUCTION
|
|
26
|
-
currency: Currency.OMR, // or other supported currencies
|
|
27
|
-
transactionType: TransactionType.CARD_WALLET,
|
|
28
|
-
locale: 'en', // or 'ar'
|
|
29
|
-
merchantId: '84131',
|
|
30
|
-
terminalId: '811018',
|
|
31
|
-
amount: '1',
|
|
32
|
-
secureHash: '8570CEED656C8818E4A7CE04F22206358F272DAD5F0227D322B654675ABF8F83',
|
|
33
|
-
customerId: 'customer-id', // optional
|
|
34
|
-
sessionToken: 'your-session-token', // optional
|
|
35
|
-
onCustomerId(customerId) {
|
|
36
|
-
console.log('Customer ID:', customerId);
|
|
37
|
-
},
|
|
38
|
-
onResponse(response) {
|
|
39
|
-
console.log('Payment Response:', response);
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// Initialize and start payment
|
|
44
|
-
const handlePayment = async () => {
|
|
45
|
-
try {
|
|
46
|
-
// Validate required fields
|
|
47
|
-
if (!isConfigValid(config)) {
|
|
48
|
-
console.error('Please fill in all required fields');
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const amwalPay = AmwalPaySDK.getInstance();
|
|
53
|
-
await amwalPay.startPayment(config);
|
|
54
|
-
} catch (error) {
|
|
55
|
-
console.error('Error starting payment:', error);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// Helper function to validate config
|
|
60
|
-
const isConfigValid = (config: Partial<AmwalPayConfig>): boolean => {
|
|
61
|
-
return Boolean(
|
|
62
|
-
config.environment &&
|
|
63
|
-
config.secureHash &&
|
|
64
|
-
config.currency &&
|
|
65
|
-
config.amount &&
|
|
66
|
-
config.merchantId &&
|
|
67
|
-
config.terminalId &&
|
|
68
|
-
config.locale &&
|
|
69
|
-
config.transactionType
|
|
70
|
-
);
|
|
71
|
-
};
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
## Configuration
|
|
75
|
-
|
|
76
|
-
The `AmwalPayConfig` interface includes the following properties:
|
|
77
|
-
|
|
78
|
-
- `environment`: The environment to use (SIT or PRODUCTION)
|
|
79
|
-
- `currency`: The currency for the transaction (e.g., OMR)
|
|
80
|
-
- `transactionType`: The type of transaction (e.g., CARD_WALLET)
|
|
81
|
-
- `locale`: The language locale ('en' or 'ar')
|
|
82
|
-
- `merchantId`: Your merchant ID
|
|
83
|
-
- `terminalId`: Your terminal ID
|
|
84
|
-
- `amount`: The transaction amount
|
|
85
|
-
- `secureHash`: Your secure hash for authentication
|
|
86
|
-
- `customerId`: (Optional) The customer's ID
|
|
87
|
-
- `sessionToken`: (Optional) Your session token
|
|
88
|
-
- `onCustomerId`: (Optional) Callback function for customer ID updates
|
|
89
|
-
- `onResponse`: (Optional) Callback function for payment response
|
|
90
|
-
|
|
91
|
-
## Contributing
|
|
92
|
-
|
|
93
|
-
See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
|
|
94
|
-
|
|
95
|
-
## License
|
|
96
|
-
|
|
97
|
-
MIT
|
|
98
|
-
|
|
99
|
-
---
|
|
100
|
-
|
|
101
|
-
Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
|
|
1
|
+
# react-amwal-pay
|
|
2
|
+
|
|
3
|
+
A React Native library for integrating Amwal Pay payment gateway into your React Native applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install react-amwal-pay
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
import {
|
|
15
|
+
AmwalPaySDK,
|
|
16
|
+
Environment,
|
|
17
|
+
Currency,
|
|
18
|
+
TransactionType,
|
|
19
|
+
type AmwalPayConfig,
|
|
20
|
+
type AmwalPayResponse
|
|
21
|
+
} from 'react-amwal-pay';
|
|
22
|
+
|
|
23
|
+
// Configure Amwal Pay
|
|
24
|
+
const config: AmwalPayConfig = {
|
|
25
|
+
environment: Environment.SIT, // or Environment.PRODUCTION
|
|
26
|
+
currency: Currency.OMR, // or other supported currencies
|
|
27
|
+
transactionType: TransactionType.CARD_WALLET,
|
|
28
|
+
locale: 'en', // or 'ar'
|
|
29
|
+
merchantId: '84131',
|
|
30
|
+
terminalId: '811018',
|
|
31
|
+
amount: '1',
|
|
32
|
+
secureHash: '8570CEED656C8818E4A7CE04F22206358F272DAD5F0227D322B654675ABF8F83',
|
|
33
|
+
customerId: 'customer-id', // optional
|
|
34
|
+
sessionToken: 'your-session-token', // optional
|
|
35
|
+
onCustomerId(customerId) {
|
|
36
|
+
console.log('Customer ID:', customerId);
|
|
37
|
+
},
|
|
38
|
+
onResponse(response) {
|
|
39
|
+
console.log('Payment Response:', response);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Initialize and start payment
|
|
44
|
+
const handlePayment = async () => {
|
|
45
|
+
try {
|
|
46
|
+
// Validate required fields
|
|
47
|
+
if (!isConfigValid(config)) {
|
|
48
|
+
console.error('Please fill in all required fields');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const amwalPay = AmwalPaySDK.getInstance();
|
|
53
|
+
await amwalPay.startPayment(config);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error('Error starting payment:', error);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Helper function to validate config
|
|
60
|
+
const isConfigValid = (config: Partial<AmwalPayConfig>): boolean => {
|
|
61
|
+
return Boolean(
|
|
62
|
+
config.environment &&
|
|
63
|
+
config.secureHash &&
|
|
64
|
+
config.currency &&
|
|
65
|
+
config.amount &&
|
|
66
|
+
config.merchantId &&
|
|
67
|
+
config.terminalId &&
|
|
68
|
+
config.locale &&
|
|
69
|
+
config.transactionType
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Configuration
|
|
75
|
+
|
|
76
|
+
The `AmwalPayConfig` interface includes the following properties:
|
|
77
|
+
|
|
78
|
+
- `environment`: The environment to use (SIT or PRODUCTION)
|
|
79
|
+
- `currency`: The currency for the transaction (e.g., OMR)
|
|
80
|
+
- `transactionType`: The type of transaction (e.g., CARD_WALLET)
|
|
81
|
+
- `locale`: The language locale ('en' or 'ar')
|
|
82
|
+
- `merchantId`: Your merchant ID
|
|
83
|
+
- `terminalId`: Your terminal ID
|
|
84
|
+
- `amount`: The transaction amount
|
|
85
|
+
- `secureHash`: Your secure hash for authentication
|
|
86
|
+
- `customerId`: (Optional) The customer's ID
|
|
87
|
+
- `sessionToken`: (Optional) Your session token
|
|
88
|
+
- `onCustomerId`: (Optional) Callback function for customer ID updates
|
|
89
|
+
- `onResponse`: (Optional) Callback function for payment response
|
|
90
|
+
|
|
91
|
+
## Contributing
|
|
92
|
+
|
|
93
|
+
See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
|
|
94
|
+
|
|
95
|
+
## License
|
|
96
|
+
|
|
97
|
+
MIT
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
|
package/ReactAmwalPay.podspec
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
require "json"
|
|
2
|
-
|
|
3
|
-
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
-
|
|
5
|
-
Pod::Spec.new do |s|
|
|
6
|
-
s.name = "ReactAmwalPay"
|
|
7
|
-
s.version = package["version"]
|
|
8
|
-
s.summary = package["description"]
|
|
9
|
-
s.homepage = package["homepage"]
|
|
10
|
-
s.license = package["license"]
|
|
11
|
-
s.authors = package["author"]
|
|
12
|
-
|
|
13
|
-
s.platforms = { :ios => min_ios_version_supported }
|
|
14
|
-
s.source = { :git => "https://github.com/amwal-pay/AnwalPaySDKReactNative.git", :tag => "#{s.version}" }
|
|
15
|
-
|
|
16
|
-
s.source_files = "ios/**/*.{h,m,mm,
|
|
17
|
-
s.private_header_files = "ios/**/*.h"
|
|
18
|
-
|
|
19
|
-
s.dependency "amwalsdk"
|
|
20
|
-
|
|
21
|
-
end
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = "ReactAmwalPay"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"]
|
|
10
|
+
s.license = package["license"]
|
|
11
|
+
s.authors = package["author"]
|
|
12
|
+
|
|
13
|
+
s.platforms = { :ios => min_ios_version_supported }
|
|
14
|
+
s.source = { :git => "https://github.com/amwal-pay/AnwalPaySDKReactNative.git", :tag => "#{s.version}" }
|
|
15
|
+
|
|
16
|
+
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
|
17
|
+
s.private_header_files = "ios/**/*.h"
|
|
18
|
+
|
|
19
|
+
s.dependency "amwalsdk"
|
|
20
|
+
install_modules_dependencies(s)
|
|
21
|
+
end
|
|
@@ -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 <React/RCTBridgeModule.h>
|
|
2
|
+
#import <React/RCTEventEmitter.h>
|
|
3
|
+
|
|
4
|
+
@interface RCT_EXTERN_MODULE(ReactAmwalPay, RCTEventEmitter)
|
|
5
|
+
|
|
6
|
+
RCT_EXTERN_METHOD(initiate:(NSDictionary *)config
|
|
7
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
8
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
9
|
+
|
|
10
|
+
RCT_EXTERN_METHOD(onResponse:(RCTResponseSenderBlock)callback)
|
|
11
|
+
|
|
12
|
+
RCT_EXTERN_METHOD(onCustomerId:(RCTResponseSenderBlock)callback)
|
|
13
|
+
|
|
14
|
+
@end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import amwalsdk
|
|
3
|
+
import React
|
|
4
|
+
|
|
5
|
+
@objc(ReactAmwalPay)
|
|
6
|
+
class ReactAmwalPay: RCTEventEmitter {
|
|
7
|
+
private var hasListeners = false
|
|
8
|
+
|
|
9
|
+
private func mapEnvironment(environment: String) -> Config.Environment {
|
|
10
|
+
switch environment {
|
|
11
|
+
case "PROD": return .PROD
|
|
12
|
+
case "UAT": return .UAT
|
|
13
|
+
case "SIT": return .SIT
|
|
14
|
+
default: return .PROD
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
private func mapCurrency(currency: String) -> Config.Currency {
|
|
19
|
+
switch currency {
|
|
20
|
+
case "OMR": return .OMR
|
|
21
|
+
default: return .OMR
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private func mapTransactionType(transactionType: String) -> Config.TransactionType {
|
|
26
|
+
switch transactionType {
|
|
27
|
+
case "CARD_WALLET": return .cardWallet
|
|
28
|
+
case "NFC": return .nfc
|
|
29
|
+
case "APPLE_PAY": return .applePay
|
|
30
|
+
default: return .cardWallet
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private func mapLocale(locale: String) -> Config.Locale {
|
|
35
|
+
switch locale {
|
|
36
|
+
case "en": return .en
|
|
37
|
+
case "ar": return .ar
|
|
38
|
+
default: return .en
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private var onResponseCallback: RCTResponseSenderBlock?
|
|
43
|
+
private var onCustomerIdCallback: RCTResponseSenderBlock?
|
|
44
|
+
private func prepareConfig(config: [String: Any]) -> Config {
|
|
45
|
+
return Config(
|
|
46
|
+
environment: mapEnvironment(environment: config["environment"] as? String ?? "PROD"),
|
|
47
|
+
sessionToken: config["sessionToken"] as? String ?? "",
|
|
48
|
+
currency: mapCurrency(currency: config["currency"] as? String ?? "OMR"),
|
|
49
|
+
amount: config["amount"] as? String ?? "",
|
|
50
|
+
merchantId: config["merchantId"] as? String ?? "",
|
|
51
|
+
terminalId: config["terminalId"] as? String ?? "",
|
|
52
|
+
customerId: config["customerId"] as? String,
|
|
53
|
+
locale: mapLocale(locale: config["locale"] as? String ?? "en"),
|
|
54
|
+
transactionType: mapTransactionType(transactionType: config["transactionType"] as? String ?? "CARD_WALLET")
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@objc
|
|
59
|
+
func initiate(_ config: [String: Any],
|
|
60
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
61
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
62
|
+
DispatchQueue.main.async {
|
|
63
|
+
do {
|
|
64
|
+
let sdkConfig = self.prepareConfig(config: config)
|
|
65
|
+
let sdk = AmwalSDK()
|
|
66
|
+
|
|
67
|
+
guard let rootVC = UIApplication.shared.keyWindow?.rootViewController else {
|
|
68
|
+
reject("NO_ROOT_VC", "No root view controller found", nil)
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let sdkVC = try sdk.createViewController(
|
|
73
|
+
config: sdkConfig,
|
|
74
|
+
onResponse: { [weak self] response in
|
|
75
|
+
self?.onResponseCallback?([[
|
|
76
|
+
"status": response != nil ? "success" : "error",
|
|
77
|
+
"message": response != nil ? "Transaction completed" : "Transaction failed",
|
|
78
|
+
"data": response ?? ""
|
|
79
|
+
]])
|
|
80
|
+
},
|
|
81
|
+
onCustomerId: { [weak self] customerId in
|
|
82
|
+
self?.onCustomerIdCallback?([customerId])
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
// Present modally (critical missing piece)
|
|
87
|
+
rootVC.present(sdkVC, animated: true)
|
|
88
|
+
|
|
89
|
+
resolve(true)
|
|
90
|
+
} catch {
|
|
91
|
+
print("Presentation failed: \(error.localizedDescription)")
|
|
92
|
+
reject("PRESENTATION_ERROR", error.localizedDescription, error)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@objc
|
|
98
|
+
func onResponse(_ callback: @escaping RCTResponseSenderBlock) {
|
|
99
|
+
onResponseCallback = callback
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@objc
|
|
103
|
+
func onCustomerId(_ callback: @escaping RCTResponseSenderBlock) {
|
|
104
|
+
onCustomerIdCallback = callback
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
override static func requiresMainQueueSetup() -> Bool {
|
|
109
|
+
return true
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -15,9 +15,9 @@ class AmwalPaySDK {
|
|
|
15
15
|
return AmwalPaySDK.instance;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
/**
|
|
19
|
-
* Initiates the payment process by first fetching a session token and then starting the payment flow
|
|
20
|
-
* @param config The payment configuration
|
|
18
|
+
/**
|
|
19
|
+
* Initiates the payment process by first fetching a session token and then starting the payment flow
|
|
20
|
+
* @param config The payment configuration
|
|
21
21
|
*/
|
|
22
22
|
async startPayment(config) {
|
|
23
23
|
try {
|
|
@@ -51,9 +51,9 @@ class AmwalPaySDK {
|
|
|
51
51
|
this.removeEventListeners();
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
/**
|
|
55
|
-
* Sets up event listeners for AmwalPay events
|
|
56
|
-
* @param config The payment configuration containing callback functions
|
|
54
|
+
/**
|
|
55
|
+
* Sets up event listeners for AmwalPay events
|
|
56
|
+
* @param config The payment configuration containing callback functions
|
|
57
57
|
*/
|
|
58
58
|
setupEventListeners(config) {
|
|
59
59
|
// Remove any existing listeners
|
|
@@ -68,8 +68,8 @@ class AmwalPaySDK {
|
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
/**
|
|
72
|
-
* Removes all event listeners
|
|
71
|
+
/**
|
|
72
|
+
* Removes all event listeners
|
|
73
73
|
*/
|
|
74
74
|
removeEventListeners() {
|
|
75
75
|
this.onResponseSubscription?.remove();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["initiate","onCustomerId","onResponse","NetworkClient","AmwalPaySDK","onResponseSubscription","onCustomerIdSubscription","constructor","getInstance","instance","startPayment","config","setupEventListeners","networkClient","sessionToken","fetchSessionToken","environment","merchantId","customerId","secureHash","completeConfig","error","console","dispose","removeEventListeners","response","log","remove"],"sourceRoot":"
|
|
1
|
+
{"version":3,"names":["initiate","onCustomerId","onResponse","NetworkClient","AmwalPaySDK","onResponseSubscription","onCustomerIdSubscription","constructor","getInstance","instance","startPayment","config","setupEventListeners","networkClient","sessionToken","fetchSessionToken","environment","merchantId","customerId","secureHash","completeConfig","error","console","dispose","removeEventListeners","response","log","remove"],"sourceRoot":"..\\..\\src","sources":["AmwalPaySDK.ts"],"mappings":";;AAAA,SAASA,QAAQ,EAAEC,YAAY,EAAEC,UAAU,QAA6B,YAAS;AACjF,OAAOC,aAAa,MAAM,4BAAyB;AAInD,MAAMC,WAAW,CAAC;EAGRC,sBAAsB,GAA2B,IAAI;EAErDC,wBAAwB,GAA2B,IAAI;EAEvDC,WAAWA,CAAA,EAAG;IACpB;EAAA;EAIF,OAAOC,WAAWA,CAAA,EAAgB;IAChC,IAAI,CAACJ,WAAW,CAACK,QAAQ,EAAE;MACzBL,WAAW,CAACK,QAAQ,GAAG,IAAIL,WAAW,CAAC,CAAC;IAC1C;IACA,OAAOA,WAAW,CAACK,QAAQ;EAC7B;;EAEA;AACF;AACA;AACA;EACE,MAAMC,YAAYA,CAACC,MAA4C,EAAiB;IAC9E,IAAI;MACF;MACA,IAAI,CAACC,mBAAmB,CAACD,MAAM,CAAC;;MAEhC;MACA,MAAME,aAAa,GAAGV,aAAa,CAACK,WAAW,CAAC,CAAC;;MAEjD;MACA,MAAMM,YAAY,GAAG,MAAMD,aAAa,CAACE,iBAAiB,CACxDJ,MAAM,CAACK,WAAW,EAClBL,MAAM,CAACM,UAAU,EACjBN,MAAM,CAACO,UAAU,EACjBP,MAAM,CAACQ,UACT,CAAC;MAED,IAAI,CAACL,YAAY,EAAE;QACjB;QACA;MACF;;MAEA;MACA,MAAMM,cAA8B,GAAG;QACrC,GAAGT,MAAM;QACTG;MACF,CAAC;;MAED;MACAd,QAAQ,CAACoB,cAAc,CAAC;IAC1B,CAAC,CAAC,OAAOC,KAAK,EAAE;MACdC,OAAO,CAACD,KAAK,CAAC,yBAAyB,EAAEA,KAAK,CAAC;IACjD;EACF;EAEAE,OAAOA,CAAA,EAAS;IACd;IACA,IAAI,CAACC,oBAAoB,CAAC,CAAC;EAC7B;;EAEA;AACF;AACA;AACA;EACUZ,mBAAmBA,CAACD,MAA4C,EAAQ;IAC9E;IACA,IAAI,CAACa,oBAAoB,CAAC,CAAC;IAE3B,IAAI,CAACnB,sBAAsB,GAAGH,UAAU,CAAEuB,QAAQ,IAAK;MACrDH,OAAO,CAACI,GAAG,CAAC,4BAA4B,EAAED,QAAQ,CAAC;MACnDd,MAAM,CAACT,UAAU,CAACuB,QAAQ,CAAC;IAC7B,CAAC,CAAC;IAEF,IAAI,CAACnB,wBAAwB,GAAGL,YAAY,CAAEiB,UAAU,IAAK;MAC3DI,OAAO,CAACI,GAAG,CAAC,sBAAsB,EAAER,UAAU,CAAC;MAC/CP,MAAM,CAACV,YAAY,CAACiB,UAAU,CAAC;IACjC,CAAC,CAAC;EACJ;;EAEA;AACF;AACA;EACUM,oBAAoBA,CAAA,EAAS;IACnC,IAAI,CAACnB,sBAAsB,EAAEsB,MAAM,CAAC,CAAC;IACrC,IAAI,CAACrB,wBAAwB,EAAEqB,MAAM,CAAC,CAAC;IACvC,IAAI,CAACtB,sBAAsB,GAAG,IAAI;IAClC,IAAI,CAACC,wBAAwB,GAAG,IAAI;EACtC;AACF;AAEA,eAAeF,WAAW","ignoreList":[]}
|