The events at key points in the payment lifecycle from initial render through approval or decline.
These events provide valuable touchpoints for monitoring and analyzing customer interactions. They track successful payments form initialization and field level behavior across the payment workflow.
By subscribing to these events you can
- React to UI state changes by showing spinners hiding preloaders and animating containers
- Build real time analytics and funnel tracking without server side instrumentation
- Adapt checkout UX dynamically based on the card the customer is entering
- Handle payment outcomes and redirect users to the appropriate next step
- Log errors and send diagnostics to monitoring tools like Sentry or Datadog
Subscribe Subscribe to any event using the SDK method that matches your framework. All event callbacks receive a typed message object. React
<Payment
{...restParams}
onEventName={callback}
/>
Vanilla JS
const form = PaymentFormSdk.init(data)
form.on('event_type', (e) => {
const body = e.data // The body of any available event as it described below.
// The code will be run when the event is received.
})
Vue
<Payment
@event-name="callback"
/>
Angular
<ngx-solid-payment
(eventName)="callback($event)"
/>
Unsubscribe
Remove event listeners before destroying the form instance or switching payment intents.
form.unsubscribeAll()removes all event subscriptionsform.unsubscribe("eventName")removes one event subscription- Pass the event name you want to stop listening to
Form lifecycle
These events track the major stages of the payment form from initialization to submission and provide feedback on whether the payment process was successful or failed.
Mounted
When the Payment Form, Google Pay, Apple Pay, or APM buttons are initialized, rendered, and displayed.
Use cases
- Hide a skeleton or preloader and reveal the checkout container
- Start a session inactivity timer to expire the session after 10 minutes of no interaction
- Log a
form_shownevent to your analytics pipeline for funnel tracking
interface MountedMessage {
type: 'mounted',
entity: 'applebtn' | 'googlebtn' | 'form' | 'resign' | 'bizum' | 'blik' | 'mbway' | 'paypal' | 'pix' | 'pix-qr' // one of listed values
}
React
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"
export const MyPayment: FC<{
merchantData: InitConfig['merchantData']
styles?: InitConfig['styles']
formParams?: InitConfig['formParams']
width?: string
}> = (props) => {
const handleMounted = useCallback((event: SdkMessage[MessageType.Mounted]) => {
// here logic
}, [])
return (<Payment
{...props}
onMounted={handleMounted}
/>)
}
Vanilla JS
form.on('mounted', e => {
const data = e.data // MountedMessage
})
Vue
<template>
<Payment
:merchant-data="merchantData"
@mounted="mounted"
/>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))
const merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
function mounted(event: SdkMessage[MessageType.Mounted]): void {
// here your logic
}
</script>
Angular
import {Component} from '@angular/core';
import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";
@Component({
selector: 'app-root',
template: `
<ngx-solid-payment
[merchantData]="merchantData"
(mounted)="onMounted($event)"
></ngx-solid-payment>
`
})
export class AppComponent {
merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
onMounted(event: SdkMessage[MessageType.Mounted]): void {
// here your logic
}
}
Submit
When the payment is successfully submitted by the customer, the event can be triggered for Payment Form, Google Pay, Apple Pay, or APM buttons.
Use cases
- Disable the Pay button to prevent duplicate submissions
- Show a loading spinner or overlay on the form
- Record the timestamp for payment latency metrics
- Lock the order summary UI so the customer cannot change quantity during processing
interface SubmitMessage {
type: 'submit',
entity: 'applebtn' | 'googlebtn' | 'form' | 'resign' | 'bizum' | 'blik' | 'mbway' | 'paypal' | 'pix' | 'pix-qr' // one of listed values, indicates how payment was processed
}
React
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"
export const MyPayment: FC<{
merchantData: InitConfig['merchantData']
styles?: InitConfig['styles']
formParams?: InitConfig['formParams']
width?: string
}> = (props) => {
const handleSubmit = useCallback((event: SdkMessage[MessageType.Submit]) => {
// here logic
}, [])
return (<Payment
{...props}
onSubmit={handleSubmit}
/>)
}
Vanilla JS
form.on('submit', e => {
const data = e.data // SubmitMessage
})
Vue
<template>
<Payment
:merchant-data="merchantData"
@submit="submit"
/>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))
const merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
function submit(event: SdkMessage[MessageType.Submit]): void {
// here your logic
}
</script>
Angular
import {Component} from '@angular/core';
import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";
@Component({
selector: 'app-root',
template: `
<ngx-solid-payment
[merchantData]="merchantData"
(submit)="onSubmit($event)"
></ngx-solid-payment>
`
})
export class AppComponent {
merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
onSubmit(event: SdkMessage[MessageType.Submit]): void {
// here your logic
}
}
Card
The card event fires on every valid card number and returns BIN level metadata including brand bin cardType cardCategory bank and binCountry before submit without exposing the PAN CVV expiry or cardholder name.
Use cases
- Apply dynamic surcharges by adding a fee for
CREDITorAMEXcards before the customer submits - Hint at likely decline before submit when payments from this bank may be unavailable
- Route to a preferred acquirer based on card scheme and issuing country
- Adapt UI and pricing and show the card brand logo in real time next to the card number field
- Prevent declines on risky
binCountrymismatches - Segment customers by issuer and tier before authorization
interface CardMessage {
type: 'card'
card: {
brand: "AMERICAN EXPRESS", // card scheme in upper case: 'VISA', 'MASTERCARD', 'AMERICAN EXPRESS', 'DISCOVER', 'JCB', 'DINERS CLUB', 'UNIONPAY', 'MAESTRO', etc., or 'unknown'
bin: "377400", // first 6 digits of the PAN as a string
cardType: "DEBIT", // funding type in upper case: 'CREDIT', 'CREDIT/DEBIT', 'DEBIT', 'PREPAID', 'CHARGE CARD', 'DEFERRED DEBIT', or 'unknown'
cardCategory: "BUSINESS", // scheme product tier in upper case: 'STANDARD', 'CLASSIC', 'CONSUMER', 'BUSINESS', 'CORPORATE', 'PLATINUM', 'WORLD', 'INFINITE', 'ELECTRON', etc.
bank: "BANK OF AMERICA", // issuing bank name in upper case (e.g. 'BANK OF AMERICA', 'CITIBANK'); empty when not resolved
binCountry: "USA" // ISO 3-letter country code of the issuing bank (e.g. 'USA', 'GBR', 'DEU')
}
}
React
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"
export const MyPayment: FC<{
merchantData: InitConfig['merchantData']
styles?: InitConfig['styles']
formParams?: InitConfig['formParams']
width?: string
}> = (props) => {
const handleCard = useCallback((event: SdkMessage[MessageType.Card]) => {
// here logic
}, [])
return (<Payment
{...props}
onCard={handleCard}
/>)
}
Vanilla JS
form.on('card', e => {
const data = e.data // CardMessage
})
Vue
<template>
<Payment
:merchant-data="merchantData"
@card="card"
/>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))
const merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
function card(event: SdkMessage[MessageType.Card]): void {
// here your logic
}
</script>
Angular
import {Component} from '@angular/core';
import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";
@Component({
selector: 'app-root',
template: `
<ngx-solid-payment
[merchantData]="merchantData"
(card)="onCard($event)"
></ngx-solid-payment>
`
})
export class AppComponent {
merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
onCard(event: SdkMessage[MessageType.Card]): void {
// here your logic
}
}
Interaction
Tracks button and input interactions with types click change focus blur enterKeyDown pageClose and resetRequested. Exposes isValid and isTouched per field and form on regular and resign flows. Wallet and
APM buttons
interactions also cover button clicks and modal close. Event distinction
pageClosefires on modal ✕ before submitresetRequestedfires on modal ✕ after submit when the APM button hasresetEnabled: true
Use cases
- Track which field users abandon first when drop on
cardCvvmay indicate UX confusion - Show contextual hints on
cardExpiryDatefocus - Monitor
cardForm.isValidin real time to progressively enable the Pay button - On
pageCloseshow an exit intent modal or save form state - On
resetRequesteddestroy the current SDK instance and reinitialize with a new payment intent - Feed interaction data to A/B testing tools to compare form layouts
interface InteractionMessage {
type: 'interaction'
target: { // Indicates source of interaction
type: 'button' | 'input' // one of the listed
name: 'submit' | 'applePay' | 'googlePay' | 'clicktopay' | 'cashapp' | 'bizum' | 'blik' | 'mbway' | 'paypal' | 'pix' | 'pix-qr' | 'cardNumber' | 'cardCvv' | 'cardExpiryDate' | 'cardHolder' | 'email' | 'zipCode' | 'resignCvv'
// Additional field names are also possible, e.g.:
// 'brazilCpf', 'brazilCustomerPhone', 'brazilZip', 'billingAddress', 'billingCity', 'billingState',
// 'pakistanCnic', 'blikCode', 'firstName', 'lastName', 'customerPhone', etc.
interaction: 'click' | 'change' | 'focus' | 'blur' | 'enterKeyDown' | 'pageClose' | 'resetRequested' // one of the listed
}
cardForm: { // Indicates current card form state
fields: {
cardNumber: {
isValid: boolean
isTouched: boolean
}
cardCvv: {
isValid: boolean
isTouched: boolean
}
cardExpiryDate: {
isValid: boolean
isTouched: boolean
}
// The rest of the fields are optional, including, but not limited to: the `cardHolder` field
}
isValid: boolean
isTouched: boolean
}
}
Resign payment type
interface InteractionMessage {
type: 'interaction'
target: { // Indicates source of interaction
type: 'button' | 'input' // one of the listed
name: 'submit' | 'resignCvv' // It could be one of the listed; furthermore, Solidgate might extend the list.
interaction: 'click' | 'change' | 'focus' | 'blur' | 'enterKeyDown' // one of the listed
}
resignForm: { // Indicates current resign form state
fields: {
resignCvv: {
isValid: boolean
isTouched: boolean
}
}
isValid: boolean
isTouched: boolean
}
}
React
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"
export const MyPayment: FC<{
merchantData: InitConfig['merchantData']
styles?: InitConfig['styles']
formParams?: InitConfig['formParams']
width?: string
}> = (props) => {
const handleInteraction = useCallback((event: SdkMessage[MessageType.Interaction]) => {
// here logic
}, [])
return (<Payment
{...props}
onInteraction={handleInteraction}
/>)
}
Vanilla JS
form.on('interaction', e => {
const data = e.data // InteractionMessage
})
Vue
<template>
<Payment
:merchant-data="merchantData"
@interaction="interaction"
/>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))
const merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
function interaction(event: SdkMessage[MessageType.Interaction]): void {
// here your logic
}
</script>
Angular
import {Component} from '@angular/core';
import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";
@Component({
selector: 'app-root',
template: `
<ngx-solid-payment
[merchantData]="merchantData"
(interaction)="onInteraction($event)"
></ngx-solid-payment>
`
})
export class AppComponent {
merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
onInteraction(event: SdkMessage[MessageType.Interaction]): void {
// here your logic
}
}
Form redirect
Indicates when the form redirects the customer to another page, status, or 3D verification page.
Use cases
- Show a redirect overlay during bank verification
- Stop any countdown timers on your page
- Save the current cart or order state before navigation
- Prevent the customer from triggering other UI actions while redirect is in progress
interface FormRedirectMessage {
type: 'formRedirect'
}
React
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"
export const MyPayment: FC<{
merchantData: InitConfig['merchantData']
styles?: InitConfig['styles']
formParams?: InitConfig['formParams']
width?: string
}> = (props) => {
const handleRedirect = useCallback((event: SdkMessage[MessageType.Redirect]) => {
// here logic
}, [])
return (<Payment
{...props}
onRedirect={handleRedirect}
/>)
}
Vanilla JS
form.on('formRedirect', e => {
const data = e.data // FormRedirectMessage
})
Vue
<template>
<Payment
:merchant-data="merchantData"
@redirect="redirect"
/>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))
const merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
function redirect(event: SdkMessage[MessageType.Redirect]): void {
// here your logic
}
</script>
Angular
import {Component} from '@angular/core';
import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";
@Component({
selector: 'app-root',
template: `
<ngx-solid-payment
[merchantData]="merchantData"
(redirect)="onRedirect($event)"
></ngx-solid-payment>
`
})
export class AppComponent {
merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
onRedirect(event: SdkMessage[MessageType.Redirect]): void {
// here your logic
}
}
Custom styles appended
If custom styles are in place, this event indicates that the form has become visible to the customer, making it helpful for hiding preloaders.
Use cases
- Remove skeleton loaders or shimmer effects once the form is fully styled and visible
- Record time to first render for performance monitoring dashboards
- Trigger an entrance animation on the checkout container
- Use instead of
mountedwhen custom styles are configured to avoid a flash of unstyled form
interface CustomStylesAppendedMessage {
type: 'customStylesAppended'
}
React
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"
export const MyPayment: FC<{
merchantData: InitConfig['merchantData']
styles?: InitConfig['styles']
formParams?: InitConfig['formParams']
width?: string
}> = (props) => {
const handleCustomStylesAppended = useCallback((event: SdkMessage[MessageType.CustomStylesAppended]) => {
// here logic
}, [])
return (<Payment
{...props}
onCustomStylesAppended={handleCustomStylesAppended}
/>)
}
Vanilla JS
form.on('customStylesAppended', e => {
const data = e.data // CustomStylesAppendedMessage
})
Vue
<template>
<Payment
:merchant-data="merchantData"
@custom-styles-appended="customStylesAppended"
/>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))
const merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
function customStylesAppended(event: SdkMessage[MessageType.CustomStylesAppended]): void {
// here your logic
}
</script>
Angular
import {Component} from '@angular/core';
import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";
@Component({
selector: 'app-root',
template: `
<ngx-solid-payment
[merchantData]="merchantData"
(customStylesAppended)="onCustomStylesAppended($event)"
></ngx-solid-payment>
`
})
export class AppComponent {
merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
onCustomStylesAppended(event: SdkMessage[MessageType.CustomStylesAppended]): void {
// here your logic
}
}
Payment processing
These events provide insights into the payment process, including 3DS verification, the order status, and details about the payment, like pricing and taxes.
Success
This event indicates that the payment has been successfully processed.
Use cases
- Show a success modal with the confirmed amount and currency from the order payload
- Fire a purchase event to Google Analytics 4 Meta Pixel or TikTok Pixel
- For subscriptions store
subscription_idin the user profile for management UI - Trigger a post purchase upsell or cross sell flow
- Clear the cart state from local storage
interface SuccessMessage {
type: 'success',
entity: 'applebtn' | 'googlebtn' | 'form' | 'resign' | 'bizum' | 'blik' | 'mbway' | 'paypal' | 'pix' | 'pix-qr' // one of listed values, indicates how payment was processed
order: { // an optional order object
status: string // an optional order status field
currency: string // an optional order currency field
amount: number // an optional order amount field
subscription_id: string // an optional subscription id field
order_id: string // an optional order id field
}
}
React
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"
export const MyPayment: FC<{
merchantData: InitConfig['merchantData']
styles?: InitConfig['styles']
formParams?: InitConfig['formParams']
width?: string
}> = (props) => {
const handleSuccess = useCallback((event: SdkMessage[MessageType.Success]) => {
// here logic
}, [])
return (<Payment
{...props}
onSuccess={handleSuccess}
/>)
}
Vanilla JS
form.on('success', e => {
const data = e.data // SuccessMessage
})
Vue
<template>
<Payment
:merchant-data="merchantData"
@success="success"
/>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))
const merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
function success(event: SdkMessage[MessageType.Success]): void {
// here your logic
}
</script>
Angular
import {Component} from '@angular/core';
import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";
@Component({
selector: 'app-root',
template: `
<ngx-solid-payment
[merchantData]="merchantData"
(success)="onSuccess($event)"
></ngx-solid-payment>
`
})
export class AppComponent {
merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
onSuccess(event: SdkMessage[MessageType.Success]): void {
// here your logic
}
}
Verify
This event informs you that the payment is undergoing processing through the 3D flow.
Use cases
- Tell the customer the bank will verify the payment
- Keep the form visible and wait for
successorfail - Show a progress indicator during the 3DS wait
- Log 3DS initiation and completion for funnel analytics
interface VerifyMessage {
type: 'verify'
}
React
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"
export const MyPayment: FC<{
merchantData: InitConfig['merchantData']
styles?: InitConfig['styles']
formParams?: InitConfig['formParams']
width?: string
}> = (props) => {
const handleVerify = useCallback((event: SdkMessage[MessageType.Verify]) => {
// here logic
}, [])
return (<Payment
{...props}
onVerify={handleVerify}
/>)
}
Vanilla JS
form.on('verify', e => {
const data = e.data // VerifyMessage
})
Vue
<template>
<Payment
:merchant-data="merchantData"
@verify="verify"
/>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))
const merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
function verify(event: SdkMessage[MessageType.Verify]): void {
// here your logic
}
</script>
Angular
import {Component} from '@angular/core';
import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";
@Component({
selector: 'app-root',
template: `
<ngx-solid-payment
[merchantData]="merchantData"
(verify)="onVerify($event)"
></ngx-solid-payment>
`
})
export class AppComponent {
merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
onVerify(event: SdkMessage[MessageType.Verify]): void {
// here your logic
}
}
Fail
This event indicates that the payment had been declined.
Use cases
- Map decline codes to friendly retry messages
- Offer Google Pay or another APM button after a decline
- Keep the form open and prefilled for quick retry
- Log the decline code and
entityfor decline analysis - Track decline rates by
entityacrossformapplebtnandgooglebtn
interface FailMessage {
type: 'fail'
entity: 'applebtn' | 'googlebtn' | 'form' | 'resign' | 'bizum' | 'blik' | 'mbway' | 'paypal' | 'pix' | 'pix-qr' // one of listed values, indicates how payment was processed
code: string // an optional error code from https://docs.solidgate.com/payments/payments-insights/error-codes/
message: string // an optional error message field
order: { // an optional order object
status: string // an optional order status field
currency: string // an optional order currency field
amount: number // an optional order amount field
subscription_id: string // an optional subscription id field
order_id: string // an optional order id field
}
}
React
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"
export const MyPayment: FC<{
merchantData: InitConfig['merchantData']
styles?: InitConfig['styles']
formParams?: InitConfig['formParams']
width?: string
}> = (props) => {
const handleFail = useCallback((event: SdkMessage[MessageType.Fail]) => {
// here logic
}, [])
return (<Payment
{...props}
onFail={handleFail}
/>)
}
Vanilla JS
form.on('fail', e => {
const data = e.data // FailMessage
})
Vue
<template>
<Payment
:merchant-data="merchantData"
@fail="fail"
/>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))
const merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
function fail(event: SdkMessage[MessageType.Fail]): void {
// here your logic
}
</script>
Angular
import {Component} from '@angular/core';
import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";
@Component({
selector: 'app-root',
template: `
<ngx-solid-payment
[merchantData]="merchantData"
(fail)="onFail($event)"
></ngx-solid-payment>
`
})
export class AppComponent {
merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
onFail(event: SdkMessage[MessageType.Fail]): void {
// here your logic
}
}
Order status
This event indicates that the order status was changed while processing. However, the event may not show all changes before the final order status approved or declined .
The response can be either the
updated card order
Webhook
or the
updated alternative order
Webhook
, depending on which payment method was used during payment.
Use cases
- Show step by step progress for Pix BLIK and iDEAL while waiting for bank confirmation
- Update a status badge in real time as the order moves through processing states
- Display a countdown or polling indicator when the customer must complete an APM buttons action
- Log intermediate states for debugging slow or stuck payments
interface OrderStatusMessage {
type: 'orderStatus',
entity: 'applebtn' | 'googlebtn' | 'form' | 'resign' | 'bizum' | 'blik' | 'mbway' | 'paypal' | 'pix' | 'pix-qr', // one of listed values, indicates how payment was processed
response: object // Partial order status response.
}
React
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"
export const MyPayment: FC<{
merchantData: InitConfig['merchantData']
styles?: InitConfig['styles']
formParams?: InitConfig['formParams']
width?: string
}> = (props) => {
const handleOrderStatus = useCallback((event: SdkMessage[MessageType.OrderStatus]) => {
// here logic
}, [])
return (<Payment
{...props}
onOrderStatus={handleOrderStatus}
/>)
}
Vanilla JS
form.on('orderStatus', e => {
const data = e.data // OrderStatusMessage
})
Vue
<template>
<Payment
:merchant-data="merchantData"
@order-status="orderStatus"
/>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))
const merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
function orderStatus(event: SdkMessage[MessageType.OrderStatus]): void {
// here your logic
}
</script>
Angular
import {Component} from '@angular/core';
import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";
@Component({
selector: 'app-root',
template: `
<ngx-solid-payment
[merchantData]="merchantData"
(orderStatus)="onOrderStatus($event)"
></ngx-solid-payment>
`
})
export class AppComponent {
merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
onOrderStatus(event: SdkMessage[MessageType.OrderStatus]): void {
// here your logic
}
}
Payment details
This event informs of updates or changes to payment details, including price, taxes, and other relevant information, enabling comprehensive tracking of customer actions through the events generated.
To change order parameters from your application call form.update() instead of relying on this event alone.
Use cases
- Render a dynamic price summary with tax next to the form
- Update the Pay button label with the final charge amount
- Show the trial period price for subscription products before the customer commits
- Display the discount amount and original price when a coupon has been applied
- Reactively update the price display when the customer switches between plans
interface PaymentDetailsMessage {
type: 'paymentDetails';
payment: {
priceBreakdown: PriceBreakdown;
};
}
interface PriceBreakdown {
productPrice: {
amount: string;
currency: string;
currencyIcon: string;
}; // Base price
discountPrice?: {
amount: string;
currency: string;
currencyIcon: string;
}; // Optional, after discount
trialPrice?: {
amount: string;
currency: string;
currencyIcon: string;
}; // Optional, price without discount (if available)
price: {
source: "productPrice" | "discountPrice" | "trialPrice";
amount: string; // Final price amount based on the selected source (e.g., "100.00")
taxAmount: string; // Tax amount applied (2% of taxableAmount, e.g., "2.00")
taxRate: number; // Fixed tax rate (2.0)
taxableAmount: string; // Amount subject to tax (e.g., "100.00")
currency: string; // ISO 4217 currency code (e.g., "USD")
currencyIcon: string; // Currency symbol (e.g., "$")
};
}
React
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"
export const MyPayment: FC<{
merchantData: InitConfig['merchantData']
styles?: InitConfig['styles']
formParams?: InitConfig['formParams']
width?: string
}> = (props) => {
const handlePaymentDetails = useCallback((event: SdkMessage[MessageType.PaymentDetails]) => {
// Validate the event structure and handle the payment details logic
}, [])
return (<Payment
{...props}
onPaymentDetails={handlePaymentDetails}
/>)
}
Vanilla JS
form.on('paymentDetails', e => {
const data = e.data // PaymentDetailsMessage
// Add validation logic for data if needed
})
Vue
<template>
<Payment
:merchant-data="merchantData"
@payment-details="paymentDetails"
/>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))
const merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
function paymentDetails(event: SdkMessage[MessageType.PaymentDetails]): void {
// Validate event structure and handle payment details here
}
</script>
Angular
import {Component} from '@angular/core';
import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";
@Component({
selector: 'app-root',
template: `
<ngx-solid-payment
[merchantData]="merchantData"
(paymentDetails)="onPaymentDetails($event)"
></ngx-solid-payment>
`
})
export class AppComponent {
merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
onPaymentDetails(event: SdkMessage[MessageType.PaymentDetails]): void {
// Validate and handle payment details here
}
}
Technical
Technical events track form resizing and errors to support proper adaptation and debugging.
Resize
When the Payment Form is resized.
Use cases
- Smoothly animate the checkout container height to match the new form dimensions
- Recalculate scroll position if the form is embedded in a scrollable panel
- Adjust a sticky summary panel that is positioned relative to the form
It may resize after displaying a validation message.
Type
interface ResizeMessage {
type: 'resize'
width: number
height: number
}
React
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"
export const MyPayment: FC<{
merchantData: InitConfig['merchantData']
styles?: InitConfig['styles']
formParams?: InitConfig['formParams']
width?: string
}> = (props) => {
const handleResize = useCallback((event: SdkMessage[MessageType.Resize]) => {
// here logic
}, [])
return (<Payment
{...props}
onResize={handleResize}
/>)
}
Vanilla JS
form.on('resize', e => {
const data = e.data // ResizeMessage
})
Vue
<template>
<Payment
:merchant-data="merchantData"
@resize="resize"
/>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))
const merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
function resize(event: SdkMessage[MessageType.Resize]): void {
// here your logic
}
</script>
Angular
import {Component} from '@angular/core';
import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";
@Component({
selector: 'app-root',
template: `
<ngx-solid-payment
[merchantData]="merchantData"
(resize)="onResize($event)"
></ngx-solid-payment>
`
})
export class AppComponent {
merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
onResize(event: SdkMessage[MessageType.Resize]): void {
// here your logic
}
}
Error
Indicates an error during form initialization or processing. The following Error classes are provided:
ConnectionError- happens when the customer experiences problems with their internet connection.InitPaymentError- happens when an error with payment intent occurs during initialization.
The message contains a strict object with code and an explanation of the particular error. Additionally, it includes adetailsfield, allowing you to create different handlers for different errors. The following error codes are supported (details.code):GatewayError- occurs when Solidgate cannot parse the response from its backend, please contact support.- 1.01 - Invalid credentials or signature generated.
-
2.01
- Invalid data in payment intent.
It could be a non-existing product ID or other properties, which is described in a message. Provides detailed description indetails.messageby pair key from payment intent with corresponding error message. - 6.01 - Something went wrong on the backend side, please contact support.
Use cases
- On
ConnectionErrorshow a connection warning with retry - On
InitPaymentErrorcode2.01logdetails.messageto your backend for field validation errors - On
InitPaymentErrorcode1.01alert your backend team when credentials or signature are wrong - Send the full error object to Sentry or Datadog for all errors
- Show a graceful fallback UI instead of a broken form
interface ErrorMessage {
type: 'error'
value: {
name: string; // "ConnectionError" | "InitPaymentError" | "GatewayError"
message: string;
}
details?: {
code: string; // 1.01, 2.01, 6.01 from https://docs.solidgate.com/payments/payments-insights/error-codes/
message: {
[key: string]: string
} | string; // Object for 2.01, otherwise string
}
}
React
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"
export const MyPayment: FC<{
merchantData: InitConfig['merchantData']
styles?: InitConfig['styles']
formParams?: InitConfig['formParams']
width?: string
}> = (props) => {
const handleError = useCallback((event: SdkMessage[MessageType.Error]) => {
// here logic
}, [])
return (<Payment
{...props}
onError={handleError}
/>)
}
Vanilla JS
form.on('error', e => {
const data = e.data // ErrorMessage
})
Vue
<template>
<Payment
:merchant-data="merchantData"
@error="error"
/>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))
const merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
function error(event: SdkMessage[MessageType.Error]): void {
// here your logic
}
</script>
Angular
import {Component} from '@angular/core';
import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";
@Component({
selector: 'app-root',
template: `
<ngx-solid-payment
[merchantData]="merchantData"
(error)="onError($event)"
></ngx-solid-payment>
`
})
export class AppComponent {
merchantData: InitConfig['merchantData'] = {
merchant: '<<--YOUR MERCHANT ID-->>',
signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}
onError(event: SdkMessage[MessageType.Error]): void {
// here your logic
}
}