react-native-bootpay-api 1.5.0 → 4.0.0-beta.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-bootpay-api",
3
- "version": "1.5.0",
3
+ "version": "4.0.0-beta.1",
4
4
  "description": "React Native를 위한 bootpay 라이브러리 입니다.",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -26,14 +26,18 @@
26
26
  "!**/__mocks__"
27
27
  ],
28
28
  "scripts": {
29
- "test": "jest",
30
- "typescript": "tsc --noEmit",
31
- "lint": "eslint \"**/*.{js,ts,tsx}\"",
32
- "prepare": "bob build",
33
- "release": "release-it",
34
- "example": "yarn --cwd example",
35
- "pods": "cd example && pod-install --quiet",
36
- "bootstrap": "yarn example && yarn && yarn pods"
29
+ "android": "react-native run-android",
30
+ "ios": "react-native run-ios --project-path example/ios",
31
+ "macos": "react-native run-macos --scheme WebviewExample --project-path example/macos",
32
+ "start": "cd example && react-native start",
33
+ "windows": "install-windows-test-app --project-directory example/windows && react-native run-windows --root example --arch x64",
34
+ "ci": "CI=true && yarn lint",
35
+ "ci:publish": "yarn semantic-release",
36
+ "lint": "yarn tsc --noEmit && yarn eslint ./src --ext .ts,.tsx",
37
+ "build": "yarn tsc",
38
+ "prepare": "yarn build",
39
+ "appium": "appium",
40
+ "test:windows": "yarn jest --setupFiles=./jest-setups/jest.setup.js"
37
41
  },
38
42
  "keywords": [
39
43
  "react-native",
@@ -51,96 +55,46 @@
51
55
  "registry": "https://registry.npmjs.org/"
52
56
  },
53
57
  "devDependencies": {
54
- "@commitlint/config-conventional": "^11.0.0",
55
- "@react-native-community/eslint-config": "^2.0.0",
56
- "@release-it/conventional-changelog": "^2.0.0",
58
+ "@babel/core": "^7.0.0",
59
+ "@babel/runtime": "^7.0.0",
60
+ "@react-native-community/cli": "^6.0.0",
61
+ "@react-native-community/cli-platform-android": "^6.0.0",
62
+ "@react-native-community/cli-platform-ios": "^6.0.0",
63
+ "@semantic-release/git": "7.0.16",
64
+ "@types/invariant": "^2.2.30",
57
65
  "@types/jest": "^26.0.0",
58
- "@types/react": "^16.9.19",
59
- "@types/react-native": "0.62.13",
60
- "commitlint": "^11.0.0",
61
- "eslint": "^7.2.0",
62
- "jest": "^26.0.1",
63
- "pod-install": "^0.1.0",
64
- "prettier": "^2.0.5",
65
- "react": "16.13.1",
66
- "react-native": "0.63.4",
67
- "react-native-builder-bob": "^0.18.0",
68
- "release-it": "^14.2.2",
69
- "typescript": "^4.1.3",
70
- "react-native-webview-bootpay": "^11.6.5",
71
- "react-native-device-info": "^8.4.0",
66
+ "@types/react": "^17.0.0",
67
+ "@types/react-native": "^0.64.0",
68
+ "@types/selenium-webdriver": "4.0.9",
69
+ "@typescript-eslint/eslint-plugin": "2.1.0",
70
+ "@typescript-eslint/parser": "2.1.0",
71
+ "appium": "1.17.0",
72
+ "eslint": "6.3.0",
73
+ "eslint-config-airbnb": "18.0.1",
74
+ "eslint-config-prettier": "6.2.0",
75
+ "eslint-plugin-import": "2.18.2",
76
+ "eslint-plugin-jsx-a11y": "6.2.3",
77
+ "eslint-plugin-react": "7.14.3",
78
+ "eslint-plugin-react-native": "3.7.0",
79
+ "jest": "^26.6.3",
80
+ "metro-react-native-babel-preset": "^0.66.2",
81
+ "react": "17.0.2",
82
+ "react-native": "^0.66.0-0",
83
+ "react-native-macos": "^0.66.0-0",
84
+ "react-native-test-app": "^1.3.2",
85
+ "react-native-windows": "^0.66.0-0",
86
+ "selenium-appium": "1.0.2",
87
+ "selenium-webdriver": "4.0.0-alpha.7",
88
+ "semantic-release": "15.13.24",
89
+ "typescript": "^4.0.0",
90
+ "react-native-webview-bootpay": "^11.18.13",
91
+ "react-native-device-info": "^8.7.0",
72
92
  "react-native-sensitive-info": "^5.5.8",
73
93
  "react-native-base64": "^0.2.1",
74
- "react-native-aes-crypto": "^1.3.10"
94
+ "react-native-aes-crypto": "^2.1.0"
75
95
  },
76
96
  "peerDependencies": {
77
97
  "react": "*",
78
98
  "react-native": "*"
79
- },
80
- "jest": {
81
- "preset": "react-native",
82
- "modulePathIgnorePatterns": [
83
- "<rootDir>/example/node_modules",
84
- "<rootDir>/lib/"
85
- ]
86
- },
87
- "commitlint": {
88
- "extends": [
89
- "@commitlint/config-conventional"
90
- ]
91
- },
92
- "release-it": {
93
- "git": {
94
- "commitMessage": "chore: release ${version}",
95
- "tagName": "v${version}"
96
- },
97
- "npm": {
98
- "publish": true
99
- },
100
- "github": {
101
- "release": true
102
- },
103
- "plugins": {
104
- "@release-it/conventional-changelog": {
105
- "preset": "angular"
106
- }
107
- }
108
- },
109
- "eslintConfig": {
110
- "root": true,
111
- "extends": [
112
- "@react-native-community",
113
- "prettier"
114
- ],
115
- "rules": {
116
- "prettier/prettier": [
117
- "error",
118
- {
119
- "quoteProps": "consistent",
120
- "singleQuote": true,
121
- "tabWidth": 2,
122
- "trailingComma": "es5",
123
- "useTabs": false
124
- }
125
- ]
126
- }
127
- },
128
- "eslintIgnore": [
129
- "node_modules/",
130
- "lib/"
131
- ],
132
- "react-native-builder-bob": {
133
- "source": "src",
134
- "output": "lib",
135
- "targets": [
136
- "commonjs",
137
- "module",
138
- [
139
- "typescript",
140
- {
141
- "project": "tsconfig.build.json"
142
- }
143
- ]
144
- ]
145
99
  }
146
100
  }
@@ -1,19 +1,37 @@
1
1
 
2
2
 
3
- import React, { Component, useRef } from 'react';
4
- import { SafeAreaView, Modal, Platform, TouchableOpacity, Image, StyleSheet } from 'react-native';
3
+ import React, { Component, useRef, useEffect } from 'react';
4
+ import { SafeAreaView, Modal, Platform, TouchableOpacity, Image, StyleSheet, BackHandler} from 'react-native';
5
5
  import WebView from 'react-native-webview-bootpay';
6
6
  import UserInfo from './UserInfo'
7
7
 
8
8
  export class BootpayWebView extends Component {
9
+
10
+
9
11
  webView = useRef<WebView>(null);
10
12
 
13
+
11
14
  state = {
12
15
  visibility: false,
13
16
  script: '',
14
17
  firstLoad: false
15
18
  }
16
- s
19
+
20
+ // canGoBack() {
21
+ // console.log('canGoBack');
22
+ // if(this.webView.current) {
23
+ // return this.webView.current.canGoBack();
24
+ // }
25
+ // return false;
26
+ // }
27
+
28
+ // goBack() {
29
+ // console.log('GoBack');
30
+ // if(this.webView.goBack) {
31
+ // this.webView.current.goBack();
32
+ // }
33
+ // }
34
+
17
35
  async componentWillUnmount() {
18
36
  this.setState(
19
37
  {
@@ -25,12 +43,13 @@ s
25
43
  UserInfo.setBootpayLastTime(Date.now());
26
44
  }
27
45
 
28
- render() {
29
-
30
-
46
+ render() {
31
47
  return <Modal
32
48
  animationType={'slide'}
33
- transparent={false}
49
+ transparent={false}
50
+ onRequestClose={()=> {
51
+ this.dismiss();
52
+ }}
34
53
  visible={this.state.visibility}>
35
54
  <SafeAreaView style={{ flex: 1 }}>
36
55
  {
@@ -58,15 +77,20 @@ s
58
77
  }
59
78
  <WebView
60
79
  ref={(wv) => this.webView = wv}
80
+ // ref={btWebView}
61
81
  useWebKit={true}
62
82
  originWhitelist={['*']}
63
83
  source={{
64
- uri: 'https://inapp.bootpay.co.kr/3.3.3/production.html'
84
+ uri: 'https://webview.bootpay.co.kr/4.0.0/'
85
+ }}
86
+ onRequestClose={()=> {
87
+ console.log('onRequestClose');
88
+ this.dismiss();
65
89
  }}
66
90
  injectedJavaScript={this.state.script}
67
91
  javaScriptEnabled={true}
68
92
  javaScriptCanOpenWindowsAutomatically={true}
69
- scalesPageToFit={true}
93
+ // scalesPageToFit={true}
70
94
  onMessage={this.onMessage}
71
95
  onShouldStartLoadWithRequest={this.onShouldStartLoadWithRequest}
72
96
  />
@@ -75,39 +99,42 @@ s
75
99
  </Modal>
76
100
  }
77
101
 
78
- request = async (payload, items, user, extra) => {
102
+ requestPayment = async (payload, items, user, extra) => {
103
+ this.bootpayRequest(payload, items, user, extra, "requestPayment");
104
+ }
105
+
106
+ requestSubscription = async (payload, items, user, extra) => {
107
+ this.bootpayRequest(payload, items, user, extra, "requestSubscription");
108
+ }
79
109
 
110
+ requestAuthentication = async (payload, items, user, extra) => {
111
+ this.bootpayRequest(payload, items, user, extra, "requestAuthentication");
112
+ }
113
+
114
+ bootpayRequest = async (payload, items, user, extra, requestMethod) => {
80
115
  payload.application_id = Platform.OS == 'ios' ? this.props.ios_application_id : this.props.android_application_id;
81
116
  payload.items = items;
82
117
  payload.user_info = user;
83
118
  payload.extra = extra;
84
-
85
-
86
- var quickPopup = '';
87
-
88
- if(extra != undefined && extra.quick_popup != undefined) {
89
- if(extra.quick_popup == 1) {
90
- quickPopup = 'BootPay.startQuickPopup();';
91
- }
92
- }
93
-
119
+
94
120
 
95
121
  //visibility가 true가 되면 webview onLoaded가 실행됨
96
122
  this.setState(
97
123
  {
98
124
  visibility: true,
99
125
  script: `
100
- ${await this.getMountJavascript()}
101
- ${quickPopup}
102
- ${this.generateScript(payload)}
126
+ ${await this.getMountJavascript()}
127
+ ${this.generateScript(payload, requestMethod)}
103
128
  `,
104
129
  firstLoad: false,
105
130
  showCloseButton: extra.show_close_button || false
106
131
  }
107
132
  )
108
133
 
109
- UserInfo.updateInfo();
134
+ UserInfo.updateInfo();
110
135
  }
136
+
137
+
111
138
 
112
139
  dismiss = () => {
113
140
  this.setState(
@@ -127,15 +154,19 @@ s
127
154
  }
128
155
 
129
156
 
130
- generateScript= (payload) => {
131
- const onError = '.error(function(data){ window.BootpayRNWebView.postMessage( JSON.stringify(data) ); })';
132
- const onCancel = '.cancel(function(data){ window.BootpayRNWebView.postMessage( JSON.stringify(data) ); })';
133
- const onReady = '.ready(function(data){ window.BootpayRNWebView.postMessage( JSON.stringify(data) ); })';
134
- const onConfirm = '.confirm(function(data){ window.BootpayRNWebView.postMessage( JSON.stringify(data) ); })';
135
- const onClose = '.close(function(data){ window.BootpayRNWebView.postMessage("close"); })';
136
- const onDone = '.done(function(data){ window.BootpayRNWebView.postMessage( JSON.stringify(data) ); })';
157
+ generateScript= (payload, requestMethod) => {
158
+ const script = "Bootpay." + requestMethod +
159
+ `(${JSON.stringify(payload)})` +
160
+ ".then( function (res) {" +
161
+ confirm() +
162
+ issued() +
163
+ done() +
164
+ "}, function (res) {" +
165
+ error() +
166
+ cancel() +
167
+ "})";
137
168
 
138
- return `BootPay.request(${JSON.stringify(payload)})` + onError + onCancel + onReady + onConfirm + onClose + onDone + '; void(0);';
169
+ this.callJavaScript(script);
139
170
  }
140
171
 
141
172
  onMessage = ({ nativeEvent }) => {
@@ -147,42 +178,47 @@ s
147
178
  action: 'BootpayClose',
148
179
  message: '결제창이 닫혔습니다'
149
180
  }
181
+ this.setState(
182
+ {
183
+ visibility: false
184
+ }
185
+ )
150
186
  this.props.onClose(json);
151
187
  this.dismiss();
152
188
  return;
153
189
  }
154
190
 
155
191
  const data = JSON.parse(nativeEvent.data);
156
- switch (data.action) {
157
- case 'BootpayCancel':
192
+ switch (data.event) {
193
+ case 'cancel':
158
194
  if(this.props.onCancel != undefined) this.props.onCancel(data);
159
- this.setState(
160
- {
161
- visibility: false
162
- }
163
- )
195
+ // this.setState(
196
+ // {
197
+ // visibility: false
198
+ // }
199
+ // )
164
200
  break;
165
- case 'BootpayError':
201
+ case 'error':
166
202
  if(this.props.onError != undefined) this.props.onError(data);
167
- this.setState(
168
- {
169
- visibility: false
170
- }
171
- )
203
+ // this.setState(
204
+ // {
205
+ // visibility: false
206
+ // }
207
+ // )
172
208
  break;
173
- case 'BootpayBankReady':
209
+ case 'issued':
174
210
  if(this.props.onReady != undefined) this.props.onReady(data);
175
211
  break;
176
- case 'BootpayConfirm':
212
+ case 'confirm':
177
213
  if(this.props.onConfirm != undefined) this.props.onConfirm(data);
178
214
  break;
179
- case 'BootpayDone':
215
+ case 'done':
180
216
  if(this.props.onDone != undefined) this.props.onDone(data);
181
- this.setState(
182
- {
183
- visibility: false
184
- }
185
- )
217
+ // this.setState(
218
+ // {
219
+ // visibility: false
220
+ // }
221
+ // )
186
222
  break;
187
223
  }
188
224
  }
@@ -193,9 +229,9 @@ s
193
229
 
194
230
  getBootpayPlatform = () => {
195
231
  if(Platform.OS == 'ios') {
196
- return "BootPay.setDevice('IOS');";
232
+ return "Bootpay.setDevice('IOS');";
197
233
  } else if(Platform.OS == 'android'){
198
- return "BootPay.setDevice('ANDROID');";
234
+ return "Bootpay.setDevice('ANDROID');";
199
235
  }
200
236
  }
201
237
 
@@ -208,18 +244,23 @@ s
208
244
  // }
209
245
  // }
210
246
 
211
- transactionConfirm = (data) => {
212
- // console.log('transactionConfirm: ' + data);
213
-
214
- var json = JSON.stringify(data)
215
- this.callJavaScript(`
216
- BootPay.transactionConfirm(${json});
217
- `);
247
+ transactionConfirm = () => {
248
+ const script = "Bootpay.confirm()" +
249
+ ".then( function (res) {" +
250
+ confirm() +
251
+ issued() +
252
+ done() +
253
+ "}, function (res) {" +
254
+ error() +
255
+ cancel() +
256
+ "})";
257
+
258
+ this.callJavaScript(script);
218
259
  }
219
260
 
220
261
  removePaymentWindow = () => {
221
262
  this.callJavaScript(`
222
- BootPay.removePaymentWindow();
263
+ Bootpay.removePaymentWindow();
223
264
  `);
224
265
  }
225
266
 
@@ -236,14 +277,38 @@ s
236
277
 
237
278
  getAnalyticsData = async () => {
238
279
  const uuid = await UserInfo.getBootpayUUID();
239
- const bootpaySK = await UserInfo.getBootpaySK();
280
+ // const bootpaySK = await UserInfo.getBootpaySK();
240
281
  const bootLastTime = await UserInfo.getBootpayLastTime();
241
282
 
242
283
 
243
284
  const elaspedTime = Date.now() - bootLastTime;
244
- return `window.BootPay.setAnalyticsData({uuid:'${uuid}',sk:'${bootpaySK}',sk_time:${bootLastTime},time:${elaspedTime}});`;
285
+ return `window.Bootpay.$analytics.setAnalyticsData({uuid:'${uuid}', time:${elaspedTime}});`;
245
286
  // this.callJavaScript(`window.BootPay.setAnalyticsData({uuid:'${uuid}',sk:'${bootpaySK}',sk_time:${bootLastTime},time:${elaspedTime}});`);
246
287
  }
288
+
289
+ confirm = () => {
290
+ return "if (res.event === 'confirm') { window.BootpayRNWebView.postMessage( JSON.stringify(res) ); }";
291
+ }
292
+
293
+ done = () => {
294
+ return "else if (res.event === 'done') { window.BootpayRNWebView.postMessage( JSON.stringify(res) ); }";
295
+ }
296
+
297
+ issued = () => {
298
+ return "else if (res.event === 'issued') { window.BootpayRNWebView.postMessage( JSON.stringify(res) ); }";
299
+ }
300
+
301
+ error = () => {
302
+ return "if (res.event === 'error') { window.BootpayRNWebView.postMessage( JSON.stringify(res) ); }";
303
+ }
304
+
305
+ cancel = () => {
306
+ return "else if (res.event === 'cancel') { window.BootpayRNWebView.postMessage( JSON.stringify(res) ); }";
307
+ }
308
+
309
+ close = () => {
310
+ return "document.addEventListener('bootpayclose', function (e) { window.BootpayRNWebView.postMessage('close'); });";
311
+ }
247
312
  }
248
313
 
249
314
 
File without changes
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserInfo.d.ts","sourceRoot":"","sources":["UserInfo.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIlC,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,SAAS;IAC3C,MAAM,CAAC,cAAc,QAAS,MAAM,cAAc,GAAG,sBAYpD;IAED,MAAM,CAAC,cAAc,QAAS,MAAM,OAAO,GAAG,sBAW7C;IAED,MAAM,CAAC,cAAc,yBAGpB;IAED,MAAM,CAAC,YAAY,yBAElB;IAED,MAAM,CAAC,YAAY,QAAS,MAAM,sBAEjC;IAED,MAAM,CAAC,YAAY,SAAU,MAAM,QAAQ,MAAM,sBAEhD;IAED,MAAM,CAAC,kBAAkB,yBAExB;IAED,MAAM,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM;IAIrC,MAAM,CAAC,gBAAgB;IAIvB,MAAM,CAAC,gBAAgB,QAAS,MAAM,sBAErC;IAED,MAAM,CAAC,UAAU,sBAWhB;CACJ"}
@@ -0,0 +1,67 @@
1
+ import { Component } from 'react';
2
+ import DeviceInfo from 'react-native-device-info';
3
+ import SInfo from 'react-native-sensitive-info';
4
+ export default class UserInfo extends Component {
5
+ static getBootpayInfo = (key, defaultVal) => {
6
+ return new Promise((resolve, reject) => {
7
+ SInfo.getItem(key, {
8
+ sharedPreferencesName: 'bootpaySharedPrefs',
9
+ keychainService: 'bootpayKeychain'
10
+ }).then((res) => {
11
+ res == undefined ? resolve(defaultVal) : resolve(res);
12
+ resolve(res);
13
+ }).catch((error) => {
14
+ reject(error);
15
+ });
16
+ });
17
+ };
18
+ static setBootpayInfo = (key, val) => {
19
+ return new Promise((resolve, reject) => {
20
+ SInfo.setItem(String(key), String(val), {
21
+ sharedPreferencesName: 'bootpaySharedPrefs',
22
+ keychainService: 'bootpayKeychain'
23
+ }).then((res) => {
24
+ resolve(res);
25
+ }).catch((error) => {
26
+ reject(error);
27
+ });
28
+ });
29
+ };
30
+ static getBootpayUUID = () => {
31
+ let uuid = DeviceInfo.getUniqueId();
32
+ return UserInfo.setBootpayInfo('uuid', uuid);
33
+ };
34
+ static getBootpaySK = () => {
35
+ return UserInfo.getBootpayInfo('bootpay_sk', '');
36
+ };
37
+ static setBootpaySK = (val) => {
38
+ return UserInfo.setBootpayInfo('bootpay_sk', val);
39
+ };
40
+ static newBootpaySK = (uuid, time) => {
41
+ return UserInfo.setBootpaySK(`${uuid}_${time}`);
42
+ };
43
+ static getBootpayLastTime = async () => {
44
+ return await UserInfo.getBootpayInfo('bootpay_last_time', 0);
45
+ };
46
+ static setBootpayLastTime(val) {
47
+ return UserInfo.setBootpayInfo('bootpay_last_time', val);
48
+ }
49
+ static getBootpayUserId() {
50
+ return UserInfo.getBootpayInfo('bootpay_user_id', '');
51
+ }
52
+ static setBootpayUserId = (val) => {
53
+ return UserInfo.setBootpayInfo('bootpay_user_id', val);
54
+ };
55
+ static updateInfo = async () => {
56
+ const uuid = await UserInfo.getBootpayUUID();
57
+ const bootpaySK = await UserInfo.getBootpaySK();
58
+ const lastTime = await UserInfo.getBootpayLastTime();
59
+ let current = Date.now();
60
+ if (bootpaySK == '')
61
+ await UserInfo.newBootpaySK(uuid, current);
62
+ const isExpired = current - lastTime > 30 * 60 * 1000;
63
+ if (isExpired)
64
+ await UserInfo.newBootpaySK(uuid, current);
65
+ await UserInfo.setBootpayLastTime(current);
66
+ };
67
+ }
package/CHANGELOG.md DELETED
@@ -1,23 +0,0 @@
1
- ### 1.5.0
2
- - webview update, android manifest 외부앱 패키지명 update
3
-
4
- ### 1.4.4
5
- - 사용하지 않은 패키지 제거
6
-
7
- ### 1.4.3
8
- - bootpay anlaytics api 추가
9
-
10
- ### 1.0.4
11
- - typescript declare 적용
12
-
13
- ### 1.0.3
14
- - close button 클릭시 onCancel, onClose 이벤트 호출
15
-
16
- ### 1.0.2
17
- - callJavascript 버그 수정
18
-
19
- ### 1.0.1
20
- - close.png 못찾는 버그 수정
21
-
22
- ### 1.0.0
23
- - first release