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): Zero gateway-specific logic. Terminal handles EMV contactless. Gateway sets cardDataSource = EMV_CONTACTLESS to TransIT.
Card-not-present: Gateway needs new endpoints. Recommended architecture: processor decryption (Apple Pay) and PAYMENT_GATEWAY tokenization (Google Pay). Both keep encrypted wallet tokens opaque, TransIT decrypts. Minimal PCI scope increase.
Estimated effort: 3 to 5 months for full production, TSYS certification is the long pole.
Architecture Overview
┌─────────────────────────────────────────────────────────────────┐
│ CARD-PRESENT (NFC) │
│ │
│ iPhone/Android ──NFC──► Terminal ──EMV Contactless──► Gateway │
│ │
│ Gateway action: Set cardDataSource=EMV_CONTACTLESS → 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:
- Device Secure Element communicates via NFC using EMVCo contactless spec (ISO/IEC 14443).
- Secure Element passes DPAN (Device PAN), dynamic cryptogram (TAVV), and transaction details to the terminal.
- Terminal processes as standard EMV contactless, sends to gateway normally.
- Gateway forwards to TransIT with
cardDataSource = EMV_CONTACTLESS. - 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:
- Browser calls
new ApplePaySession(version, paymentRequest)andonvalidatemerchantfires. - Event provides a
validationURL(Apple server URL). - Gateway makes mTLS POST to
validationURLusing the Merchant Identity Certificate (.p12 from Apple Developer portal). - Apple returns a
merchantSessionopaque object. - Gateway returns it to browser and
session.completeMerchantValidation(). - Payment sheet appears.
New endpoint needed: 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, typetransactionIdentifier: unique transaction ID
Two decryption paths:
| Path | Who Decrypts | PCI Impact |
|---|---|---|
| Processor Decryption (recommended) | TransIT/TSYS holds cert | Gateway stays out of scope |
| Merchant Decryption | Gateway decrypts | SAQ-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
| Asset | Description | Rotation |
|---|---|---|
| Apple Developer Account (Organization, $99/yr) | Required for all certs | Annual |
Merchant ID (merchant.com.myriad.gateway) | Registered in Apple portal | Never expires |
| Payment Processing Certificate | Public key encrypts tokens; private key held by TSYS | Annually |
| Merchant Identity Certificate (.p12) | mTLS cert for session validation | Every 25 months |
| Domain Verification File | .well-known/apple-developer-merchantid-domain-association | Per domain, one-time |
For multi-tenant: Apply for Apple's Payment Platform status to use the Web Merchant Registration API for programmatic domain registration.
Section 2: Google Pay
Card-Present (NFC Tap)
Identical to Apple Pay card-present. Standard EMV contactless. No Google Pay-specific logic. Gateway sets cardDataSource = EMV_CONTACTLESS.
Card-Not-Present (Web / Android)
Simpler than Apple Pay, no merchant session validation required.
- Client initializes
PaymentsClientwith gateway config. - User taps Google Pay button, selects card, authenticates.
- Google returns encrypted
PaymentMethodToken(ECv2 protocol). - Client sends token to gateway.
- 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
| Method | Description | Security |
|---|---|---|
CRYPTOGRAM_3DS | Device-bound DPAN + TAVV cryptogram | Higher, equivalent to Apple Pay |
PAN_ONLY | Card stored in Google account, no device binding | Lower, returns real PAN, no cryptogram |
Google Pay Registration
- Create profile at https://pay.google.com/business/console
- Accept Terms of Service.
- Merchant ID appears in console.
- Submit integration for production review.
- No domain verification file needed. No mTLS certificates needed.
Google Pay API vs Google Wallet
| Google Pay API | Google Wallet | |
|---|---|---|
| Purpose | Accept payments | Store passes/loyalty/transit |
| Our use case | Yes | Not relevant |
| Token type | PaymentMethodToken (ECv2) | N/A |
Section 3: TransIT API Integration
Card-Present Fields
| Field | Value | Notes |
|---|---|---|
cardDataSource | EMV_CONTACTLESS | Confirmed supported by TSYS MultiPass |
| EMV tag data | Standard contactless tags | Terminal handles; DPAN in track data |
Card-Not-Present Fields
Based on TSYS-family processor documentation (Heartland Portico WalletData):
| Field | Values | Description |
|---|---|---|
PaymentSource | ApplePayWeb, ApplePayApp, GooglePayWeb, GooglePayApp | Wallet type |
Cryptogram | Base64/Hex encoded | TAVV (Apple) or TAVV/DSRP (Google) |
ECI | 05, 06, 07 | Electronic Commerce Indicator |
WalletType | APPLE_PAY, GOOGLE_PAY | Processor-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 Type | What It Is | PCI Scope |
|---|---|---|
| FPAN (Funding PAN) | Real card number | Full scope, never touch |
| DPAN (Device PAN) | Network token (DPAN != FPAN) | In scope if decrypted |
| Encrypted PKPaymentToken | Apple's encrypted blob | Out of scope if passthrough |
| Encrypted ECv2 token | Google's encrypted blob | Out of scope if passthrough |
| Cryptogram (TAVV) | One-time auth value | In scope only if decrypted |
By Integration Path
| Path | PCI Impact |
|---|---|
| Full passthrough (recommended) | Minimal, encrypted tokens are not cardholder data |
| Gateway decrypts | SAQ-D scope, HSM required, annual QSA audit |
| Card-present NFC | Same 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: Implementation Checklist
New Endpoints
Apple Pay
| Endpoint | Method | Description | Effort |
|---|---|---|---|
/v1/wallet/apple-pay/session | POST | Merchant session validation (mTLS to Apple) | Medium |
/v1/wallet/apple-pay/charge | POST | Process Apple Pay token (CNP) | Small |
/v1/wallet/apple-pay/authorize | POST | Authorize Apple Pay token (CNP) | Small |
Google Pay
| Endpoint | Method | Description | Effort |
|---|---|---|---|
/v1/wallet/google-pay/charge | POST | Process Google Pay token (CNP) | Small |
/v1/wallet/google-pay/authorize | POST | Authorize Google Pay token (CNP) | Small |
/v1/wallet/google-pay/config | GET | Return gateway/merchantId config | Small |
Card-Present
No new endpoints, handled by existing terminal flow with cardDataSource = EMV_CONTACTLESS.
SDK Additions
interface WalletService {
// Apple Pay CNP
suspend fun validateApplePayMerchant(
validationUrl: String,
domain: String,
): MerchantSession
suspend fun chargeApplePay(
token: ApplePayToken,
amount: Money,
merchantId: String,
): ChargeResponse
// Google Pay CNP
fun getGooglePayConfig(merchantId: String): GooglePayConfig
suspend fun chargeGooglePay(
token: GooglePayToken,
amount: Money,
merchantId: String,
): ChargeResponse
}
Certificates & Keys
| Asset | Who Holds It | Storage | Rotation |
|---|---|---|---|
| Apple Merchant Identity Certificate (.p12) | Gateway | Secret Manager | Every 25 months |
| Apple Payment Processing Cert private key | TSYS (processor decryption) | N/A | Annually |
| Apple domain verification file | Gateway domain | Cloud Run / CDN | One-time per domain |
| Google Pay ECDSA key pair | N/A (PAYMENT_GATEWAY mode) | N/A | N/A |
| Google Pay Merchant ID | Configuration | Spanner / config | N/A |
Third-Party Registrations
| Registration | Where | Effort |
|---|---|---|
| Apple Developer Account (Organization) | developer.apple.com | Small ($99/yr) |
| Apple Merchant ID + certs | Apple Developer portal | Small to medium |
| Apple Pay Web Merchant Registration API | Apple (application) | Medium |
| Google Pay & Wallet Console | pay.google.com/business/console | Small |
| Google Pay production approval | Google review | Small to medium |
| TSYS digital wallet certification | TSYS account team | Large |
Effort Estimates
| Component | Effort |
|---|---|
| Apple Pay merchant session endpoint | Medium |
| Apple Pay CNP charge/auth endpoints | Small |
| Google Pay CNP charge/auth endpoints | Small |
| Google Pay client config endpoint | Small |
| Multi-tenant merchant registration (Apple) | Large |
| Certificate management infrastructure | Medium |
| TransIT digital wallet API integration | Medium |
| TSYS certification testing | Large |
| Card-present NFC | Small |
| PCI documentation update | Small to medium |
| Domain verification automation | Medium |
Total: 3 to 5 months, TSYS certification is the long pole item.
Section 6: Blockers, Must Confirm with TSYS
Before writing implementation code, get answers from TSYS account team:
- Is TransIT registered as a Google Pay gateway partner? What is the
gatewayidentifier forPAYMENT_GATEWAYtokenization? - Does TransIT offer Apple Pay processor decryption? What is the process for registering the Payment Processing Certificate with them?
- What are the exact TransIT API fields for submitting wallet tokens (encrypted passthrough vs. decrypted fields)?
- What is the certification timeline for digital wallet transaction types?
- Does TransIT support multi-merchant wallet configurations (one gateway, many merchant IDs)?
Reference Links
| Resource | URL |
|---|---|
| Apple Pay Platform Integration Guide | https://developer.apple.com/download/files/Apple-Pay-Platform-Integration-Guide.pdf |
| Apple Pay Token Format Reference | https://developer.apple.com/documentation/passkit/payment-token-format-reference |
| Apple Pay Environment Setup | https://developer.apple.com/documentation/applepayontheweb/configuring-your-environment |
| Google Pay Web API | https://developers.google.com/pay/api/web/overview |
| Google Pay Payment Data Cryptography | https://developers.google.com/pay/api/web/guides/resources/payment-data-cryptography |
| Google Pay Console | https://pay.google.com/business/console |
| GOV.UK Pay Connector (reference impl) | https://github.com/alphagov/pay-connector |
| Adyen Apple Pay Decryption | https://docs.adyen.com/payment-methods/apple-pay/api-only/apple-pay-token-decryption |
| TransIT Developer Portal | https://developers.tsys.com |