@@ -2698,6 +2698,50 @@ describe("webhooks", () => {
26982698 expect ( createHmac ( "sha256" , secret ) . update ( parse ( string ( ) , options ?. body ) ) . digest ( "hex" ) ) . toBe ( headers . Signature ) ;
26992699 } ) ;
27002700
2701+ it ( "forwards declined transaction webhook" , async ( ) => {
2702+ const cardId = `${ webhookAccount } -card` ;
2703+ const fetch = globalThis . fetch ;
2704+ let publish = false ;
2705+ const mockFetch = vi . spyOn ( globalThis , "fetch" ) . mockImplementation ( async ( url , init ) => {
2706+ if ( url === "https://exa.test" ) {
2707+ publish = true ;
2708+ return { ok : true , status : 200 , text : ( ) => Promise . resolve ( "OK" ) } as Response ;
2709+ }
2710+ return fetch ( url , init ) ;
2711+ } ) ;
2712+
2713+ const response = await appClient . index . $post ( {
2714+ ...authorization ,
2715+ json : {
2716+ ...authorization . json ,
2717+ action : "created" ,
2718+ body : {
2719+ ...authorization . json . body ,
2720+ id : "declined-webhook-tx" ,
2721+ spend : {
2722+ ...authorization . json . body . spend ,
2723+ cardId,
2724+ userId : webhookAccount ,
2725+ status : "declined" ,
2726+ declinedReason : "webhook declined" ,
2727+ } ,
2728+ } ,
2729+ } ,
2730+ } ) ;
2731+
2732+ expect ( response . status ) . toBe ( 200 ) ;
2733+ await vi . waitUntil ( ( ) => publish , 60_000 ) ;
2734+ const options = mockFetch . mock . calls . find ( ( [ url ] ) => url === "https://exa.test" ) ?. [ 1 ] ;
2735+ const headers = parse ( object ( { Signature : string ( ) } ) , options ?. headers ) ;
2736+ expect ( createHmac ( "sha256" , secret ) . update ( parse ( string ( ) , options ?. body ) ) . digest ( "hex" ) ) . toBe ( headers . Signature ) ;
2737+ expect ( JSON . parse ( parse ( string ( ) , options ?. body ) ) ) . toMatchObject ( {
2738+ resource : "transaction" ,
2739+ action : "created" ,
2740+ body : { spend : { status : "declined" , declinedReason : "webhook declined" } } ,
2741+ } ) ;
2742+ expect ( captureException ) . not . toHaveBeenCalled ( ) ;
2743+ } ) ;
2744+
27012745 it ( "forwards card updated active" , async ( ) => {
27022746 const mockFetch = vi . spyOn ( globalThis , "fetch" ) . mockResolvedValueOnce ( {
27032747 ok : true ,
0 commit comments