增加alchemy支付的功能
This commit is contained in:
parent
3aafc04f97
commit
a9feeda7b9
@ -8,3 +8,10 @@ GOOGLE_OAUTH_CLIENT="53206975661-asnf3qe4bg29p8h981pgf099osvrjbme.apps.googleuse
|
||||
GOOGLE_OAUTH_CLIENT2="53206975661-ih3r0ubph3rqejdq97b029difbrk2bqj.apps.googleusercontent.com"
|
||||
GOOGLE_OAUTH_CLIENT_IOS="53206975661-qan0rnefniegjv53ohild375pv0p7ekd.apps.googleusercontent.com"
|
||||
DB_MAIN=mongodb://localhost/wallet-development
|
||||
|
||||
EMAIL_VERIFY_URL="http://127.0.0.1:3007"
|
||||
|
||||
ALCHEMY_APPID="f83Is2y7L425rxl8"
|
||||
ALCHEMY_APP_SECRET="4Yn8RkxDXN71Q3p0"
|
||||
ALCHEMY_API_BASE="https://openapi-test.alchemypay.org"
|
||||
ALCHEMY_PAGE_BASE="https://ramptest.alchemypay.org"
|
||||
|
44
src/controllers/alchemy.controller.ts
Normal file
44
src/controllers/alchemy.controller.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import logger from 'logger/logger'
|
||||
import BaseController from 'common/base.controller'
|
||||
import {ZError} from 'common/ZError'
|
||||
import { router } from 'decorators/router'
|
||||
import {createPageSign, refreshToken} from 'service/alchemy.svr'
|
||||
import {generateKVStr} from 'utils/net.util'
|
||||
|
||||
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)
|
||||
console.log(tokenResult)
|
||||
if (!tokenResult.success) {
|
||||
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 = ''
|
||||
const callbackUrl = ''
|
||||
const merchantOrderNo = ''
|
||||
let dataOrign:any = {
|
||||
token: accessToken,
|
||||
email,
|
||||
id,
|
||||
showTable: 'buy',
|
||||
}
|
||||
if (chain) dataOrign.network=chain
|
||||
if (currency) dataOrign.crypto=currency
|
||||
let dataSign = {
|
||||
appId: process.env.ALCHEMY_APPID,
|
||||
address
|
||||
}
|
||||
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}
|
||||
}
|
||||
}
|
@ -22,13 +22,14 @@ export class NetClient {
|
||||
return this.request(reqData)
|
||||
}
|
||||
|
||||
request(data: AxiosRequestConfig): Promise<any> {
|
||||
async request(data: AxiosRequestConfig): Promise<any> {
|
||||
let defaultCfg: AxiosRequestConfig = {
|
||||
method: 'get',
|
||||
headers: {'Content-Type': 'application/json'}
|
||||
}
|
||||
Object.assign(defaultCfg, data)
|
||||
console.log(defaultCfg)
|
||||
return axios(defaultCfg).then(res => res.data)
|
||||
const res = await axios(defaultCfg)
|
||||
return res.data
|
||||
}
|
||||
}
|
||||
|
53
src/service/alchemy.svr.ts
Normal file
53
src/service/alchemy.svr.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import axios from 'axios'
|
||||
import {sha1} from 'utils/security.util'
|
||||
import crypto from 'crypto'
|
||||
|
||||
export function createSimpleSign() {
|
||||
let timestamp = Date.now()
|
||||
let appid = process.env.ALCHEMY_APPID
|
||||
let secret = process.env.ALCHEMY_APP_SECRET
|
||||
let sign = sha1(appid+secret+timestamp)
|
||||
return {
|
||||
appid,
|
||||
timestamp,
|
||||
sign
|
||||
}
|
||||
}
|
||||
|
||||
export function createPageSign(plainText: string) {
|
||||
let secret = process.env.ALCHEMY_APP_SECRET
|
||||
try {
|
||||
const plainTextData = Buffer.from(plainText, 'utf8');
|
||||
const secretKey = Buffer.from(secret, 'utf8');
|
||||
const iv = secret.substring(0, 16);
|
||||
|
||||
const cipher = crypto.createCipheriv('aes-128-cbc', secretKey, iv);
|
||||
|
||||
let encrypted = cipher.update(plainTextData);
|
||||
encrypted = Buffer.concat([encrypted, cipher.final()]);
|
||||
|
||||
return encrypted.toString('base64');
|
||||
} catch (e) {
|
||||
console.log(`AES encrypting exception, msg is ${e.toString()}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function refreshToken(email: string) {
|
||||
const data = JSON.stringify({email})
|
||||
const {appid, timestamp, sign} = createSimpleSign()
|
||||
const host = process.env.ALCHEMY_API_BASE
|
||||
const config = {
|
||||
method: 'post',
|
||||
url: `${host}/merchant/getToken`,
|
||||
headers: {
|
||||
'appId': appid,
|
||||
'timestamp': timestamp,
|
||||
'sign': sign,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
data : data
|
||||
}
|
||||
let response = await axios(config)
|
||||
return response.data
|
||||
}
|
@ -17,7 +17,7 @@ export interface IMailData {
|
||||
}
|
||||
|
||||
const DEFAULT_MSG_DATA: IMailData = {
|
||||
from: '自己人 <zhl010101@163.com>',
|
||||
from: 'CEBG <noreply@cebg.games>',
|
||||
to: '',
|
||||
subject: 'Please verify your email address'
|
||||
}
|
||||
|
@ -114,3 +114,73 @@ function logOrRethrowError(error: any, codesToCatch: number[] = []) {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 key1=val1&key2=val2的字符串
|
||||
* @param {object} data 需要处理的对象
|
||||
* @param {boolean} sort 是否按key生序重排
|
||||
* @param {boolean} ignoreNull 是否过滤空值(空格或者null值不参与拼接)
|
||||
* @param splitChar 连接的字符, 默认是&
|
||||
* @param equalChar =
|
||||
*/
|
||||
export function generateKVStr({
|
||||
data = {},
|
||||
sort = false,
|
||||
encode = false,
|
||||
ignoreNull = true,
|
||||
splitChar = "&",
|
||||
equalChar = "=",
|
||||
uri = "",
|
||||
}: {
|
||||
data?: any;
|
||||
sort?: boolean;
|
||||
encode?: boolean;
|
||||
ignoreNull?: boolean;
|
||||
splitChar?: string;
|
||||
equalChar?: string;
|
||||
uri?: string;
|
||||
}) {
|
||||
const keys = Object.keys(data);
|
||||
sort && keys.sort();
|
||||
let result = "";
|
||||
let i = 0;
|
||||
for (let key of keys) {
|
||||
if (ignoreNull && !data[key]) {
|
||||
continue;
|
||||
}
|
||||
if (i++ > 0) result += splitChar;
|
||||
if (encode) {
|
||||
result += `${key}${equalChar}${encodeURIComponent(data[key])}`;
|
||||
} else {
|
||||
result += `${key}${equalChar}${data[key]}`;
|
||||
}
|
||||
}
|
||||
if (uri) {
|
||||
const joinChar = uri.search(/\?/) === -1 ? "?" : "&";
|
||||
result = uri + joinChar + result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将key1=val&key2=val的字符串组装成对象
|
||||
* @param str key1=val&key2=val的字符串
|
||||
* @param splitChar 连接的字符, 默认是&
|
||||
* @param equalChar =
|
||||
*/
|
||||
export function keyValToObject(
|
||||
str: string,
|
||||
splitChar: string = "&",
|
||||
equalChar = "="
|
||||
): {} {
|
||||
let result: any = {};
|
||||
if (!str) {
|
||||
return result;
|
||||
}
|
||||
let arrs = str.split(splitChar);
|
||||
for (let sub of arrs) {
|
||||
let subArr = sub.split(equalChar);
|
||||
result[subArr[0]] = subArr[1];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -32,3 +32,13 @@ export function shortUuid() {
|
||||
let uid = uuid()
|
||||
return compressUuid(uid)
|
||||
}
|
||||
|
||||
export function md5(content: string) {
|
||||
var md5 = crypto.createHash('md5')
|
||||
return md5.update(content).digest('hex')
|
||||
}
|
||||
|
||||
export function sha1(content: string) {
|
||||
var md5 = crypto.createHash('sha1')
|
||||
return md5.update(content).digest('hex')
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user