@@ -32,7 +32,8 @@ import {
3232 SetParamsError ,
3333 SetSignatureError ,
3434 SignatureGeneratingError ,
35- SignatureNotFoundError
35+ SignatureNotFoundError ,
36+ ErrorDuringVerificationError
3637} from './utils/errors'
3738import { validateContext , validateFunctionParams , validateParameters , validateSignature , validateURL , validateModalOptions } from './utils/validationUtils'
3839import { fetchStatusUrl , initSession , updateSession } from './utils/sessionUtils'
@@ -166,6 +167,8 @@ const emptyTemplateData: TemplateData = {
166167 context : '' ,
167168 parameters : { } ,
168169 redirectUrl : '' ,
170+ errorCallbackUrl : '' ,
171+ errorRedirectUrl : '' ,
169172 acceptAiProviders : false ,
170173 sdkVersion : '' ,
171174 providerVersion : '' ,
@@ -185,6 +188,8 @@ export class ReclaimProofRequest {
185188 private resolvedProviderVersion ?: string ;
186189 private parameters : { [ key : string ] : string } ;
187190 private redirectUrl ?: string ;
191+ private errorCallbackUrl ?: TemplateData [ 'errorCallbackUrl' ] ;
192+ private errorRedirectUrl ?: TemplateData [ 'errorRedirectUrl' ] ;
188193 private intervals : Map < string , NodeJS . Timer > = new Map ( ) ;
189194 private timeStamp : string ;
190195 private sdkVersion : string ;
@@ -370,6 +375,8 @@ export class ReclaimProofRequest {
370375 parameters,
371376 signature,
372377 redirectUrl,
378+ errorCallbackUrl,
379+ errorRedirectUrl,
373380 timeStamp,
374381 timestamp,
375382 appCallbackUrl,
@@ -405,6 +412,14 @@ export class ReclaimProofRequest {
405412 validateURL ( appCallbackUrl , 'fromJsonString' ) ;
406413 }
407414
415+ if ( errorRedirectUrl ) {
416+ validateURL ( errorRedirectUrl , 'fromJsonString' ) ;
417+ }
418+
419+ if ( errorCallbackUrl ) {
420+ validateURL ( errorCallbackUrl , 'fromJsonString' ) ;
421+ }
422+
408423 if ( context ) {
409424 validateContext ( context ) ;
410425 }
@@ -450,6 +465,8 @@ export class ReclaimProofRequest {
450465 proofRequestInstance . resolvedProviderVersion = resolvedProviderVersion ;
451466 proofRequestInstance . modalOptions = modalOptions ;
452467 proofRequestInstance . jsonProofResponse = jsonProofResponse ?? false ;
468+ proofRequestInstance . errorCallbackUrl = errorCallbackUrl ;
469+ proofRequestInstance . errorRedirectUrl = errorRedirectUrl ;
453470 return proofRequestInstance
454471 } catch ( error ) {
455472 logger . info ( 'Failed to parse JSON string in fromJsonString:' , error ) ;
@@ -500,6 +517,43 @@ export class ReclaimProofRequest {
500517 this . redirectUrl = url ;
501518 }
502519
520+ /**
521+ * Sets a custom callback URL where errors will be submitted via HTTP POST
522+ *
523+ * Errors will be HTTP POSTed with `header 'Content-Type': 'application/json'`.
524+ * When a custom error callback URL is set, Reclaim will no longer receive errors upon submission,
525+ * and listeners on the startSession method will not be triggered. Your application must
526+ * coordinate with your backend to receive errors.
527+ *
528+ * @param url - The URL where errors should be submitted via HTTP POST
529+ * @throws {InvalidParamError } When URL is invalid
530+ *
531+ * @example
532+ * ```typescript
533+ * proofRequest.setErrorCallbackUrl('https://your-backend.com/error-callback');
534+ * ```
535+ */
536+ setErrorCallbackUrl ( url : string ) : void {
537+ validateURL ( url , 'setErrorCallbackUrl' )
538+ this . errorCallbackUrl = url
539+ }
540+
541+ /**
542+ * Sets an error redirect URL where users will be redirected after error in verification process
543+ *
544+ * @param url - The URL where users should be redirected after error in verification process
545+ * @throws {InvalidParamError } When URL is invalid
546+ *
547+ * @example
548+ * ```typescript
549+ * proofRequest.setErrorRedirectUrl('https://your-app.com/error');
550+ * ```
551+ */
552+ setErrorRedirectUrl ( url : string ) : void {
553+ validateURL ( url , 'setErrorRedirectUrl' ) ;
554+ this . errorRedirectUrl = url ;
555+ }
556+
503557 /**
504558 * Sets the claim creation type for the proof request
505559 *
@@ -661,6 +715,31 @@ export class ReclaimProofRequest {
661715 }
662716 }
663717
718+ /**
719+ * Returns the currently configured error callback URL
720+ *
721+ * If no custom error callback URL was set via setErrorCallbackUrl(), this returns the default
722+ * Reclaim service error callback URL with the current session ID.
723+ *
724+ * @returns The error callback URL where proofs will be submitted
725+ * @throws {GetAppCallbackUrlError } When unable to retrieve the error callback URL
726+ *
727+ * @example
728+ * ```typescript
729+ * const callbackUrl = proofRequest.getErrorCallbackUrl();
730+ * console.log('Errors will be sent to:', callbackUrl);
731+ * ```
732+ */
733+ getErrorCallbackUrl ( ) : string {
734+ try {
735+ validateFunctionParams ( [ { input : this . sessionId , paramName : 'sessionId' , isString : true } ] , 'getErrorCallbackUrl' ) ;
736+ return this . errorCallbackUrl || `${ constants . DEFAULT_RECLAIM_ERROR_CALLBACK_URL } ${ this . sessionId } `
737+ } catch ( error ) {
738+ logger . info ( "Error getting error callback url" , error )
739+ throw new GetAppCallbackUrlError ( "Error getting error callback url" , error as Error )
740+ }
741+ }
742+
664743 /**
665744 * Returns the status URL for monitoring the current session
666745 *
@@ -782,6 +861,8 @@ export class ReclaimProofRequest {
782861 parameters : this . parameters ,
783862 signature : this . signature ,
784863 redirectUrl : this . redirectUrl ,
864+ errorCallbackUrl : this . errorCallbackUrl ,
865+ errorRedirectUrl : this . errorRedirectUrl ,
785866 timestamp : this . timeStamp , // New field with correct spelling
786867 timeStamp : this . timeStamp , // @deprecated : Remove in future versions
787868 options : this . options ,
@@ -821,6 +902,8 @@ export class ReclaimProofRequest {
821902 resolvedProviderVersion : this . resolvedProviderVersion ?? '' ,
822903 parameters : this . parameters ,
823904 redirectUrl : this . redirectUrl ?? '' ,
905+ errorCallbackUrl : this . getErrorCallbackUrl ( ) ,
906+ errorRedirectUrl : this . errorRedirectUrl ,
824907 acceptAiProviders : this . options ?. acceptAiProviders ?? false ,
825908 sdkVersion : this . sdkVersion ,
826909 jsonProofResponse : this . jsonProofResponse ,
@@ -1208,6 +1291,10 @@ export class ReclaimProofRequest {
12081291 return ; // Continue monitoring if under timeout
12091292 }
12101293
1294+ if ( statusUrlResponse . session . statusV2 === SessionStatus . ERROR_SUBMISSION_FAILED || statusUrlResponse . session . statusV2 === SessionStatus . ERROR_SUBMITTED ) {
1295+ throw new ErrorDuringVerificationError ( ) ;
1296+ }
1297+
12111298 const isDefaultCallbackUrl = this . getAppCallbackUrl ( ) === `${ constants . DEFAULT_RECLAIM_CALLBACK_URL } ${ this . sessionId } ` ;
12121299
12131300 if ( isDefaultCallbackUrl ) {
0 commit comments