react-amwal-pay 0.1.15 → 0.1.17
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 +2 -1
- package/android/gradle.properties +1 -1
- package/ios/ReactAmwalPay.swift +13 -10
- package/lib/module/AmwalPaySDK.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 +4 -4
- package/lib/module/utils/SecureHashUtil.js.map +1 -1
- package/lib/module/utils/UuidUtil.js +2 -1
- package/lib/module/utils/UuidUtil.js.map +1 -1
- package/lib/typescript/src/AmwalPaySDK.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/network/NetworkClient.d.ts.map +1 -1
- package/lib/typescript/src/utils/SecureHashUtil.d.ts.map +1 -1
- package/lib/typescript/src/utils/UuidUtil.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/AmwalPaySDK.ts +30 -11
- package/src/index.tsx +7 -6
- package/src/network/NetworkClient.ts +87 -84
- package/src/utils/SecureHashUtil.ts +52 -45
- package/src/utils/UuidUtil.ts +9 -6
package/README.md
CHANGED
|
@@ -54,7 +54,7 @@ Add the following configuration to your `ios/Podfile` inside the `post_install`
|
|
|
54
54
|
```ruby
|
|
55
55
|
post_install do |installer|
|
|
56
56
|
react_native_post_install(installer, config[:reactNativePath])
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
# Set "Build Libraries for Distribution" to NO for amwalsdk
|
|
59
59
|
installer.pods_project.targets.each do |target|
|
|
60
60
|
if target.name == 'amwalsdk'
|
|
@@ -112,6 +112,7 @@ No additional Android configuration is required. The SDK uses React Native's aut
|
|
|
112
112
|
minSdkVersion = 24
|
|
113
113
|
```
|
|
114
114
|
|
|
115
|
+
|
|
115
116
|
### Step 5: Clean and Rebuild
|
|
116
117
|
|
|
117
118
|
After installation, clean and rebuild your project:
|
package/ios/ReactAmwalPay.swift
CHANGED
|
@@ -258,7 +258,8 @@ open class ReactAmwalPay: RCTEventEmitter {
|
|
|
258
258
|
transactionType: mapTransactionType(transactionType: config["transactionType"] as? String ?? "CARD_WALLET"),
|
|
259
259
|
transactionId: config["transactionId"] as? String ?? Config.generateTransactionId(),
|
|
260
260
|
additionValues: additionValues,
|
|
261
|
-
merchantReference: config["merchantReference"] as? String
|
|
261
|
+
merchantReference: config["merchantReference"] as? String,
|
|
262
|
+
secureHash: config["secureHash"] as? String
|
|
262
263
|
)
|
|
263
264
|
}
|
|
264
265
|
|
|
@@ -284,29 +285,31 @@ open class ReactAmwalPay: RCTEventEmitter {
|
|
|
284
285
|
config: sdkConfig,
|
|
285
286
|
onResponse: { [weak self] response in
|
|
286
287
|
print("🟠 SDK onResponse callback fired!")
|
|
287
|
-
print("🟠 Response type: \(type(of: response))")
|
|
288
288
|
print("🟠 Response value: \(response ?? "nil")")
|
|
289
289
|
|
|
290
|
-
//
|
|
290
|
+
// Always dismiss SDK window when this callback fires
|
|
291
291
|
DispatchQueue.main.async {
|
|
292
292
|
self?.dismissSDKWindow()
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
+
// nil response means SDK was dismissed without completing a payment
|
|
296
|
+
// (e.g., error during initialization). Don't emit to React Native.
|
|
297
|
+
guard let response = response else {
|
|
298
|
+
print("🟠 nil response - SDK dismissed without payment, not emitting to JS")
|
|
299
|
+
return
|
|
300
|
+
}
|
|
301
|
+
|
|
295
302
|
// The SDK returns a JSON string, we need to parse it
|
|
296
|
-
if let
|
|
297
|
-
let data = responseString.data(using: .utf8),
|
|
303
|
+
if let data = response.data(using: .utf8),
|
|
298
304
|
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {
|
|
299
305
|
print("🟠 Successfully parsed JSON string to dictionary")
|
|
300
306
|
self?.emitOnResponse(json)
|
|
301
|
-
} else if let responseDict = response as? [String: Any] {
|
|
302
|
-
print("🟠 Response is already a dictionary")
|
|
303
|
-
self?.emitOnResponse(responseDict)
|
|
304
307
|
} else {
|
|
305
|
-
print("🟠 Could not parse response, sending
|
|
308
|
+
print("🟠 Could not parse response as JSON, sending error")
|
|
306
309
|
let errorData: [String: Any] = [
|
|
307
310
|
"status": "error",
|
|
308
311
|
"message": "Invalid response format",
|
|
309
|
-
"rawResponse":
|
|
312
|
+
"rawResponse": response
|
|
310
313
|
]
|
|
311
314
|
self?.emitOnResponse(errorData)
|
|
312
315
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["initiate","onCustomerId","onResponse","NetworkClient","AmwalPaySDK","onResponseSubscription","onCustomerIdSubscription","constructor","getInstance","instance","startPayment","config","setupEventListeners","networkClient","console","log","environment","sessionToken","fetchSessionToken","merchantId","customerId","secureHash","completeConfig","JSON","stringify","error","dispose","removeEventListeners","response","remove"],"sourceRoot":"../../src","sources":["AmwalPaySDK.ts"],"mappings":";;AAAA,
|
|
1
|
+
{"version":3,"names":["initiate","onCustomerId","onResponse","NetworkClient","AmwalPaySDK","onResponseSubscription","onCustomerIdSubscription","constructor","getInstance","instance","startPayment","config","setupEventListeners","networkClient","console","log","environment","sessionToken","fetchSessionToken","merchantId","customerId","secureHash","completeConfig","JSON","stringify","error","dispose","removeEventListeners","response","remove"],"sourceRoot":"../../src","sources":["AmwalPaySDK.ts"],"mappings":"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","ignoreList":[]}
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ReactAmwalPay","Environment","Currency","TransactionType","AmwalPaySDK","UuidUtil","NativeEventEmitter","eventEmitter","initiate","config","defaultAdditionValues","merchantIdentifier","finalAdditionValues","additionValues","nativeConfig","environment","secureHash","currency","amount","merchantId","terminalId","locale","customerId","transactionType","sessionToken","transactionId","generateTransactionId","merchantReference","onResponse","callback","addListener","onCustomerId"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,aAAa,IAClBC,WAAW,EACXC,QAAQ,EACRC,eAAe,QAIV,0BAAuB;AAC9B,OAAOC,WAAW,MAAM,kBAAe;AACvC,SAASC,QAAQ,QAAQ,qBAAkB;AAC3C,
|
|
1
|
+
{"version":3,"names":["ReactAmwalPay","Environment","Currency","TransactionType","AmwalPaySDK","UuidUtil","NativeEventEmitter","eventEmitter","initiate","config","defaultAdditionValues","merchantIdentifier","finalAdditionValues","additionValues","nativeConfig","environment","secureHash","currency","amount","merchantId","terminalId","locale","customerId","transactionType","sessionToken","transactionId","generateTransactionId","merchantReference","onResponse","callback","addListener","onCustomerId"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,aAAa,IAClBC,WAAW,EACXC,QAAQ,EACRC,eAAe,QAIV,0BAAuB;AAC9B,OAAOC,WAAW,MAAM,kBAAe;AACvC,SAASC,QAAQ,QAAQ,qBAAkB;AAC3C,SAASC,kBAAkB,QAAgC,cAAc;;AAEzE;AACA,MAAMC,YAAY,GAAG,IAAID,kBAAkB,CAACN,aAAoB,CAAC;AAEjE,OAAO,SAASQ,QAAQA,CAACC,MAAsB,EAAQ;EACrD;EACA,MAAMC,qBAAqB,GAAG;IAC5BC,kBAAkB,EAAE;EACtB,CAAC;EAED,MAAMC,mBAAmB,GAAG;IAC1B,GAAGF,qBAAqB;IACxB,GAAGD,MAAM,CAACI;EACZ,CAAC;EAED,MAAMC,YAAkC,GAAG;IACzCC,WAAW,EAAEN,MAAM,CAACM,WAAW;IAC/BC,UAAU,EAAEP,MAAM,CAACO,UAAU;IAC7BC,QAAQ,EAAER,MAAM,CAACQ,QAAQ;IACzBC,MAAM,EAAET,MAAM,CAACS,MAAM;IACrBC,UAAU,EAAEV,MAAM,CAACU,UAAU;IAC7BC,UAAU,EAAEX,MAAM,CAACW,UAAU;IAC7BC,MAAM,EAAEZ,MAAM,CAACY,MAAM;IACrBC,UAAU,EAAEb,MAAM,CAACa,UAAU;IAC7BC,eAAe,EAAEd,MAAM,CAACc,eAAe;IACvCC,YAAY,EAAEf,MAAM,CAACe,YAAY;IACjCC,aAAa,EAAEhB,MAAM,CAACgB,aAAa,IAAIpB,QAAQ,CAACqB,qBAAqB,CAAC,CAAC;IACvEb,cAAc,EAAED,mBAAmB;IACnCe,iBAAiB,EAAElB,MAAM,CAACkB;EAC5B,CAAC;;EAED;EACA3B,aAAa,CAACQ,QAAQ,CAACM,YAAY,CAAC;AACtC;AAEA,OAAO,SAASc,UAAUA,CACxBC,QAA8C,EAC3B;EACnB,OAAOtB,YAAY,CAACuB,WAAW,CAAC,YAAY,EAAED,QAAQ,CAAC;AACzD;AACA,OAAO,SAASE,YAAYA,CAC1BF,QAAsC,EACnB;EACnB,OAAOtB,YAAY,CAACuB,WAAW,CAAC,cAAc,EAAED,QAAQ,CAAC;AAC3D;AAEA,SACE5B,WAAW,EACXC,QAAQ,EACRC,eAAe,EAGfC,WAAW,EACXC,QAAQ","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Alert","Environment","SecureHashUtil","NetworkClient","constructor","getInstance","instance","getWebhookUrl","env","SIT","UAT","PROD","fetchSessionToken","merchantId","customerId","secureHashValue","webhookUrl","dataMap","secureHash","clearSecureHash","response","fetch","method","headers","body","JSON","stringify","responseData","json","ok","success","data","sessionToken","errorMessage","errorList","join","showErrorDialog","error","message","alert","text"],"sourceRoot":"../../../src","sources":["network/NetworkClient.ts"],"mappings":";;AAAA,SAASA,KAAK,QAAQ,cAAc;AACpC,SAASC,WAAW,QAAQ,2BAAwB;AACpD,OAAOC,cAAc,MAAM,4BAAyB;AAEpD,MAAMC,aAAa,CAAC;EAGVC,WAAWA,CAAA,EAAG,CAAC;EAEvB,OAAOC,WAAWA,CAAA,EAAkB;IAClC,IAAI,CAACF,aAAa,CAACG,QAAQ,EAAE;MAC3BH,aAAa,CAACG,QAAQ,GAAG,IAAIH,aAAa,CAAC,CAAC;IAC9C;IACA,OAAOA,aAAa,CAACG,QAAQ;EAC/B;EAEQC,aAAaA,CAACC,GAAgB,EAAU;IAC9C,QAAQA,GAAG;MACT,KAAKP,WAAW,CAACQ,GAAG;QAClB,OAAO,iCAAiC;MAC1C,KAAKR,WAAW,CAACS,GAAG;QAClB,OAAO,iCAAiC;MAC1C,KAAKT,WAAW,CAACU,IAAI;QACnB,OAAO,8BAA8B;MACvC;QACE,OAAO,iCAAiC;IAC5C;EACF;EAEA,MAAMC,iBAAiBA,CACrBJ,GAAgB,EAChBK,UAAkB,EAClBC,UAAyB,EACzBC,eAAuB,EACC;IACxB,IAAI;MACF,MAAMC,UAAU,GAAG,IAAI,CAACT,aAAa,CAACC,GAAG,CAAC;MAE1C,MAAMS,OAAO,GAAG;QACdJ,UAAU;QACVC;MACF,CAAC;MAED,MAAMI,UAAU,GAAGhB,cAAc,CAACiB,eAAe,
|
|
1
|
+
{"version":3,"names":["Alert","Environment","SecureHashUtil","NetworkClient","constructor","getInstance","instance","getWebhookUrl","env","SIT","UAT","PROD","fetchSessionToken","merchantId","customerId","secureHashValue","webhookUrl","dataMap","secureHash","clearSecureHash","response","fetch","method","headers","body","JSON","stringify","responseData","json","ok","success","data","sessionToken","errorMessage","errorList","join","showErrorDialog","error","message","alert","text"],"sourceRoot":"../../../src","sources":["network/NetworkClient.ts"],"mappings":";;AAAA,SAASA,KAAK,QAAQ,cAAc;AACpC,SAASC,WAAW,QAAQ,2BAAwB;AACpD,OAAOC,cAAc,MAAM,4BAAyB;AAEpD,MAAMC,aAAa,CAAC;EAGVC,WAAWA,CAAA,EAAG,CAAC;EAEvB,OAAOC,WAAWA,CAAA,EAAkB;IAClC,IAAI,CAACF,aAAa,CAACG,QAAQ,EAAE;MAC3BH,aAAa,CAACG,QAAQ,GAAG,IAAIH,aAAa,CAAC,CAAC;IAC9C;IACA,OAAOA,aAAa,CAACG,QAAQ;EAC/B;EAEQC,aAAaA,CAACC,GAAgB,EAAU;IAC9C,QAAQA,GAAG;MACT,KAAKP,WAAW,CAACQ,GAAG;QAClB,OAAO,iCAAiC;MAC1C,KAAKR,WAAW,CAACS,GAAG;QAClB,OAAO,iCAAiC;MAC1C,KAAKT,WAAW,CAACU,IAAI;QACnB,OAAO,8BAA8B;MACvC;QACE,OAAO,iCAAiC;IAC5C;EACF;EAEA,MAAMC,iBAAiBA,CACrBJ,GAAgB,EAChBK,UAAkB,EAClBC,UAAyB,EACzBC,eAAuB,EACC;IACxB,IAAI;MACF,MAAMC,UAAU,GAAG,IAAI,CAACT,aAAa,CAACC,GAAG,CAAC;MAE1C,MAAMS,OAAO,GAAG;QACdJ,UAAU;QACVC;MACF,CAAC;MAED,MAAMI,UAAU,GAAGhB,cAAc,CAACiB,eAAe,CAC/CJ,eAAe,EACfE,OACF,CAAC;MAED,MAAMG,QAAQ,GAAG,MAAMC,KAAK,CAC1B,GAAGL,UAAU,+BAA+B,EAC5C;QACEM,MAAM,EAAE,MAAM;QACdC,OAAO,EAAE;UACP,QAAQ,EAAE,YAAY;UACtB,iBAAiB,EAAE,gBAAgB;UACnC,cAAc,EAAE;QAClB,CAAC;QACDC,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;UACnBb,UAAU;UACVE,eAAe,EAAEG,UAAU;UAC3BJ;QACF,CAAC;MACH,CACF,CAAC;MAED,MAAMa,YAAY,GAAG,MAAMP,QAAQ,CAACQ,IAAI,CAAC,CAAC;MAE1C,IAAIR,QAAQ,CAACS,EAAE,IAAIF,YAAY,CAACG,OAAO,EAAE;QACvC,OAAOH,YAAY,CAACI,IAAI,CAACC,YAAY;MACvC,CAAC,MAAM;QACL,MAAMC,YAAY,GAChBN,YAAY,CAACO,SAAS,EAAEC,IAAI,CAAC,GAAG,CAAC,IAAI,eAAe;QACtD,IAAI,CAACC,eAAe,CAACH,YAAY,CAAC;QAClC,OAAO,IAAI;MACb;IACF,CAAC,CAAC,OAAOI,KAAK,EAAE;MACd,IAAI,CAACD,eAAe,CAAC,sBAAsB,CAAC;MAC5C,OAAO,IAAI;IACb;EACF;EAEQA,eAAeA,CAACE,OAAe,EAAQ;IAC7CtC,KAAK,CAACuC,KAAK,CAAC,OAAO,EAAED,OAAO,EAAE,CAAC;MAAEE,IAAI,EAAE;IAAK,CAAC,CAAC,CAAC;EACjD;AACF;AAEA,eAAerC,aAAa","ignoreList":[]}
|
|
@@ -13,19 +13,19 @@ class SecureHashUtil {
|
|
|
13
13
|
}
|
|
14
14
|
static generateSecureHash(message, secretKey) {
|
|
15
15
|
try {
|
|
16
|
-
// Convert hex string to byte array
|
|
16
|
+
// Convert hex string to byte array
|
|
17
17
|
const keyBytes = secretKey.match(/.{2}/g)?.map(byte => parseInt(byte, 16));
|
|
18
18
|
if (!keyBytes) {
|
|
19
19
|
throw new Error('Invalid secret key format');
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
// Convert key bytes to hex string for crypto-js
|
|
22
|
+
// Convert key bytes to hex string for crypto-js
|
|
23
23
|
const keyHex = keyBytes.map(byte => byte.toString(16).padStart(2, '0')).join('');
|
|
24
24
|
|
|
25
|
-
// Generate HMAC-SHA256
|
|
25
|
+
// Generate HMAC-SHA256
|
|
26
26
|
const hash = HmacSHA256(message, Hex.parse(keyHex));
|
|
27
27
|
|
|
28
|
-
// Convert to uppercase hex string
|
|
28
|
+
// Convert to uppercase hex string
|
|
29
29
|
return hash.toString(Hex).toUpperCase();
|
|
30
30
|
} catch (e) {
|
|
31
31
|
console.error('Error generating secure hash:', e);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["HmacSHA256","Hex","SecureHashUtil","clearSecureHash","secretKey","data","secureHashValue","concatenatedString","composeData","generateSecureHash","requestParameters","Object","entries","sort","keyA","keyB","localeCompare","filter","_","value","map","key","join","message","keyBytes","match","byte","parseInt","Error","keyHex","toString","padStart","hash","parse","toUpperCase","e","console","error"],"sourceRoot":"../../../src","sources":["utils/SecureHashUtil.ts"],"mappings":";;AAAA,OAAOA,UAAU,MAAM,uBAAuB;AAC9C,OAAOC,GAAG,MAAM,mBAAmB;AAInC,MAAMC,cAAc,CAAC;EACnB,OAAOC,eAAeA,CAACC,SAAiB,EAAEC,IAAa,EAAU;IAC/D,OAAOA,IAAI,CAACC,eAAe;IAC3B,MAAMC,kBAAkB,GAAG,IAAI,CAACC,WAAW,CAACH,IAAI,CAAC;IACjD,OAAO,IAAI,CAACI,kBAAkB,CAACF,kBAAkB,EAAEH,SAAS,CAAC;EAC/D;EAEA,OAAeI,WAAWA,CAACE,iBAA0B,EAAU;IAC7D,OAAOC,MAAM,CAACC,OAAO,CAACF,iBAAiB,CAAC,CACrCG,IAAI,CAAC,CAAC,CAACC,IAAI,CAAC,EAAE,CAACC,IAAI,CAAC,KAAKD,IAAI,CAACE,aAAa,CAACD,IAAI,CAAC,CAAC,CAClDE,MAAM,CAAC,CAAC,CAACC,CAAC,EAAEC,KAAK,CAAC,KAAKA,KAAK,IAAI,IAAI,IAAIA,KAAK,KAAK,EAAE,CAAC,CACrDC,GAAG,CAAC,CAAC,CAACC,GAAG,EAAEF,KAAK,CAAC,KAAK,GAAGE,GAAG,IAAIF,KAAK,EAAE,CAAC,CACxCG,IAAI,CAAC,GAAG,CAAC;EACd;EAEA,OAAeb,kBAAkBA,
|
|
1
|
+
{"version":3,"names":["HmacSHA256","Hex","SecureHashUtil","clearSecureHash","secretKey","data","secureHashValue","concatenatedString","composeData","generateSecureHash","requestParameters","Object","entries","sort","keyA","keyB","localeCompare","filter","_","value","map","key","join","message","keyBytes","match","byte","parseInt","Error","keyHex","toString","padStart","hash","parse","toUpperCase","e","console","error"],"sourceRoot":"../../../src","sources":["utils/SecureHashUtil.ts"],"mappings":";;AAAA,OAAOA,UAAU,MAAM,uBAAuB;AAC9C,OAAOC,GAAG,MAAM,mBAAmB;AAInC,MAAMC,cAAc,CAAC;EACnB,OAAOC,eAAeA,CAACC,SAAiB,EAAEC,IAAa,EAAU;IAC/D,OAAOA,IAAI,CAACC,eAAe;IAC3B,MAAMC,kBAAkB,GAAG,IAAI,CAACC,WAAW,CAACH,IAAI,CAAC;IACjD,OAAO,IAAI,CAACI,kBAAkB,CAACF,kBAAkB,EAAEH,SAAS,CAAC;EAC/D;EAEA,OAAeI,WAAWA,CAACE,iBAA0B,EAAU;IAC7D,OAAOC,MAAM,CAACC,OAAO,CAACF,iBAAiB,CAAC,CACrCG,IAAI,CAAC,CAAC,CAACC,IAAI,CAAC,EAAE,CAACC,IAAI,CAAC,KAAKD,IAAI,CAACE,aAAa,CAACD,IAAI,CAAC,CAAC,CAClDE,MAAM,CAAC,CAAC,CAACC,CAAC,EAAEC,KAAK,CAAC,KAAKA,KAAK,IAAI,IAAI,IAAIA,KAAK,KAAK,EAAE,CAAC,CACrDC,GAAG,CAAC,CAAC,CAACC,GAAG,EAAEF,KAAK,CAAC,KAAK,GAAGE,GAAG,IAAIF,KAAK,EAAE,CAAC,CACxCG,IAAI,CAAC,GAAG,CAAC;EACd;EAEA,OAAeb,kBAAkBA,CAC/Bc,OAAe,EACfnB,SAAiB,EACT;IACR,IAAI;MACF;MACA,MAAMoB,QAAQ,GAAGpB,SAAS,CACvBqB,KAAK,CAAC,OAAO,CAAC,EACbL,GAAG,CAAEM,IAAI,IAAKC,QAAQ,CAACD,IAAI,EAAE,EAAE,CAAC,CAAC;MAErC,IAAI,CAACF,QAAQ,EAAE;QACb,MAAM,IAAII,KAAK,CAAC,2BAA2B,CAAC;MAC9C;;MAEA;MACA,MAAMC,MAAM,GAAGL,QAAQ,CACpBJ,GAAG,CAAEM,IAAI,IAAKA,IAAI,CAACI,QAAQ,CAAC,EAAE,CAAC,CAACC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CACjDT,IAAI,CAAC,EAAE,CAAC;;MAEX;MACA,MAAMU,IAAI,GAAGhC,UAAU,CAACuB,OAAO,EAAEtB,GAAG,CAACgC,KAAK,CAACJ,MAAM,CAAC,CAAC;;MAEnD;MACA,OAAOG,IAAI,CAACF,QAAQ,CAAC7B,GAAG,CAAC,CAACiC,WAAW,CAAC,CAAC;IACzC,CAAC,CAAC,OAAOC,CAAC,EAAE;MACVC,OAAO,CAACC,KAAK,CAAC,+BAA+B,EAAEF,CAAC,CAAC;MACjD,OAAO,EAAE;IACX;EACF;AACF;AAEA,eAAejC,cAAc","ignoreList":[]}
|
|
@@ -12,7 +12,8 @@ export class UuidUtil {
|
|
|
12
12
|
*/
|
|
13
13
|
static generateV4() {
|
|
14
14
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
|
15
|
-
const r = Math.random() * 16
|
|
15
|
+
const r = Math.floor(Math.random() * 16);
|
|
16
|
+
// eslint-disable-next-line no-bitwise
|
|
16
17
|
const v = c === 'x' ? r : r & 0x3 | 0x8;
|
|
17
18
|
return v.toString(16);
|
|
18
19
|
}).toLowerCase();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["UuidUtil","generateV4","replace","c","r","Math","random","v","toString","toLowerCase","generateTransactionId"],"sourceRoot":"../../../src","sources":["utils/UuidUtil.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA,OAAO,MAAMA,QAAQ,CAAC;EACpB;AACF;AACA;AACA;AACA;EACE,OAAOC,UAAUA,CAAA,EAAW;IAC1B,OAAO,sCAAsC,
|
|
1
|
+
{"version":3,"names":["UuidUtil","generateV4","replace","c","r","Math","floor","random","v","toString","toLowerCase","generateTransactionId"],"sourceRoot":"../../../src","sources":["utils/UuidUtil.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA,OAAO,MAAMA,QAAQ,CAAC;EACpB;AACF;AACA;AACA;AACA;EACE,OAAOC,UAAUA,CAAA,EAAW;IAC1B,OAAO,sCAAsC,CAC1CC,OAAO,CAAC,OAAO,EAAGC,CAAC,IAAK;MACvB,MAAMC,CAAC,GAAGC,IAAI,CAACC,KAAK,CAACD,IAAI,CAACE,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;MACxC;MACA,MAAMC,CAAC,GAAGL,CAAC,KAAK,GAAG,GAAGC,CAAC,GAAIA,CAAC,GAAG,GAAG,GAAI,GAAG;MACzC,OAAOI,CAAC,CAACC,QAAQ,CAAC,EAAE,CAAC;IACvB,CAAC,CAAC,CACDC,WAAW,CAAC,CAAC;EAClB;;EAEA;AACF;AACA;AACA;EACE,OAAOC,qBAAqBA,CAAA,EAAW;IACrC,OAAOX,QAAQ,CAACC,UAAU,CAAC,CAAC;EAC9B;AACF","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AmwalPaySDK.d.ts","sourceRoot":"","sources":["../../../src/AmwalPaySDK.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"AmwalPaySDK.d.ts","sourceRoot":"","sources":["../../../src/AmwalPaySDK.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,SAAS,CAAC;AAIjB,cAAM,WAAW;IACf,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAc;IAErC,OAAO,CAAC,sBAAsB,CAAkC;IAEhE,OAAO,CAAC,wBAAwB,CAAkC;IAElE,OAAO;IAIP,MAAM,CAAC,WAAW,IAAI,WAAW;IAOjC;;;OAGG;IACG,YAAY,CAChB,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC,GAC3C,OAAO,CAAC,IAAI,CAAC;IA4ChB,OAAO,IAAI,IAAI;IAKf;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAuC3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAM7B;AAED,eAAe,WAAW,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAsB,EACpB,WAAW,EACX,QAAQ,EACR,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,cAAc,EAEpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAsB,EACpB,WAAW,EACX,QAAQ,EACR,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,cAAc,EAEpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAsB,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAK1E,wBAAgB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CA6BrD;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAC7C,iBAAiB,CAEnB;AACD,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,GACrC,iBAAiB,CAEnB;AAED,OAAO,EACL,WAAW,EACX,QAAQ,EACR,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,WAAW,EACX,QAAQ,GACT,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NetworkClient.d.ts","sourceRoot":"","sources":["../../../../src/network/NetworkClient.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGrD,cAAM,aAAa;IACjB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgB;IAEvC,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,aAAa;IAOnC,OAAO,CAAC,aAAa;IAaf,iBAAiB,CACrB,GAAG,EAAE,WAAW,EAChB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"NetworkClient.d.ts","sourceRoot":"","sources":["../../../../src/network/NetworkClient.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGrD,cAAM,aAAa;IACjB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgB;IAEvC,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,aAAa;IAOnC,OAAO,CAAC,aAAa;IAaf,iBAAiB,CACrB,GAAG,EAAE,WAAW,EAChB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA+CzB,OAAO,CAAC,eAAe;CAGxB;AAED,eAAe,aAAa,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecureHashUtil.d.ts","sourceRoot":"","sources":["../../../../src/utils/SecureHashUtil.ts"],"names":[],"mappings":"AAGA,KAAK,OAAO,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAEhD,cAAM,cAAc;IAClB,MAAM,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM;IAMhE,OAAO,CAAC,MAAM,CAAC,WAAW;IAQ1B,OAAO,CAAC,MAAM,CAAC,kBAAkB;
|
|
1
|
+
{"version":3,"file":"SecureHashUtil.d.ts","sourceRoot":"","sources":["../../../../src/utils/SecureHashUtil.ts"],"names":[],"mappings":"AAGA,KAAK,OAAO,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAEhD,cAAM,cAAc;IAClB,MAAM,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM;IAMhE,OAAO,CAAC,MAAM,CAAC,WAAW;IAQ1B,OAAO,CAAC,MAAM,CAAC,kBAAkB;CA6BlC;AAED,eAAe,cAAc,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UuidUtil.d.ts","sourceRoot":"","sources":["../../../../src/utils/UuidUtil.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,QAAQ;IACnB;;;;OAIG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM;
|
|
1
|
+
{"version":3,"file":"UuidUtil.d.ts","sourceRoot":"","sources":["../../../../src/utils/UuidUtil.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,QAAQ;IACnB;;;;OAIG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM;IAW3B;;;OAGG;IACH,MAAM,CAAC,qBAAqB,IAAI,MAAM;CAGvC"}
|
package/package.json
CHANGED
package/src/AmwalPaySDK.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
initiate,
|
|
3
|
+
onCustomerId,
|
|
4
|
+
onResponse,
|
|
5
|
+
type AmwalPayConfig,
|
|
6
|
+
} from './index';
|
|
2
7
|
import NetworkClient from './network/NetworkClient';
|
|
3
8
|
import { type EventSubscription } from 'react-native';
|
|
4
9
|
|
|
5
|
-
|
|
6
10
|
class AmwalPaySDK {
|
|
7
11
|
private static instance: AmwalPaySDK;
|
|
8
12
|
|
|
@@ -12,7 +16,6 @@ class AmwalPaySDK {
|
|
|
12
16
|
|
|
13
17
|
private constructor() {
|
|
14
18
|
// Initialize the event emitter
|
|
15
|
-
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
static getInstance(): AmwalPaySDK {
|
|
@@ -26,7 +29,9 @@ class AmwalPaySDK {
|
|
|
26
29
|
* Initiates the payment process by first fetching a session token and then starting the payment flow
|
|
27
30
|
* @param config The payment configuration
|
|
28
31
|
*/
|
|
29
|
-
async startPayment(
|
|
32
|
+
async startPayment(
|
|
33
|
+
config: Omit<AmwalPayConfig, 'sessionToken'>
|
|
34
|
+
): Promise<void> {
|
|
30
35
|
try {
|
|
31
36
|
// Set up event listeners before starting the payment process
|
|
32
37
|
this.setupEventListeners(config);
|
|
@@ -35,7 +40,10 @@ class AmwalPaySDK {
|
|
|
35
40
|
const networkClient = NetworkClient.getInstance();
|
|
36
41
|
|
|
37
42
|
// Fetch session token
|
|
38
|
-
console.log(
|
|
43
|
+
console.log(
|
|
44
|
+
'Fetching session token for environment:',
|
|
45
|
+
config.environment
|
|
46
|
+
);
|
|
39
47
|
const sessionToken = await networkClient.fetchSessionToken(
|
|
40
48
|
config.environment,
|
|
41
49
|
config.merchantId,
|
|
@@ -53,11 +61,14 @@ class AmwalPaySDK {
|
|
|
53
61
|
// Create complete config with session token
|
|
54
62
|
const completeConfig: AmwalPayConfig = {
|
|
55
63
|
...config,
|
|
56
|
-
sessionToken
|
|
64
|
+
sessionToken,
|
|
57
65
|
};
|
|
58
66
|
|
|
59
67
|
// Initiate the payment process
|
|
60
|
-
console.log(
|
|
68
|
+
console.log(
|
|
69
|
+
'Initiating native payment with config:',
|
|
70
|
+
JSON.stringify(completeConfig)
|
|
71
|
+
);
|
|
61
72
|
initiate(completeConfig);
|
|
62
73
|
} catch (error) {
|
|
63
74
|
console.error('Error starting payment:', error);
|
|
@@ -73,13 +84,21 @@ class AmwalPaySDK {
|
|
|
73
84
|
* Sets up event listeners for AmwalPay events
|
|
74
85
|
* @param config The payment configuration containing callback functions
|
|
75
86
|
*/
|
|
76
|
-
private setupEventListeners(
|
|
87
|
+
private setupEventListeners(
|
|
88
|
+
config: Omit<AmwalPayConfig, 'sessionToken'>
|
|
89
|
+
): void {
|
|
77
90
|
// Remove any existing listeners
|
|
78
91
|
this.removeEventListeners();
|
|
79
92
|
|
|
80
93
|
console.log('🟢 Setting up event listeners...');
|
|
81
|
-
console.log(
|
|
82
|
-
|
|
94
|
+
console.log(
|
|
95
|
+
'🟢 onResponse callback exists?',
|
|
96
|
+
typeof config.onResponse === 'function'
|
|
97
|
+
);
|
|
98
|
+
console.log(
|
|
99
|
+
'🟢 onCustomerId callback exists?',
|
|
100
|
+
typeof config.onCustomerId === 'function'
|
|
101
|
+
);
|
|
83
102
|
|
|
84
103
|
this.onResponseSubscription = onResponse((response) => {
|
|
85
104
|
console.log('🟢 SDK onResponse listener triggered with:', response);
|
|
@@ -115,4 +134,4 @@ class AmwalPaySDK {
|
|
|
115
134
|
}
|
|
116
135
|
}
|
|
117
136
|
|
|
118
|
-
export default AmwalPaySDK;
|
|
137
|
+
export default AmwalPaySDK;
|
package/src/index.tsx
CHANGED
|
@@ -8,10 +8,7 @@ import ReactAmwalPay, {
|
|
|
8
8
|
} from './NativeReactAmwalPay';
|
|
9
9
|
import AmwalPaySDK from './AmwalPaySDK';
|
|
10
10
|
import { UuidUtil } from './utils/UuidUtil';
|
|
11
|
-
import {
|
|
12
|
-
NativeEventEmitter,
|
|
13
|
-
type EventSubscription,
|
|
14
|
-
} from 'react-native';
|
|
11
|
+
import { NativeEventEmitter, type EventSubscription } from 'react-native';
|
|
15
12
|
|
|
16
13
|
// Create an event emitter for the native module
|
|
17
14
|
const eventEmitter = new NativeEventEmitter(ReactAmwalPay as any);
|
|
@@ -47,10 +44,14 @@ export function initiate(config: AmwalPayConfig): void {
|
|
|
47
44
|
ReactAmwalPay.initiate(nativeConfig);
|
|
48
45
|
}
|
|
49
46
|
|
|
50
|
-
export function onResponse(
|
|
47
|
+
export function onResponse(
|
|
48
|
+
callback: (response: AmwalPayResponse) => void
|
|
49
|
+
): EventSubscription {
|
|
51
50
|
return eventEmitter.addListener('onResponse', callback);
|
|
52
51
|
}
|
|
53
|
-
export function onCustomerId(
|
|
52
|
+
export function onCustomerId(
|
|
53
|
+
callback: (customerId: string) => void
|
|
54
|
+
): EventSubscription {
|
|
54
55
|
return eventEmitter.addListener('onCustomerId', callback);
|
|
55
56
|
}
|
|
56
57
|
|
|
@@ -1,84 +1,87 @@
|
|
|
1
|
-
import { Alert } from 'react-native';
|
|
2
|
-
import { Environment } from '../NativeReactAmwalPay';
|
|
3
|
-
import SecureHashUtil from '../utils/SecureHashUtil';
|
|
4
|
-
|
|
5
|
-
class NetworkClient {
|
|
6
|
-
private static instance: NetworkClient;
|
|
7
|
-
|
|
8
|
-
private constructor() {}
|
|
9
|
-
|
|
10
|
-
static getInstance(): NetworkClient {
|
|
11
|
-
if (!NetworkClient.instance) {
|
|
12
|
-
NetworkClient.instance = new NetworkClient();
|
|
13
|
-
}
|
|
14
|
-
return NetworkClient.instance;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
private getWebhookUrl(env: Environment): string {
|
|
18
|
-
switch (env) {
|
|
19
|
-
case Environment.SIT:
|
|
20
|
-
return 'https://test.amwalpg.com:24443/';
|
|
21
|
-
case Environment.UAT:
|
|
22
|
-
return 'https://test.amwalpg.com:14443/';
|
|
23
|
-
case Environment.PROD:
|
|
24
|
-
return 'https://webhook.amwalpg.com/';
|
|
25
|
-
default:
|
|
26
|
-
return 'https://test.amwalpg.com:24443/';
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async fetchSessionToken(
|
|
31
|
-
env: Environment,
|
|
32
|
-
merchantId: string,
|
|
33
|
-
customerId: string | null,
|
|
34
|
-
secureHashValue: string
|
|
35
|
-
): Promise<string | null> {
|
|
36
|
-
try {
|
|
37
|
-
const webhookUrl = this.getWebhookUrl(env);
|
|
38
|
-
|
|
39
|
-
const dataMap = {
|
|
40
|
-
merchantId,
|
|
41
|
-
customerId
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const secureHash = SecureHashUtil.clearSecureHash(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
'
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
1
|
+
import { Alert } from 'react-native';
|
|
2
|
+
import { Environment } from '../NativeReactAmwalPay';
|
|
3
|
+
import SecureHashUtil from '../utils/SecureHashUtil';
|
|
4
|
+
|
|
5
|
+
class NetworkClient {
|
|
6
|
+
private static instance: NetworkClient;
|
|
7
|
+
|
|
8
|
+
private constructor() {}
|
|
9
|
+
|
|
10
|
+
static getInstance(): NetworkClient {
|
|
11
|
+
if (!NetworkClient.instance) {
|
|
12
|
+
NetworkClient.instance = new NetworkClient();
|
|
13
|
+
}
|
|
14
|
+
return NetworkClient.instance;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
private getWebhookUrl(env: Environment): string {
|
|
18
|
+
switch (env) {
|
|
19
|
+
case Environment.SIT:
|
|
20
|
+
return 'https://test.amwalpg.com:24443/';
|
|
21
|
+
case Environment.UAT:
|
|
22
|
+
return 'https://test.amwalpg.com:14443/';
|
|
23
|
+
case Environment.PROD:
|
|
24
|
+
return 'https://webhook.amwalpg.com/';
|
|
25
|
+
default:
|
|
26
|
+
return 'https://test.amwalpg.com:24443/';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async fetchSessionToken(
|
|
31
|
+
env: Environment,
|
|
32
|
+
merchantId: string,
|
|
33
|
+
customerId: string | null,
|
|
34
|
+
secureHashValue: string
|
|
35
|
+
): Promise<string | null> {
|
|
36
|
+
try {
|
|
37
|
+
const webhookUrl = this.getWebhookUrl(env);
|
|
38
|
+
|
|
39
|
+
const dataMap = {
|
|
40
|
+
merchantId,
|
|
41
|
+
customerId,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const secureHash = SecureHashUtil.clearSecureHash(
|
|
45
|
+
secureHashValue,
|
|
46
|
+
dataMap
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const response = await fetch(
|
|
50
|
+
`${webhookUrl}Membership/GetSDKSessionToken`,
|
|
51
|
+
{
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers: {
|
|
54
|
+
'Accept': 'text/plain',
|
|
55
|
+
'Accept-Language': 'en-US,en;q=0.9',
|
|
56
|
+
'Content-Type': 'application/json',
|
|
57
|
+
},
|
|
58
|
+
body: JSON.stringify({
|
|
59
|
+
merchantId,
|
|
60
|
+
secureHashValue: secureHash,
|
|
61
|
+
customerId,
|
|
62
|
+
}),
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const responseData = await response.json();
|
|
67
|
+
|
|
68
|
+
if (response.ok && responseData.success) {
|
|
69
|
+
return responseData.data.sessionToken;
|
|
70
|
+
} else {
|
|
71
|
+
const errorMessage =
|
|
72
|
+
responseData.errorList?.join(',') || 'Unknown error';
|
|
73
|
+
this.showErrorDialog(errorMessage);
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
} catch (error) {
|
|
77
|
+
this.showErrorDialog('Something Went Wrong');
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private showErrorDialog(message: string): void {
|
|
83
|
+
Alert.alert('Error', message, [{ text: 'OK' }]);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export default NetworkClient;
|
|
@@ -1,45 +1,52 @@
|
|
|
1
|
-
import HmacSHA256 from 'crypto-js/hmac-sha256';
|
|
2
|
-
import Hex from 'crypto-js/enc-hex';
|
|
3
|
-
|
|
4
|
-
type DataMap = { [key: string]: string | null };
|
|
5
|
-
|
|
6
|
-
class SecureHashUtil {
|
|
7
|
-
static clearSecureHash(secretKey: string, data: DataMap): string {
|
|
8
|
-
delete data.secureHashValue;
|
|
9
|
-
const concatenatedString = this.composeData(data);
|
|
10
|
-
return this.generateSecureHash(concatenatedString, secretKey);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
private static composeData(requestParameters: DataMap): string {
|
|
14
|
-
return Object.entries(requestParameters)
|
|
15
|
-
.sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
|
|
16
|
-
.filter(([_, value]) => value != null && value !== '')
|
|
17
|
-
.map(([key, value]) => `${key}=${value}`)
|
|
18
|
-
.join('&');
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
private static generateSecureHash(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
1
|
+
import HmacSHA256 from 'crypto-js/hmac-sha256';
|
|
2
|
+
import Hex from 'crypto-js/enc-hex';
|
|
3
|
+
|
|
4
|
+
type DataMap = { [key: string]: string | null };
|
|
5
|
+
|
|
6
|
+
class SecureHashUtil {
|
|
7
|
+
static clearSecureHash(secretKey: string, data: DataMap): string {
|
|
8
|
+
delete data.secureHashValue;
|
|
9
|
+
const concatenatedString = this.composeData(data);
|
|
10
|
+
return this.generateSecureHash(concatenatedString, secretKey);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
private static composeData(requestParameters: DataMap): string {
|
|
14
|
+
return Object.entries(requestParameters)
|
|
15
|
+
.sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
|
|
16
|
+
.filter(([_, value]) => value != null && value !== '')
|
|
17
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
18
|
+
.join('&');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
private static generateSecureHash(
|
|
22
|
+
message: string,
|
|
23
|
+
secretKey: string
|
|
24
|
+
): string {
|
|
25
|
+
try {
|
|
26
|
+
// Convert hex string to byte array
|
|
27
|
+
const keyBytes = secretKey
|
|
28
|
+
.match(/.{2}/g)
|
|
29
|
+
?.map((byte) => parseInt(byte, 16));
|
|
30
|
+
|
|
31
|
+
if (!keyBytes) {
|
|
32
|
+
throw new Error('Invalid secret key format');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Convert key bytes to hex string for crypto-js
|
|
36
|
+
const keyHex = keyBytes
|
|
37
|
+
.map((byte) => byte.toString(16).padStart(2, '0'))
|
|
38
|
+
.join('');
|
|
39
|
+
|
|
40
|
+
// Generate HMAC-SHA256
|
|
41
|
+
const hash = HmacSHA256(message, Hex.parse(keyHex));
|
|
42
|
+
|
|
43
|
+
// Convert to uppercase hex string
|
|
44
|
+
return hash.toString(Hex).toUpperCase();
|
|
45
|
+
} catch (e) {
|
|
46
|
+
console.error('Error generating secure hash:', e);
|
|
47
|
+
return '';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default SecureHashUtil;
|
package/src/utils/UuidUtil.ts
CHANGED
|
@@ -9,11 +9,14 @@ export class UuidUtil {
|
|
|
9
9
|
* @returns A lowercase UUID string
|
|
10
10
|
*/
|
|
11
11
|
static generateV4(): string {
|
|
12
|
-
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
|
|
13
|
+
.replace(/[xy]/g, (c) => {
|
|
14
|
+
const r = Math.floor(Math.random() * 16);
|
|
15
|
+
// eslint-disable-next-line no-bitwise
|
|
16
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
17
|
+
return v.toString(16);
|
|
18
|
+
})
|
|
19
|
+
.toLowerCase();
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
/**
|
|
@@ -23,4 +26,4 @@ export class UuidUtil {
|
|
|
23
26
|
static generateTransactionId(): string {
|
|
24
27
|
return UuidUtil.generateV4();
|
|
25
28
|
}
|
|
26
|
-
}
|
|
29
|
+
}
|