チュートリアル

このチュートリアルでは、Google Play ストアで配布される Android アプリケーションを Google Pay API と統合して支払いカードを受け入れる方法について説明します。

    手順 1: Google Pay API のバージョンを定義する

    アプリで使用する Google Pay API のバージョンを宣言します。メジャーとマイナーのバージョンは、渡された各オブジェクトで予想されるフィールドに影響を与え、レスポンスに含まれます。

    他のすべてのリクエスト オブジェクトに存在するプロパティを含んだベース リクエスト オブジェクトを作成します。

    private static JSONObject getBaseRequest() {
      return new JSONObject()
        .put("apiVersion", 2)
        .put("apiVersionMinor", 0);
    }

    手順 2: 支払いトークン化方法を選択する

    Google は、販売者のゲートウェイまたは販売者のセキュア サーバーで安全に処理されるように、支払人が選択したカードに関する情報を暗号化します。両方のオプションの例を以下に示します。

    ゲートウェイ

    private static JSONObject getTokenizationSpecification() {
      JSONObject tokenizationSpecification = new JSONObject();
      tokenizationSpecification.put("type", "PAYMENT_GATEWAY");
      tokenizationSpecification.put(
          "parameters",
          new JSONObject()
              .put("gateway", "example")
              .put("gatewayMerchantId", "exampleMerchantId"));
    
      return tokenizationSpecification;
    }

    example は、Google がサポートするゲートウェイのゲートウェイ ID で置き換えます。exampleGatewayMerchantId は、ゲートウェイが提供する一意の販売者 ID に置き換えます。

    サポートされているゲートウェイと固有の ID については、ゲートウェイのトークン化に関するドキュメントをご覧ください。販売者が Google Pay API のカード支払い方法を統合する際に最もよく使用するトークン化タイプは、PAYMENT_GATEWAY です。

    直接

    private static JSONObject getTokenizationSpecification() {
      JSONObject tokenizationSpecification = new JSONObject();
      tokenizationSpecification.put("type", "DIRECT");
      tokenizationSpecification.put(
          "parameters",
          new JSONObject()
              .put("protocolVersion", "ECv2")
              .put("publicKey", "BOdoXP1aiNp.....kh3JUhiSZKHYF2Y="));
    
      return tokenizationSpecification;
    }

    短縮された publicKey 値は、Google Play デベロッパー プロフィールで提供した公開鍵に置き換えます。提供される支払い情報は、この鍵で暗号化されます。Google Pay API に適した暗号鍵の構成方法については、支払いデータの暗号方式のドキュメントをご覧ください。

    手順 3: サポートされている支払いカード ネットワークを定義する

    アプリで承認されたカード ネットワークを定義します。

    private static JSONArray getAllowedCardNetworks() {
      return new JSONArray()
          .put("AMEX")
          .put("DISCOVER")
          .put("INTERAC");
          .put("JCB")
          .put("MASTERCARD")
          .put("VISA");
    }

    Google Pay API は、Google.com のファイルに保存されたカード情報(PAN_ONLY)、または 3D セキュア クリプトグラムで認証された Android 搭載端末の端末トークン(CRYPTOGRAM_3DS)を返します。

    private static JSONArray getAllowedCardAuthMethods() {
      return new JSONArray()
          .put("PAN_ONLY")
          .put("CRYPTOGRAM_3DS");
    }

    詳しくは、JSON オブジェクト リファレンスの CardParameters をご覧ください。サポートされているカード ネットワークと Android 搭載端末トークンのサポートについて、ゲートウェイまたはデータ処理者に確認します。

    手順 4: 許可された支払い方法を記述する

    サポートされている認証方法とサポートされているカード ネットワークを組み合わせて、サイトでの CARD 支払い方法のサポートについて記述します。

    private static JSONObject getBaseCardPaymentMethod() {
      JSONObject cardPaymentMethod = new JSONObject();
      cardPaymentMethod.put("type", "CARD");
      cardPaymentMethod.put(
          "parameters",
          new JSONObject()
              .put("allowedAuthMethods", getAllowedCardAuthMethods())
              .put("allowedCardNetworks", getAllowedCardNetworks()));
    
      return cardPaymentMethod;
    }

    基本カード支払い方法オブジェクトを拡張し、アプリケーションに返す必要がある情報(トークン化された支払いデータなど)を記述します。

    private static JSONObject getCardPaymentMethod() {
      JSONObject cardPaymentMethod = getBaseCardPaymentMethod();
      cardPaymentMethod.put("tokenizationSpecification", getTokenizationSpecification());
    
      return cardPaymentMethod;
    }
    

    サポートされている parameters について詳しくは、JSON オブジェクト リファレンスの CardParameters をご覧ください。

    CARD に加えて、Google Pay は PAYPAL によるお支払い方法もサポートしています。お支払い方法として PAYPAL を Google Pay に追加する方法について詳しくは、PayPal のデベロッパー向けドキュメントをご覧ください。

    手順 5: PaymentsClient インスタンスを作成する

    ActivityonCreate メソッドで PaymentsClient のインスタンスを作成します。PaymentsClient は、Google Pay API とのやり取りに使用されます。

    private PaymentsClient mPaymentsClient;
    
    @Override
    public void onCreate() {
      super.onCreate();
    
      mPaymentsClient =
          Wallet.getPaymentsClient(
              this,
              new Wallet.WalletOptions.Builder()
                  .setEnvironment(WalletConstants.ENVIRONMENT_TEST)
                  .build());
    }

    手順 6: Google Pay API での支払いが可能かどうかを確認する

    次のコードスニペットを使用して、許可された支払い方法をベース リクエスト オブジェクトに追加します。

    public static JSONObject getIsReadyToPayRequest() {
      JSONObject isReadyToPayRequest = getBaseRequest();
      isReadyToPayRequest.put(
        "allowedPaymentMethods",
        new JSONArray()
          .put(getBaseCardPaymentMethod()));
    
      return isReadyToPayRequest;
    }
    

    isReadyToPay API を呼び出して、ユーザーが Google Pay API を使用して支払いを行えるかどうかを判断します。構成プロパティの完全なリストについては、IsReadyToPayRequest JSON オブジェクトのドキュメントをご覧ください。

    IsReadyToPayRequest request =
        IsReadyToPayRequest.fromJson(getIsReadyToPayRequest().toString());
    Task<Boolean> task = mPaymentsClient.isReadyToPay(request);
    task.addOnCompleteListener(
        new OnCompleteListener<Boolean>() {
          @Override
          public void onComplete(@NonNull Task<Boolean> task) {
            try {
              boolean result = task.getResult(ApiException.class);
              if (result) {
                // show Google Pay as a payment option
              }
            } catch (ApiException e) {
            }
          }
        });

    isReadyToPay から正しい結果を受け取った後、Google Pay を支払いオプションとして提示する必要があります。レイアウト include を通じて Google Pay 支払いボタンを表示することが、最も一般的な実装です。アプリで使用できる Google Pay 支払いボタン、ロゴ、マークについて詳しくは、ブランド ガイドラインをご覧ください。

    手順 7: PaymentDataRequest オブジェクトを作成する

    PaymentDataRequest JSON オブジェクトは、Google Pay 支払いシートの支払人に対してリクエストする情報を記述します。

    取引価格と提供された価格のステータスに関する情報を提供します。詳しくは、TransactionInfo JSON オブジェクトのドキュメントをご覧ください。

    private static JSONObject getTransactionInfo() {
      JSONObject transactionInfo = new JSONObject();
      transactionInfo.put("totalPrice", "12.34");
      transactionInfo.put("totalPriceStatus", "FINAL");
      transactionInfo.put("currencyCode", "USD");
    
      return transactionInfo;
    }
    

    ユーザーに表示される販売者名を入力します。詳しくは、MerchantInfo JSON オブジェクトのドキュメントをご覧ください。

    private static JSONObject getMerchantInfo() {
      return new JSONObject()
          .put("merchantName", "Example Merchant");
    }

    ベース リクエスト オブジェクトを新しい PaymentDataRequest JSON オブジェクトに割り当てます。レスポンスで予想される追加データの構成など、アプリでサポートされている支払い方法を追加します。また、取引とリクエスト側の販売者に関する情報を追加します。

    public static JSONObject getPaymentDataRequest() {
      JSONObject paymentDataRequest = getBaseRequest();
      paymentDataRequest.put(
        "allowedPaymentMethods",
        new JSONArray()
            .put(getCardPaymentMethod()));
      paymentDataRequest.put("transactionInfo", getTransactionInfo());
      paymentDataRequest.put("merchantInfo", getMerchantInfo());
    
      return paymentDataRequest;
    }

    詳しくは、PaymentDataRequest JSON オブジェクトのドキュメントをご覧ください。

    手順 8: ユーザー ジェスチャのイベント ハンドラを登録する

    OnClickListener を定義し、ユーザーが Google Pay 支払いボタンをクリックした後に Google Pay 支払いシートが表示されるようにします。

    findViewById(R.id.googlepay)
        .setOnClickListener(
            new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                PaymentDataRequest request =
                    PaymentDataRequest.fromJson(paymentDataRequest.toString());
                if (request != null) {
                  AutoResolveHelper.resolveTask(
                      mPaymentsClient.loadPaymentData(request),
                      this,
                      // LOAD_PAYMENT_DATA_REQUEST_CODE is a constant integer value you define
                      LOAD_PAYMENT_DATA_REQUEST_CODE);
                }
              }
            });

    PaymentDataRequest オブジェクトは、支払いデータのリクエストを表す Parcelable です。これにより、支払いのサポートに必要な情報が提供されます。AutoResolveHelper クラスを使用して Task を自動的に解決し、その結果を Activity クラスの onActivityResult メソッドで処理します。

    手順 9: レスポンス オブジェクトを処理する

    支払人が Google Pay 支払いシートでリクエストされた情報を正しく提供した後、PaymentData オブジェクトが onActivityResult に返されます。

    支払い情報をデータ処理者に渡し、ユーザーに購入の確認を提示するために、成功したレスポンスを JSON に変換します。PaymentDataRequest に渡された transactionInfo.totalPriceStatusESTIMATED であった場合、返されたお支払い方法に代金を請求する前に、最終価格を表示する必要があります。

    paymentData レスポンスから支払いトークンを抽出します。ゲートウェイ統合を実装する場合は、このトークンをそのままゲートウェイに渡します。

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      switch (requestCode) {
          // value passed in AutoResolveHelper
        case LOAD_PAYMENT_DATA_REQUEST_CODE:
          switch (resultCode) {
            case Activity.RESULT_OK:
              PaymentData paymentData = PaymentData.getFromIntent(data);
              String json = paymentData.toJson();
              // if using gateway tokenization, pass this token without modification
              String paymentMethodData = new JSONObject(json)
                                           .getJSONObject(“paymentMethodData”);
              String paymentToken = paymentMethodData
                                      .getJSONObject("tokenizationData")
                                      .getString("token");
              break;
            case Activity.RESULT_CANCELED:
              break;
            case AutoResolveHelper.RESULT_ERROR:
              Status status = AutoResolveHelper.getStatusFromIntent(data);
              // Log the status for debugging.
              // Generally, there is no need to show an error to the user.
              // The Google Pay payment sheet will present any account errors.
              break;
            default:
              // Do nothing.
          }
          break;
        default:
          // Do nothing.
      }
    }

    レスポンスの内容と構造について詳しくは、PaymentData JSON オブジェクト リファレンスをご覧ください。

    まとめ

    次の例は、適切に構成されたプロジェクトの完全な例を示します。プロジェクトレベルの設定については、Google Pay API の設定の「プロジェクトを構成する」セクションをご覧ください。

    YourActivity.java

    次の Activity の例では、googlepayID 属性を持つ Google Pay 支払いボタンがレイアウトに存在していることを想定しています。

    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.support.annotation.NonNull;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import com.google.android.gms.common.api.ApiException;
    import com.google.android.gms.common.api.Status;
    import com.google.android.gms.tasks.OnCompleteListener;
    import com.google.android.gms.tasks.Task;
    import com.google.android.gms.wallet.AutoResolveHelper;
    import com.google.android.gms.wallet.IsReadyToPayRequest;
    import com.google.android.gms.wallet.PaymentData;
    import com.google.android.gms.wallet.PaymentDataRequest;
    import com.google.android.gms.wallet.PaymentsClient;
    import com.google.android.gms.wallet.Wallet;
    import com.google.android.gms.wallet.WalletConstants;
    import java.util.Optional;
    import org.json.JSONObject;
    
    public class YourActivity extends AppCompatActivity {
      /**
       * A client for interacting with the Google Pay API
       *
       * @see <a
       *     href="https://developers.google.com/android/reference/com/google/android/gms/wallet/PaymentsClient">PaymentsClient</a>
       */
      private PaymentsClient mPaymentsClient;
    
      /**
       * A Google Pay payment button presented to the viewer for interaction
       *
       * @see <a href="https://developers.google.com/pay/api/android/guides/brand-guidelines">Google Pay
       *     payment button brand guidelines</a>
       */
      private View mGooglePayButton;
    
      /** A constant integer you define to track a request for payment data activity */
      private static final int LOAD_PAYMENT_DATA_REQUEST_CODE = 42;
    
      /**
       * Initialize the Google Pay API on creation of the activity
       *
       * @see Activity#onCreate(android.os.Bundle)
       */
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        // initialize a Google Pay API client for an environment suitable for testing
        mPaymentsClient =
            Wallet.getPaymentsClient(
                this,
                new Wallet.WalletOptions.Builder()
                    .setEnvironment(WalletConstants.ENVIRONMENT_TEST)
                    .build());
    
        possiblyShowGooglePayButton();
      }
    
      /**
       * Determine the viewer's ability to pay with a payment method supported by your app and display a
       * Google Pay payment button
       *
       * @see <a
       *     href="https://developers.google.com/android/reference/com/google/android/gms/wallet/PaymentsClient#isReadyToPay(com.google.android.gms.wallet.IsReadyToPayRequest)">PaymentsClient#IsReadyToPay</a>
       */
      private void possiblyShowGooglePayButton() {
        final Optional<JSONObject> isReadyToPayJson = GooglePay.getIsReadyToPayRequest();
        if (!isReadyToPayJson.isPresent()) {
          return;
        }
        IsReadyToPayRequest request = IsReadyToPayRequest.fromJson(isReadyToPayJson.get().toString());
        if (request == null) {
          return;
        }
        Task<Boolean> task = mPaymentsClient.isReadyToPay(request);
        task.addOnCompleteListener(
            new OnCompleteListener<Boolean>() {
              @Override
              public void onComplete(@NonNull Task<Boolean> task) {
                try {
                  boolean result = task.getResult(ApiException.class);
                  if (result) {
                    // show Google as a payment option
                    mGooglePayButton = findViewById(R.id.googlepay);
                    mGooglePayButton.setOnClickListener(
                        new View.OnClickListener() {
                          @Override
                          public void onClick(View view) {
                            requestPayment(view);
                          }
                        });
                    mGooglePayButton.setVisibility(View.VISIBLE);
                  }
                } catch (ApiException exception) {
                  // handle developer errors
                }
              }
            });
      }
    
      /**
       * Display the Google Pay payment sheet after interaction with the Google Pay payment button
       *
       * @param view optionally uniquely identify the interactive element prompting for payment
       */
      public void requestPayment(View view) {
        Optional<JSONObject> paymentDataRequestJson = GooglePay.getPaymentDataRequest();
        if (!paymentDataRequestJson.isPresent()) {
          return;
        }
        PaymentDataRequest request =
            PaymentDataRequest.fromJson(paymentDataRequestJson.get().toString());
        if (request != null) {
          AutoResolveHelper.resolveTask(
              mPaymentsClient.loadPaymentData(request), this, LOAD_PAYMENT_DATA_REQUEST_CODE);
        }
      }
    
      /**
       * Handle a resolved activity from the Google Pay payment sheet
       *
       * @param requestCode the request code originally supplied to AutoResolveHelper in
       *     requestPayment()
       * @param resultCode the result code returned by the Google Pay API
       * @param data an Intent from the Google Pay API containing payment or error data
       * @see <a href="https://developer.android.com/training/basics/intents/result">Getting a result
       *     from an Activity</a>
       */
      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            // value passed in AutoResolveHelper
          case LOAD_PAYMENT_DATA_REQUEST_CODE:
            switch (resultCode) {
              case Activity.RESULT_OK:
                PaymentData paymentData = PaymentData.getFromIntent(data);
                String json = paymentData.toJson();
                // if using gateway tokenization, pass this token without modification
                String paymentMethodData = new JSONObject(json)
                                             .getJSONObject(“paymentMethodData”);
                String paymentToken = paymentMethodData
                                        .getJSONObject("tokenizationData")
                                        .getString("token");
                break;
              case Activity.RESULT_CANCELED:
                break;
              case AutoResolveHelper.RESULT_ERROR:
                Status status = AutoResolveHelper.getStatusFromIntent(data);
                // Log the status for debugging.
                // Generally, there is no need to show an error to the user.
                // The Google Pay payment sheet will present any account errors.
                break;
              default:
                // Do nothing.
            }
            break;
          default:
            // Do nothing.
        }
      }
    }
    

    GooglePay.java

    次のサンプル ファイルは、IsReadyToPayRequest または PaymentDataRequest の構築に適した JSON オブジェクトを作成します。

    import java.util.Optional;
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    
    /**
     * Google Pay API request configurations
     *
     * @see <a href="https://developers.google.com/pay/api/android/">Google Pay API Android
     *     documentation</a>
     */
    public class GooglePay {
      /**
       * Create a Google Pay API base request object with properties used in all requests
       *
       * @return Google Pay API base request object
       * @throws JSONException
       */
      private static JSONObject getBaseRequest() throws JSONException {
        return new JSONObject()
            .put("apiVersion", 2)
            .put("apiVersionMinor", 0);
      }
    
      /**
       * Identify your gateway and your app's gateway merchant identifier
       *
       * <p>The Google Pay API response will return an encrypted payment method capable of being charged
       * by a supported gateway after payer authorization
       *
       * <p>TODO: check with your gateway on the parameters to pass
       *
       * @return payment data tokenization for the CARD payment method
       * @throws JSONException
       * @see <a
       *     href="https://developers.google.com/pay/api/android/reference/object#PaymentMethodTokenizationSpecification">PaymentMethodTokenizationSpecification</a>
       */
      private static JSONObject getTokenizationSpecification() throws JSONException {
        JSONObject tokenizationSpecification = new JSONObject();
        tokenizationSpecification.put("type", "PAYMENT_GATEWAY");
        tokenizationSpecification.put(
            "parameters",
            new JSONObject()
                .put("gateway", "example")
                .put("gatewayMerchantId", "exampleGatewayMerchantId"));
    
        return tokenizationSpecification;
      }
    
      /**
       * Card networks supported by your app and your gateway
       *
       * <p>TODO: confirm card networks supported by your app and gateway
       *
       * @return allowed card networks
       * @see <a
       *     href="https://developers.google.com/pay/api/android/reference/object#CardParameters">CardParameters</a>
       */
      private static JSONArray getAllowedCardNetworks() {
        return new JSONArray()
            .put("AMEX")
            .put("DISCOVER")
            .put("JCB")
            .put("MASTERCARD")
            .put("VISA");
      }
    
      /**
       * Card authentication methods supported by your app and your gateway
       *
       * <p>TODO: confirm your processor supports Android device tokens on your supported card networks
       *
       * @return allowed card authentication methods
       * @see <a
       *     href="https://developers.google.com/pay/api/android/reference/object#CardParameters">CardParameters</a>
       */
      private static JSONArray getAllowedCardAuthMethods() {
        return new JSONArray()
            .put("PAN_ONLY")
            .put("CRYPTOGRAM_3DS");
      }
    
      /**
       * Describe your app's support for the CARD payment method
       *
       * <p>The provided properties are applicable to both an IsReadyToPayRequest and a
       * PaymentDataRequest
       *
       * @return a CARD PaymentMethod object describing accepted cards
       * @throws JSONException
       * @see <a
       *     href="https://developers.google.com/pay/api/android/reference/object#PaymentMethod">PaymentMethod</a>
       */
      private static JSONObject getBaseCardPaymentMethod() throws JSONException {
        JSONObject cardPaymentMethod = new JSONObject();
        cardPaymentMethod.put("type", "CARD");
        cardPaymentMethod.put(
            "parameters",
            new JSONObject()
                .put("allowedAuthMethods", GooglePay.getAllowedCardAuthMethods())
                .put("allowedCardNetworks", GooglePay.getAllowedCardNetworks()));
    
        return cardPaymentMethod;
      }
    
      /**
       * Describe the expected returned payment data for the CARD payment method
       *
       * @return a CARD PaymentMethod describing accepted cards and optional fields
       * @throws JSONException
       * @see <a
       *     href="https://developers.google.com/pay/api/android/reference/object#PaymentMethod">PaymentMethod</a>
       */
      private static JSONObject getCardPaymentMethod() throws JSONException {
        JSONObject cardPaymentMethod = GooglePay.getBaseCardPaymentMethod();
        cardPaymentMethod.put("tokenizationSpecification", GooglePay.getTokenizationSpecification());
    
        return cardPaymentMethod;
      }
    
      /**
       * Provide Google Pay API with a payment amount, currency, and amount status
       *
       * @return information about the requested payment
       * @throws JSONException
       * @see <a
       *     href="https://developers.google.com/pay/api/android/reference/object#TransactionInfo">TransactionInfo</a>
       */
      private static JSONObject getTransactionInfo() throws JSONException {
        JSONObject transactionInfo = new JSONObject();
        transactionInfo.put("totalPrice", "12.34");
        transactionInfo.put("totalPriceStatus", "FINAL");
        transactionInfo.put("currencyCode", "USD");
    
        return transactionInfo;
      }
    
      /**
       * Information about the merchant requesting payment information
       *
       * @return information about the merchant
       * @throws JSONException
       * @see <a
       *     href="https://developers.google.com/pay/api/android/reference/object#MerchantInfo">MerchantInfo</a>
       */
      private static JSONObject getMerchantInfo() throws JSONException {
        return new JSONObject()
            .put("merchantName", "Example Merchant");
      }
    
      /**
       * An object describing accepted forms of payment by your app, used to determine a viewer's
       * readiness to pay
       *
       * @return API version and payment methods supported by the app
       * @see <a
       *     href="https://developers.google.com/pay/api/android/reference/object#IsReadyToPayRequest">IsReadyToPayRequest</a>
       */
      public static Optional<JSONObject> getIsReadyToPayRequest() {
        try {
          JSONObject isReadyToPayRequest = GooglePay.getBaseRequest();
          isReadyToPayRequest.put(
              "allowedPaymentMethods", new JSONArray().put(getBaseCardPaymentMethod()));
          return Optional.of(isReadyToPayRequest);
        } catch (JSONException e) {
          return Optional.empty();
        }
      }
    
      /**
       * An object describing information requested in a Google Pay payment sheet
       *
       * @return payment data expected by your app
       * @see <a
       *     href="https://developers.google.com/pay/api/android/reference/object#PaymentDataRequest">PaymentDataRequest</a>
       */
      public static Optional<JSONObject> getPaymentDataRequest() {
        try {
          JSONObject paymentDataRequest = GooglePay.getBaseRequest();
          paymentDataRequest.put(
              "allowedPaymentMethods", new JSONArray().put(GooglePay.getCardPaymentMethod()));
          paymentDataRequest.put("transactionInfo", GooglePay.getTransactionInfo());
          paymentDataRequest.put("merchantInfo", GooglePay.getMerchantInfo());
          return Optional.of(paymentDataRequest);
        } catch (JSONException e) {
          return Optional.empty();
        }
      }
    }