モバイルSDKをご利用の場合、3Dセキュアを導入するにあたってこちらのガイドで説明する手順が必要となります。
実装の前に
はじめに、トークン作成時に3Dセキュアを要求するには管理画面からトークン3Dセキュアオプションを有効にしてください。
モバイルSDKをご利用の場合、さらにリダイレクトURL設定にアプリ用のリダイレクトURLの設定を追加します。
モバイルSDKでは、カード会社が提供する3Dセキュア認証画面を表示するためにブラウザアプリを利用します。認証を実施したのち、モバイルアプリにて再度処理を継続するためにリダイレクトURLとその識別子を登録します。URLスキームはhttps以外にカスタムURLスキームを利用することもできます。httpsスキームのURLの場合はiOSではUniversal Link、AndroidではApp Linksの設定を行ってください。

管理画面での設定を終えたらご利用のSDKに応じて設定を追加してください。
payjp-iosの場合
XcodeでURLスキームを設定する
管理画面で追加したリダイレクトURLの設定に合わせて、アプリにもURLスキームの設定をします。
参考: Defining a Custom URL Scheme for Your App | Apple Developer Documentation
Xcodeを開き、プロジェクト設定でアプリのターゲットを選択し Info
タブに切り替えます。 URL Types
という項目の +
ボタンからスキーム設定を追加し、管理画面で登録したリダイレクトURLのスキームを設定します。
例として、リダイレクトURLが jp.pay.example://tds/finish
であれば以下のように jp.pay.example
を設定します。

リダイレクトURLを登録する
管理画面で指定したリダイレクトURLと識別子を登録します。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
PAYJPSDK.publicKey = YourPayjpPublicKey
PAYJPSDK.locale = Locale.current
PAYJPSDK.threeDSecureURLConfiguration =
ThreeDSecureURLConfiguration(redirectURL: URL(string: "jp.pay.example://tds/finish")!,
redirectURLKey: "mobileapp")
return true
}
カスタムURLスキームによってアプリが起動された際に、 ThreeDSecureProcessHandler
の completeThreeDSecureProcess(url:)
を呼び出すことで、認証フローを完了します。
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return ThreeDSecureProcessHandler.shared.completeThreeDSecureProcess(url: url)
}
カード所有者を3Dセキュアに誘導する
カードフォーム画面を利用している場合
CardFormViewController.createCardFormViewController()
を利用してカードフォーム画面を呼び出している場合は、SDKが自動的にハンドリングするため、カード所有者を3Dセキュアに誘導するために必要な追加の実装はありません。
それ以外の場合
createTokenによって得られるTokenの Token.card.threeDSecureStatus
が .unverified
の場合、3Dセキュアの認証を開始してください。
まず、 ThreeDSecureProcessHandler.startThreeDSecureProcess(viewController:delegate:token:)
の第3引数に取得した Token
を渡します。
これによって、SDKはブラウザを開きカード所有者を認証画面へと誘導します。認証が完了、失敗、またはキャンセルによって終了するまで、SDKによるトークン作成処理は中断状態となります。
self.cardFormView.createToken() { [weak self] result in
guard let self = self else { return }
switch result {
case .success(let token):
if tdsStatus = token.card.threeDSecureStatus, status == .unverified {
ThreeDSecureProcessHandler.shared.startThreeDSecureProcess(viewController: self,
delegate: self,
token: token)
} else {
// 取得したトークンを扱う
self.onSuccess(token)
}
case .failure(let error):
// エラー処理
}
}
}
認証が終了し、リダイレクトURLによって ThreeDSecureProcessHandler.completeThreeDSecureProcess(url:)
が呼び出されることで、SDKは認証フローの終了を検知します。 ThreeDSecureProcessHandlerDelegate
をアプリのViewControllerに適合し、 threeDSecureProcessHandlerDidFinish(_:status:)
で受け取る ThreeDSecureProcessStatus
に応じてトークン作成処理を完了させてください。
public func threeDSecureProcessHandlerDidFinish(_ handler: ThreeDSecureProcessHandler,
status: ThreeDSecureProcessStatus) {
switch status {
case .completed:
// 3DSの処理を完了する
completeTokenTds()
case .canceled:
// UI更新など
default:
break
}
}
ThreeDSecureProcessStatus
が .completed
の場合、先に取得した Token
を利用して認証済みの Token
を取得できます。 APIClient.finishTokenThreeDSecure(tokenId:completion:)
を利用して再取得を行なってください。
let completion: (Result<Token, APIError>) -> Void = { [weak self] result in
guard let self = self else { return }
switch result {
case .success(let token):
self.onSuccess(token)
case .failure(let error):
self.onFailure(error)
}
}
if let token = self.pendingToken {
APIClient.shared.finishTokenThreeDSecure(tokenId: token.identifer, completion: completion)
}
以上でトークン作成時に3Dセキュアを要求するiOSの実装は完了です。
payjp-androidの場合
リダイレクトURLを登録する
管理画面で指定したリダイレクトURLと識別子を登録します。
Payjp.init(PayjpConfiguration.Builder(YOUR_PUBLIC_KEY)
.setThreeDSecureRedirectName("mobileapp") // URLではなく識別子を登録します
.build())
AndroidManifest.xmlにIntentFilterを追加する
アプリの AndroidManifest.xml
に管理画面で指定したリダイレクトURLを追加します。アクティビティとして jp.pay.android.verifier.ui.PayjpThreeDSecureStepActivity
を追加し、IntentFilter
を設定します。
例としてリダイレクトURLが my-app://tds/complete
の場合、以下のように記述します。
<activity android:name="jp.pay.android.verifier.ui.PayjpThreeDSecureStepActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="my-app" android:host="tds" android:path="complete" />
</intent-filter>
</activity>
カード所有者を3Dセキュアに誘導する
カードフォーム画面を利用している場合
Payjp.cardForm().start()
を利用してカードフォーム画面を呼び出している場合は、SDKが自動的にハンドリングするため、カード所有者を3Dセキュアに誘導するために必要な追加の実装はありません。
それ以外の場合
createTokenによって得られる Token
の Token.card.threeDSecureStatus
が UNVERIFIED
のとき、3Dセキュアの認証を開始してください。
まず、 Token.retrieveId()
で得られる TokenId
を、 Payjp.verifier().startThreeDSecureFlow(TokenId, Activity)
の第1引数に渡します。
これによって、SDKはブラウザを開きカード所有者を認証画面へと誘導します。認証が完了、失敗、またはキャンセルによって終了するまで、SDKによるトークン作成処理は中断状態となります。
以下の例は PayjpCardFormFragment#createToken
を利用した場合です。
cardFormFragment.createToken().enqueue(object : Task.Callback<Token> {
override fun onSuccess(data: Token) {
if (data.card.threeDSecureStatus == ThreeDSecureStatus.UNVERIFIED) {
Payjp.verifier()
.startThreeDSecureFlow(data.retrieveId(), this@SampleActivity)
} else {
sendTokenToServer(token: data)
}
}
override fun onError(throwable: Throwable) {
updateUI(throwable)
}
})
認証が終了すると、Payjp.verifier().startThreeDSecureFlow(TokenId, Activity)
の第2引数に渡した呼び出し元のActivity(あるいはFragment)で onActivityResult
に結果を受け取ります。
Payjp.verifier().handleThreeDSecureResult(requestCode, callback)
を使って認証フローの結果を取り出し、コールバックで渡される PayjpThreeDSecureResult
に応じて処理を再開してください。 PayjpThreeDSecureResult#isSuccess()
がtrueの場合は認証フローが完了していることを表します。
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
Payjp.verifier().handleThreeDSecureResult(requestCode) { result ->
if (result.isSuccess()) {
this.onCompleteTds(result)
} else {
Toast.makeText(this, "3-D Secure canceled.", Toast.LENGTH_SHORT).show()
}
})
}
3Dセキュアの認証に成功した場合、Payjp.verifier().completeTokenThreeDSecure(result)
で、認証済みの Token
を取得します。
if (!result.isSuccess()) {
return
}
Payjp.token().completeTokenThreeDSecure(result)
.enqueue(object : Task.Callback<Token> {
override fun onSuccess(data: Token) {
Log.i("PAY.JP", "token => $data")
}
override fun onError(throwable: Throwable) {
Log.e("PAY.JP", "failure getting token", throwable)
}
})
以上でトークン作成時に3Dセキュアを要求するAndroidの実装は完了です。
payjp-react-native-pluginの場合
カードフォーム画面を利用する方法以外はサポートしていません。
各プラットフォームごとにリダイレクトの設定をする
iOSでは、payjp-ios同様、XcodeでURLスキームを設定します。 Androidでは、payjp-android同様、AndroidManifest.xmlにIntentFilterを追加します。
リダイレクトURLを登録する
管理画面で設定したリダイレクトURLと識別子を登録します。
PayjpCore#init
の引数となるオブジェクトに threeDSecureRedirect
というキーで下記のようにURLと識別子を指定してください。
PayjpCore.init({
publicKey: YOUR_PUBLIC_KEY,
threeDSecureRedirect: {
url: "jp.pay.example://tds/finish",
key: "mobileapp",
},
});
payjp-flutter-pluginの場合
カードフォーム画面を利用する方法以外はサポートしていません。
各プラットフォームごとにリダイレクトの設定をする
iOSでは、payjp-ios同様、XcodeでURLスキームを設定します。 Androidでは、payjp-android同様、AndroidManifest.xmlにIntentFilterを追加します。
リダイレクトURLを登録する
管理画面で設定したリダイレクトURLと識別子を登録します。
Payjp#init
の引数となるオブジェクトに threeDSecureRedirect
というキーで下記のようにURLと識別子を指定してください。
Future<void> _initPayjp() async {
await Payjp.init(
publicKey: YOUR_PUBLIC_KEY,
threeDSecureRedirect: PayjpThreeDSecureRedirect(
url: 'jp.pay.example://tds/finish', key: 'mobileapp'));
}