アプリ内認証
アプリ内認証フロー
Apple Pay
Google & Samsung Pay
Google Pay Wallet 状態更新
最終更新
役に立ちましたか?
役に立ちましたか?
//digitalCardID: ウォレットアプリから渡される EXTRA_TEXT から解析されます。
fun activeDigitalCard(d1Task: D1Task, digitalCardID: String) {
//カードを有効化するために D1PushWallet.activateDigitalCard を呼び出します。
d1Task.d1PushWallet.activateDigitalCard(
digitalCardID,
object : D1Task.Callback<Void?> {
override fun onSuccess(data: Void?) {
Log.w(TAG, "カード有効化 - 完了")
//有効化結果をユーザーに表示します。
//ユーザーの確認後、ユーザーを Google Wallet にリダイレクトします。
}
override fun onError(exception: D1Exception) {
//有効化結果をユーザーに表示します。
}
}
)
}let digitalCardID = "" // PKPass から取得
d1Task.activateDigitalCard(withDigitalCardID: digitalCardID) { error in
if let error = error {
// エラーを処理
} else {
//後続のフローに進みます。たとえば、UI を更新します。
}
}func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else {
// エラーを処理 例: ログ出力
return false
}
guard let queryItems = components.queryItems else {
// エラーを処理 例: ログ出力
return false
}
// クエリアイテムを確認する例
let containsPassTypeIdentifier = queryItems.contains(where: { $0.name == "passTypeIdentifier" && $0.value == "paymentpass.com.apple" })
let indexSerialNumber = queryItems.firstIndex(where: { $0.name == "serialNumber" })
let containsAction = queryItems.contains(where: { $0.name == "action" })
let validated = containsPassTypeIdentifier && indexSerialNumber != nil && containsAction
guard validated, let indexSerialNumber = indexSerialNumber else {
// エラーを処理 例: エラー UI を表示
return false
}
guard let serialNumber = queryItems[indexSerialNumber].value else {
// エラーを処理 例: エラー UI を表示
return false
}
do {
guard let pkPass = try d1Task.digitalCardPass(forSerialNumber: serialNumber) else {
// エラーを処理 例: エラー UI を表示
return false
}
guard let deviceAccountIdentifier = pkPass.secureElementPass?.deviceAccountIdentifier,
let primaryAccountNumberSuffix = pkPass.secureElementPass?.primaryAccountNumberSuffix else {
// エラーを処理 例: エラー UI を表示
return false
}
// 確認 UI 用に primaryAccountNumberSuffix を表示
// カード有効化を続行
let digitalCardID = deviceAccountIdentifier
d1Task.activateDigitalCard(withDigitalCardID: digitalCardID) { error in
if let error = error {
// エラーを処理 例: エラー UI を表示
} else {
// 有効化結果をユーザーに表示します。
}
}
return true
} catch {
// エラーを処理 例: エラー UI を表示
return false
}
}/*
* イシュアのモバイルアプリ内 AppToAppActivity (CardActivationActivity)
* 追加ライブラリ: com.fasterxml.jackson.core:jackson-core & com.fasterxml.jackson.core:jackson-databind
* import android.util.Base64;
* import com.fasterxml.jackson.databind.JsonNode;
* import com.fasterxml.jackson.databind.ObjectMapper;
*/
fun activeDigitalCard_inAppAuthentication(d1Task: D1Task, activity: Activity) {
/*
* Intent を受信した後、アプリケーションは Activity.getCallingPackage() API を使用して
* リクエストが次のように Google Pay または Samsung Pay から来ていることを検証する必要があります:
*/
// 呼び出し元が Google Wallet(Google Play Services)または Samsung Pay かどうかを検証します
if ("com.google.android.gms".equals(getCallingPackage()) ||
"com.samsung.android.spay".equals(getCallingPackage())) {
// トークンの有効化を続行します。
} else {
// トークンの有効化を中止: エラーを処理します。
}
val data: String? = activity.getIntent().getStringExtra(Intent.EXTRA_TEXT)
if (data == null){
// トークンの有効化を中止: エラーを処理
}
try {
// base64 を解析し、文字列内の JSON オブジェクトとして有効化パラメータを取得します。
val decodedDataBytes = Base64.decode(data, Base64.DEFAULT)
val decodedData = String(decodedDataBytes, StandardCharsets.UTF_8)
// Jackson を使用して JSON 文字列を読み取ります。
val mapper = ObjectMapper()
val node = mapper.readTree(decodedData)
var digitalCardId: String = ""
var scheme = CardScheme.VISA.scheme
var panLast4: String = ""
var tokenRequestorId: String = ""
if (node["tokenReferenceID"] != null) { // VISA スキーム
// VISA の場合 -> tokenReferenceID : digitalCardId。
digitalCardId = node["tokenReferenceID"].asText() // VISA
panLast4 = node["panLast4"].asText() // VISA
// tokenRequestorId -> Google Pay の場合は "40010075001"、Samsung Pay の場合は "40010043095"。
// これは SCHEME が VISA の場合にのみ関連します。MASTERCARD の場合は空文字列を設定します。
tokenRequestorId = node["tokenRequestorID"].asText() // VISA
} else { // MASTERCARD
// MasterCard の場合 -> tokenUniqueReference : D1 -> digitalCardId。
digitalCardId = node["tokenUniqueReference"].asText() // MasterCard
panLast4 = node["accountPanSuffix"].asText() // MasterCard
scheme = CardScheme.MASTERCARD.scheme
}
// 注: アプリケーションは panLast4 をカード識別として表示する必要があります。
// デジタルカードを有効化する前にログインします。
// カードを有効化するために D1PushWallet.activateDigitalCard を呼び出します。
d1Task.d1PushWallet.activateDigitalCard(
digitalCardId,
object : D1Task.Callback<Void?> {
override fun onSuccess(data: Void?) {
Log.w(TAG, "カード有効化 - 完了");
// 有効化結果をユーザーに表示します。
// ユーザーの確認後、ユーザーを Google Wallet にリダイレクトします。
sendResultToWalletApp(activity, null)
}
override fun onError(exception: D1Exception) {
// 有効化結果をユーザーに表示します。
sendResultToWalletApp(activity, exception)
}
}
)
} catch (exception: IOException) {
// トークンの有効化を中止: エラーを処理します。
}
}
private fun sendResultToWalletApp(activity: Activity, exception: D1Exception?) {
val resultIntent = Intent()
// "approved"、または "failure"
resultIntent.putExtra("BANKING_APP_ACTIVATION_RESPONSE",if (exception == null) "approved" else "failure")
activity.setResult(Activity.RESULT_OK, resultIntent)
activity.finish()
}fun updateGooglePayWalletState(d1Task: D1Task) {
// コールバックの登録は、たとえば d1Task.configure() が成功した直後など、できるだけ早く行う必要があります。
d1Task.registerCardDataChangedListener {
// ここでカードステータス/情報を更新します。
}
// コールバックの登録解除は、エンドユーザーがアプリを終了するときに行う必要があります
d1Task.unRegisterCardDataChangedListener()
}