Toggle navigation
Toggle navigation
This project
Loading...
Sign in
fe
/
yoho-blk
·
Commits
Go to a project
GitLab
Go to group
Project
Activity
Files
Commits
Pipelines
0
Builds
0
Graphs
Milestones
Issues
0
Merge Requests
1
Members
Labels
Wiki
Forks
Network
Create a new issue
Download as
Email Patches
Plain Diff
Browse Files
Authored by
姜枫
9 years ago
Commit
66fec9e80c309abb26704c21b1d14c197fed16c0
1 parent
2e15ce3a
完成下单签名
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
274 additions
and
123 deletions
apps/shopping/helpers/pay/common.js
apps/shopping/helpers/pay/sign.js
apps/shopping/helpers/pay/wechat.js
apps/shopping/helpers/payment.js
apps/shopping/models/pay.js
package.json
apps/shopping/helpers/pay/common.js
View file @
66fec9e
...
...
@@ -5,6 +5,7 @@
*/
'use strict'
;
const
moment
=
require
(
'moment'
);
const
xml2js
=
require
(
'xml2js'
);
const
common
=
{
getPayExpireMin
(
expire
)
{
...
...
@@ -23,6 +24,49 @@ const common = {
}
else
{
return
defaultValue
;
}
},
getPayExpireCouple
(
expire
)
{
let
start
=
expire
?
moment
(
expire
,
'YYYY-MM-DD HH:mm:ss'
)
:
moment
();
let
end
=
expire
?
moment
(
expire
,
'YYYY-MM-DD HH:mm:ss'
)
:
moment
();
return
{
start
:
start
.
subtract
(
2
,
'hours'
),
end
:
end
.
add
(
5
,
'minutes'
)
};
},
nonceStr
(
length
)
{
length
=
length
||
32
;
let
chars
=
'abcdefghijklmnopqrstuvwxyz0123456789'
;
let
str
=
''
;
for
(
let
i
=
0
;
i
<
length
;
i
++
)
{
str
+=
chars
[
parseInt
(
Math
.
random
()
*
length
,
10
)];
}
return
str
;
},
toXml
(
obj
,
root
)
{
let
xmlBuilder
=
new
xml2js
.
Builder
({
rootName
:
root
||
'xml'
});
return
xmlBuilder
.
buildObject
(
obj
);
},
xml2Obj
(
xml
)
{
let
xmlParser
=
new
xml2js
.
Parser
({
trim
:
true
,
explicitArray
:
false
});
return
new
Promise
((
resolve
,
reject
)
=>
{
xmlParser
.
parseString
(
xml
,
(
err
,
result
)
=>
{
if
(
err
)
{
reject
(
err
);
}
else
{
resolve
(
result
);
}
});
});
}
};
...
...
apps/shopping/helpers/pay/sign.js
View file @
66fec9e
...
...
@@ -12,7 +12,7 @@ const Sign = {
keys
=
keys
.
sort
();
return
keys
.
map
(
k
=>
{
return
k
.
toLowerCase
()
+
'='
+
args
[
k
];
return
k
+
'='
+
args
[
k
];
}).
join
(
'&'
);
},
...
...
apps/shopping/helpers/pay/wechat.js
View file @
66fec9e
...
...
@@ -5,3 +5,103 @@
*/
'use strict'
;
const
moment
=
require
(
'moment'
);
const
rq
=
require
(
'request-promise'
);
const
common
=
require
(
'./common'
);
const
sign
=
require
(
'./sign'
);
const
md5
=
require
(
'md5'
);
const
_
=
require
(
'lodash'
);
const
logger
=
global
.
yoho
.
logger
;
const
config
=
global
.
yoho
.
config
;
const
wechatUnifiedOrderUrl
=
'https://api.mch.weixin.qq.com/pay/unifiedorder'
;
const
Wechat
=
{
pay
(
user
,
order
,
info
)
{
let
expire
=
common
.
getPayExpireCouple
(
order
.
payExpire
);
info
=
JSON
.
parse
(
info
.
payParams
||
'{}'
);
let
unifiedOrder
=
{
body
:
'BLK订单号:'
+
order
.
orderCode
,
out_trade_no
:
order
.
orderCode
,
total_fee
:
parseInt
(
order
.
paymentAmount
*
100
,
10
),
time_start
:
moment
(
expire
.
start
).
format
(
'YYYYMMDDHHmmss'
),
time_expire
:
moment
(
expire
.
end
).
format
(
'YYYYMMDDHHmmss'
),
trade_type
:
'NATIVE'
,
product_id
:
order
.
orderCode
,
notify_url
:
config
.
pay
.
serviceNotify
+
'payment/weixin_notify'
,
appid
:
info
.
app_id
,
mch_id
:
info
.
partner_id
,
nonce_str
:
common
.
nonceStr
()
};
let
signStr
=
md5
(
sign
.
raw
(
unifiedOrder
)
+
'&key='
+
info
.
partner_key
);
unifiedOrder
.
sign
=
_
.
toUpper
(
signStr
);
return
this
.
unifiedOrder
(
unifiedOrder
).
then
(
result
=>
{
console
.
log
(
result
);
if
(
result
&&
result
.
xml
)
{
let
data
=
result
.
xml
||
{};
if
(
data
.
return_code
===
'SUCCESS'
&&
Wechat
.
checkSign
(
data
,
info
))
{
return
{
code
:
200
,
data
:
{
href
:
data
.
code_url
}
};
}
}
return
{
code
:
400
,
message
:
'请稍后重试'
};
});
},
unifiedOrder
(
unifiedOrder
)
{
let
xml
=
common
.
toXml
(
unifiedOrder
);
return
rq
({
method
:
'POST'
,
uri
:
wechatUnifiedOrderUrl
,
headers
:
{
'Content-Type'
:
'application/x-www-form-urlencoded'
,
'Content-Length'
:
Buffer
.
byteLength
(
xml
)
},
body
:
xml
,
timeout
:
1000
}).
then
(
result
=>
{
console
.
log
(
result
);
if
(
result
)
{
return
common
.
xml2Obj
(
result
);
}
else
{
return
{};
}
}).
catch
(
err
=>
{
logger
.
error
(
`
call
wechat
pay
unifiedOrder
fail
.
order
=
$
{
JSON
.
stringify
(
unifiedOrder
)}
`
,
err
);
return
{};
});
},
notify
(
data
,
info
)
{
// eslint-disable-line
},
checkSign
(
data
,
info
)
{
if
(
data
&&
data
.
sign
)
{
let
signStr
=
data
.
sign
||
''
;
delete
data
.
sign
;
return
signStr
===
md5
(
sign
.
raw
(
data
)
+
info
.
partner_key
);
}
return
false
;
}
};
module
.
exports
=
Wechat
;
...
...
apps/shopping/helpers/payment.js
View file @
66fec9e
...
...
@@ -10,6 +10,7 @@
const
PayData
=
require
(
'../models/pay'
);
const
OrderData
=
require
(
'../models/order'
);
const
Alipay
=
require
(
'./pay/alipay'
);
const
Wechat
=
require
(
'./pay/wechat'
);
const
Promise
=
require
(
'bluebird'
);
const
co
=
Promise
.
coroutine
;
const
logger
=
global
.
yoho
.
logger
;
...
...
@@ -26,6 +27,8 @@ const Payment = {
if
(
payInfo
&&
payInfo
.
id
===
method
)
{
if
(
method
===
PayData
.
payments
.
alipay
)
{
result
=
Alipay
.
pay
(
user
,
order
,
payInfo
);
}
else
if
(
method
===
PayData
.
payments
.
wechat
)
{
result
=
yield
Wechat
.
pay
(
user
,
order
,
payInfo
);
}
}
...
...
@@ -83,11 +86,13 @@ const Payment = {
if
(
payId
===
PayData
.
payments
.
alipay
)
{
payResult
=
Alipay
.
notify
(
query
,
payInfo
);
payResult
.
bankName
=
payResult
.
bankName
||
payInfo
.
payName
||
''
;
payResult
.
bankCode
=
payResult
.
bankCode
||
payInfo
.
pay_code
||
''
;
}
else
if
(
payId
===
PayData
.
payments
.
wechat
)
{
payResult
=
Wechat
.
notify
(
query
,
payInfo
);
}
payResult
.
bankName
=
payResult
.
bankName
||
payInfo
.
payName
||
''
;
payResult
.
bankCode
=
payResult
.
bankCode
||
payInfo
.
pay_code
||
''
;
if
(
payResult
&&
payResult
.
payResult
===
200
)
{
if
(
payResult
.
orderCode
)
{
logger
.
info
(
'pay back confirm'
);
...
...
apps/shopping/models/pay.js
View file @
66fec9e
...
...
@@ -18,7 +18,8 @@ const logger = global.yoho.logger;
const
_
=
require
(
'lodash'
);
const
payments
=
{
alipay
:
33
alipay
:
33
,
wechat
:
34
};
/**
...
...
@@ -32,7 +33,7 @@ const getOnlinePayProvider = () => {
}
let
online
=
_
(
result
.
data
)
.
filter
(
i
=>
_
.
includes
(
[
payments
.
alipay
]
,
i
.
id
))
.
filter
(
i
=>
_
.
includes
(
_
.
values
(
payments
)
,
i
.
id
))
.
map
(
i
=>
{
return
{
id
:
i
.
id
,
...
...
package.json
View file @
66fec9e
{
"name"
:
"yoho-blk"
,
"version"
:
"0.0.1"
,
"private"
:
true
,
"description"
:
"A New Yohoblk Project With Express"
,
"repository"
:
{
"type"
:
"git"
,
"url"
:
"http://git.yoho.cn/fe/yoho-blk.git"
},
"scripts"
:
{
"start"
:
"node app.js"
,
"dev"
:
"nodemon -e js,hbs -i public/ app.js"
,
"online"
:
"NODE_ENV=\"production\" node app.js"
,
"debug"
:
"DEBUG=\"express:*\" nodemon -e js,hbs -i public/ app.js"
,
"lint-js"
:
"eslint -c .eslintrc --cache --fix ."
,
"lint-css"
:
"stylelint --config .stylelintrc public/scss/**/*.css"
,
"precommit"
:
"node lint.js"
,
"test"
:
"NODE_ENV=test nyc ./node_modules/.bin/ava"
,
"posttest"
:
"nyc report --reporter=html"
},
"ava"
:
{
"tap"
:
true
,
"require"
:
[
"babel-register"
],
"babel"
:
{
"presets"
:
[
"es2015"
]
}
},
"license"
:
"MIT"
,
"dependencies"
:
{
"bluebird"
:
"^3.4.0"
,
"body-parser"
:
"^1.15.0"
,
"captchapng"
:
"0.0.1"
,
"connect-memcached"
:
"^0.2.0"
,
"connect-multiparty"
:
"^2.0.0"
,
"cookie-parser"
:
"^1.4.3"
,
"csurf"
:
"^1.9.0"
,
"express"
:
"^4.13.1"
,
"express-handlebars"
:
"^3.0.0"
,
"express-session"
:
"^1.13.0"
,
"influxdb-winston"
:
"^1.0.1"
,
"lodash"
:
"^4.13.1"
,
"md5"
:
"^2.1.0"
,
"memcached"
:
"^2.2.2"
,
"moment"
:
"^2.13.0"
,
"morgan"
:
"^1.7.0"
,
"oneapm"
:
"^1.2.20"
,
"passport"
:
"^0.3.2"
,
"passport-douban"
:
"0.0.1"
,
"passport-local"
:
"^1.0.0"
,
"passport-qq"
:
"0.0.3"
,
"passport-renren"
:
"^0.1.3"
,
"passport-sina"
:
"^0.1.0"
,
"passport-strategy"
:
"1.x.x"
,
"passport-weixin"
:
"^0.1.0"
,
"request"
:
"^2.73.0"
,
"request-promise"
:
"^3.0.0"
,
"serve-favicon"
:
"^2.3.0"
,
"uuid"
:
"^2.0.2"
,
"winston"
:
"^2.2.0"
,
"winston-daily-rotate-file"
:
"^1.1.4"
,
"xss"
:
"^0.2.13"
,
"yoho-node-lib"
:
"0.0.45"
},
"devDependencies"
:
{
"autoprefixer"
:
"^6.3.6"
,
"ava"
:
"^0.15.2"
,
"babel-preset-es2015"
:
"^6.9.0"
,
"babel-register"
:
"^6.9.0"
,
"eslint"
:
"^2.12.0"
,
"eslint-config-yoho"
:
"^1.0.1"
,
"gulp"
:
"^3.9.1"
,
"gulp-cssnano"
:
"^2.1.2"
,
"gulp-ftp"
:
"^1.1.0"
,
"gulp-postcss"
:
"^6.1.0"
,
"gulp-sourcemaps"
:
"^2.0.0-alpha"
,
"gulp-util"
:
"^3.0.7"
,
"handlebars-loader"
:
"^1.3.0"
,
"husky"
:
"^0.11.4"
,
"nodemon"
:
"1.9.2"
,
"nyc"
:
"^6.6.1"
,
"postcss-assets"
:
"^4.0.1"
,
"postcss-cachebuster"
:
"^0.1.3"
,
"postcss-calc"
:
"^5.2.1"
,
"postcss-center"
:
"^1.0.0"
,
"postcss-clearfix"
:
"^1.0.0"
,
"postcss-crip"
:
"^2.0.0"
,
"postcss-opacity"
:
"^3.0.0"
,
"postcss-position"
:
"^0.5.0"
,
"postcss-pxtorem"
:
"^3.3.1"
,
"postcss-short"
:
"^1.4.0"
,
"postcss-sprites"
:
"^3.1.2"
,
"postcss-use"
:
"^2.0.2"
,
"precss"
:
"^1.4.0"
,
"rewire"
:
"^2.5.1"
,
"shelljs"
:
"^0.7.0"
,
"stylelint"
:
"^7.1.0"
,
"stylelint-config-yoho"
:
"^1.2.7"
,
"webpack"
:
"^1.13.1"
,
"webpack-dev-server"
:
"^1.14.1"
,
"webpack-stream"
:
"^3.1.0"
,
"yoho-eventproxy"
:
"^0.3.6"
,
"yoho-handlebars"
:
"^4.0.5"
,
"yoho-jquery"
:
"^1.12.4"
,
"yoho-jquery-accordion"
:
"0.0.2"
,
"yoho-jquery-dotdotdot"
:
"0.0.1"
,
"yoho-jquery-lazyload"
:
"^1.9.7"
,
"yoho-jquery-nanoscroller"
:
"0.0.1"
,
"yoho-jquery-placeholder"
:
"^2.3.1"
,
"yoho-jquery-qrcode"
:
"0.0.3"
,
"yoho-json2"
:
"^1.0.0"
,
"yoho-slider"
:
"0.0.2"
}
}
{
"name"
:
"yoho-blk"
,
"version"
:
"0.0.1"
,
"private"
:
true
,
"description"
:
"A New Yohoblk Project With Express"
,
"repository"
:
{
"type"
:
"git"
,
"url"
:
"http://git.yoho.cn/fe/yoho-blk.git"
},
"scripts"
:
{
"start"
:
"node app.js"
,
"dev"
:
"nodemon -e js,hbs -i public/ app.js"
,
"online"
:
"NODE_ENV=\"production\" node app.js"
,
"debug"
:
"DEBUG=\"express:*\" nodemon -e js,hbs -i public/ app.js"
,
"lint-js"
:
"eslint -c .eslintrc --cache --fix ."
,
"lint-css"
:
"stylelint --config .stylelintrc public/scss/**/*.css"
,
"precommit"
:
"node lint.js"
,
"test"
:
"NODE_ENV=test nyc ./node_modules/.bin/ava"
,
"posttest"
:
"nyc report --reporter=html"
},
"ava"
:
{
"tap"
:
true
,
"require"
:
[
"babel-register"
],
"babel"
:
{
"presets"
:
[
"es2015"
]
}
},
"license"
:
"MIT"
,
"dependencies"
:
{
"bluebird"
:
"^3.4.0"
,
"body-parser"
:
"^1.15.0"
,
"captchapng"
:
"0.0.1"
,
"connect-memcached"
:
"^0.2.0"
,
"connect-multiparty"
:
"^2.0.0"
,
"cookie-parser"
:
"^1.4.3"
,
"csurf"
:
"^1.9.0"
,
"express"
:
"^4.13.1"
,
"express-handlebars"
:
"^3.0.0"
,
"express-session"
:
"^1.13.0"
,
"influxdb-winston"
:
"^1.0.1"
,
"lodash"
:
"^4.13.1"
,
"md5"
:
"^2.1.0"
,
"memcached"
:
"^2.2.2"
,
"moment"
:
"^2.13.0"
,
"morgan"
:
"^1.7.0"
,
"oneapm"
:
"^1.2.20"
,
"passport"
:
"^0.3.2"
,
"passport-douban"
:
"0.0.1"
,
"passport-local"
:
"^1.0.0"
,
"passport-qq"
:
"0.0.3"
,
"passport-renren"
:
"^0.1.3"
,
"passport-sina"
:
"^0.1.0"
,
"passport-strategy"
:
"1.x.x"
,
"passport-weixin"
:
"^0.1.0"
,
"request"
:
"^2.73.0"
,
"request-promise"
:
"^3.0.0"
,
"serve-favicon"
:
"^2.3.0"
,
"uuid"
:
"^2.0.2"
,
"winston"
:
"^2.2.0"
,
"winston-daily-rotate-file"
:
"^1.1.4"
,
"xml2js"
:
"^0.4.17"
,
"xss"
:
"^0.2.13"
,
"yoho-node-lib"
:
"0.0.45"
},
"devDependencies"
:
{
"autoprefixer"
:
"^6.3.6"
,
"ava"
:
"^0.15.2"
,
"babel-preset-es2015"
:
"^6.9.0"
,
"babel-register"
:
"^6.9.0"
,
"eslint"
:
"^2.12.0"
,
"eslint-config-yoho"
:
"^1.0.1"
,
"gulp"
:
"^3.9.1"
,
"gulp-cssnano"
:
"^2.1.2"
,
"gulp-ftp"
:
"^1.1.0"
,
"gulp-postcss"
:
"^6.1.0"
,
"gulp-sourcemaps"
:
"^2.0.0-alpha"
,
"gulp-util"
:
"^3.0.7"
,
"handlebars-loader"
:
"^1.3.0"
,
"husky"
:
"^0.11.4"
,
"nodemon"
:
"1.9.2"
,
"nyc"
:
"^6.6.1"
,
"postcss-assets"
:
"^4.0.1"
,
"postcss-cachebuster"
:
"^0.1.3"
,
"postcss-calc"
:
"^5.2.1"
,
"postcss-center"
:
"^1.0.0"
,
"postcss-clearfix"
:
"^1.0.0"
,
"postcss-crip"
:
"^2.0.0"
,
"postcss-opacity"
:
"^3.0.0"
,
"postcss-position"
:
"^0.5.0"
,
"postcss-pxtorem"
:
"^3.3.1"
,
"postcss-short"
:
"^1.4.0"
,
"postcss-sprites"
:
"^3.1.2"
,
"postcss-use"
:
"^2.0.2"
,
"precss"
:
"^1.4.0"
,
"rewire"
:
"^2.5.1"
,
"shelljs"
:
"^0.7.0"
,
"stylelint"
:
"^7.1.0"
,
"stylelint-config-yoho"
:
"^1.2.7"
,
"webpack"
:
"^1.13.1"
,
"webpack-dev-server"
:
"^1.14.1"
,
"webpack-stream"
:
"^3.1.0"
,
"yoho-eventproxy"
:
"^0.3.6"
,
"yoho-handlebars"
:
"^4.0.5"
,
"yoho-jquery"
:
"^1.12.4"
,
"yoho-jquery-accordion"
:
"0.0.2"
,
"yoho-jquery-dotdotdot"
:
"0.0.1"
,
"yoho-jquery-lazyload"
:
"^1.9.7"
,
"yoho-jquery-nanoscroller"
:
"0.0.1"
,
"yoho-jquery-placeholder"
:
"^2.3.1"
,
"yoho-jquery-qrcode"
:
"0.0.3"
,
"yoho-json2"
:
"^1.0.0"
,
"yoho-slider"
:
"0.0.2"
}
}
...
...
Please
register
or
login
to post a comment