Wallet Elements provide Apple Pay and Google Pay buttons backed by the same transaction object and callback contract.
Use them to collect tokenized wallet payment data and forward encrypted payloads to your backend for transaction processing.
Supported Wallet Elements
const applePay = await rinne.elements.applePay(transaction, options)
const googlePay = await rinne.elements.googlePay(transaction, options)
Both elements support the same core options (button, onCapture, onError, onCancel).
googlePay() also supports colorScheme.
Options
interface WalletMountOptions {
button?: {
color?: 'black' | 'white' // default: 'black'
locale?: 'pt' | 'en' | 'es' // default: 'pt'
type?: 'book' | 'buy' | 'checkout' | 'donate' | 'order' | 'pay' | 'plain' | 'subscribe' // default: 'plain'
borderRadius?: number
size?: {
width: string | number // default: '100%'
height: string | number // default: '40px'
}
}
colorScheme?: 'light' | 'dark' // Google Pay only: iframe root color-scheme
onCapture?: (payload, fail) => Promise<void> | void
onError?: (error) => void
onCancel?: () => void
}
Event Lifecycle
| Stage | Callback | What you should do |
|---|
| User authorizes wallet payment | onCapture(payload, fail) | Send payload.card_data to your backend and create/confirm the transaction |
| Backend processing fails | fail({ message }) | Call fail() so the wallet UI exits processing state and can retry |
| User closes wallet sheet | onCancel() | Restore your checkout UI and keep cart state |
| Provider or SDK issue | onError(error) | Show a fallback payment method and log details for debugging |
| Capability | Apple Pay | Google Pay |
|---|
| Button color | black, white | black, white |
| Button types | book, buy, checkout, donate, order, pay, plain, subscribe | Same as Apple Pay |
| Locale input | pt, en, es | pt, en, es |
Wallet Availability
Apple Pay and Google Pay buttons are not rendered when the environment does not support them. This happens silently — mount() resolves without rendering any visible element. Conditions that prevent rendering include:
- Non-HTTPS origin
- Browser or device without wallet support
- No eligible card registered in the wallet
- Apple Pay domain not verified (Apple Pay only)
Design your checkout layout so it gracefully handles an empty wallet button slot, or check support before mounting.
Apple Pay Domain Verification
Apple Pay only appears on domains that are verified with Apple. If your domain is not verified, the Apple Pay button will not render.
Before going live:
- Ask Rinne support to validate every production domain/subdomain where Apple Pay is used and get your verification file
- Keep the verification file available at
/.well-known/apple-developer-merchantid-domain-association
- Re-run verification when you add a new domain or subdomain
If this verification file is removed, replaced, or becomes unavailable, Apple can invalidate the domain and Apple Pay will stop working until the domain is verified again.
onCapture Contract
onCapture gives you encrypted wallet card data, payment method, and the transaction object you created.
interface WalletSuccessPayload {
card_data: {
network_token?: string
cryptogram: string
expiry_month: string
expiry_year: string
eci?: string | null
token_provider?: string
brand?: string
last_digits?: string
wallet_type?: 'APPLE_PAY' | 'GOOGLE_PAY'
authentication_type?: string
display_name?: string
}
payment_method: 'CREDIT_CARD' | 'DEBIT_CARD'
transaction: EvTransaction
}
payment_method is inferred from wallet funding data and defaults to CREDIT_CARD when funding type is not provided by the provider.
onCapture: async (payload, fail) => {
try {
await sendToBackend(payload.card_data, payload.payment_method, payload.transaction)
} catch (error) {
fail({ message: error instanceof Error ? error.message : 'Payment failed' })
}
}
If backend processing fails, call fail() inside onCapture. Without it, the wallet may stay in a processing state.
RinneJS only supports tokenized Google Pay payments with 3DS cryptogram authentication. Non-tokenized (PAN-only) payment methods are not accepted and will not be available for payment.
colorScheme (Google Pay)
Use colorScheme to align the Google Pay iframe with your page theme.
const colorScheme =
document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
const googlePay = await rinne.elements.googlePay(transaction, {
button: { color: 'black', type: 'pay', locale: 'pt' },
colorScheme,
...walletHandlers
})
Mount and Unmount
const element = await rinne.elements.applePay(transaction, options)
const mounted = await element.mount('#apple-pay-container')
// Later
mounted.unmount()
mount() accepts either a CSS selector or an HTMLElement.
Mount Errors
mount() throws if the target is missing or the provider cannot render the wallet button.
try {
const applePay = await rinne.elements.applePay(transaction, options)
await applePay.mount('#missing-wallet-slot')
} catch (error) {
console.error('Wallet mount failed', error)
}
Full Wallet Example
const transaction = await rinne.transaction.create({
amount: 1999,
lineItems: [{ label: 'Demo Product', amount: 1999 }]
})
const colorScheme =
document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
const walletHandlers = {
onCapture: async (payload, fail) => {
try {
const response = await fetch('/api/wallet/charge', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
cardData: payload.card_data,
paymentMethod: payload.payment_method,
amount: payload.transaction.details.amount
})
})
if (!response.ok) {
const body = await response.json()
throw new Error(body.message ?? 'Charge failed')
}
} catch (error) {
fail({ message: error instanceof Error ? error.message : 'Charge failed' })
}
},
onError: (error) => console.error(error),
onCancel: () => console.log('Cancelled')
}
const applePay = await rinne.elements.applePay(transaction, {
button: { color: 'black', type: 'pay', locale: 'pt', borderRadius: 0 },
...walletHandlers
})
await applePay.mount('#apple-pay')
const googlePay = await rinne.elements.googlePay(transaction, {
button: { color: 'black', type: 'pay', locale: 'pt', borderRadius: 0 },
colorScheme,
...walletHandlers
})
await googlePay.mount('#google-pay')