> ## 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.

# Quickstart

> Accept wallet and card payments with 3D Secure using rinne-js.

This quickstart builds a checkout that supports Apple Pay, Google Pay, and card entry with 3D Secure — all from one SDK instance.

## Goal

In this guide, you will:

* Initialize the SDK
* Mount wallet buttons and card fields
* Run 3D Secure when required
* Forward encrypted payment data to your backend

## 1. Initialize Rinne

```typescript checkout.ts theme={null}
import { Rinne } from '@rinnebr/js'

const rinne = new Rinne({
  merchantId: 'your-merchant-id',
  environment: 'sandbox'
})
```

## 2. Mount Payment Elements

Mount wallet buttons for Apple Pay and Google Pay, and a card element for manual entry.

```typescript checkout.ts theme={null}
const transaction = await rinne.transaction.create({
  amount: 2500,
  lineItems: [
    { label: 'Premium Plan', amount: 2000 },
    { label: 'Tax', amount: 500 }
  ]
})

const walletHandlers = {
  onCapture: async (payload, fail) => {
    try {
      await submitToBackend(payload)
    } catch (error) {
      fail({ message: error instanceof Error ? error.message : 'Payment failed' })
    }
  }
}

const applePay = await rinne.elements.applePay(transaction, {
  button: { type: 'pay', color: 'black', locale: 'pt' },
  ...walletHandlers
})
await applePay.mount('#apple-pay-button')

const googlePay = await rinne.elements.googlePay(transaction, {
  button: { type: 'pay', color: 'black', locale: 'pt' },
  ...walletHandlers
})
await googlePay.mount('#google-pay-button')

const submitButton = document.querySelector<HTMLButtonElement>('#submit-button')!

const cardElement = await rinne.elements.card({
  theme: 'material',
  locale: 'pt',
  fields: ['number', 'expiry', 'cvc'],
  onChange: (state) => {
    submitButton.disabled = !state.isComplete || !state.isValid
  }
})

const mountedCard = await cardElement.mount('#card-element')
```

<Info>
  If you omit `currency` and `country`, the SDK defaults to `BRL` and `BR`.
</Info>

<Warning>
  Always call `fail()` inside `onCapture` when backend processing fails. This lets the wallet UI show a proper failure state and allows retry.
</Warning>

## 3. Handle Card Submission with 3DS

This example follows the **session-first** pattern: create a 3DS session, authenticate, then create the transaction. When the customer submits the card form, read the encrypted values, run the challenge if the issuer requires it, and create the transaction after authentication succeeds.

```typescript checkout.ts theme={null}
async function submitCardPayment(amountInCents: number) {
  if (!mountedCard.isComplete || !mountedCard.isValid) return

  const cardValues = mountedCard.values

  const session = await create3DSSession({
    amount: amountInCents,
    currency: 'BRL',
    card: {
      number: cardValues.card.number,
      expiry: { month: cardValues.card.expiry_month, year: cardValues.card.expiry_year }
    }
  })

  if (session.auth_status === 'FAILED') {
    throw new Error(session.failure_reason ?? '3DS authentication failed')
  }

  if (session.auth_status === 'ACTION_REQUIRED') {
    await run3DSChallenge(session.tds_session_id)
  }

  return await createTransaction({
    amount: amountInCents,
    cardData: cardValues.card,
    three_d_secure_session_id: session.id
  })
}

async function run3DSChallenge(tdsSessionId: string) {
  return new Promise<void>((resolve, reject) => {
    rinne.elements.threeDSecure({
      target: '#three-ds-container',
      onSuccess: () => resolve(),
      onFailure: (error) => reject(new Error(error?.message ?? 'Authentication failed')),
      onError: (error) => reject(new Error(error.message))
    }).then((threeDS) => threeDS.mount(tdsSessionId))
  })
}
```

<Note>
  `create3DSSession` and `createTransaction` represent calls to your backend. Rinne also supports a **transaction-first** pattern where you create the transaction before authentication. See the [Card + 3DS Guide](/rinne-js/guides/card-3ds-checkout) for both flows with full backend examples.
</Note>

<Warning>
  Never collect raw PAN/CVC in your own inputs. Use only encrypted values from `mountedCard.values`.
</Warning>

## 4. Verify Success

<Check>
  Your checkout is correctly wired when:

  * Wallet authorization triggers `onCapture` and your backend receives an encrypted payload
  * Card submission creates a 3DS session, runs the challenge via `onSuccess`, and creates the transaction with the authenticated session ID
  * `fail()` is called whenever wallet backend processing fails
</Check>

## Next Steps

<CardGroup cols={2}>
  <Card title="Card + 3DS Guide" icon="shield-check" href="/rinne-js/guides/card-3ds-checkout">
    Explore session-first and transaction-first flows for production card payments.
  </Card>

  <Card title="Wallet Guide" icon="wallet" href="/rinne-js/guides/wallet-checkout">
    Build the backend endpoint that processes wallet capture payloads.
  </Card>

  <Card title="Card Element" icon="credit-card" href="/rinne-js/card-element">
    Configure themes, validation events, and field options.
  </Card>

  <Card title="3D Secure Element" icon="lock" href="/rinne-js/three-d-secure-element">
    Handle modal vs embedded challenges, retries, and session expiry.
  </Card>
</CardGroup>
