@authvia/payment-method-create
v1.0.8
Published
Authvia Payment Method Form Web Component - Payment method form built with Vue 3 and Vuetify 3
Downloads
1,714
Readme
Authvia Payment Method Form
Vue 3 + Vuetify 3 component and standalone web component for adding a saved payment method (card, ACH, PayPal, Venmo, Paze, and related options). You choose which methods to expose; only enabled methods appear. On success the host receives a payment method id.
Full prop and behavior notes live in Storybook (AuthviaPaymentMethodForm story docs) and in exported TypeScript types.
Requirements
- Vue
>= 3.4.0 - Vuetify
3.x(your app creates the Vuetify instance; this package does not) - MDI font CSS on the host page (Material Design Icons)
If Vue, Vuetify, or styles are missing in a web-component embed, the element may emit authvia:dependency-missing.
Installation
npm install @authvia/payment-method-createExports:
- Vue plugin / module:
@authvia/payment-method-create(default build) - Standalone web component:
@authvia/payment-method-create/web-component
Features (summary)
- Token: A valid JWT is required for the inner form to render. The token must include
https://authvia.com/uuidandpayment_methods:createinscope. Missing, empty, invalid, or expired tokens keep the form hidden; the wrapper emitserroras{ phase: 'init', error }and logs a warning, and does not emitready.readyis emitted only after the token passes validation. - Enabled methods: Props such as
card,ach,paypal,venmo, andpazecontrol what appears. Methods you do not configure stay off the list. - Runtime errors: Failures while saving emit
errorwith a payload that usually includes amessagestring (shape is not{ phase: 'init', … }). Incomplete Paze or PayPal/Venmo (for non-payoutsintent) config hides those methods in the list instead of erroring on open. The embed usually stays mounted so the user can retry. - Sentry: Supports standalone widget ownership (
VITE_WIDGET_SENTRY_DSN) and host-owned ownership (VITE_SENTRY_EMBED_MODE=lockorwindow.__AUTHVIA_EMBED__.sentry='host') without double-init. - Success:
successcarries payment method details (see Events). The host decides navigation or hiding the embed. - Styling: Accent color, border radius, and field
variantare configurable; CSS variables use the--avwc-*prefix on the form root.
Vue: register the plugin
Your application must call createVuetify() (and load Vuetify styles + MDI) before registering this plugin.
import { createApp } from 'vue';
import { createVuetify } from 'vuetify';
import AuthviaPaymentMethodFormPlugin from '@authvia/payment-method-create';
import App from './App.vue';
const app = createApp(App);
const vuetify = createVuetify();
app.use(vuetify);
app.use(AuthviaPaymentMethodFormPlugin);
app.mount('#app');Named export AuthviaPaymentMethodFormPlugin is also available for explicit imports.
Vue: use the component
<template>
<AuthviaPaymentMethodForm
:token="token"
merchant-id="demo-merchant"
customer-ref="demo-customer"
intent="payments"
:card="{ demoMode: false }"
:ach="{ demoMode: false, online: true }"
@ready="onReady"
@success="onSuccess"
@error="onError"
/>
</template>
<script setup lang="ts">
import { AuthviaPaymentMethodForm } from '@authvia/payment-method-create';
function onReady(): void {
/* JWT passed validation; inner form can render */
}
function onSuccess(detail: unknown): void {
/* includes paymentMethodId — see types */
}
function onError(detail: unknown): void {
/* init: { phase: 'init', error }; runtime: often { message } */
}
</script>Web component
Load Vue 3, Vuetify CSS, and MDI before the bundle. Use the data- prefix for attributes; object props are JSON strings on the element.
See demo.html in this repo for a full page example.
<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" data-vuetify />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" data-mdi /><authvia-create-payment-method-form
data-token="YOUR_JWT"
data-merchant-id="demo-merchant"
data-customer-ref="demo-customer"
data-intent="payments"
data-card='{"demoMode":false,"submitBtnText":"Add card"}'
data-color="#4CAF50"
data-border-radius="1rem"
></authvia-create-payment-method-form>Load the built script after Vue (for example the output of npm run build:wc):
<script type="module" src="https://cdn.authvia.com/web-components/authvia-payment-method-create/authvia-payment-method-create.js"></script>Web component events
Listen on the custom element for:
| Event | detail |
|--------|----------|
| ready | Emitted only when the JWT passes validation (non-empty, parseable, not expired, required scope). Not emitted for missing, invalid, expired, or under-scoped tokens; use error with { phase: 'init', error } instead. |
| submit | Emitted from some inner flows (for example ACH / PayPal) with form-related payloads. |
| success | Saved payment method; includes paymentMethodId in the normalized payload. |
| error | Init failures: { phase: 'init', error }. Runtime: often { message: string } or similar. |
| authvia:dependency-missing | Host is missing Vue, Vuetify, or required styles. |
<script>
const component = document.querySelector('authvia-create-payment-method-form');
component?.addEventListener('ready', () => { /* … */ });
component?.addEventListener('success', (e) => { console.log(e.detail); });
component?.addEventListener('error', (e) => { console.log(e.detail); });
</script>Sentry behavior
The package uses a single-client ownership model:
- Standalone widget mode: set
VITE_WIDGET_SENTRY_DSN; the widget callsSentry.initonce and tags events withcomponent=payment-method-createandintegration=standalone-web-component. - Embedded host mode (Lock or another host): set
VITE_SENTRY_EMBED_MODE=lockat build time, or setwindow.__AUTHVIA_EMBED__.sentry = 'host'before widget mount; the widget skipsSentry.initand attaches handlers to the active host client. - No active Sentry client: capture helpers are safe no-ops.
Supported Sentry env vars:
| Variable | Purpose | Default |
|----------|---------|---------|
| VITE_WIDGET_SENTRY_DSN | DSN for standalone widget ownership | unset |
| VITE_SENTRY_EMBED_MODE | Set to lock to force host-owned mode | unset |
| VITE_SENTRY_RELEASE | Optional release version sent to Sentry | unset |
| VITE_SENTRY_REPLAY_SESSION_SAMPLE_RATE | Session replay sample rate (0..1) | 0 |
| VITE_SENTRY_REPLAY_ON_ERROR_SAMPLE_RATE | Replay-on-error sample rate (0..1) | 1 |
Props (overview)
Details and examples match Storybook (src/components/AuthviaPaymentMethodForm.stories.ts).
| Area | Props |
|------|--------|
| Auth / context | token, merchantId, customerRef, intent |
| Methods | card, ach, paypal, venmo, paze |
| List UI | paymentMethodDisplay (titles, subtitles, order; optional root gap) |
| Legal / footer | terms (privacy + terms links) |
| Behavior | forgetHidden, forgetDefault |
| Styling | color (default #4CAF50, from DEFAULT_AVWC_PRIMARY_COLOR), borderRadius (default 1rem, from DEFAULT_AVWC_BORDER_RADIUS), variant (default outlined, from DEFAULT_AVWC_FIELD_VARIANT), vuetifyOverrides (web component: plain CSS string for Shadow DOM) |
paymentMethodDisplay
Controls the payment method picker list (labels and order). It does not turn methods on or off; use card, ach, paypal, etc. for that.
| Field | Description |
|--------|-------------|
| gap (root, optional) | Vertical space between option rows. Any CSS length (1rem, 12px, …). If omitted, this prop does not add spacing; layout matches the previous behavior (no list-level gap from this object). |
| card, ach, paypal, venmo, paze | Optional title, subtitle, and order. Lower order values appear higher in the list. |
Vue
:payment-method-display="{
gap: '1rem',
card: { title: 'Credit / debit card', subtitle: '…', order: 1 },
ach: { title: 'Bank account', subtitle: '…', order: 2 }
}"Web component (data-payment-method-display): pass a single JSON object string. Use commas between properties. Invalid JSON is ignored (check the console).
data-payment-method-display='{"gap":"1rem","card":{"title":"Card","order":1},"ach":{"title":"Bank","order":2}}'Paze (paze)
Requires amount, clientId, profileId, and name on the object you pass; all must be non-empty (after trim). If any are missing or blank, Paze is not shown in the picker. The inner flow runs in two steps: Initializing Paze (SDK load) then Processing Paze payment (checkout → complete → create). Failures emit error and return the user to the payment method list without an inline error banner on that step; details are logged for developers.
PayPal / Venmo
intent="payouts":paypalandvenmocan be booleans; PayPal and Venmo stay listed even whenmerchantIdis incomplete (same as before for payouts).intent="payments"(and any intent other thanpayouts): PayPal and Venmo appear in the picker only whenmerchantIdis non-empty on the resolved wallet settings and the build definesVITE_APP_PAYPAL_CLIENT_ID. Otherwise those rows are hidden (same rules as the former click-timeerror, without showing a dead option).- Pass
merchantIdand optionalredirectUrlon thepaypal/venmoobject when you want the payments flow to succeed.
Stable styling hook classes (overrides)
Use these hooks in data-vuetify-overrides (web component) or host CSS. Canonical strings live in src/constants/avwcStylingHooks.ts (avwcPaymentMethodFormHooks).
| Class | Where |
|--------|--------|
| avwc-payment-method-form__root | Main form wrapper (AuthviaPaymentMethodForm) |
| avwc-payment-method-form__options-root | Options container (AuthviaPaymentMethodOptions v-container) |
| avwc-payment-method-form__options-card | Payment method selection v-card |
| avwc-payment-method-form__options-list | List area wrapping picker rows |
| avwc-payment-method-form__method-dialog | Each payment-method v-dialog content v-card |
| avwc-payment-method-form__method-row | Each picker row (AuthviaPaymentMethodCard) |
| avwc-payment-method-form__credit-card-section | Credit card block inside the card/PayPal dialog |
| avwc-payment-method-form__ach-root | ACH add-bank flow root (AuthviaPaymentMethodAddAch) |
Inside each picker row (data-vuetify-overrides): combine with the row hook, e.g. .avwc-payment-method-form__method-row .payment-method-card__title { color: #1565c0 !important; } for title text, .payment-method-card__logo-slot for icon tint, .payment-method-card__subtitle for the description line.
CSS variables
The form root sets theming variables, including:
--avwc-color(accent; mirrorscolorprop, default#4CAF50fromDEFAULT_AVWC_PRIMARY_COLOR)--avwc-border-radius(mirrorsborderRadius, default1remfromDEFAULT_AVWC_BORDER_RADIUS)
Additional tokens (for example --avwc-text-color-light) are documented in variables.css and Storybook.
Development
Prerequisites: Node.js 18+, npm 9+.
npm install
npm run dev # app dev server
npm run build # Vue module
npm run build:wc # web component
npm run type-check
npm run lint
npm testBundle and assets
- The Vue module expects Vue and Vuetify as peer dependencies; your app supplies Vuetify and MDI.
- The standalone web component bundles Vuetify JavaScript but expects Vuetify CSS + MDI from the host (same as
demo.html). - Component styles ship with the JS; add Vuetify + MDI at the app level.
Browser support
Chrome 88+, Firefox 85+, Safari 14+, Edge 88+.
Changelog
Version 1.0.3
Added Storybook stories and expanded unit tests; fixed duplicate tender-type filtering in useWalletMerchantService. See git history for details.
Version 1.0.2
Unified success payloads for ACH and card ({ type, paymentMethodId, use }), --avwc-* CSS variables with backward-compatible fallbacks, and named plugin export.
Documentation (current)
README aligned with AuthviaPaymentMethodForm.stories.ts (including paymentMethodDisplay.gap), demo.html, and package exports (@authvia/payment-method-create).
License
MIT License — see the LICENSE file.
Support
For support and questions, contact the Authvia UI Team.
