0

As you can see in my short video example event message:successful_payment sometimes doesn't run after payment. In my video example there was only one execution after 3 payments (only the second payment trigger message:successful_payment , u can see in logs telegram_payment_charge_id).

short video example

Here is my code:

This is StoreModule, here i register 2 events

@Module({
    imports: [ProductModule, PaymentModule, GatewayModule],
    providers: [StoreService],
    controllers: [StoreController],
})
export class StoreModule implements OnModuleInit {
    constructor(
        @Inject(PROVIDERS.TG_PROVIDER) private readonly tgProvider: TgProvider,
        private readonly storeService: StoreService,
    ) {}

    private onTgBotInit() {
        this.tgProvider.bot.on('pre_checkout_query', this.storeService.handlePreCheckoutQuery.bind(this.storeService));

        this.tgProvider.bot.on(
            'message:successful_payment',
            this.storeService.handleSuccessfulPayment.bind(this.storeService),
        );
    }

    onModuleInit() {
        this.tgProvider.subscribe(this.onTgBotInit.bind(this));
    }
}

This is successful_payment and pre_checkout_query handlers:

public handleSuccessfulPayment = async (ctx: Context, next: NextFunction) => {
    console.log(ctx.message.successful_payment);
    const payload: InvoicePayload = JSON.parse(ctx.message.successful_payment.invoice_payload);
    const payedAt = new Date().toISOString();
    console.log(payload);
    // await this.paymentService.findOneAndUpdate(
    //     { requestId: payload.requestId },
    //     { 
    //         payedAt,
    //         status: PAYMENT_STATUS.PAID, 
    //         telegramPaymentChargeId: ctx.message.successful_payment.telegram_payment_charge_id
    //     },
    // );

    // this.gatewayService.sockets.get(payload.userId)?.forEach((socket) => {
    //     socket.emit(STORE_EVENTS.PRODUCT_BUY, payedAt);
    // });
};

public handlePreCheckoutQuery = async (ctx: Context) => {
    const { requestId }: InvoicePayload = JSON.parse(ctx.preCheckoutQuery.invoice_payload);
    
    return ctx.answerPreCheckoutQuery(!(await this.paymentService.exists({ requestId, status: PAYMENT_STATUS.PAID })));
};

I also tried to use :successful_payment and msg:successful_payment they all works the same way. Also i tried to handle successful_payment by myself using middleware in use, but sometimes after payment ctx.message.successful_payment is undefined. I think this is a reason why :successful_payment events doesn't work sometimes.

2
  • Because handleSuccessfulPayment responds to a successful payment event, maybe the event is not being triggered or erroring out? Is there an event for a payment error you could log the result? could there be any execptions happening prior to that event killing the execution? for example if your JSON.parse fails, it will not get to answerPreCheckoutQuery, blocking the payment right? Could you try adding a try catch block around the parse function and see if it's succeeding every time? In summary I would check error cases and see what events are being dispatched Commented 2 days ago
  • Please remember that your question is going to outlast your need to have it answered by potentially decades: your video is going to become a 404 much sooner than that, please make sure that your post contains all the information without needing to rely on external links. Commented 2 days ago

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.