Skip to content

Commit 92ba517

Browse files
authored
chore: 토스 페이먼츠 세팅 (#67)
* chore: 토스 페이먼츠 세팅 * chore: pod install * fix: remove unuse code
1 parent 8566648 commit 92ba517

File tree

7 files changed

+221
-22
lines changed

7 files changed

+221
-22
lines changed

android/app/src/main/AndroidManifest.xml

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
android:roundIcon="@mipmap/ic_launcher_round"
1010
android:allowBackup="false"
1111
android:theme="@style/AppTheme"
12-
android:supportsRtl="true">
12+
android:supportsRtl="true"
13+
android:usesCleartextTraffic="true">
1314
<activity
1415
android:name=".MainActivity"
1516
android:label="@string/app_name"

ios/Podfile.lock

+56
Original file line numberDiff line numberDiff line change
@@ -1259,6 +1259,8 @@ PODS:
12591259
- react-native-config/App (= 1.5.3)
12601260
- react-native-config/App (1.5.3):
12611261
- React-Core
1262+
- react-native-date-picker (5.0.7):
1263+
- React-Core
12621264
- react-native-encrypted-storage (4.0.3):
12631265
- React-Core
12641266
- react-native-safe-area-context (4.11.0):
@@ -1610,6 +1612,48 @@ PODS:
16101612
- ReactCommon/turbomodule/core
16111613
- Yoga
16121614
- SocketRocket (0.7.0)
1615+
- tosspayments-react-native-webview (1.0.0):
1616+
- DoubleConversion
1617+
- glog
1618+
- hermes-engine
1619+
- RCT-Folly (= 2024.01.01.00)
1620+
- RCTRequired
1621+
- RCTTypeSafety
1622+
- React-Core
1623+
- React-debug
1624+
- React-Fabric
1625+
- React-featureflags
1626+
- React-graphics
1627+
- React-ImageManager
1628+
- React-NativeModulesApple
1629+
- React-RCTFabric
1630+
- React-rendererdebug
1631+
- React-utils
1632+
- ReactCodegen
1633+
- ReactCommon/turbomodule/bridging
1634+
- ReactCommon/turbomodule/core
1635+
- Yoga
1636+
- widget-sdk-react-native (1.3.5):
1637+
- DoubleConversion
1638+
- glog
1639+
- hermes-engine
1640+
- RCT-Folly (= 2024.01.01.00)
1641+
- RCTRequired
1642+
- RCTTypeSafety
1643+
- React-Core
1644+
- React-debug
1645+
- React-Fabric
1646+
- React-featureflags
1647+
- React-graphics
1648+
- React-ImageManager
1649+
- React-NativeModulesApple
1650+
- React-RCTFabric
1651+
- React-rendererdebug
1652+
- React-utils
1653+
- ReactCodegen
1654+
- ReactCommon/turbomodule/bridging
1655+
- ReactCommon/turbomodule/core
1656+
- Yoga
16131657
- Yoga (0.0.0)
16141658

16151659
DEPENDENCIES:
@@ -1652,6 +1696,7 @@ DEPENDENCIES:
16521696
- React-Mapbuffer (from `../node_modules/react-native/ReactCommon`)
16531697
- React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`)
16541698
- react-native-config (from `../node_modules/react-native-config`)
1699+
- react-native-date-picker (from `../node_modules/react-native-date-picker`)
16551700
- react-native-encrypted-storage (from `../node_modules/react-native-encrypted-storage`)
16561701
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
16571702
- React-nativeconfig (from `../node_modules/react-native/ReactCommon`)
@@ -1684,6 +1729,8 @@ DEPENDENCIES:
16841729
- "RNNaverLogin (from `../node_modules/@react-native-seoul/naver-login`)"
16851730
- RNScreens (from `../node_modules/react-native-screens`)
16861731
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
1732+
- tosspayments-react-native-webview (from `../node_modules/tosspayments-react-native-webview`)
1733+
- "widget-sdk-react-native (from `../node_modules/@tosspayments/widget-sdk-react-native`)"
16871734
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
16881735

16891736
SPEC REPOS:
@@ -1771,6 +1818,8 @@ EXTERNAL SOURCES:
17711818
:path: "../node_modules/react-native/ReactCommon/react/nativemodule/microtasks"
17721819
react-native-config:
17731820
:path: "../node_modules/react-native-config"
1821+
react-native-date-picker:
1822+
:path: "../node_modules/react-native-date-picker"
17741823
react-native-encrypted-storage:
17751824
:path: "../node_modules/react-native-encrypted-storage"
17761825
react-native-safe-area-context:
@@ -1835,6 +1884,10 @@ EXTERNAL SOURCES:
18351884
:path: "../node_modules/react-native-screens"
18361885
RNVectorIcons:
18371886
:path: "../node_modules/react-native-vector-icons"
1887+
tosspayments-react-native-webview:
1888+
:path: "../node_modules/tosspayments-react-native-webview"
1889+
widget-sdk-react-native:
1890+
:path: "../node_modules/@tosspayments/widget-sdk-react-native"
18381891
Yoga:
18391892
:path: "../node_modules/react-native/ReactCommon/yoga"
18401893

@@ -1881,6 +1934,7 @@ SPEC CHECKSUMS:
18811934
React-Mapbuffer: 1c08607305558666fd16678b85ef135e455d5c96
18821935
React-microtasksnativemodule: 87b8de96f937faefece8afd2cb3a518321b2ef99
18831936
react-native-config: 8f7283449bbb048902f4e764affbbf24504454af
1937+
react-native-date-picker: 06a4d96ab525a163c7a90bccd68833d136b0bb13
18841938
react-native-encrypted-storage: db300a3f2f0aba1e818417c1c0a6be549038deb7
18851939
react-native-safe-area-context: 851c62c48dce80ccaa5637b6aa5991a1bc36eca9
18861940
React-nativeconfig: 57781b79e11d5af7573e6f77cbf1143b71802a6d
@@ -1914,6 +1968,8 @@ SPEC CHECKSUMS:
19141968
RNScreens: 19719a9c326e925498ac3b2d35c4e50fe87afc06
19151969
RNVectorIcons: 6382277afab3c54658e9d555ee0faa7a37827136
19161970
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
1971+
tosspayments-react-native-webview: 34b2e7891a242dc44bed02f31b02ef2839c9a81b
1972+
widget-sdk-react-native: 2d163a01edeaa598337a5559c06dda6fef894de4
19171973
Yoga: a1d7895431387402a674fd0d1c04ec85e87909b8
19181974

19191975
PODFILE CHECKSUM: 06c40fb6714089135ec9e5328c02abea7ae4e3cd

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"@react-navigation/bottom-tabs": "^6.6.1",
2121
"@react-navigation/native": "^6.1.18",
2222
"@react-navigation/stack": "^6.4.1",
23+
"@tosspayments/widget-sdk-react-native": "^1.3.5",
2324
"@types/react-native-vector-icons": "^6.4.18",
2425
"axios": "^1.7.4",
2526
"dayjs": "^1.11.13",
@@ -32,7 +33,8 @@
3233
"react-native-paper": "^5.12.5",
3334
"react-native-safe-area-context": "^4.10.9",
3435
"react-native-screens": "^3.34.0",
35-
"react-native-vector-icons": "^10.1.0"
36+
"react-native-vector-icons": "^10.1.0",
37+
"tosspayments-react-native-webview": "^1.0.0"
3638
},
3739
"devDependencies": {
3840
"@babel/core": "^7.20.0",

src/context/TossPaymentProvider.tsx

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from 'react';
2+
import {PaymentWidgetProvider} from '@tosspayments/widget-sdk-react-native';
3+
4+
// TODO: Replace the clientKey and customerKey with your own keys
5+
const TossPaymentProvider = ({children}: {children: React.ReactNode}) => {
6+
return (
7+
<PaymentWidgetProvider
8+
clientKey={`test_gck_docs_Ovk5rk1EwkEbP0W43n07xlzm`}
9+
customerKey={`wGidPqu8iPkhWTQaqm_Ad`}>
10+
{children}
11+
</PaymentWidgetProvider>
12+
);
13+
};
14+
15+
export default TossPaymentProvider;

src/context/index.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ import React from 'react';
22
import NavigationProvider from './NavigationProvider';
33
import ReactNativePaperProvider from './ReactNativePaperProvider';
44
import EmotionProvider from './EmotionProvider';
5+
import TossPaymentProvider from './TossPaymentProvider';
56

67
const RootProvider = ({children}: {children: React.ReactNode}) => {
78
return (
89
<NavigationProvider>
910
<EmotionProvider>
10-
<ReactNativePaperProvider>{children}</ReactNativePaperProvider>
11+
<ReactNativePaperProvider>
12+
<TossPaymentProvider>{children}</TossPaymentProvider>
13+
</ReactNativePaperProvider>
1114
</EmotionProvider>
1215
</NavigationProvider>
1316
);

src/screens/PaymentScreen/PaymentPage.tsx

+74-9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
import React, {useMemo} from 'react';
2-
import {Text} from 'react-native-paper';
1+
import React, {useMemo, useState} from 'react';
2+
import {Alert} from 'react-native';
33

44
import {useNavigation} from '@react-navigation/native';
55
import {StackNavigationProp} from '@react-navigation/stack';
66

7+
import {
8+
AgreementWidget,
9+
AgreementWidgetControl,
10+
PaymentMethodWidget,
11+
usePaymentWidget,
12+
} from '@tosspayments/widget-sdk-react-native';
13+
714
import {CartType} from '@/types/OrderType';
815
import {RootStackParamList} from '@/types/StackNavigationType';
916
import {BottomButton} from '@components/common';
@@ -28,23 +35,81 @@ const PaymentPage = ({cart}: Props) => {
2835
[cart.products],
2936
);
3037

38+
const paymentWidgetControl = usePaymentWidget();
39+
const [agreementWidgetControl, setAgreementWidgetControl] =
40+
useState<AgreementWidgetControl | null>(null);
41+
3142
return (
3243
<S.PaymentPage>
3344
<S.ScrollView>
3445
<DatePickerCard />
35-
<Text>{'// TODO: 결제수단 서버에서 받아와야 함'}</Text>
46+
<>
47+
<PaymentMethodWidget
48+
selector="payment-methods"
49+
onLoadEnd={() => {
50+
paymentWidgetControl
51+
.renderPaymentMethods(
52+
'payment-methods',
53+
{value: 50000},
54+
{
55+
variantKey: 'DEFAULT',
56+
},
57+
)
58+
.then(control => {
59+
console.log({control});
60+
});
61+
}}
62+
/>
63+
<AgreementWidget
64+
selector="agreement"
65+
onLoadEnd={() => {
66+
paymentWidgetControl
67+
.renderAgreement('agreement', {
68+
variantKey: 'DEFAULT',
69+
})
70+
.then(control => {
71+
setAgreementWidgetControl(control);
72+
});
73+
}}
74+
/>
75+
</>
3676
<PaymentSummary
3777
originalPrice={originalPrice}
3878
discountPrice={discountPrice}
3979
/>
4080
</S.ScrollView>
4181
<BottomButton
42-
onPress={() =>
43-
navigation.navigate('Detail', {
44-
screen: 'OrderDone',
45-
params: {orderId: 1},
46-
})
47-
}>
82+
onPress={async () => {
83+
if (paymentWidgetControl == null || agreementWidgetControl == null) {
84+
Alert.alert('주문 정보가 초기화되지 않았습니다.');
85+
return;
86+
}
87+
88+
const agreeement = await agreementWidgetControl.getAgreementStatus();
89+
if (agreeement.agreedRequiredTerms !== true) {
90+
Alert.alert('약관에 동의하지 않았습니다.');
91+
return;
92+
}
93+
94+
paymentWidgetControl
95+
.requestPayment?.({
96+
orderId: '1lB4sMvBNySuMmzDy5PPv',
97+
orderName: '토스 티셔츠 외 2건',
98+
})
99+
.then(result => {
100+
if (result?.success) {
101+
// 결제 성공 비즈니스 로직을 구현하세요.
102+
// result.success에 있는 값을 서버로 전달해서 결제 승인을 호출하세요.
103+
navigation.navigate('Detail', {
104+
screen: 'OrderDone',
105+
params: {orderId: 1},
106+
});
107+
} else if (result?.fail) {
108+
// 결제 실패 비즈니스 로직을 구현하세요.
109+
Alert.alert('결제 실패');
110+
}
111+
});
112+
}}>
48113
{`${discountPrice.toLocaleString()}원 결제하기`}
49114
</BottomButton>
50115
</S.PaymentPage>

0 commit comments

Comments
 (0)