Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

카카오페이 결제 이후 써드파티에서 본 앱으로 복귀하지 못하고 카카오톡으로 가지네요 #170

Open
nogal2 opened this issue Jun 10, 2022 · 8 comments

Comments

@nogal2
Copy link

nogal2 commented Jun 10, 2022

정확하게는 카카오페이 결제 이후 써드파티에서 '완료'를 누르면 본 앱으로 복귀하지 못하고 카카오톡으로 가지네요
테스트용입니다.
카카오톡으로 가지고 난 후 본 앱을 다시 실행하면 navigate한 곳으로 이동해 있습니다. PaymentResult.tsx 화면으로여.
써드파티에서 다시 본앱으로는 안되는걸까요?

package.json -> dependencies
"@react-native-picker/picker": "^2.4.1",
"@react-navigation/bottom-tabs": "^6.3.1",
"@react-navigation/native": "^6.0.10",
"@react-navigation/native-stack": "^6.6.2",
"axios": "^0.24.0",
"iamport-react-native": "^2.0.1",
"qs": "^6.10.3",
"react": "17.0.2",
"react-native": "0.66.4",
"react-native-calendars": "^1.1284.0",
"react-native-safe-area-context": "^4.2.5",
"react-native-screens": "^3.13.1",
"react-native-webview": "^11.17.2"

코드 공유합니다. 여기에 있는 example과 거의 똑같이 했습니다.

import { NavigationProp, RouteProp, useNavigation, useRoute } from "@react-navigation/native";
import IMP from "iamport-react-native";
import React from "react";
import { SafeAreaView, } from "react-native";
import Loading from "../pages/Loading";
import { StackParamList } from "../pages/PaymentsNavigator";
import { getUserCode } from "../utils";

const Payments = () => {

const navigation = useNavigation<NavigationProp<StackParamList>>();
const route = useRoute<RouteProp<StackParamList>>();
const params = route.params?.params;
const tierCode = route.params?.tierCode;
const userCode = getUserCode(params!.pg, tierCode);

return (
    <SafeAreaView style={{flex:1, justifyContent:'center'}}>
        <IMP.Payment 
            userCode={userCode}
            tierCode={tierCode}
            loading={<Loading />}
            data={params!}
            callback={(response) => navigation.navigate('PaymentsResult', response)}
        />
    </SafeAreaView>
)

}

export default Payments;

import { NavigationProp, useNavigation } from "@react-navigation/native";
import { IMPConst } from "iamport-react-native";
import React, { useState } from "react";
import { KeyboardAvoidingView, Platform, Pressable, SafeAreaView, ScrollView, StyleSheet, Switch, Text, TextInput, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { PaymentsParams, StackParamList } from "../pages/PaymentsNavigator";
import { getMethods, getQuotas, PGS, TIER_CODES } from "../utils";
import CustomPicker from "./CustomPicker";

const PaymentsTest = () => {
const navigation = useNavigation<NavigationProp>();
const [pg, setPg] = useState('html5_inicis');
const [tierCode, setTierCode] = useState(undefined);
const [method, setMethod] = useState('card');
const [cardQuota, setCardQuota] = useState(0);
const [merchantUid, setMerchantUid] = useState(mid_${new Date().getTime()});
const [name, setName] = useState('아임포트 결제데이터분석');
const [amount, setAmount] = useState('39000');
const [buyerName, setBuyerName] = useState('홍길동');
const [buyerTel, setBuyerTel] = useState('01012341234');
const [buyerEmail, setBuyerEmail] = useState('[email protected]');
const [vbankDue, setVbankDue] = useState('');
const [bizNum, setBizNum] = useState('');
const [escrow, setEscrow] = useState(false);
const [digital, setDigital] = useState(false);
console.log(method)
const insets = useSafeAreaInsets();

return (
    <SafeAreaView style={[styles.container, {flex:1, paddingTop: -insets.top}]}>
        <KeyboardAvoidingView
            contentContainerStyle={{flex:1}}
            behavior={Platform.OS === 'ios' ? 'padding' : undefined}
            keyboardVerticalOffset={Platform.OS === 'ios' ? 95 : undefined}
        >
            <ScrollView style={{backgroundColor:'#fff'}}>
                <View style={[styles.form]}>
                    <View>
                        <Text style={[styles.formText]}>PG사</Text>
                    </View>
                    <CustomPicker 
                        data={PGS}
                        selectValue={pg}
                        onValueChange={(value) => {
                            setPg(value);
                            const methods = getMethods(value);
                            setMethod(methods[0].value);
                        }}
                    />
                    <View>
                        <Text style={[styles.formText]}>티어코드</Text>
                    </View>
                    <CustomPicker 
                        data={TIER_CODES}
                        selectValue={tierCode}
                        onValueChange={(value) => setTierCode(value)}
                    />
                    <View>
                        <Text style={[styles.formText]}>결제수단</Text>
                    </View>
                    <CustomPicker
                        data={getMethods(pg)}
                        selectValue={method}
                        onValueChange={(value) => setMethod(value)}
                    />
                    {method === 'card' && (
                        <>
                        <View>
                            <Text style={[styles.formText]}>할부개월수</Text>
                        </View>
                        <CustomPicker 
                            data={getQuotas(pg)}
                            selectValue={cardQuota}
                            onValueChange={(value) => setCardQuota(parseInt(value, 10))}
                        />
                        </>
                    )}
                    {method === 'vbank' && (
                         <>
                         <View>
                            <Text style={[styles.formText]}>입금기한</Text>
                         </View>
                         <TextInput 
                            style={[styles.formTextInput, {flex:1}]}
                            value={vbankDue}
                            onChangeText={(value) => setVbankDue(value)}
                         />
                         </>
                    )}
                    {method === 'vbank' && pg === 'danal_tpay' && (
                        <>
                        <View>
                            <Text style={[styles.formText]}>사업자번호</Text>
                        </View>
                        <TextInput 
                            style={[styles.formTextInput, {flex:1}]}
                            value={bizNum}
                            onChangeText={(value) => setBizNum(value)}
                        />
                        </>
                    )}
                    {method === 'phone' && (
                        <>
                        <View>
                            <Text style={[styles.formText]}>실물컨텐츠</Text>
                        </View>
                        <Switch 
                            style={[styles.formSwitch]}
                            value={digital}
                            onValueChange={(value) => setDigital(value)}
                        />
                        </>
                    )}
                    <View>
                        <Text style={[styles.formText]}>에스크로</Text>
                    </View>
                    <Switch 
                        style={[styles.formSwitch]}
                        value={escrow}
                        onValueChange={(value) => setEscrow(value)}
                    />
                    <View>
                        <Text style={[styles.formText]}>주문명</Text>
                    </View>
                    <TextInput 
                        style={[styles.formTextInput, {flex:1}]}
                        value={name}
                        onChangeText={(value) => setName(value)}
                    />
                    <View>
                        <Text style={[styles.formText]}>결제금액</Text>
                    </View>
                    <TextInput
                        style={[styles.formTextInput, {flex:1}]}
                        value={amount}
                        keyboardType="number-pad"
                        returnKeyType={'done'}
                        onChangeText={(value) => setAmount(value)}
                    />
                    <View>
                        <Text style={[styles.formText]}>주문번호</Text>
                    </View>
                    <TextInput 
                        style={[styles.formTextInput, {flex:1}]}
                        value={merchantUid}
                        onChangeText={(value) => setMerchantUid(value)}
                    />
                    <View>
                        <Text style={[styles.formText]}>이름</Text>
                    </View>
                    <TextInput 
                        style={[styles.formTextInput, {flex:1}]}
                        value={buyerName}
                        onChangeText={(value) => setBuyerName(value)}
                    />
                    <View>
                        <Text style={[styles.formText]}>전화번호</Text>
                    </View>
                    <TextInput 
                        style={[styles.formTextInput, {flex:1}]}
                        value={buyerTel}
                        keyboardType="number-pad"
                        returnKeyType={'done'}
                        onChangeText={(value) => setBuyerTel(value)}
                    />
                    <View>
                        <Text style={[styles.formText]}>이메일</Text>
                    </View>
                    <TextInput 
                        style={[styles.formTextInput, {flex:1}]}
                        value={buyerEmail}
                        onChangeText={(value) => setBuyerEmail(value)}
                    />
                    <Pressable
                        style={[styles.pressable]}
                        onPress={() => {
                            const data: PaymentsParams = {
                                params: {
                                    pg,
                                    pay_method: method,
                                    currency: undefined,
                                    notice_url: undefined,
                                    display: undefined,
                                    merchant_uid: merchantUid,
                                    name,
                                    amount,
                                    app_scheme: 'exampleforrn',
                                    tax_free: undefined,
                                    buyer_name: buyerName,
                                    buyer_tel: buyerTel,
                                    buyer_email: buyerEmail,
                                    buyer_addr: undefined,
                                    buyer_postcode: undefined,
                                    custom_data: undefined,
                                    vbank_due: undefined,
                                    digital: undefined,
                                    language: undefined,
                                    biz_num: undefined,
                                    customer_uid: undefined,
                                    naverPopupMode: undefined,
                                    naverUseCfm: undefined,
                                    m_redirect_url: IMPConst.M_REDIRECT_URL,
                                    niceMobileV2: true,
                                    escrow,
                                },
                                tierCode,
                            };

                            // 신용카드의 경우, 할부기한 추가
                            if (method === 'card' && cardQuota !== 0) {
                                data.params.display = {
                                    card_quota: cardQuota === 1 ? [] : [cardQuota]
                                };
                            }

                            // 가상계좌의 경우, 입금기한 추가
                            if (method === 'vbank' && vbankDue) {
                                data.params.vbank_due = vbankDue;
                            }

                            // 다날 && 가상계좌의 경우, 사업자 등록번호 10자리 추가
                            if (method === 'vbank' && pg === 'danal_tpay') {
                                data.params.biz_num = bizNum;
                            }

                            // 휴대폰 소액결제의 경우, 실물 컨텐츠 여부 추가
                            if (method === 'phone') {
                                data.params.digital = digital;
                            }

                            // 정기결제의 경우, customer_uid 추가
                            if (method === 'phone') {
                                data.params.digital = digital;
                            }

                            if (pg === 'naverpay') {
                                const today = new Date();
                                const oneMonthLater = new Date(
                                    today.setMonth(today.getMonth() + 1)
                                );
                                const dd = String(oneMonthLater.getDate()).padStart(2, '0');
                                const mm = String(oneMonthLater.getMonth() + 1).padStart(2, '0');
                                const yyyy = oneMonthLater.getFullYear();

                                data.params.naverPopupMode = false;
                                data.params.naverUseCfm = `${yyyy}${mm}${dd}`;
                                data.params.naverProducts = [
                                    {
                                        categoryType: 'BOOK',
                                        categoryId: 'GENERAL',
                                        uid: '107922211',
                                        name: '한국사',
                                        payReferrer: 'NAVER_BOOK',
                                        count: 10,
                                    },
                                ];
                            }
                            navigation.navigate('Payments', data);
                        }}
                    >
                        <Text style={{fontWeight:'bold', color:'#fff'}}>결제하기</Text>

                    </Pressable>
                </View>
            </ScrollView>

        </KeyboardAvoidingView>
    </SafeAreaView>
);

};

export default PaymentsTest;

@nogal2
Copy link
Author

nogal2 commented Jun 10, 2022

방금 다시 하니 또 되네요. 이게 됐다가 안됐다가 하는데, 확인 부탁드립니다 :)

@anymate98
Copy link
Contributor

안녕하세요. 혹시 문제가 발생하는 곳이 ios인가요?

@nogal2
Copy link
Author

nogal2 commented Jun 10, 2022

아 ios는 제 폰이 아니라 확인까지는 못했고, 안드로이드 카카오페이 한정해서 그렇습니다.

@anymate98
Copy link
Contributor

네 이쪽에서 확인해보고 결과 알려드리겠습니다.

@anymate98
Copy link
Contributor

혹시 "써드파티"의 뜻이 정확이 무엇인지 알 수 있을까요?
또 문제가 되는 과정이 본앱 -> 써드파티 -> 카카오톡 ->(수동)-> 본앱 이 맞나요?

@nogal2
Copy link
Author

nogal2 commented Jun 10, 2022

본앱에서 카카오 결제로 가고 거기서 결제 완료 화면이 한번더 화면이 옮겨져서 써드파티라고 명명하였고,
본앱 -> 카카오 페이 결제 "다음" 버튼 누르는 화면 => "결제하기" 버튼 화면(금액과 pay머니가 나오는) => '확인'버튼 누르는 화면 에서 '확인'을 누르면 본 앱으로 돌아가져야 하는데, 카카오톡 화면으로 가진다는 뜻이었습니다. 이게 PaymentResult 화면으로 가질 때도 있고, 카카오톡 화면으로 가질 때도 있어서, 원인이 뭔지 모르겠어서요.

@nogal2
Copy link
Author

nogal2 commented Jun 10, 2022

의도적으로 카카오톡 앱으로 간 적은 없고, 순서대로 사진 올려드릴게요.
KakaoTalk_Photo_2022-06-10-18-44-22 001
'결제 테스트 클릭'

KakaoTalk_Photo_2022-06-10-18-44-22 002
'결제하기' 클릭(카카오페이로 선택했습니다)

KakaoTalk_Photo_2022-06-10-18-44-22 003
'다음' 클릭

KakaoTalk_Photo_2022-06-10-18-44-22 004
'테스트 결제하기' 클릭

KakaoTalk_Photo_2022-06-10-18-44-22 005
'확인' 클릭

KakaoTalk_Photo_2022-06-10-18-44-22 006
'확인'클릭

하면 카카오톡 으로 가지네요.

방금 캡처하면서 될 때와 안 될 때의 차이를 알아냈는데
스마트폰에서 카카오톡을 실행시킨뒤, 본 앱을 실행해서 카카오페이 후 위와 같은 순서로 진행하면 본 앱으로 가는게 아니라 카카오톡으로 가지고
카카오톡이 꺼져있을시(스마트폰 내에서 강제종료)에 할 때는 본 앱으로 돌아옵니다.

@anymate98
Copy link
Contributor

스크린샷 감사합니다.
이미지의 비율로 보아 아마 폴드를 사용하시는 것 같은데 저희측에서도 폴드에서만 이 문제가 확인되었기 때문에 폴드 특유의 현상이라고 보여집니다.
다른 안드로이드 폰에서 시도해보시고 재현이 되는지 확인 부탁드리겠습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants