UNPKG

dotwallet

Version:
339 lines (316 loc) 11.9 kB
import {DWUser} from './dwUser' import WebRequest from 'web-request' import {DotWalletResult,Vout, MircoOrderInformation, SupportCoinType,DWError, DepositBalance,PushChainResult,DepositAccount, CreateSignature} from './dwCom' interface MircoOrderDetail{ merchant_order_sn:string; amount:number; item_name:string; receive_address:string; pay_time:string; order_sn:string; status:number; create_time:string; } interface OrderRequest{ app_id:string; merchant_order_sn:string; item_name:string; order_amount:number; nonce_str:string; sign:string; notice_uri:string; } interface PaymentOrder{ app_id:string; merchant_order_sn:string; item_name:string; order_amount:number; //单位 nonce_str:string; sign:string; notice_uri:string; redirect_uri:string; check_order_uri:string; opreturn:string; //opreturn hex string receive_address:string; // coinType:SupportCoinType; } export enum DomainOption{ CN = 'https://www.ddpurse.com', HK = 'https://overseas.ddpurse.com' } export interface ClientOptions{ redirectURI:string, noticeURI:string, checkOrderURI:string, receiveAddress:string,//商家默认收款地址,default receive address merchantName:string, timeOut:number, isMobile:boolean, domain:DomainOption, } export interface OrderResult{ orderSn:string, redirect:string, redirectFront:string, } export class DWMerchant { public m_appID:string; public m_secret:string; public m_merchantName:string; public m_redirectURI:string; public m_noticeURI:string; public m_checkOrderURI:string; public m_receiveAddr:string; public m_timeout:number; public m_opts:ClientOptions; public m_users:DWUser[] =[]; public m_mapUsers:Map<string,DWUser> = new Map<string,DWUser>(); public static DotWalletOpenURL:string = DomainOption.CN; public static feeToken = "561b756d12572020ea9a104c3441b71790acbbce95a6ddbf7e0630971af9424b"; public m_depositCoinType = SupportCoinType.BSV; public m_depositAddress = ''; constructor(appID:string, secret:string, opts?:ClientOptions){ this.m_appID = appID; this.m_secret = secret; const defaultOpts:ClientOptions = { redirectURI:'', noticeURI:'', checkOrderURI:'', receiveAddress:'', merchantName:'', timeOut:5000, isMobile:false, domain:DomainOption.CN }; opts = opts||defaultOpts; this.m_redirectURI = opts.redirectURI || ''; this.m_noticeURI = opts.noticeURI || ''; this.m_checkOrderURI = opts.checkOrderURI|| ''; this.m_merchantName = opts.merchantName || "unkown"; this.m_receiveAddr = opts.receiveAddress || ''; this.m_timeout = opts.timeOut || 5000; DWMerchant.DotWalletOpenURL = opts.domain || defaultOpts.domain; this.m_opts = opts; this.initInerval(); } private async initInerval(){ let userMap = this.m_mapUsers; setInterval(async function () { for(let value of userMap){ let user = value[1]; await user.RefreshAccessToken(); } }, 7200*1000); } public GetAuthURL():string{ const getAuthURL = new URL( "openapi/get_code", DWMerchant.DotWalletOpenURL); getAuthURL.searchParams.append('app_id', this.m_appID); getAuthURL.searchParams.append('redirect_uri', this.m_redirectURI); return getAuthURL.href; } public GetMircoPaymentURL():string{ const getURL = new URL( "openapi/set_pay_config", DWMerchant.DotWalletOpenURL); getURL.searchParams.append('app_id', this.m_appID); getURL.searchParams.append('redirect_uri', this.m_redirectURI); return getURL.href; } public GetUserPayURL(orderSN:string){ let getURL; if (this.m_opts.isMobile){ getURL = new URL( "wallet/open/pay", DWMerchant.DotWalletOpenURL); }else{ getURL = new URL( "desktop/open/order", DWMerchant.DotWalletOpenURL); } getURL.searchParams.append('order_sn', orderSN); return getURL.href; } public async mpiFeeQuote():Promise<any>{ const orderURL = new URL( "openapi/mapi/feeQuote", DWMerchant.DotWalletOpenURL); const rsp = await WebRequest.get(orderURL.href,{ timeout:this.m_timeout, headers:{token:DWMerchant.feeToken} }); return JSON.parse(rsp.content); } public async mpiTxQuery(txid:string):Promise<any>{ const orderURL = new URL( `openapi/mapi/tx/${txid}`, DWMerchant.DotWalletOpenURL); const rsp = await WebRequest.get(orderURL.href,{ timeout:this.m_timeout, headers:{token:DWMerchant.feeToken} }); return JSON.parse(rsp.content); } public async mpiSendTx(rawtx:string):Promise<any>{ const orderURL = new URL( `openapi/mapi/tx`, DWMerchant.DotWalletOpenURL); const rsp = await WebRequest.post(orderURL.href,{ timeout:this.m_timeout, headers:{ token:DWMerchant.feeToken, 'Content-Type': 'application/json', }},JSON.stringify({ rawtx:rawtx })); return JSON.parse(rsp.content); } /** * 创建订单号,并返回用户授权URL * @param orderSN * @param itemName * @param payAmount * @param opreturnHex * @param receiveAddress * @returns redirect url * <a href="https://www.ddpurse.com/desktop/open/order?order_sn=948a19d6b779b2abcfd21c0fa0a9a615">https://www.ddpurse.com/desktop/open/order?order_sn=948a19d6b779b2abcfd21c0fa0a9a615</a> */ public async CreateOrder(orderSN:string, itemName:string, payAmount:number, opreturnHex:string, receiveAddress:string |undefined):Promise<DotWalletResult>{ //todo, check payAmount >= dust , //todo,check receiveAddress. //todo, add money type support. let recvMuti = [{ address: receiveAddress || this.m_receiveAddr, amount: payAmount }]; return await this.CreateOrderMuti(orderSN, itemName, payAmount, recvMuti, opreturnHex); } public async CreateOrderMuti(orderSN:string,itemName:string, payAmount:number,receiveMuti:Vout[], opreturnHex:string):Promise<DotWalletResult>{ let order:PaymentOrder = { app_id:this.m_appID, merchant_order_sn:orderSN, item_name:itemName, order_amount:payAmount, nonce_str:new Date().getTime().toString(), sign:'', notice_uri:this.m_noticeURI, redirect_uri:this.m_redirectURI, check_order_uri:this.m_checkOrderURI, opreturn:opreturnHex, //opreturn hex string receive_address:JSON.stringify(receiveMuti), }; order.sign = CreateSignature(order, this.m_secret); const orderURL = new URL( "openapi/order", DWMerchant.DotWalletOpenURL); const rsp = await WebRequest.post(orderURL.href,{ timeout:this.m_timeout, headers:{ 'Content-Type': 'application/json', } },JSON.stringify(order)); const result = <DotWalletResult>JSON.parse(rsp.content); return result; } //please call this function when user redirect from dotwallet public async AddUser(code:string, userName:string){ let newUser = new DWUser(this, userName); await newUser.GetAccessCode(code); await newUser.GetUserInfo(); this.m_mapUsers.set(userName, newUser); } public GetUser(userName:string):DWUser{ return this.m_mapUsers.get(userName); } //---------------------mirco payment 小额支付相关----------------------------------- /** * 小额支持订单接口 * @param userName * @param orderSN * @param payAmount * @param opreturnHex * @param receiveAddress */ public async CreateMircoOrder(userName:string, orderSN:string, payAmount:number, opreturnHex:string,receiveAddress:string |undefined):Promise<DotWalletResult>{ let user = this.m_mapUsers.get(userName); return await user.CreateMircoOrder(orderSN, payAmount, opreturnHex, receiveAddress); } /** * 根据订单号查询小额支付订单详情 * @param orderSN */ public async QueryMircoOrder(orderSN:string):Promise<MircoOrderDetail>{ const orderURL = new URL( "openapi/search_order", DWMerchant.DotWalletOpenURL); const rsp = await WebRequest.create<DotWalletResult>(orderURL.href,{ timeout:this.m_timeout, method:'POST' },{ app_id:this.m_appID, secret:this.m_secret, merchant_order_sn:orderSN, }).response; const result = rsp.content; let rst:MircoOrderDetail = <MircoOrderDetail>result.data; return rst; } //----------------------push chain data,托管账户数据上链接口--------------------------------------------- public async pushChainCommon(url:string, req:any):Promise<any>{ var rsp = await WebRequest.post(url,{ timeout:this.m_timeout, method:'POST', headers:{ 'Content-Type': 'application/json', appid:this.m_appID, appsecret:this.m_secret, } },JSON.stringify(req)); const result = <DotWalletResult>JSON.parse(rsp.content); if (result.code < 0){ throw new DWError(result.code, result.msg); } return result.data; } /** * 查询托管账户余额接口 */ public async DepositBalance():Promise<DepositBalance>{ const durl = new URL( "openapi/getDepositBalance", DWMerchant.DotWalletOpenURL); let result = <DepositBalance>await this.pushChainCommon(durl.href, { coinType:SupportCoinType.BSV, }); return result; } /** * 获取托管账户信息,主要是托管账户地址,用户需要往该地址充值,数据上链的手续费从该地址扣除 */ public async DepositAddress():Promise<string>{ const durl = new URL( "openapi/newDepositAccount", DWMerchant.DotWalletOpenURL); let result = <DepositAccount>await this.pushChainCommon(durl.href, { coinType:SupportCoinType.BSV, }); this.m_depositAddress = result.address; return this.m_depositAddress; } /** * 数据上链接口 * @param opreturn */ public async PushChainData(opreturn:string):Promise<PushChainResult>{ const durl = new URL( "openapi/pushChainData", DWMerchant.DotWalletOpenURL); let result = <PushChainResult>await this.pushChainCommon(durl.href, { coinType:SupportCoinType.BSV, opreturn:opreturn, }); return result; } } /** * 非托管账户的数据上链服务 * @param email 打点钱包用户的email * @param signCallback 回调签名服务器 * @param opreturn 要上链的Opreturn */ export async function PushChainData(email:string,signCallback:string, opreturn:string):Promise<PushChainResult>{ const durl = new URL( "/api/pushChainData", DWMerchant.DotWalletOpenURL); var rsp = await WebRequest.post(durl.href,{ method:'POST', headers:{ 'Content-Type': 'application/json', } },JSON.stringify({ coinType:SupportCoinType.BSV, email:email, opreturn:opreturn, signCallback:signCallback, })); const result = <DotWalletResult>JSON.parse(rsp.content); if (result.code < 0){ throw new DWError(result.code, result.msg); } return result.data; }