デビットカードとクレジット カードの認識

Google Payment Card Recognition API は、カメラを使用して支払いカードの情報を認識する機能を提供します。この API は光学式文字認識(OCR)を使用して、クレジット カードまたはデビットカードに記載されたカード番号(PAN)と有効期限を認識します。この API は、カードスキャンのタスクを Google Play 開発者サービスに委任します。そのため、アプリはカメラに対する権限をリクエストする必要がなく、スキャン結果のみを受け取ります。画像処理はすべてデバイス上で行われ、Google が結果の保存や画像データの共有を行うことはありません。

最適なユーザー エクスペリエンスと機能を確保するため、この API には次の制約があります。

  • デバイスが次の国または地域にある: AU、BR、CA、CH、CZ、DK、ES、FI、FR、GB、HK、IE、JP、KR、NL、NO、NZ、PL、RU、SE、SG、TW、UA、US
  • デバイスに 1 GB 以上の RAM が搭載されている。
  • デバイスに背面カメラが搭載されている。
  • デバイスが PORTRAIT の向きに対応している。

リクエストの作成

ActivityonCreate メソッドで PaymentsClient インスタンスを作成します。PaymentsClient を使用して Google Pay API を利用できます。

Kotlin

    fun createPaymentsClient(activity: Activity): PaymentsClient {
        val walletOptions = Wallet.WalletOptions.Builder()
                .setEnvironment(Constants.PAYMENTS_ENVIRONMENT)
                .build()

        return Wallet.getPaymentsClient(activity, walletOptions)
    }

Java

  public static PaymentsClient createPaymentsClient(Activity activity) {
    Wallet.WalletOptions walletOptions =
        new Wallet.WalletOptions.Builder().setEnvironment(Constants.PAYMENTS_ENVIRONMENT).build();
    return Wallet.getPaymentsClient(activity, walletOptions);
  }

レスポンスを作成した後、PendingIntent の非同期リクエストを送信し、それを使用して支払いカード認識アクティビティを開始できます。

リクエストは必ず成功するとは限りません。API が有効になっていない場合、リクエストは失敗します。リクエストに対するレスポンスに応じてアプリの動作を調整することをおすすめします。サンプルアプリでは、正常なレスポンスを受け取った後にのみボタンが表示されます。

Kotlin

    private fun possiblyShowPaymentCardOcrButton() {
        // The request can be used to configure the type of the payment card recognition. Currently
        // the only supported type is card OCR, so it is sufficient to call the getDefaultInstance()
        // method.
        val request = PaymentCardRecognitionIntentRequest.getDefaultInstance()
        paymentsClient
            .getPaymentCardRecognitionIntent(request)
            .addOnSuccessListener { intentResponse ->
                cardRecognitionPendingIntent = intentResponse.paymentCardRecognitionPendingIntent
                paymentCardOcrButton.visibility = View.VISIBLE
            }
            .addOnFailureListener { e ->
                // The API is not available either because the feature is not enabled on the device
                // or because your app is not registered.
                Log.e(TAG, "Payment card ocr not available.", e)
            }
    }

Java

  public void possiblyShowPaymentCardOcrButton() {
    // The request can be used to configure the type of the payment card recognition. Currently the
    // only supported type is card OCR, so it is sufficient to call the getDefaultInstance() method.
    PaymentCardRecognitionIntentRequest request =
        PaymentCardRecognitionIntentRequest.getDefaultInstance();
    paymentsClient
        .getPaymentCardRecognitionIntent(request)
        .addOnSuccessListener(intentResponse -> {
          cardRecognitionPendingIntent = intentResponse.getPaymentCardRecognitionPendingIntent();
          paymentCardOcrButton.setVisibility(View.VISIBLE);
        })
        .addOnFailureListener(e -> {
          // The API is not available either because the feature is not enabled on the device
          // or because your app is not registered.
          Log.e(TAG, "Payment card ocr not available.", e);
        });
  }

支払いカード認識アクティビティを開始するには、次のコードサンプルを使用します。

Kotlin

    private fun startPaymentCardOcr() {
        try {
            ActivityCompat.startIntentSenderForResult(
                this@CheckoutActivity,
                cardRecognitionPendingIntent.intentSender,
                PAYMENT_CARD_RECOGNITION_REQUEST_CODE,
                null, 0, 0, 0, null
            )
        } catch (e: SendIntentException) {
            throw RuntimeException("Failed to start payment card recognition.", e)
        }
    }

Java

  public void startPaymentCardOcr(View view) {
    try {
      ActivityCompat.startIntentSenderForResult(
          CheckoutActivity.this, cardRecognitionPendingIntent.getIntentSender(),
          PAYMENT_CARD_RECOGNITION_REQUEST_CODE,
          null, 0, 0, 0, null);
    } catch (SendIntentException e) {
      throw new RuntimeException("Failed to start payment card recognition.", e);
    }
  }

結果を解釈する

認識プロセスでは、Google のアルゴリズムにより支払いカードの認識が試みられます。結果が正常に認識されると、API は結果を PaymentCardRecognitionResult として返します。結果には常にカード番号が含まれます。アルゴリズムが有効期限の日付を検出できない場合、またはカードの有効期限が切れている場合は、有効期限の日付が含まれないことがあります。さまざまな理由でカードが認識されないことがあります。これは通常、ユーザーがフローをキャンセルし、API が Activity.RESULT_CANCELLED を返した場合に発生します。

Kotlin

    private fun handlePaymentCardRecognitionSuccess(
        cardRecognitionResult: PaymentCardRecognitionResult
    ) {
        val creditCardExpirationDate = cardRecognitionResult.creditCardExpirationDate
        val expirationDate = creditCardExpirationDate?.let { "%02d/%d".format(it.month, it.year) }
        val cardResultText = "PAN: ${cardRecognitionResult.pan}\nExpiration date: $expirationDate"
        Toast.makeText(this, cardResultText, Toast.LENGTH_LONG).show()
    }

Java

  private void handleCardRecognitionSuccess(PaymentCardRecognitionResult cardResult) {

    String expirationDate = null;
    Locale locale = Locale.getDefault();
    CreditCardExpirationDate cardExpirationDate = cardResult.getCreditCardExpirationDate();
    if(cardExpirationDate != null) {
      expirationDate = String.format(locale,
          "%02d/%d", cardExpirationDate.getMonth(), cardExpirationDate.getYear());
    }

    String cardResultString = String.format(locale,
        "PAN: %s\nExpiration date: %s", cardResult.getPan(), expirationDate);
    Toast.makeText(this, cardResultString, Toast.LENGTH_LONG).show();
  }