Skip to content

Commit

Permalink
Add endpoints that provide callback data
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelKim20 committed Aug 28, 2024
1 parent 7b0125b commit ca9b8d6
Show file tree
Hide file tree
Showing 10 changed files with 434 additions and 127 deletions.
4 changes: 4 additions & 0 deletions packages/relay/src/DefaultServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { HistoryRouter } from "./routers/HistoryRouter";
import { PhoneLinkRouter } from "./routers/PhoneLinkRouter";
import { ProviderRouter } from "./routers/ProviderRouter";
import { StorePurchaseRouter } from "./routers/StorePurchaseRouter";
import { TaskRouter } from "./routers/TaskRouter";
import { TokenRouter } from "./routers/TokenRouter";
import { GraphStorage } from "./storage/GraphStorage";
import { RelayStorage } from "./storage/RelayStorage";
Expand All @@ -40,6 +41,7 @@ export class DefaultServer extends WebService {
public readonly etcRouter: ETCRouter;
public readonly purchaseRouter: StorePurchaseRouter;
public readonly tokenRouter: TokenRouter;
public readonly taskRouter: TaskRouter;
public readonly phoneLinkRouter: PhoneLinkRouter;
public readonly providerRouter: ProviderRouter;
public readonly bridgeRouter: BridgeRouter;
Expand Down Expand Up @@ -187,6 +189,7 @@ export class DefaultServer extends WebService {
this.graph_mainchain,
this.relaySigners
);
this.taskRouter = new TaskRouter(this, this.config, this.contractManager, this.metrics, this.storage);

if (schedules) {
schedules.forEach((m) => this.schedules.push(m));
Expand Down Expand Up @@ -232,6 +235,7 @@ export class DefaultServer extends WebService {
await this.providerRouter.registerRoutes();
await this.bridgeRouter.registerRoutes();
await this.historyRouter.registerRoutes();
await this.taskRouter.registerRoutes();

for (const m of this.schedules) await m.start();

Expand Down
70 changes: 35 additions & 35 deletions packages/relay/src/routers/PaymentRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -650,11 +650,17 @@ export class PaymentRouter {
if (ContractUtils.getTimeStamp() - item.openNewTimestamp > this.config.relay.paymentTimeoutSecond) {
const data = ResponseMessage.getErrorMessage("7000");

await this.sendPaymentResult(
await this.storage.postCallBackOfPayment(
TaskResultType.NEW,
TaskResultCode.TIMEOUT,
data.error.message,
this.getCallBackResponse(item)
item
);
await this.sendTaskResult(
TaskResultType.NEW,
TaskResultCode.TIMEOUT,
data.error.message,
ContractUtils.getCallBackResponseOfPayment(item)
);
return res.status(200).json(data);
}
Expand Down Expand Up @@ -725,11 +731,17 @@ export class PaymentRouter {
item.paymentStatus = LoyaltyPaymentTaskStatus.DENIED_NEW;
await this.storage.updatePaymentStatus(item.paymentId, item.paymentStatus);

await this.sendPaymentResult(
await this.storage.postCallBackOfPayment(
TaskResultType.NEW,
TaskResultCode.DENIED,
"Denied by user",
this.getCallBackResponse(item)
item
);
await this.sendTaskResult(
TaskResultType.NEW,
TaskResultCode.DENIED,
"Denied by user",
ContractUtils.getCallBackResponseOfPayment(item)
);

this.metrics.add("success", 1);
Expand Down Expand Up @@ -1253,11 +1265,17 @@ export class PaymentRouter {
if (ContractUtils.getTimeStamp() - item.openCancelTimestamp > this.config.relay.paymentTimeoutSecond) {
const msg = ResponseMessage.getErrorMessage("7000");

await this.sendPaymentResult(
await this.storage.postCallBackOfPayment(
TaskResultType.CANCEL,
TaskResultCode.TIMEOUT,
msg.error.message,
this.getCallBackResponse(item)
item
);
await this.sendTaskResult(
TaskResultType.CANCEL,
TaskResultCode.TIMEOUT,
msg.error.message,
ContractUtils.getCallBackResponseOfPayment(item)
);

return res.status(200).json(msg);
Expand Down Expand Up @@ -1323,11 +1341,17 @@ export class PaymentRouter {
item.paymentStatus = LoyaltyPaymentTaskStatus.DENIED_CANCEL;
await this.storage.updatePaymentStatus(item.paymentId, item.paymentStatus);

await this.sendPaymentResult(
await this.storage.postCallBackOfPayment(
TaskResultType.CANCEL,
TaskResultCode.DENIED,
"Denied by user",
item
);
await this.sendTaskResult(
TaskResultType.CANCEL,
TaskResultCode.DENIED,
"Denied by user",
this.getCallBackResponse(item)
ContractUtils.getCallBackResponseOfPayment(item)
);

this.metrics.add("success", 1);
Expand Down Expand Up @@ -1570,25 +1594,6 @@ export class PaymentRouter {
}
}

private getCallBackResponse(item: LoyaltyPaymentTaskData): any {
return {
paymentId: item.paymentId,
purchaseId: item.purchaseId,
amount: item.amount.toString(),
currency: item.currency,
shopId: item.shopId,
account: item.account,
paidPoint: item.paidPoint.toString(),
paidValue: item.paidValue.toString(),
feePoint: item.feePoint.toString(),
feeValue: item.feeValue.toString(),
totalPoint: item.totalPoint.toString(),
totalValue: item.totalValue.toString(),
terminalId: item.terminalId,
paymentStatus: item.paymentStatus,
};
}

private updateEvent(event: ContractLoyaltyPaymentEvent, item: LoyaltyPaymentTaskData): void {
if (item.paymentId !== event.paymentId) return;
item.purchaseId = event.purchaseId;
Expand Down Expand Up @@ -1634,12 +1639,7 @@ export class PaymentRouter {
} else return undefined;
}

private async sendPaymentResult(
type: TaskResultType,
code: TaskResultCode,
message: string,
data: PaymentResultData
) {
private async sendTaskResult(type: TaskResultType, code: TaskResultCode, message: string, data: PaymentResultData) {
try {
const client = new HTTPClient();
const res = await client.post(this.config.relay.callbackEndpoint, {
Expand All @@ -1652,9 +1652,9 @@ export class PaymentRouter {
logger.info(JSON.stringify(res.data));
} catch (error) {
if (error instanceof Error) {
logger.error(`sendPaymentResult : ${error.message}`);
logger.error(`sendTaskResult : ${error.message}`);
} else {
logger.error(`sendPaymentResult : ${JSON.stringify(error)}`);
logger.error(`sendTaskResult : ${JSON.stringify(error)}`);
}
}
}
Expand Down
76 changes: 30 additions & 46 deletions packages/relay/src/routers/ShopRouter.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
import { Shop } from "../../typechain-types";
import { Config } from "../common/Config";
import { logger } from "../common/Logger";
import { ISignerItem, RelaySigners } from "../contract/Signers";
import { INotificationSender } from "../delegator/NotificationSender";
import { WebService } from "../service/WebService";
import { GraphStorage } from "../storage/GraphStorage";
import { RelayStorage } from "../storage/RelayStorage";
import {
ContractShopStatus,
ContractShopUpdateEvent,
MobileType,
ShopTaskData,
ShopTaskStatus,
TaskResultCode,
TaskResultType,
} from "../types";
import { ContractShopStatus, MobileType, ShopTaskData, ShopTaskStatus, TaskResultCode, TaskResultType } from "../types";
import { ContractUtils } from "../utils/ContractUtils";
import { ResponseMessage } from "../utils/Errors";
import { HTTPClient } from "../utils/Utils";
import { Validation } from "../validation";

import { ContractTransaction, ethers } from "ethers";
import { ethers } from "ethers";
import express from "express";
import { body, param, query, validationResult } from "express-validator";
import * as hre from "hardhat";
Expand Down Expand Up @@ -747,11 +738,17 @@ export class ShopRouter {
item.taskStatus = ShopTaskStatus.TIMEOUT;
await this.storage.updateTaskStatus(item.taskId, item.taskStatus);

await this.storage.postCallBackOfShop(
TaskResultType.UPDATE,
TaskResultCode.TIMEOUT,
data.error.message,
item
);
await this.sendTaskResult(
TaskResultType.UPDATE,
TaskResultCode.TIMEOUT,
data.error.message,
this.getCallBackResponse(item)
ContractUtils.getCallBackResponseOfTask(item)
);

return res.status(200).json(data);
Expand Down Expand Up @@ -794,11 +791,17 @@ export class ShopRouter {
item.taskStatus = ShopTaskStatus.DENIED;
await this.storage.updateTaskStatus(item.taskId, item.taskStatus);

await this.storage.postCallBackOfShop(
TaskResultType.UPDATE,
TaskResultCode.DENIED,
"Denied by user",
item
);
await this.sendTaskResult(
TaskResultType.UPDATE,
TaskResultCode.DENIED,
"Denied by user",
this.getCallBackResponse(item)
ContractUtils.getCallBackResponseOfTask(item)
);

this.metrics.add("success", 1);
Expand Down Expand Up @@ -1025,11 +1028,17 @@ export class ShopRouter {
item.taskStatus = ShopTaskStatus.TIMEOUT;
await this.storage.updateTaskStatus(item.taskId, item.taskStatus);

await this.storage.postCallBackOfShop(
TaskResultType.STATUS,
TaskResultCode.TIMEOUT,
data.error.message,
item
);
await this.sendTaskResult(
TaskResultType.STATUS,
TaskResultCode.TIMEOUT,
data.error.message,
this.getCallBackResponse(item)
ContractUtils.getCallBackResponseOfTask(item)
);
this.metrics.add("success", 1);
return res.status(200).json(data);
Expand Down Expand Up @@ -1072,11 +1081,17 @@ export class ShopRouter {
item.taskStatus = ShopTaskStatus.DENIED;
await this.storage.updateTaskStatus(item.taskId, item.taskStatus);

await this.storage.postCallBackOfShop(
TaskResultType.STATUS,
TaskResultCode.DENIED,
"Denied by user",
item
);
await this.sendTaskResult(
TaskResultType.STATUS,
TaskResultCode.DENIED,
"Denied by user",
this.getCallBackResponse(item)
ContractUtils.getCallBackResponseOfTask(item)
);

this.metrics.add("success", 1);
Expand Down Expand Up @@ -1151,37 +1166,6 @@ export class ShopRouter {
}
}

private getCallBackResponse(item: ShopTaskData): any {
return {
taskId: item.taskId,
shopId: item.shopId,
name: item.name,
currency: item.currency,
status: item.status,
account: item.account,
terminalId: item.terminalId,
};
}

private async waitAndAddEvent(
contract: Shop,
tx: ContractTransaction
): Promise<ContractShopUpdateEvent | undefined> {
const contractReceipt = await tx.wait();
const log = ContractUtils.findLog(contractReceipt, contract.interface, "AddedShop");
if (log !== undefined) {
const parsedLog = contract.interface.parseLog(log);

return {
shopId: parsedLog.args.shopId,
name: parsedLog.args.name,
currency: parsedLog.args.currency,
account: parsedLog.args.account,
status: parsedLog.args.status,
};
} else return undefined;
}

private async sendTaskResult(type: TaskResultType, code: TaskResultCode, message: string, data: any) {
try {
const client = new HTTPClient();
Expand Down
88 changes: 88 additions & 0 deletions packages/relay/src/routers/TaskRouter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { Config } from "../common/Config";
import { logger } from "../common/Logger";
import { ContractManager } from "../contract/ContractManager";
import { Metrics } from "../metrics/Metrics";
import { WebService } from "../service/WebService";
import { RelayStorage } from "../storage/RelayStorage";
import { ResponseMessage } from "../utils/Errors";

// tslint:disable-next-line:no-implicit-dependencies
import express from "express";
import { param, validationResult } from "express-validator";

export class TaskRouter {
private web_service: WebService;
private readonly config: Config;
private readonly contractManager: ContractManager;
private readonly metrics: Metrics;
private storage: RelayStorage;

constructor(
service: WebService,
config: Config,
contractManager: ContractManager,
metrics: Metrics,
storage: RelayStorage
) {
this.web_service = service;
this.config = config;
this.contractManager = contractManager;
this.metrics = metrics;
this.storage = storage;
}

private get app(): express.Application {
return this.web_service.app;
}

/**
* Make the response data
* @param code The result code
* @param data The result data
* @param error The error
* @private
*/
private makeResponseData(code: number, data: any, error?: any): any {
return {
code,
data,
error,
};
}

public async registerRoutes() {
this.app.get("/v1/tasks/:sequence", [param("sequence").exists()], this.tasks.bind(this));
}

private async tasks(req: express.Request, res: express.Response) {
logger.http(`GET /v1/tasks/items/:sequence ${req.ip}:${JSON.stringify(req.params)}`);

const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(200).json(ResponseMessage.getErrorMessage("2001", { validation: errors.array() }));
}

try {
const value = String(req.params.sequence);
if (value === "latest") {
const tasks = await this.storage.readCallBackLatest();
this.metrics.add("success", 1);
return res.status(200).json(this.makeResponseData(0, tasks));
} else if (value === "0") {
const tasks = await this.storage.readCallBackDefault();
this.metrics.add("success", 1);
return res.status(200).json(this.makeResponseData(0, tasks));
} else {
const sequence = BigInt(value);
const tasks = await this.storage.readCallBack(sequence);
this.metrics.add("success", 1);
return res.status(200).json(this.makeResponseData(0, tasks));
}
} catch (error: any) {
const msg = ResponseMessage.getEVMErrorMessage(error);
logger.error(`GET /v1/tasks/items/:sequence : ${msg.error.message}`);
this.metrics.add("failure", 1);
return res.status(200).json(this.makeResponseData(msg.code, undefined, msg.error));
}
}
}
Loading

0 comments on commit ca9b8d6

Please sign in to comment.