@@ -4,13 +4,15 @@ import { Request } from 'express';
44import { ProviderType } from './ProviderType' ;
55import { EscrowRequest } from '../middleware/transaction-escrow-middleware' ;
66import { Response } from 'express' ;
7+ import { transfer } from 'transferWithAuth' ;
78import { getVideoModelPrice } from 'services/AccountingService' ;
89import { HttpError , UnknownModelError } from 'errors/http' ;
910import { Decimal } from 'generated/prisma/runtime/library' ;
1011import { Transaction } from '../types' ;
1112import { prisma } from '../server' ;
1213import { EchoDbService } from '../services/DbService' ;
1314import logger from '../logger' ;
15+ import { decimalToUsdcBigInt } from 'utils' ;
1416
1517export class OpenAIVideoProvider extends BaseProvider {
1618 static detectPassthroughProxy (
@@ -173,9 +175,72 @@ export class OpenAIVideoProvider extends BaseProvider {
173175 }
174176
175177 const responseData = await response . json ( ) ;
178+ switch ( responseData . status ) {
179+ case 'completed' :
180+ await this . handleSuccessfulVideoGeneration ( responseData . id as string ) ;
181+ break ;
182+ case 'failed' :
183+ await this . handleFailedVideoGeneration ( responseData . id as string ) ;
184+ break ;
185+ default :
186+ break ;
187+ }
176188 res . json ( responseData ) ;
177189 }
178190
191+ // ====== Refund methods ======
192+ private async handleSuccessfulVideoGeneration (
193+ videoId : string
194+ ) : Promise < void > {
195+ await prisma . $transaction ( async tx => {
196+ const result = await tx . $queryRawUnsafe (
197+ `SELECT * FROM "video_generation_x402" WHERE "videoId" = $1 FOR UPDATE` ,
198+ videoId
199+ ) ;
200+ const video = ( result as any [ ] ) [ 0 ] ;
201+ if ( video && ! video . isFinal ) {
202+ await tx . videoGenerationX402 . update ( {
203+ where : {
204+ videoId : video . videoId ,
205+ } ,
206+ data : {
207+ isFinal : true ,
208+ } ,
209+ } ) ;
210+ }
211+ } ) ;
212+ }
213+
214+ private async handleFailedVideoGeneration ( videoId : string ) : Promise < void > {
215+ await prisma . $transaction ( async tx => {
216+ const result = await tx . $queryRawUnsafe (
217+ `SELECT * FROM "video_generation_x402" WHERE "videoId" = $1 FOR UPDATE` ,
218+ videoId
219+ ) ;
220+ const video = ( result as any [ ] ) [ 0 ] ;
221+ // Exit early if video already final
222+ if ( ! video || video . isFinal ) {
223+ return ;
224+ }
225+ if ( video . wallet ) {
226+ const refundAmount = decimalToUsdcBigInt ( video . cost ) ;
227+ await transfer ( video . wallet as `0x${string } `, refundAmount ) ;
228+ }
229+ if ( video . userId ) {
230+ // Proccess the refund to the user. There is some level of complexity here since there is a markup. Not as simple as just credit grant.
231+ logger . info ( `Refunding video generation ${ video . videoId } to user ${ video . userId } on app ${ video . echoAppId } ` ) ;
232+ }
233+ await tx . videoGenerationX402 . update ( {
234+ where : {
235+ videoId : video . videoId ,
236+ } ,
237+ data : {
238+ isFinal : true ,
239+ } ,
240+ } ) ;
241+ } ) ;
242+ }
243+
179244 // ========== Video Download Handling ==========
180245
181246 private isVideoContentDownload ( path : string ) : boolean {
0 commit comments