AI-generated Key Takeaways
- 
          The Google Pay Virtual Cards API requires testing after implementation, with Google providing test cases to assist in this process. 
- 
          Test cases are categorized into outbound (Google to Integrator) and inbound (Integrator to Google) scenarios for different API endpoints. 
- 
          Outbound tests cover various scenarios, including request validation, successful and failed enrollment attempts, card retrieval with challenge flows, transaction retrieval, and unenrollment. 
- 
          Inbound tests focus on the TransactionEventNotificationendpoint to confirm successful transaction event communication.
- 
          Integrators can configure sandbox environments to simulate specific card enrollment and retrieval behaviors, including risk declines and challenge requirements. 
Once the Virtual Cards APIs have been implemented, it's time to test them. Google provides test cases that may aid you in this process.
Test cases
This section outlines the test cases expected to be executed to validate your Virtual Cards APIs implementation.
Outbound tests
Outbound tests refer to flow direction Google -> Integrator.
Common (applies to all outbound endpoints)
- Invalid encryption returns invalidPayloadEncryption
- Invalid signature returns invalidPayloadSignature
- Invalid JSON returns invalidDecryptedRequest
- Timestamp not within +/- 60 seconds returns requestTimestampOutOfRange(this requirement helps protect against replay attacks)
- RequestId missing returns missingRequiredField
- Invalid
PIAID (paymentIntegratorAccountId)
returns invalidIdentifier
Echo
- Happy Path (clientMessage is echoed in response)
Enroll
- Happy Path
- PAN is not found returns unknownPandecline
- PAN is recognized but is no longer valid returns panNoLongerValid
- PAN is recognized but the card account has been closed returns cardAccountClosed
- PAN is not eligible returns cardIneligibledecline
- PAN invalid format returns invalidFieldValueerror
- Expiration date mismatch returns incorrectExpirationdecline
- Red-path PAN* returns riskDeclineddecline
- Externally-managed terms of service not accepted by user returns
tosNotAccepteddecline
- Externally-managed terms of service acceptance timestamp out of date returns
tosAcceptanceOutdateddecline
- Idempotency - Same requestId+ same PAN returnssuccess
- Idempotency - Same requestId+ different PAN returnsidempotencyViolation
- Different requestId+ same PAN returnssuccess(2nd enrollment)- This can happen if the same PAN is registered by multiple users (different
hashedEmailAddress) or a single user (samehashedEmailAddress) with multiple payment profiles
 
- This can happen if the same PAN is registered by multiple users (different
RetrieveVirtualCardNumber
- Green path* returns success
- Yellow path* returns challengeRequireddecline
- Yellow path* (including valid challenge result) returns success
- Yellow path* (including INVALID challenge result) returns
challengeResultInvaliddecline
- Yellow path* (too many** attempts at challenge result) returns
challengeResultVerificationLimitExceededdecline
- Yellow path* (including expired** OTP challenge result) returns
challengeResultExpireddecline
- Yellow path* (including expired** challenge option) returns
challengeResultExpireddecline- for example if the send OTP limit is 3, OTP timeout is 10 min, and the challenge option timeout is 15 min, the user could timeout the first OTP at 10 min but then timeout the whole challenge at 15 min
 
- Red path* returns riskDeclined
- Idempotency - Same requestId+ same contents returns same response- Green path returns success
- Yellow path returns challengeRequireddecline
- Yellow path (including valid challenge result) returns success
 
- Green path returns 
- Idempotency - Same requestId+ different contents returnsidempotencyViolation
- enrollmentRequestIdnot found returns- invalidIdentifiererror
- enrollmentRequestIdthat has been unenrolled returns- invalidIdentifiererror
SendOTP
- Happy Path
- Expired** challenge option returns challengeOptionExpireddecline
- Too many** sendOtps returns sendLimitExceededdecline
- enrollmentRequestIdhas been unenrolled returns- challengeOptionExpired- for example, if (1) retrieveVirtualCardNumberreturnschallengeRequired, (2) the card is unenrolled in virtual cards, and then (3)sendOtpis called.
 
- for example, if (1) 
- challengeOptionIdnot found returns- invalidIdentifiererror
- Idempotency - Same requestId+ same contents returns same response- Does not cause sendLimitExceededfor multiple retries (send count only incremented once)
- Does not resend SMS OTP if it was already sent
- Does not change expiration result (example w/ 30 min expiration timer: first
attempt at 29 minutes, retry (same request ID) at 31 minutes. It should return
the same result from the first attempt, not challengeOptionExpired)
 
- Does not cause 
- Idempotency - same requestId+ different contents returnsidempotencyViolation
- enrollmentRequestIdnot found returns- invalidIdentifiererror
GetTransactions
- getTransactionswithout- transactionListContinuationTokenreturns all transactions for the maximum period prior to the request
- getTransactionswith- transactionListContinuationTokenreturns all transactions added or updated since the request represented by the token
- transactionListContinuationTokennot found returns- unknownTransactionListContinuationToken(not an- ErrorResponsewith- invalidIdentifierlike other APIs)
- Idempotency - Same requestId+ same contents returns same transaction list andtransactionListContinuationTokenin response
- Idempotency - Same requestId+ different contents returnsidempotencyViolation
- enrollmentRequestIdnot found returns- unknownEnrollment(not an- ErrorResponsewith- invalidIdentifierlike other APIs)
Unenroll
- Happy Path
- Idempotency - enrollmentRequestIdthat has already been unenrolled returns success
Inbound tests
Inbound tests refer to flow direction Integrator -> Google.
TransactionEventNotification
- Happy Path