モバイル SDK を利用して 3Dセキュアを導入する
モバイル SDK でトークン作成時に 3Dセキュアを導入する
ここでは、モバイル SDK を利用してトークン作成時に 3Dセキュアを導入する方法について説明します。
3Dセキュアの概要については、下記ドキュメントをご覧ください。
リダイレクト URL を設定する(各 SDK 共通)
まずはじめに、管理画面 > API設定 > 3Dセキュアからリダイレクト URL を設定します。
モバイル SDK では、カード会社が提供する 3Dセキュア認証画面を表示するためにブラウザアプリを利用します。 認証を実施した後、モバイルアプリで再度処理を継続するためにリダイレクト URL とその識別子を登録します(ここで設定した URL と識別子は実装に利用します)。
URL スキームは HTTPS 以外にカスタム URL スキームを利用できます。 HTTPS スキームの URL の場合、iOS では Universal Link、Android では App Links の設定を行ってください。
3Dセキュア開始方法
各 SDK でカードフォーム開始時にオプションを指定することで、トークン作成時に 3Dセキュアを開始できます。
また、管理画面 > API設定 > 3Dセキュアよりトークン 3Dセキュアの実施モードを指定することで、パラメーターを指定することなく全てのトークン作成に 3Dセキュアを必須にすることが可能です。
管理画面でトークン 3Dセキュアを実施するモードが有効になっている場合、たとえ SDK でカードフォーム開始時に 3Dセキュアを実施しないオプションを指定しても、3Dセキュアは実施されます。
| 管理画面でのモード | SDK でのオプション( useThreeDSecure ) | トークン作成時の3Dセキュア |
|---|---|---|
| 有効 | true | 実施 |
| 有効 | false | 実施 |
| 無効 | true | 実施 |
| 無効 | false | 実施されない |
ここから先の設定方法は、各 SDK によって異なります。利用する 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セキュアの実施を指定するのみです。
let cardFormViewController = CardFormViewController.createCardFormViewController(
delegate: self,
useThreeDSecure: true
)それ以外の場合
3Dセキュアの認証を実施するには、 createToken の引数 useThreeDSecure に true を指定します。
createToken によって取得した Token の Token.card.threeDSecureStatus が .unverified の場合、3Dセキュアの認証を開始してください。
まず、 ThreeDSecureProcessHandler.startThreeDSecureProcess(viewController:delegate:token:) の第3引数に取得した Token を渡します。
これにより、SDK はブラウザを開きカード所有者を認証画面へと誘導します。認証が完了、失敗、またはキャンセルによって終了するまで、SDK によるトークン作成処理は中断状態となります。
self.cardFormView.createToken(useThreeDSecure: true) { [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セキュアの実施を指定するのみです。
Payjp.cardForm().start(
activity = this,
face = PayjpCardForm.FACE_MULTI_LINE,
extraAttributes = arrayOf(ExtraAttribute.Email()),
useThreeDSecure = true,
)それ以外の場合
3Dセキュアの認証を実施するには、 createToken の引数に useThreeDSecure = true を指定します。
createToken によって取得した Token の Token.card.threeDSecureStatus が UNVERIFIED のとき、3Dセキュアの認証を開始してください。
まず、 Token.retrieveId() で得られる TokenId を、 Payjp.verifier().startThreeDSecureFlow(TokenId, Activity) の第1引数に渡します。
これにより、SDK はブラウザを開きカード所有者を認証画面へと誘導します。認証が完了、失敗、またはキャンセルによって終了するまで、SDK によるトークン作成処理は中断状態となります。
以下の例は PayjpCardFormFragment#createToken を利用した場合です。
cardFormFragment.createToken(useThreeDSecure = true).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",
},
});カードフォーム開始時に 3Dセキュアの実施を指定する
PayjpCardForm.startCardForm() の引数となる CardFormOption オブジェクトに useThreeDSecure というキーで true を指定してください。
PayjpCardForm.startCardForm({
useThreeDSecure: true
});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'));
}カードフォーム開始時に 3Dセキュアの実施を指定する
Payjp#startCardForm の引数 useThreeDSecure に true を指定してください。
await Payjp.startCardForm(
onCardFormCanceledCallback: _onCardFormCanceled,
onCardFormCompletedCallback: _onCardFormCompleted,
onCardFormProducedTokenCallback: _onCardFormProducedToken,
useThreeDSecure: true);まとめ
モバイル SDK を利用して 3Dセキュアを導入する手順は以下のとおりです。
- 管理画面でリダイレクト URL と識別子を設定する
- 各 SDK ごとに必要な設定を行う
- iOS の場合は Xcode で URL スキームを設定
- Android の場合は AndroidManifest.xml に IntentFilter を追加
- SDK の初期化時にリダイレクト URL と識別子を登録する
- カードフォーム画面開始時(またはトークン作成時)に、3Dセキュアの実施を指定する(管理画面の設定によっては不要)
- トークン作成後、3Dセキュアが必要な場合は SDK の機能を使ってカード所有者を認証フローに誘導する
- 認証後のリダイレクトを受け取り、SDK の機能で認証済みのトークンを取得する
これらの手順に沿って実装を行うことで、モバイルアプリでも安全なクレジットカード決済を提供できます。 セキュリティ強化のため、ぜひ 3Dセキュアの導入をご検討ください。