Invoice validation
Before accepting a Loan, we require the invoice or receivable to be validated by the Debtor. This helps reduce the risk of disputes, for example, if the invoice is later contested. Our goal is to ensure we’re advancing funds against a confirmed and undisputed receivable.
There are three possible situations:
- All invoices sent to Aria are already validated in your platform, which includes a mechanism where the buyer (debtor) validates the invoice before a Loan is created.
- No debtor interaction at all: Your product does not include any mechanism to validate the invoice, nor does it interact with the debtor.
- You have a debtor interface, but no validation: Your product includes a debtor interface (e.g., to view invoices), but no action is taken to validate or confirm the invoice.
In the last case, we built a widget that can be integrated in a few lines of code, that handles debtor authentication and validation.
Case | Solution |
---|---|
| Use the create invoice validation endpoint. |
| Let Aria send an email to the Debtor to get the invoice validated. |
| Embed our invoice validation widget. |
How it works
The widget displays a two-step pop-in (modal) triggered when the debtor clicks a “Validate Invoice” button on your platform.
- The debtor opens your invoice view and click the “Validate Invoice” button, which triggers our widget.
- The pop-in appears automatically.
- The debtor reviews and updates their professional information.
- Aria sends a verification code to the debtor’s email.
- The debtor enters the code.
- Your front-end is updated with the validation status, you can display the right payment method.

Our recommendations
- Wait for the invoice validation to be done to display our bank account for Debtor payment.
- If it takes too long for the invoice to be validated by the debtor, replace the validation button for the supplier's bank account directly, and cancel the loan creation process.
Features
User experience
- Secure iframe-based validation
- Design customization (via CSS variables)
- Supported localization: EN/FR/NL
- Accessible and screen-reader friendly
- Origin checking and sandboxing
- Simple lifecycle with
.render()
and.destroy()
- Lightweight and framework-agnostic
Security & accessibility
- Origin checking (messages only accepted from your domain)
- Sandboxed iframe
- Tab trapping and ESC-to-close
- Screen reader-friendly
aria-*
attributes - Timeout handling for stale widgets
Implementation
Option 1: Package manager
- Install the package
npm install @hello-aria/embed
# or
yarn add @hello-aria/embed
# or
pnpm add @hello-aria/embed
- Initialize the library
import AriaEmbed from '@hello-aria/embed'
AriaEmbed.init({
language: 'EN',
styles: {
'--color-primary': '#3b82f6'
}
})
- Render the validation widget
AriaEmbed.invoiceValidation.render({
contact: {
email: '[email protected]',
firstName: 'Alice',
lastName: 'Martin'
},
invoiceId: 'inv_12345',
onSuccess: (payload) => console.log('Validated:', payload),
onError: (error) => console.error('Validation error:', error)
})
Option 2: CDN
You can also include the widget directly via a CDN in your HTML page:
<script src="https://cdn.jsdelivr.net/npm/@hello-aria/embed/dist/index.umd.min.js"></script>
<script>
AriaEmbed.init({
language: 'EN',
styles: {
'--color-primary': '#3b82f6'
}
})
AriaEmbed.invoiceValidation.render({
contact: {
email: '[email protected]',
firstName: 'Alice',
lastName: 'Martin'
},
invoiceId: 'inv_12345',
onSuccess: (payload) => console.log('Validated:', payload),
onError: (error) => console.error('Validation error:', error)
})
</script>
The global
AriaEmbed
object is available when using the CDN. Make sure to include the script before you callinit()
orrender()
.
API
Initialization
Initializes the widget with your language, and optional theme styles.
init(options: InitOptions): AriaEmbedAPI
Option | Type/Enum | Required | Description |
---|---|---|---|
|
| ✅ True | Supported localization |
| object | False | Custom CSS variables for theming |
Rendering
Renders the modal with the validation iframe.
invoiceValidation.render(options: InvoiceValidationRenderOptions): void
Option | Type/Enum | Required | Description |
---|---|---|---|
|
| ✅ True | Debtor contact info |
| string | ✅ True | ID of the invoice to validate |
|
| False | Called when validation is successful |
|
| False | Called when an error occurs |
Lifecycle
invoiceValidation.destroy(): void
: Destroys the widget and removes all resources.
invoiceValidation.isRendered(): boolean
: Checks if the modal is currently open.
reinit(options: InitOptions): AriaEmbedAPI
: Reinitializes the widget with new options.
destroy(): void
: Completely resets the widget and removes all styles and listeners.
Theming
You can customize the look and feel of the widget using CSS variables passed in styles
:
{
'--color-primary': '#3b82f6',
'--color-textPrimaryButton': '#ffffff',
'--fonts-serif': '"Georgia", serif'
}
Available Variables
--color-primary
: Main color that will be used for main CTA background, input focus, loaders...--color-textPrimaryButton
: Text color for the main CTA.--fonts-noserif
: A font of your choosing.--fonts-serif
: A font of your choosing.
Error Handling
We provide two custom error classes:
InitializationError
— thrown duringinit()
if required options are missing or malformed.RenderError
— thrown duringrender()
if the widget fails to mount or receives invalid options.
Cleanup and Lifecycle
- Automatically restores body scroll after destroy
- Adds and removes
aria-live
announcements - Prevents double rendering
- Handles iframe load timeout
Updated 1 day ago