Google Payment Card Recognition API 可讓您透過相機識別付款卡上的資訊。這個 API 採用了光學字元辨識 (OCR) 技術,因此可以識別信用卡或簽帳金融卡上的主要帳號 (PAN) 和到期日。另外,這個 API 會將掃描卡片的工作委派給 Google Play 服務。因此,您的應用程式無須要求取得相機權限,而且只會收到掃描結果。所有影像處理作業都會在裝置中完成,Google 不會儲存結果或分享影像資料。
為確保使用者可以享有最佳體驗和功能,這個 API 設有下列限制:
- 裝置必須位於下列國家/地區:澳洲、巴西、加拿大、瑞士、捷克、丹麥、西班牙、芬蘭、法國、英國、香港、愛爾蘭、日本、韓國、荷蘭、挪威、紐西蘭、波蘭、俄羅斯、瑞典、新加坡、台灣、阿拉伯聯合大公國、美國。
- 裝置至少須有 1 GB 的 RAM。
- 裝置必須搭載後置鏡頭。
- 裝置必須支援
PORTRAIT
螢幕方向。
建立要求
在 Activity
的 onCreate
方法中建立 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(); }