Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
5
51business
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
方斌
51business
Commits
90359d5a
Commit
90359d5a
authored
Sep 09, 2019
by
李尚科
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wexin pay
parent
de7f088d
Pipeline
#13534
passed with stage
in 1 minute 5 seconds
Changes
9
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
462 additions
and
8 deletions
+462
-8
order.js
app/controller/credit/order.js
+45
-1
helper.js
app/extend/helper.js
+42
-1
credit_callrisk_call_active.js
app/model/prometheus/credit_callrisk_call_active.js
+28
-4
credit_pay.js
app/model/prometheus/credit_pay.js
+130
-0
credit.js
app/router/credit.js
+2
-0
callrisk.js
app/service/credit/callrisk.js
+1
-1
common.js
app/service/credit/common.js
+191
-0
order.js
app/service/credit/order.js
+21
-0
package.json
package.json
+2
-1
No files found.
app/controller/credit/order.js
View file @
90359d5a
'use strict'
;
const
Controller
=
require
(
'egg'
).
Controller
;
const
xml2js
=
require
(
'xml2js'
).
parseString
;
class
OrderController
extends
Controller
{
/**
...
...
@@ -27,6 +27,50 @@ class OrderController extends Controller {
ctx
.
success
({
results
});
}
//微信支付
async
payOrder
()
{
const
{
ctx
}
=
this
;
const
order_id
=
ctx
.
params
.
order_id
;
const
result
=
await
ctx
.
service
.
credit
.
common
.
unifiedOrder
(
'wexin'
,
order_id
);
ctx
.
success
({
result
});
}
async
payNotice
()
{
const
{
ctx
}
=
this
;
let
data
=
''
;
ctx
.
req
.
setEncoding
(
'utf8'
);
ctx
.
req
.
on
(
'data'
,
function
(
chunk
)
{
data
+=
chunk
;
});
const
getxml
=
await
new
Promise
(
function
(
resolve
)
{
ctx
.
req
.
on
(
'end'
,
function
()
{
resolve
(
data
);
});
});
const
ret_obj
=
await
ctx
.
helper
.
xmlTojson
(
getxml
);
ctx
.
logger
.
info
({
notice_params
:
ret_obj
});
const
ret
=
await
ctx
.
service
.
credit
.
common
.
WexinNotify
(
ret_obj
);
ctx
.
success
({
ret_obj
,
ret
});
return
;
ctx
.
success
(
"<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>"
);
}
async
checkPay
()
{
const
{
ctx
}
=
this
;
const
order_id
=
ctx
.
params
.
order_id
;
const
is_pay
=
ctx
.
service
.
credit
.
order
.
checkOrderPay
(
order_id
);
let
result
=
false
;
if
(
is_pay
)
{
result
=
true
;
}
ctx
.
success
({
result
});
}
}
...
...
app/extend/helper.js
View file @
90359d5a
'use strict'
;
const
XML2JS
=
require
(
'xml2js'
);
module
.
exports
=
{
// 获取 Token
...
...
@@ -269,6 +269,22 @@ module.exports = {
return
ip
;
},
/**
* @author lisk
* @description 生成随机字串
* @param {*} length
*/
createNoncestr
(
length
=
32
)
{
const
chars
=
'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
;
const
clen
=
chars
.
length
;
let
str
=
''
;
for
(
let
i
=
0
;
i
<
length
;
i
++
)
{
str
+=
chars
.
substr
(
parseInt
(
Math
.
random
()
*
clen
)
-
1
,
1
);
}
return
str
;
},
JsonParse
(
jsonStr
)
{
try
{
...
...
@@ -297,5 +313,30 @@ module.exports = {
return
1
;
},
//固定位数前补充 0 操作
PrefixInteger
(
num
,
length
)
{
return
(
Array
(
length
).
join
(
'0'
)
+
num
).
slice
(
-
length
);
},
async
xmlTojson
(
data
)
{
const
ret_p
=
new
Promise
((
resolve
,
reject
)
=>
{
XML2JS
.
parseString
(
data
,
(
err
,
result
)
=>
{
if
(
err
)
{
this
.
ctx
.
failed
(
err
);
reject
();
}
else
{
const
ret
=
result
.
xml
;
resolve
(
ret
);
}
});
});
let
ret_json
=
{};
await
ret_p
.
then
((
resolve
,
reject
)
=>
{
ret_json
=
resolve
});
return
ret_json
;
},
jsonToxml
(
data
)
{
const
bulider
=
new
XML2JS
.
Builder
();
const
xml_params
=
bulider
.
buildObject
(
data
);
return
xml_params
;
}
};
app/model/prometheus/credit_callrisk_call_active.js
View file @
90359d5a
...
...
@@ -33,12 +33,36 @@ module.exports = app => {
allowNull
:
false
,
},
time_interval_active
:
{
type
:
INTEGER
,
allowNull
:
false
,
type
:
STRING
,
allowNull
:
true
,
field
:
'time_interval_active'
,
get
()
{
const
time_interval_active
=
this
.
getDataValue
(
'time_interval_active'
);
if
(
time_interval_active
)
{
try
{
return
JSON
.
parse
(
time_interval_active
);
}
catch
(
error
)
{
return
[];
}
}
return
[];
},
},
city_active
:
{
type
:
INTEGER
,
allowNull
:
false
,
type
:
STRING
,
allowNull
:
true
,
field
:
'city_active'
,
get
()
{
const
city_active
=
this
.
getDataValue
(
'city_active'
);
if
(
city_active
)
{
try
{
return
JSON
.
parse
(
city_active
);
}
catch
(
error
)
{
return
[];
}
}
return
[];
},
},
// is_deleted: {
// type: INTEGER,
...
...
app/model/prometheus/credit_pay.js
0 → 100644
View file @
90359d5a
'use strict'
;
const
moment
=
require
(
'moment'
);
module
.
exports
=
app
=>
{
const
{
STRING
,
INTEGER
,
DATE
,
DECIMAL
,
TEXT
,
ENUM
}
=
app
.
Sequelize
;
const
CreditPay
=
app
.
prometheusModel
.
define
(
'credit_pay'
,
{
id
:
{
type
:
INTEGER
,
primaryKey
:
true
,
autoIncrement
:
true
},
order_id
:
{
type
:
INTEGER
,
allowNull
:
false
,
},
trade_no
:
{
type
:
STRING
,
allowNull
:
false
,
},
prepay_id
:
{
type
:
STRING
,
allowNull
:
false
,
},
transaction_id
:
{
type
:
STRING
,
allowNull
:
true
,
},
amount
:
{
type
:
DECIMAL
,
allowNull
:
false
,
},
description
:
{
type
:
STRING
,
allowNull
:
true
,
},
client_ip
:
{
type
:
STRING
,
allowNull
:
true
,
},
unifiedorder_result
:
{
type
:
STRING
,
allowNull
:
false
,
},
pay_result
:
{
type
:
STRING
,
allowNull
:
true
,
},
status
:
{
type
:
INTEGER
,
allowNull
:
true
,
},
created_at
:
{
type
:
DATE
,
allowNull
:
true
,
get
()
{
const
date
=
this
.
getDataValue
(
'created_at'
);
return
date
?
moment
(
date
).
format
(
'YYYY-MM-DD HH:mm:ss'
)
:
undefined
;
},
}
},
{
timestamps
:
false
,
tableName
:
'credit_pay'
,
});
CreditPay
.
one
=
async
(
data
)
=>
{
const
attributes
=
data
.
attributes
?
data
.
attributes
:
{};
const
where
=
data
.
where
?
data
.
where
:
{};
return
await
CreditPay
.
findOne
({
attributes
:
attributes
,
where
:
where
,
});
}
CreditPay
.
all
=
async
(
data
)
=>
{
const
attributes
=
data
.
attributes
?
data
.
attributes
:
{};
const
where
=
data
.
where
?
data
.
where
:
{};
const
order
=
data
.
order
?
data
.
order
:
[];
return
await
CreditPay
.
findAll
({
attributes
:
attributes
,
where
:
where
,
order
,
});
}
CreditPay
.
list
=
async
(
data
=
{})
=>
{
const
limit
=
data
.
limit
?
Number
(
data
.
limit
)
:
10
;
const
page
=
data
.
page
?
data
.
page
:
1
;
const
order
=
data
.
order
?
data
.
order
:
[];
const
attributes
=
data
.
attributes
?
data
.
attributes
:
{};
const
where
=
data
.
where
?
data
.
where
:
{};
const
condition
=
{
offset
:
(
page
-
1
)
*
limit
,
limit
,
where
:
where
,
order
:
order
,
attributes
:
attributes
,
};
const
{
count
,
rows
}
=
await
CreditPay
.
findAndCountAll
(
condition
);
return
{
page
,
count
,
rows
};
}
CreditPay
.
add
=
async
(
data
)
=>
{
try
{
//返回promise对象实力 instance
const
res
=
await
CreditPay
.
create
(
data
);
//从promise 实例中中获得需要的id号,id 必须是自增长,而且必须主键,否则返回null
return
res
.
id
;
}
catch
(
error
)
{
throw
(
error
);
}
}
CreditPay
.
edit
=
async
(
data
)
=>
{
const
where
=
data
.
where
;
const
params
=
data
.
params
;
try
{
const
res
=
await
CreditPay
.
update
(
params
,
{
where
:
where
})
return
res
;
}
catch
(
error
)
{
throw
(
error
);
}
}
return
CreditPay
;
};
\ No newline at end of file
app/router/credit.js
View file @
90359d5a
...
...
@@ -5,6 +5,8 @@ module.exports = app => {
router
.
get
(
'third'
,
'/home'
,
'credit.order.getMyCredit'
);
router
.
get
(
'third'
,
'/history/:type'
,
'credit.order.getRecord'
);
router
.
get
(
'third'
,
'/order/pay/:order_id'
,
'credit.order.payOrder'
);
router
.
post
(
'third'
,
'/order/pay_notice'
,
'credit.order.payNotice'
);
//我的信用-黑名单报告
router
.
get
(
'third'
,
'/blacklist/report/:report_id'
,
'credit.blacklist.getBlacklistReport'
);
//获取报告信息
...
...
app/service/credit/callrisk.js
View file @
90359d5a
...
...
@@ -36,7 +36,7 @@ class CallriskService extends Service {
const
{
ctx
}
=
this
;
const
basics
=
await
ctx
.
prometheusModel
.
CreditCallriskReport
.
one
({
where
:
{
report_id
}
});
const
basics
=
await
ctx
.
prometheusModel
.
CreditCallriskReport
.
one
({
where
:
{
id
:
report_id
}
});
if
(
!
basics
||
!
basics
.
id
)
{
ctx
.
failed
(
'error report_id'
);
}
...
...
app/service/credit/common.js
View file @
90359d5a
...
...
@@ -64,6 +64,197 @@ class CommonService extends Service {
return
sign
;
}
async
unifiedOrder
(
type
,
order_id
)
{
const
{
ctx
}
=
this
;
const
order
=
await
ctx
.
service
.
credit
.
order
.
getOrderInfo
(
order_id
);
const
price
=
order
.
price
*
100
-
order
.
preferential_price
*
100
;
console
.
info
(
price
);
if
(
price
<=
0
)
{
ctx
.
failed
(
'error price'
);
}
if
(
type
===
'wexin'
)
{
let
body
=
'黑名单报告检测支付'
;
if
(
order
.
type
===
2
)
{
body
=
'个人通话风险检测支付'
;
}
const
data
=
{
body
,
order_id
,
trade_no
:
moment
().
valueOf
()
+
ctx
.
helper
.
PrefixInteger
(
order_id
,
11
),
total_fee
:
price
,
notify_url
:
''
,
product_id
:
order
.
order_no
,
scene_info
:
{
h5_info
:
{
type
:
'Wap'
,
wap_url
:
this
.
config
.
PHP_URL
,
wap_name
:
'我的信用'
},
},
};
const
ret
=
await
this
.
WexinUnifiedOrder
(
data
);
const
pay_data
=
{
order_id
,
trade_no
:
data
.
trade_no
,
description
:
data
.
body
,
prepay_id
:
ret
.
prepay_id
||
0
,
amount
:
data
.
total_fee
,
unifiedorder_result
:
JSON
.
stringify
(
ret
),
client_ip
:
ctx
.
helper
.
getClientIP
(),
};
await
this
.
addCreditPay
(
pay_data
);
return
{
url
:
ret
.
mweb_url
};
}
else
if
(
type
===
'alipay'
)
{
//TODO
}
return
false
;
}
async
WexinUnifiedOrder
(
params
)
{
const
{
ctx
}
=
this
;
const
{
body
,
trade_no
,
total_fee
,
notify_url
,
product_id
,
scene_info
}
=
params
;
const
appid
=
''
;
const
mch_id
=
''
;
const
trade_type
=
'MWEB'
;
const
nonce_str
=
ctx
.
helper
.
createNoncestr
();
const
spbill_create_ip
=
ctx
.
helper
.
getClientIP
();
let
json_data
=
{
appid
,
mch_id
,
body
,
trade_no
,
total_fee
,
spbill_create_ip
,
notify_url
,
product_id
,
scene_info
,
trade_type
,
nonce_str
,
};
const
sign
=
this
.
getWexinSign
(
json_data
);
json_data
.
sign
=
sign
;
const
xml_data
=
ctx
.
helper
.
jsonToxml
(
json_data
);
const
url
=
'https://api.mch.weixin.qq.com/pay/unifiedorder'
;
const
result_wexin
=
await
ctx
.
curl
(
url
,
{
timeout
:
3000
,
method
:
'POST'
,
data
:
xml_data
,
headers
:
{
'content-type'
:
'text/html'
,
},
streaming
:
false
,
dataType
:
'text'
,
});
console
.
info
(
result_wexin
);
if
(
result_wexin
.
status
!==
200
)
{
ctx
.
failed
(
'wexin pay failed'
);
}
const
result
=
await
ctx
.
helper
.
xmlTojson
(
result_wexin
.
data
);
ctx
.
logger
.
info
({
pay_wexin_params
:
json_data
,
pay_wexin_result
:
result
});
let
ret
=
{};
for
(
let
key
in
result
)
{
ret
[
key
]
=
result
[
key
][
0
];
}
let
error_msg
=
'wexin pay error'
;
if
(
!
ret
.
return_code
||
ret
.
return_code
!==
'SUCCESS'
)
{
error_msg
=
ret
.
return_msg
||
error_msg
;
// ctx.failed(error_msg);
}
if
(
!
ret
.
result_code
||
ret
.
result_code
!==
'SUCCESS'
)
{
error_msg
=
ret
.
err_code_des
||
error_msg
;
// ctx.failed(error_msg);
}
return
ret
;
}
async
addCreditPay
(
params
)
{
const
{
ctx
}
=
this
;
const
{
order_id
,
trade_no
,
prepay_id
,
amount
,
description
,
unifiedorder_result
,
client_ip
}
=
params
;
const
data
=
{
order_id
,
trade_no
,
prepay_id
,
amount
,
description
,
unifiedorder_result
,
client_ip
,
}
const
ret
=
await
ctx
.
prometheusModel
.
CreditPay
.
add
(
data
);
return
ret
;
}
async
alipay
()
{
}
async
WexinCheckPay
(
params
)
{
const
{
ctx
}
=
this
;
const
{
transaction_id
,
out_trade_no
,
nonce_str
}
=
params
;
}
/**
* @description 支付回调通知
* @param {*} result
*/
async
WexinNotify
(
result
)
{
const
{
ctx
}
=
this
;
// && result.appid === this.config.MCH_APPID
if
(
result
)
{
let
sign_data
=
{};
for
(
let
key
in
result
)
{
sign_data
[
key
]
=
result
[
key
][
0
];
}
if
(
sign_data
.
return_code
&&
sign_data
.
return_code
===
'SUCCESS'
&&
sign_data
.
result_code
&&
sign_data
.
result_code
===
'SUCCESS'
)
{
const
wexin_return_sign
=
sign_data
.
sign
;
delete
sign_data
.
sign
;
const
sign
=
this
.
getSign
(
sign_data
);
const
out_trade_no
=
sign_data
.
out_trade_no
;
const
total_fee
=
sign_data
.
total_fee
;
const
pay_info
=
await
ctx
.
prometheusModel
.
CreditPay
.
findOne
({
where
:
{
trade_no
:
out_trade_no
},
order
:
[[
'id'
,
'desc'
]]
});
if
(
!
pay_info
||
!
pay_info
.
order_id
)
{
ctx
.
failed
(
'error pay'
);
}
const
order
=
await
ctx
.
prometheusModel
.
CreditOrder
.
findOne
({
where
:
{
id
:
pay_info
.
order_id
}
});
if
(
!
order
||
!
order
.
id
)
{
ctx
.
failed
(
'error order'
);
}
const
price
=
order
.
price
*
100
-
order
.
preferential_price
*
100
;
if
(
total_fee
==
price
&&
sign
==
wexin_return_sign
)
{
const
state_time
=
moment
().
format
(
'YYYY-MM-DD HH:mm:ss'
);
await
ctx
.
prometheusModel
.
CreditPay
.
edit
({
where
:
{
id
:
pay_info
.
id
},
params
:
{
pay_result
:
JSON
.
stringify
(
result
),
status
:
1
}
});
await
ctx
.
prometheusModel
.
CreditOrder
.
update
({
state
:
'已支付'
,
state_time
:
state_time
,
pay_status
:
1
},
{
where
:
{
id
:
order
.
id
}
});
console
.
info
(
'7777777777777777777777'
);
return
true
;
}
}
}
return
false
;
}
/**
* @author lisk
* @description 参数签名
* @param {*} params
*/
getWexinSign
(
params
)
{
const
{
ctx
,
app
}
=
this
;
let
ret
=
[];
for
(
let
val
of
Object
.
keys
(
params
).
sort
())
{
ret
[
val
]
=
params
[
val
];
}
let
str
=
''
;
for
(
let
key
in
ret
)
{
str
+=
key
+
'='
+
ret
[
key
]
+
'&'
;
}
const
mch_key
=
this
.
config
.
MCH_KEY
;
const
sign
=
ctx
.
helper
.
md5
(
str
+
'key='
+
mch_key
).
toLocaleUpperCase
();
return
sign
;
}
}
module
.
exports
=
CommonService
;
app/service/credit/order.js
View file @
90359d5a
...
...
@@ -5,6 +5,7 @@ const Service = require('egg').Service;
const
moment
=
require
(
'moment'
);
const
_
=
require
(
'lodash'
);
class
OrderService
extends
Service
{
//历史订单
...
...
@@ -119,6 +120,26 @@ class OrderService extends Service {
return
valid
;
}
async
getOrderInfo
(
order_id
)
{
const
{
ctx
}
=
this
;
const
order
=
await
ctx
.
prometheusModel
.
CreditOrder
.
findOne
({
where
:
{
id
:
order_id
}
});
if
(
!
order
||
!
order
.
id
)
{
ctx
.
failed
(
'error order'
);
}
return
order
;
}
async
checkOrderPay
(
order_id
)
{
const
{
ctx
}
=
this
;
const
order
=
await
ctx
.
prometheusModel
.
CreditOrder
.
findOne
({
where
:
{
id
:
order_id
}
});
if
(
order
&&
order
.
pay_status
===
1
){
return
true
;
}
}
}
...
...
package.json
View file @
90359d5a
...
...
@@ -25,7 +25,8 @@
"
parameter
"
:
"^3.3.1"
,
"
ramda
"
:
"^0.25.0"
,
"
request
"
:
"^2.88.0"
,
"
uuid
"
:
"^3.3.2"
"
uuid
"
:
"^3.3.2"
,
"
xml2js
"
:
"^0.4.22"
},
"devDependencies"
:
{
"
autod
"
:
"^3.0.1"
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment