2025. 1. 25. 21:12ㆍiOS
웹뷰로 구현된 결제 페이지에서 카드 결제를 선택한 뒤, 카드 앱으로 이동 후 결제가 완료되었을 때 다시 앱으로 돌아와 결제 완료를 처리하려면, 딥 링크(Deep Link) 또는 Universal Link를 활용하는 방법을 주로 사용합니다. 이와 함께 웹뷰의 네비게이션 동작과 앱 간 호출 흐름을 관리해야 합니다.
구현 단계
1. 카드 결제 연동 흐름
- 사용자 → 앱의 웹뷰에서 결제 페이지에 접근.
- 사용자 → 카드 결제를 선택하면, 카드사의 앱이 실행됨.
- 사용자 → 카드 앱에서 결제 완료 후 앱의 딥 링크/유니버설 링크를 통해 다시 원래 앱으로 복귀.
- 앱 → 복귀 시 결제 결과를 확인하여 처리.
2. 카드사 앱 연동 방식
- 대부분의 카드사 결제 앱은 딥 링크(URL 스키마)를 지원하며, 결제 완료 후 앱으로 돌아올 수 있도록 설정할 수 있습니다.
- 결제 요청 시 returnUrl 또는 callbackUrl을 설정하여 앱으로 복귀 경로를 지정합니다.
예시
3. 딥 링크 설정 방법
(1) Info.plist 설정
앱에서 특정 URL 스키마를 처리하려면, Info.plist 파일에 아래와 같이 설정합니다:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string> <!-- 딥 링크 스키마 -->
</array>
<key>CFBundleURLName</key>
<string>com.mycompany.myapp</string>
</dict>
</array>
(2) AppDelegate에서 URL 처리
앱으로 돌아왔을 때 AppDelegate 또는 SceneDelegate에서 URL을 처리하여 결제 결과를 확인합니다.
AppDelegate Example:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if url.scheme == "myapp", url.host == "payment-complete" {
// URL에서 필요한 정보 추출
let queryItems = URLComponents(string: url.absoluteString)?.queryItems
let paymentStatus = queryItems?.first(where: { $0.name == "status" })?.value
if paymentStatus == "success" {
print("결제 성공!") // 결제 성공 처리 (예: 화면 갱신, 서버 API 호출 등)
} else {
print("결제 실패") // 결제 실패 처리
}
return true
}
return false
}
(3) SceneDelegate에서 URL 처리 (iOS 13+)
iOS 13 이상에서는 SceneDelegate의 scene(_:openURLContexts:)를 사용합니다:
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else { return }
if url.scheme == "myapp", url.host == "payment-complete" {
// URL에서 정보 추출 및 처리
let queryItems = URLComponents(string: url.absoluteString)?.queryItems
let paymentStatus = queryItems?.first(where: { $0.name == "status" })?.value
if paymentStatus == "success" {
print("결제 성공!") // 결제 성공 처리
} else {
print("결제 실패") // 결제 실패 처리
}
}
}
4. 웹뷰에서 결제 처리
WKNavigationDelegate로 URL 처리
카드 결제 후, 카드사에서 앱으로 복귀하기 전에 결제 완료를 위한 특정 URL을 처리해야 할 수 있습니다. 이를 위해 WKNavigationDelegate를 활용합니다.
class PaymentViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let config = WKWebViewConfiguration()
webView = WKWebView(frame: self.view.frame, configuration: config)
webView.navigationDelegate = self
self.view.addSubview(webView) // 결제 페이지 로드
if let url = URL(string: "https://payment.gateway.com/initiate") {
webView.load(URLRequest(url: url))
}
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
let url = navigationAction.request.url
if url?.scheme == "myapp" {
// 앱으로 돌아가기 전 URL 처리
if url?.host == "payment-complete" {
print("결제 완료 URL 감지")
let queryItems = URLComponents(url: url!, resolvingAgainstBaseURL: false)?.queryItems
let status = queryItems?.first(where: { $0.name == "status" })?.value
if status == "success" {
print("결제 성공!") // 성공 처리 로직
} else {
print("결제 실패") // 실패 처리 로직
}
}
decisionHandler(.cancel) // URL 열기를 중단하고 앱 내에서 처리
return
}
decisionHandler(.allow) // 기타 URL은 정상 처리
}
}
5. 서버와의 결제 상태 확인 (옵션)
앱이 결제 완료 상태를 신뢰할 수 있도록 서버와 상태를 확인하는 과정을 추가합니다.
- 카드 앱이 returnUrl로 결제 결과를 전달하면, 앱에서 해당 결과를 서버로 보내고 확인 후 UI를 업데이트합니다.
6. Universal Link 사용
딥 링크 대신 Universal Link를 사용하면 HTTP/HTTPS 기반 URL로 앱을 호출할 수 있습니다. 이 경우:
- Associated Domains를 설정 (apple-app-site-association 파일 필요).
- 앱 내에서 application(_:continue:restorationHandler:) 또는 scene(_:continue:)를 사용.
결론
위 과정을 통해 웹뷰 기반 결제와 카드 앱 연동을 구현할 수 있습니다. 딥 링크와 Universal Link 설정, 그리고 WKNavigationDelegate와 AppDelegate/SceneDelegate의 URL 처리를 적절히 활용하세요.
'iOS' 카테고리의 다른 글
[iOS] State Restoration(상태 복원) shouldSaveApplicationState (1) | 2025.01.26 |
---|---|
[iOS] WebView 백그라운드 시 앱 새로고침 이슈 (1) | 2025.01.25 |
[iOS] WKWebView (1) | 2025.01.25 |
iOS의 동시성(Concurrency) (2) | 2025.01.24 |
모바일 개발 시 협업의 중요성 (1) | 2025.01.21 |