識別簽帳金融卡和信用卡

Google Payment Card Recognition API 可讓您透過相機識別付款卡上的資訊。這個 API 採用了光學字元辨識 (OCR) 技術,因此可以識別信用卡或簽帳金融卡上的主要帳號 (PAN) 和到期日。另外,這個 API 會將掃描卡片的工作委派給 Google Play 服務。因此,您的應用程式無須要求取得相機權限,而且只會收到掃描結果。所有影像處理作業都會在裝置中完成,Google 不會儲存結果或分享影像資料。

為確保使用者可以享有最佳體驗和功能,這個 API 設有下列限制:

  • 裝置必須位於下列國家/地區:澳洲、巴西、加拿大、瑞士、捷克、丹麥、西班牙、芬蘭、法國、英國、香港、愛爾蘭、日本、韓國、荷蘭、挪威、紐西蘭、波蘭、俄羅斯、瑞典、新加坡、台灣、阿拉伯聯合大公國、美國。
  • 裝置至少須有 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);
    }
  }

解讀結果

在識別程序中,我們的演算法會嘗試識別付款卡。如果成功識別出結果,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();
  }