> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rinne.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Wallet Elements

> Configure and mount Apple Pay and Google Pay elements with shared handlers.

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

```typescript theme={null}
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

```typescript theme={null}
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                |

## Button Behavior

| 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

<Warning>
  Apple Pay only appears on domains that are verified with Apple. If your domain is not verified, the Apple Pay button will not render.
</Warning>

Before going live:

1. Download the <a href="data:application/octet-stream;base64,N2IyMjc2NjU3MjczNjk2ZjZlMjIzYTMxMmMyMjcwNzM3MDQ5NjQyMjNhMjIzNjM5NDIzMjQ2NDEzMTM0MzM0NTMzNDU0MjM4MzkzMzMxMzAzMTM5NDMzOTQ2Mzg0NTM0MzEzMDQxNDI0MzMyMzEzMTQxMzg0NTMwMzQ0NDMyNDQzMzQzMzEzMTMxNDQ0NTM3MzE0NDMxMzkzMjMzNDIzMTM5NDM0NTM4MzY0NDIyMmMyMjYzNzI2NTYxNzQ2NTY0NGY2ZTIyM2EzMTM3MzMzMDM5MzEzMDMxMzYzNjM2MzYzODdk" download="apple-developer-merchantid-domain-association">Apple Pay domain association file</a>. Keep the filename exactly as it downloads — `apple-developer-merchantid-domain-association` with no extension.
2. Host it on every domain and subdomain where Apple Pay is used, at the exact path `/.well-known/apple-developer-merchantid-domain-association`, served over HTTPS.
3. Let Rinne know which domains and subdomains to register so they can be submitted to Apple for verification.

If the 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.

```typescript theme={null}
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.

```typescript theme={null}
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' })
  }
}
```

<Warning>
  If backend processing fails, call `fail()` inside `onCapture`. Without it, the wallet may stay in a processing state.
</Warning>

<Warning>
  rinne-js 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.
</Warning>

## colorScheme (Google Pay)

Use `colorScheme` to align the Google Pay iframe with your page theme.

```typescript theme={null}
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

```typescript theme={null}
const element = await rinne.elements.applePay(transaction, options)
const mounted = await element.mount('#apple-pay-container')

// Later
mounted.unmount()
```

<Info>
  `mount()` accepts either a CSS selector or an `HTMLElement`.
</Info>

## Mount Errors

`mount()` throws if the target is missing or the provider cannot render the wallet button.

```typescript theme={null}
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

```typescript theme={null}
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')
```
