バックエンド実装

この章では、サンプルコードを使用して、加盟店アプリのバックエンドへの実装方法について説明します。

Note

サンプルコードに目を通し、実装してから、次に進んでください。

バックエンドには3DSリクエスターを実装する必要があります。次の図は、3DSリクエスターに含まれる主なファイルを示します。これらはサンプルコード/finalディレクトリの中にあります。必要に応じディレクトリ構想を確認してください。

AuthControllerは3DS認証用のリクエストを処理するコントローラークラスで、ステップ.2ステップ.3のように3DS-web-adapterからのリクエストを処理してActiveServerに転送します。

front-end files

処理 1: 認証の初期化

認証を初期化するためには、3DSリクエスターが以下のように動作する必要があります。

AuthControllerで、3DSリクエスターは、@PostMapping("/auth/init")を使用してinitAuthハンドラーメソッドを実行し認証の初期化リクエストを処理します。フロンドエンドがこのリクエストをどうやって送信しているかの説明は、ここを参照してください。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class AuthController {

  @PostMapping("/auth/init")
  public InitAuthResponseBRW initAuth(@RequestBody InitAuthRequestBRW request) {
    String initBrwUrl = THREE_DS_SERVER_URL + "/api/v1/auth/brw/init/pa";
    // 認証の初期化を/brw/init/{messageCategory} (ステップ. 3)にPOST要求する 
    RequestEntity<InitAuthRequestBRW> req =
        new RequestEntity<>(request, HttpMethod.POST, URI.create(initBrwUrl));

    try {
      ResponseEntity<InitAuthResponseBRW> resp =
          restTemplate.exchange(req, InitAuthResponseBRW.class);

      InitAuthResponseBRW initRespBody = resp.getBody();
      logger.info("initAuthResponseBRW {}", initRespBody);

      // set InitAuthResponseBRW for future use
      transactionInfo.setInitAuthResponseBRW(initRespBody);
      return initRespBody;

    } catch (HttpClientErrorException | HttpServerErrorException ex) {

      logger.error("initAuthReq failed, {}, {}", ex.getStatusCode(), ex.getResponseBodyAsString());

      throw ex;
    }
  }
}

initAuthハンドラーメソッドは、まずURL initBrwUrl = THREE_DS_SERVER_URL + ../brw/init/{messageCategory}を初期化します(行5)。リクエストは、このURLにPOST送信されます(ステップ.3)

Note

  • 文字列THREE_DS_SERVER_URLは、デフォルトの設定で与えられるURLです。THREE_DS_SERVER_URLは、Settings > 3D Secure 2の中にあるAUTH_API_URLです。詳細は、ここを参照してください。
  • {messageCategory}pa(決済認証)またはnpa(非決済認証)のいずれかであり、この例ではpaを使用しています。

次に、行11と12initAuthコントローラーはリクエストをPOST送信して応答を待ちます。リクエストと応答のデータ構造はそれぞれInitAuthRequestBRWInitAuthResponseBRWです。

  • InitAuthRequestBRW - /brw/init/{messageCategory}へのAPI呼び出しを行うのに必要なすべての情報を保持しています(ステップ.3)
  • InitAuthResponseBRW - /brw/init/{messageCategory}へのAPI呼び出しに対する応答に関する情報を保持しています(ステップ.4)

InitAuthRequestBRWInitAuthResponseBRWのデータ構造については、API Documentを参照してください。

Note

3DSリクエスターを実装する際には、次の2つの事項が重要です。

Tip

3DSリクエスターはSSLを使用してActiveServerに接続します。API呼び出しを行うには、RESTTemplateクライアント証明書を添付する必要があります。

  • /resources/certsディレクトリ内のクライアント証明書(.p12ファイル)とcacerts.jksトラストストアファイルを確認してください。.p12ファイルの取得についてはIntroductionを参照してください。
  • SSL設定はRestClientConfigクラスに実装されています。このクラスはrequestor/configディレクトリにあります。

Tip

次の例のコードでは、3DSリクエスターInitAuthRequestBRWリクエストを挿入してから3DSサーバーに送信しています。
1
2
3
4
5
6
//AuthController.java
public InitAuthResponseBRW initAuth(@RequestBody InitAuthRequestBRW request) {
...
    fillInitAuthRequestBRW(request, THREE_DS_REQUESTOR_URL + "/3ds-notify");
...
}
次に、AuthController.javaの中にあるfillInitAuthRequestBRWメソッドについて説明します。このメソッドではInitAuthRequestBRWにデモ用のデフォルトデータを挿入していますが、実際の状況では、データベースからのデータ、あるいはフロンドエンドから送信されたカード会員情報をロードするように、このメソッドの部分を入れ替えることができます。

  • 文字列THREE_DS_REQUESTOR_URLは、デフォルト設定で与えられるURLであり、http://localhost:8082になります。このURLを、ホストされる3DSリクエスターのURLに更新することができます。
  • ここでは、eventCallBackUrlTHREE_DS_REQUESTOR_URL/3ds-notifyに設定しています。こうすることで、3DSサーバーは、ブラウザー情報収集(ステップ.7)の完了時に通知を行えます。

処理 2: 認証の実行

認証を実行するためには、3DSリクエスターが以下のように動作する必要があります。

ブラウザー情報収集(ステップ.7)が完了したら、ActiveServerは、THREE_DS_REQUESTOR_URL/3ds-notifyに設定されているeventCallBackUrliframeを通して通知します。3DSリクエスターは、MainController.javaにてこの通知を処理します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// MainController.java
@PostMapping("/3ds-notify")
public String notifyResult(
        @RequestParam("requestorTransId") String transId,
        @RequestParam("event") String callbackType,
        @RequestParam(name = "param", required = false) String param,
        Model model) {

    String callbackName;
    // check the callbackType and initialise callbackName
    if ("3DSMethodFinished".equals(callbackType)) {

        callbackName = "_on3DSMethodFinished";

    } else if ("3DSMethodSkipped".equals(callbackType)) {

        callbackName = "_on3DSMethodSkipped";

    } else {
        throw new IllegalArgumentException("invalid callback type");
    }

    //オブジェクトの情報をnotify_3ds_eventsに送る。
    model.addAttribute("transId", transId);
    model.addAttribute("callbackName", callbackName);
    model.addAttribute("callbackParam", param);

    return "notify_3ds_events";
}

このハンドラーメソッドは、パラメーターtransIdcallbackType、およびオプションのparamを取り込みます。callbackTypeは、3DSMethodFinishedまたは3DSMethodSkippedのいずれかです。ハンドラーメソッドは文字列notify_3ds_eventsを返します。これは、名前がnotify_3ds_events.htmlであるHTMLページを返すことを意味します。フロンドエンドでのnotify_3ds_events.htmlの実装については、ここを参照してください。

AuthControllerで、3DSリクエスターは、@PostMapping("/auth")を使用してauthハンドラーメソッドを実行し認証の実行リクエストを処理します(ステップ.9)。このメソッドは、threeDSRequestorTransIDthreeDSServerTransIDを使用して/brwへのPOST APIリクエストを行います(ステップ.10)ActiveServerは、AReqを初期化して送信することで3DS処理を開始し(ステップ.11)AResを受信します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
//AuthController.java
@PostMapping("/auth")
public AuthResponseBRW auth(@RequestParam("id") String transId) {

    MerchantTransaction transaction = transMgr.findTransaction(transId);

    //create authentication request.
    AuthRequestBRW authRequest = new AuthRequestBRW();
    authRequest.setThreeDSRequestorTransID(transaction.getId());
    authRequest.setThreeDSServerTransID(transaction.getInitAuthResponseBRW().getThreeDSServerTransID());

    String brwUrl = THREE_DS_SERVER_URL + "/api/v1/auth/brw";
    AuthResponseBRW response = restTemplate.postForObject(brwUrl, authRequest, AuthResponseBRW.class);

    logger.info("authResponseBRW {}", response);

    return response;
}

authハンドラーメソッドはフロンドエンドに応答します。応答に含まれているtransStatusの値はY, N, U,R, AまたはCであり、この応答結果に応じて以後のフローを加盟店が決定できます。ステップ毎の実装ガイドにおいては主にYCそれぞれフリクションレス、チャレンジのフローについて解説しています。フロンドエンドでのtransStatusの処理については、ここを参照してください。また、AuthRequestBRWAuthResponseBRWのデータ構造については、API documentを参照してください。

処理 3: 認証結果の取得

認証結果を取得するためには、3DSリクエスターが以下のように動作する必要があります。

認証結果の準備ができると、ActiveServereventCallBackUrlを使用して通知を送信します。3DSリクエスター_onAuthResultメッセージをnotify_3ds_events.htmlに返して通知を処理します。フロンドエンドでの_onAuthResultメッセージの実装については、ここを参照してください。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
//MainController.java
@PostMapping("/3ds-notify")
public String notifyResult(
    ...
    if ("3DSMethodFinished".equals(callbackType)) {
        callbackName = "_on3DSMethodFinished";
    } else if ("3DSMethodSkipped".equals(callbackType)) {
        callbackName = "_on3DSMethodSkipped";
    } else if ("AuthResultReady".equals(callbackType)) {
        callbackName = "_onAuthResult";
    }
    ...

3DSリクエスターは、@GetMapping("/auth/result")を使用してresultハンドラーメソッドを実行し認証結果を取得します。このハンドラーメソッドは、/brw/resultを呼び出してActiveServerに認証結果を要求し、フロンドエンドにresultを返します。フロンドエンドはresult.htmlページを使用して結果を表示します。フロンドエンドでの実装については、ここを参照してください。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@GetMapping("/auth/result")
public String result(
        @RequestParam("txid") String transId,
        Model model) {

    MerchantTransaction transaction = transMgr.findTransaction(transId);
    String resultUrl = AuthController.THREE_DS_SERVER_URL + "/api/v1/auth/brw/result?threeDSServerTransID=" +
                    transaction.getInitAuthResponseBRW().getThreeDSServerTransID();
    AuthResponseBRW response = restTemplate.getForObject(resultUrl, AuthResponseBRW.class);
    model.addAttribute("result", response);
    return "result";
}

Success

お疲れ様でした。これでバックエンドの導入は完了です。

次のチャプター

「次へ」ボタンを選択し、ステップ毎の実装ガイドに従って加盟店のウェブサイトに3DSリクエスターを統合してください。