import logger from 'logger/logger' import BaseController, { ROLE_ANON } from 'common/base.controller' import { ZError } from 'common/ZError' import { role, router } from 'decorators/router' import { checkPayResultSign, createPageSign, refreshToken } from 'service/alchemy.svr' import { generateKVStr } from 'utils/net.util' import { PayRecord, PayStatus } from 'modules/PayRecord' const CALL_BACK_URL = `${process.env.ALCHEMY_PAY_CB_URL}/pay/alchemy/cb` class AlchemyController extends BaseController { @router('post /pay/alchemy/buy') async beginPay(req, res) { const user = req.user const { chain, currency, address } = req.params const tokenResult = await refreshToken(user.emailReal || user.email) console.log(tokenResult) if (!tokenResult.success || tokenResult.returnCode !== '0000') { logger.info(`fetch pay token error::code: ${tokenResult.returnCode} msg: ${tokenResult.returnMsg}`) throw new ZError(10, 'fetch pay token error') } const { id, email, accessToken } = tokenResult.data const redirectUrl = '' let record = new PayRecord({ account: user.id, address, chain, currency }) await record.save() const merchantOrderNo = record.id let dataOrign: any = { token: accessToken, email, id, showTable: 'buy', merchantOrderNo, } if (chain) dataOrign.network = chain if (currency) dataOrign.crypto = currency let dataSign: any = { appId: process.env.ALCHEMY_APPID, address, callbackUrl: CALL_BACK_URL, } let signStr = generateKVStr({ data: dataSign, sort: true }) let sign = createPageSign(signStr) dataOrign.sign = sign Object.assign(dataOrign, dataSign) const urlBase = process.env.ALCHEMY_PAGE_BASE let url = `${urlBase}/` url = generateKVStr({ data: dataOrign, encode: true, uri: url }) return { url } } @role(ROLE_ANON) @router('post /pay/alchemy/cb') async alchemyCallback(req, res) { let { orderNo, status, crypto, network, merchantOrderNo } = req.params if (!merchantOrderNo) { logger.info(`alchemy callback merchantOrderNo not found`) throw new ZError(11, 'alchemy callback merchantOrderNo not found') } let record = await PayRecord.findById(merchantOrderNo) if (!record) { logger.info(`alchemy callback record not found`) throw new ZError(12, 'alchemy callback record not found') } if (record.status !== PayStatus.PENDING) { logger.info(`alchemy callback record status error`) throw new ZError(13, 'alchemy callback record status error') } if (!checkPayResultSign(req.params)) { logger.info(`alchemy callback sign error`) record.status = PayStatus.FAIL await record.save() throw new ZError(14, 'alchemy callback sign error') } record.outOrderId = orderNo record.chain = network record.currency = crypto record.outData = req.params record.status = status == 'PAY_SUCCESS' ? PayStatus.SUCCESS : PayStatus.FAIL await record.save() return {} } }