Skip to main content

Digital Wallet Integration

Executive Summary

Apple Pay and Google Pay integration through the gateway requires fundamentally different work for card-present (NFC) vs. card-not-present (web/in-app) flows.

Card-present (NFC): Traditional certified terminals handle EMV contactless before the gateway receives the transaction. Do not use EMV_CONTACTLESS as a confirmed TransIT value; the local TransIT source list contains EMV and CONTACTLESS, and the EMVContactless samples submit cardDataSource = EMV.

Card-not-present: Gateway exposes wallet endpoints through online-txn, delegates wallet sale/authorization to processing, and publishes matching Kotlin/TypeScript SDK methods. Current architecture uses processor decryption (Apple Pay) and PAYMENT_GATEWAY tokenization (Google Pay) so encrypted wallet tokens remain opaque to gateway services.

Remaining production work: keep merchant/account configuration, certificate rotation, processor routing, and TSYS certification evidence aligned before production cutovers.


Architecture Overview

┌─────────────────────────────────────────────────────────────────┐
│ CARD-PRESENT (NFC) │
│ │
│ iPhone/Android ──NFC──► Terminal ──EMV Contactless──► Gateway │
│ │
│ Gateway action: submit terminal EMV/contactless result to TransIT│
│ Decryption: NONE (terminal + card network handle it) │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│ CARD-NOT-PRESENT: APPLE PAY │
│ │
│ 1. Browser → Gateway: POST /apple-pay/session │
│ Gateway → Apple (mTLS): validate merchant │
│ Gateway → Browser: merchantSession │
│ │
│ 2. Browser → Gateway: POST /apple-pay/charge │
│ { applePayToken: "<encrypted PKPaymentToken>" } │
│ Gateway → TransIT: digital wallet charge │
│ { walletType: APPLE_PAY, encryptedToken: "..." } │
│ TransIT decrypts (holds Payment Processing Cert) │
│ │
│ Decryption: TransIT (processor decryption model) │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│ CARD-NOT-PRESENT: GOOGLE PAY │
│ │
│ 1. Browser → Gateway: GET /google-pay/config │
│ Returns: { gateway: "tsys", gatewayMerchantId: "..." } │
│ (No session validation needed) │
│ │
│ 2. Browser → Gateway: POST /google-pay/charge │
│ { googlePayToken: "<ECv2 encrypted token>" } │
│ Gateway → TransIT: digital wallet charge │
│ { walletType: GOOGLE_PAY, encryptedToken: "..." } │
│ TransIT decrypts (PAYMENT_GATEWAY mode, holds private key) │
│ │
│ Decryption: TransIT (PAYMENT_GATEWAY tokenization) │
└─────────────────────────────────────────────────────────────────┘

Section 1: Apple Pay

Card-Present (NFC Tap)

No gateway-specific logic required. When a customer taps an iPhone/Apple Watch on an NFC terminal:

  1. Device Secure Element communicates via NFC using EMVCo contactless spec (ISO/IEC 14443).
  2. Secure Element passes DPAN (Device PAN), dynamic cryptogram (TAVV), and transaction details to the terminal.
  3. Terminal processes as standard EMV contactless, sends to gateway normally.
  4. Gateway forwards the terminal-originated EMV/contactless result to TransIT using the certified terminal integration mapping.
  5. Card network detokenizes DPAN to FPAN and authorizes with issuer.

Card-Not-Present (Web / In-App)

Two server-side steps required:

Step A: Merchant Session Validation (Web only)

Before the Apple Pay sheet appears, Apple requires server-side merchant validation:

  1. Browser calls new ApplePaySession(version, paymentRequest) and onvalidatemerchant fires.
  2. Event provides a validationURL (Apple server URL).
  3. Gateway makes mTLS POST to validationURL using the Merchant Identity Certificate (.p12 from Apple Developer portal).
  4. Apple returns a merchantSession opaque object.
  5. Gateway returns it to browser and session.completeMerchantValidation().
  6. Payment sheet appears.

Gateway endpoint: POST /v1/wallet/apple-pay/session

Step B: Payment Token Handling

After Face ID / Touch ID auth, Apple generates a PKPaymentToken containing:

  • paymentData: encrypted blob (DPAN + TAVV cryptogram + transaction details)
  • paymentMethod: card network, display name, type
  • transactionIdentifier: unique transaction ID

Two decryption paths:

PathWho DecryptsPCI Impact
Processor Decryption (recommended)TransIT/TSYS holds certGateway stays out of scope
Merchant DecryptionGateway decryptsSAQ-D scope, avoid

Recommendation: Use processor decryption. Register Payment Processing Certificate with TSYS/TransIT. Gateway passes raw paymentData blob through opaquely.

Apple Pay Registration Requirements

AssetDescriptionRotation
Apple Developer Account (Organization, $99/yr)Required for all certsAnnual
Merchant ID (merchant.com.myriad.gateway)Registered in Apple portalNever expires
Payment Processing CertificatePublic key encrypts tokens; private key held by TSYSAnnually
Merchant Identity Certificate (.p12)mTLS cert for session validationEvery 25 months
Domain Verification File.well-known/apple-developer-merchantid-domain-associationPer domain, one-time

For multi-tenant: Apply for Apple's Payment Platform status to use the Web Merchant Registration API for programmatic domain registration.

For operational setup and rotation, keep certificate and key material out of Terraform state. Terraform creates the Secret Manager containers and Cloud Run bindings; operators upload Apple-issued certificate/key versions out-of-band. Use the secrets rotation runbook for the current CSR, upload, redeploy, and verification procedure. For local synthetic-token development only, use scripts/generate-apple-pay-keys.sh.

Apple Pay / TSYS Material

Apple Pay / TSYS credential material includes Apple Pay payment-processing certificate material, Apple WWDR G2 certificate files, and password/private-key files for processor upload workflows. Do not copy these files or passwords into documentation. Move live secrets into the approved secret-management path before implementation, and track only non-secret inventory metadata under the source root.

This material is evidence for the Apple Pay card-not-present processor-decryption workstream. Apple Tap to Pay on iPhone is a separate Apple-native path: ABR / Partner Hub setup, PSP KEK and terminal-profile artifacts, Proximity Payment Service configuration, and card-present network certification evidence must be verified from the Apple partner/onboarding records without copying secret material into repo docs.


Section 2: Google Pay

Card-Present (NFC Tap)

Identical to Apple Pay card-present. Standard certified-terminal EMV contactless, with no Google Pay-specific gateway logic for the tap itself. The exact cardDataSource value belongs to the terminal/TransIT certification profile; local EMVContactless samples use EMV.

Card-Not-Present (Web / Android)

Simpler than Apple Pay, no merchant session validation required.

  1. Client initializes PaymentsClient with gateway config.
  2. User taps Google Pay button, selects card, authenticates.
  3. Google returns encrypted PaymentMethodToken (ECv2 protocol).
  4. Client sends token to gateway.
  5. Gateway passes through to TransIT.

Tokenization Modes

PAYMENT_GATEWAY (recommended):

const tokenizationSpecification = {
type: 'PAYMENT_GATEWAY',
parameters: {
'gateway': 'tsys', // Must confirm with TSYS
'gatewayMerchantId': 'YOUR_MERCHANT_ID'
}
};
  • Google encrypts with TransIT's public key (registered by TSYS with Google).
  • Gateway passes encrypted blob straight through.
  • No key management. No PCI scope increase.

DIRECT (not recommended):

  • Google encrypts with your gateway's ECDSA public key.
  • Gateway must decrypt using Google's Tink library.
  • Requires annual key rotation and PCI DSS compliance for card data.

Auth Methods in Google Pay Tokens

MethodDescriptionSecurity
CRYPTOGRAM_3DSDevice-bound DPAN + TAVV cryptogramHigher, equivalent to Apple Pay
PAN_ONLYCard stored in Google account, no device bindingLower, returns real PAN, no cryptogram

Google Pay Registration

  1. Create profile at https://pay.google.com/business/console
  2. Accept Terms of Service.
  3. Merchant ID appears in console.
  4. Submit integration for production review.
  5. No domain verification file needed. No mTLS certificates needed.

Google Pay API vs Google Wallet

Google Pay APIGoogle Wallet
PurposeAccept paymentsStore passes/loyalty/transit
Our use caseYesNot relevant
Token typePaymentMethodToken (ECv2)N/A

Section 3: TransIT API Integration

Card-Present Fields

FieldCurrent local evidenceNotes
cardDataSourceEMV in local EMVContactless samples; CONTACTLESS listed in the support-doc source tableEMV_CONTACTLESS is not confirmed in the local TransIT materials reviewed so far
EMV tag dataStandard EMV/contactless tags in emvTags.tag[]Terminal handles card read and emits the tag set

Card-Not-Present Fields

Based on TSYS-family processor documentation (Heartland Portico WalletData):

FieldValuesDescription
PaymentSourceApplePayWeb, ApplePayApp, GooglePayWeb, GooglePayAppWallet type
CryptogramBase64/Hex encodedTAVV (Apple) or TAVV/DSRP (Google)
ECI05, 06, 07Electronic Commerce Indicator
WalletTypeAPPLE_PAY, GOOGLE_PAYProcessor-level wallet identifier

Certification

TSYS was among the first processors certified for Apple Pay (2015). Digital wallet certification involves:

  • Running test transactions through TSYS sandbox (stagegw.transnox.com)
  • Wallet-specific test data scenarios
  • Passthrough mode, simpler certification than decryption mode

Section 4: PCI Scope Impact

Token Types

Token TypeWhat It IsPCI Scope
FPAN (Funding PAN)Real card numberFull scope, never touch
DPAN (Device PAN)Network token (DPAN != FPAN)In scope if decrypted
Encrypted PKPaymentTokenApple's encrypted blobOut of scope if passthrough
Encrypted ECv2 tokenGoogle's encrypted blobOut of scope if passthrough
Cryptogram (TAVV)One-time auth valueIn scope only if decrypted

By Integration Path

PathPCI Impact
Full passthrough (recommended)Minimal, encrypted tokens are not cardholder data
Gateway decryptsSAQ-D scope, HSM required, annual QSA audit
Card-present NFCSame as existing EMV scope

Recommendation: Use PAYMENT_GATEWAY (Google) + processor decryption (Apple). Gateway never sees plaintext DPAN or cryptogram. No PCI scope expansion.


Section 5: Current Gateway Surface

Public Wallet Endpoints

Apple Pay

EndpointMethodRuntime roleSource of truth
/v1/wallet/apple-pay/sessionPOSTMerchant session validation (mTLS to Apple)Public OpenAPI, online-txn WalletController, SDK WalletApi
/v1/wallet/apple-pay/chargePOSTProcess Apple Pay token (CNP)Public OpenAPI, online-txn WalletController, SDK WalletApi
/v1/wallet/apple-pay/authorizePOSTAuthorize Apple Pay token (CNP)Public OpenAPI, online-txn WalletController, SDK WalletApi

Google Pay

EndpointMethodRuntime roleSource of truth
/v1/wallet/google-pay/chargePOSTProcess Google Pay token (CNP)Public OpenAPI, online-txn WalletController, SDK WalletApi
/v1/wallet/google-pay/authorizePOSTAuthorize Google Pay token (CNP)Public OpenAPI, online-txn WalletController, SDK WalletApi
/v1/wallet/google-pay/configGETReturn gateway/merchantId configPublic OpenAPI, online-txn WalletController, SDK WalletApi

Card-Present

No new endpoints are required for traditional certified-terminal NFC. SoftPOS / Tap to Pay on iPhone remains card-present certification work; host-submission mapping stays governed by the TransIT SoftPOS mapping boundary and disabled capability flag until TSYS evidence confirms the request fields.

SDK Surface

class WalletApi(private val client: HttpClient) {
suspend fun validateApplePaySession(request: ApplePaySessionRequest): ApplePaySession
suspend fun chargeApplePay(request: ApplePayChargeRequest): WalletChargeResult
suspend fun authorizeApplePay(request: ApplePayAuthorizeRequest): WalletChargeResult
suspend fun getGooglePayConfig(): GooglePayConfig
suspend fun chargeGooglePay(request: GooglePayChargeRequest): WalletChargeResult
suspend fun authorizeGooglePay(request: GooglePayAuthorizeRequest): WalletChargeResult
}

The TypeScript SDK exposes the same wallet surface through GatewayPayClient.wallet and WalletApi.

Certificates & Keys

AssetWho Holds ItStorageRotation
Apple Merchant Identity Certificate (.p12)GatewaySecret ManagerEvery 25 months
Apple Payment Processing Cert private keyTSYS (processor decryption)N/AAnnually
Apple domain verification fileGateway domainCloud Run / CDNOne-time per domain
Google Pay ECDSA key pairN/A (PAYMENT_GATEWAY mode)N/AN/A
Google Pay Merchant IDConfigurationSpanner / configN/A

Third-Party Registrations

RegistrationWhereOperational owner
Apple Developer Account (Organization)developer.apple.comGateway platform / business owner
Apple Merchant ID + certsApple Developer portalGateway platform
Apple Pay Web Merchant Registration APIApple (application)Gateway platform
Google Pay & Wallet Consolepay.google.com/business/consoleGateway platform
Google Pay production approvalGoogle reviewGateway platform / merchant onboarding
TSYS digital wallet certificationTSYS account teamGateway platform / certification owner
SoftPOS / Tap to Pay processor mappingTSYS account teamCard-present certification owner

Remaining Production Controls

ControlCurrent boundary
Merchant wallet registrationKeep per-merchant Apple/Google IDs aligned with management and online-txn configuration before enablement.
Certificate rotationStore Apple Merchant Identity certificates in Secret Manager and rotate before the 25-month expiration.
Processor routingDo not change TransIT wallet-token serialization or processor routing without certification evidence.
SoftPOS / Tap to PayKeep production host submission disabled until the TransIT mapping questions in the TransIT integration doc are answered.

Section 6: Vendor Verification Boundaries

The gateway owns the card-not-present wallet flow: Apple Pay merchant-session validation, Google Pay configuration, wallet charge/authorize endpoints, Apple merchant registration, and processing handoff are implemented in the online-txn, management, processing services, and SDKs. Vendor and account-team confirmation is still required before changing processor routing or certification scope:

  1. Google Pay gateway identifier: keep the configured PAYMENT_GATEWAY tokenization identifier aligned with the TSYS/TransIT account profile.
  2. Apple Pay processor-decryption registration: confirm Payment Processing Certificate registration, certificate rollover, and merchant registration with Apple/TSYS before production cutovers.
  3. TransIT wallet-token fields: validate encrypted-token and decrypted-field mappings against authenticated TransIT docs and certification evidence before changing request serialization.
  4. Certification scope and timing: schedule separate wallet transaction certification for Apple Pay and Google Pay when enabling new merchant or processor profiles.
  5. Multi-merchant wallet configuration: confirm whether each merchant/location needs separate Apple, Google, and TSYS registration or can share the gateway profile.
  6. Card-present Tap to Pay/SoftPOS: treat Tap to Pay on iPhone and terminal contactless output as separate card-present certification work; local EMVContactless samples are not sufficient network evidence by themselves.

ResourceURL
Apple Pay Platform Integration Guidehttps://developer.apple.com/download/files/Apple-Pay-Platform-Integration-Guide.pdf
Apple Pay Token Format Referencehttps://developer.apple.com/documentation/passkit/payment-token-format-reference
Apple Pay Environment Setuphttps://developer.apple.com/documentation/applepayontheweb/configuring-your-environment
Google Pay Web APIhttps://developers.google.com/pay/api/web/overview
Google Pay Payment Data Cryptographyhttps://developers.google.com/pay/api/web/guides/resources/payment-data-cryptography
Google Pay Consolehttps://pay.google.com/business/console
GOV.UK Pay Connector (reference impl)https://github.com/alphagov/pay-connector
Adyen Apple Pay Decryptionhttps://docs.adyen.com/payment-methods/apple-pay/api-only/apple-pay-token-decryption
TransIT Developer Portalhttps://developers.tsys.com