Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in
Toggle navigation
T
tamp_course_order
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
彭熊
tamp_course_order
Commits
cfee2007
Commit
cfee2007
authored
Nov 25, 2020
by
pengxiong@wealthgrow.cn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
创建充值订单调用不同支付方式业务
parent
8fcd5db0
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
173 additions
and
267 deletions
+173
-267
errors.py
app/config/errors.py
+2
-0
errorhandler.py
app/controller/errorhandler.py
+0
-1
order.py
app/controller/order.py
+52
-35
version1.py
app/router/version1.py
+3
-0
order_service.py
app/service/order_service.py
+82
-5
alipayWap.py
app/utils/alipay/alipayWap.py
+0
-1
apple_pay.py
app/utils/apple_pay.py
+7
-13
wx_app_pay.py
app/utils/wxpay/wx_app_pay.py
+10
-5
wx_pay.py
app/utils/wxpay/wx_pay.py
+0
-207
tamp_course_order.log
logs/tamp_course_order.log
+17
-0
No files found.
app/config/errors.py
View file @
cfee2007
...
...
@@ -12,8 +12,10 @@ class Errors:
TOKEN_INVALID
=
'9001'
USER_ALREADY_EXISTS
=
'9002'
APPLE_VOCHER_INVALID
=
'9003'
MSG
=
{
TOKEN_INVALID
:
'TOKEN失效'
,
USER_ALREADY_EXISTS
:
'用户已经存在'
,
APPLE_VOCHER_INVALID
:
'苹果证书无效'
}
app/controller/errorhandler.py
View file @
cfee2007
...
...
@@ -63,5 +63,4 @@ def add_errorhandler(app):
@
app
.
after_request
def
after_request
(
response
):
response
.
headers
[
'content-type'
]
=
"application/json"
return
response
app/controller/order.py
View file @
cfee2007
...
...
@@ -8,7 +8,7 @@
# -----------------------------------------------------------------------------
import
json
from
flask_restful
import
Resource
,
reqparse
from
flask
import
request
from
flask
import
request
,
make_response
from
app.api
import
app
from
app.controller.errorhandler
import
CustomFlaskErr
...
...
@@ -26,21 +26,23 @@ class TopUpOrder(Resource):
def
get
(
self
):
"""."""
# raise CustomFlaskErr(Errors.USER_ALREADY_EXISTS)
self
.
parser
.
add_argument
(
'user_id'
,
type
=
str
,
required
=
True
,
help
=
'用户ID不能为空'
)
args
=
self
.
parser
.
parse_args
()
data
=
order_service
.
TopUpOrderService
()
.
get_order
(
args
)
user_id
=
request
.
user_id
data
=
order_service
.
TopUpOrderService
()
.
get_order
(
user_id
)
resp
=
request
.
return_success
resp
[
'attributes'
]
=
data
return
resp
def
post
(
self
):
"""."""
self
.
parser
.
add_argument
(
'user_id'
,
type
=
str
,
required
=
True
,
help
=
'用户ID不能为空'
)
self
.
parser
.
add_argument
(
'amount'
,
type
=
int
,
required
=
True
,
help
=
'订单总额不能为空'
)
self
.
parser
.
add_argument
(
'pay_method'
,
type
=
int
,
required
=
True
,
help
=
'支付方式不能为空'
)
args
=
self
.
parser
.
parse_args
()
order_service
.
TopUpOrderService
()
.
create_order
(
args
)
return
request
.
return_success
args
[
'user_id'
]
=
request
.
user_id
args
[
'remote_addr'
]
=
request
.
remote_addr
res
=
order_service
.
TopUpOrderService
()
.
create_order
(
args
)
resp
=
make_response
(
res
[
'body'
])
resp
.
hearders
[
'Content-Type'
]
=
res
[
'header'
][
'Content-Type'
]
return
resp
def
put
(
self
,
id
):
"""."""
...
...
@@ -60,9 +62,8 @@ class ConsumeOrder(Resource):
def
get
(
self
):
"""."""
self
.
parser
.
add_argument
(
'user_id'
,
type
=
str
,
required
=
True
,
help
=
'用户ID不能为空'
)
args
=
self
.
parser
.
parse_args
()
data
=
order_service
.
CurriculumOrderService
()
.
get_order
(
args
)
user_id
=
request
.
user_id
data
=
order_service
.
CurriculumOrderService
()
.
get_order
(
user_id
)
resp
=
request
.
return_success
resp
[
'attributes'
]
=
data
return
resp
...
...
@@ -73,9 +74,9 @@ class ConsumeOrder(Resource):
self
.
parser
.
add_argument
(
'prod_id'
,
type
=
str
,
required
=
True
,
help
=
'商品ID不能为空'
)
self
.
parser
.
add_argument
(
'prod_name'
,
type
=
str
,
required
=
True
,
help
=
'商品名称不能为空'
)
self
.
parser
.
add_argument
(
'prod_quantity'
,
type
=
int
,
required
=
True
,
help
=
'商品数量不能为空'
)
self
.
parser
.
add_argument
(
'user_id'
,
type
=
str
,
required
=
True
,
help
=
'用户ID不能为空'
)
self
.
parser
.
add_argument
(
'pay_method'
,
type
=
int
,
required
=
True
,
help
=
'支付方式不能为空'
)
args
=
self
.
parser
.
parse_args
()
args
[
'user_id'
]
=
request
.
user_id
order_service
.
CurriculumOrderService
()
.
create_order
(
args
)
return
request
.
return_success
...
...
@@ -97,22 +98,18 @@ class TopUpOrderNotify(Resource):
def
get
(
self
):
"""."""
# raise CustomFlaskErr(Errors.USER_ALREADY_EXISTS)
self
.
parser
.
add_argument
(
'user_id'
,
type
=
str
,
required
=
True
,
help
=
'用户ID不能为空'
)
args
=
self
.
parser
.
parse_args
()
data
=
order_service
.
TopUpOrderService
()
.
get_order
(
args
)
resp
=
request
.
return_success
resp
[
'data'
]
=
data
return
resp
def
post
(
self
):
"""."""
self
.
parser
.
add_argument
(
'user_id'
,
type
=
str
,
required
=
True
,
help
=
'用户ID不能为空'
)
self
.
parser
.
add_argument
(
'amount'
,
type
=
int
,
required
=
True
,
help
=
'订单总额不能为空'
)
self
.
parser
.
add_argument
(
'pay_method'
,
type
=
int
,
required
=
True
,
help
=
'支付方式不能为空'
)
args
=
self
.
parser
.
parse_args
()
order_service
.
TopUpOrderService
()
.
create_order
(
args
)
return
request
.
return_success
res_info
=
request
.
stream
.
read
(
request
.
content_length
or
0
)
.
decode
()
res
=
order_service
.
alipayWxPayCheck
(
res_info
)
if
res
[
'success'
]:
order_service
.
topUpSuccessAction
(
res
[
'order_no'
])
resp
=
make_response
(
res
[
'body'
])
resp
.
hearders
[
'Content-Type'
]
=
res
[
'header'
][
'Content-Type'
]
return
resp
def
put
(
self
,
id
):
"""."""
...
...
@@ -132,24 +129,18 @@ class ConsumeOrderNotify(Resource):
def
get
(
self
):
"""."""
self
.
parser
.
add_argument
(
'user_id'
,
type
=
str
,
required
=
True
,
help
=
'用户ID不能为空'
)
args
=
self
.
parser
.
parse_args
()
data
=
order_service
.
CurriculumOrderService
()
.
get_order
(
args
)
resp
=
request
.
return_success
resp
[
'data'
]
=
data
return
resp
def
post
(
self
):
"""."""
self
.
parser
.
add_argument
(
'prod_type'
,
type
=
int
,
required
=
True
,
help
=
'商品类型不能为空'
)
self
.
parser
.
add_argument
(
'prod_id'
,
type
=
str
,
required
=
True
,
help
=
'商品ID不能为空'
)
self
.
parser
.
add_argument
(
'prod_name'
,
type
=
str
,
required
=
True
,
help
=
'商品名称不能为空'
)
self
.
parser
.
add_argument
(
'prod_quantity'
,
type
=
int
,
required
=
True
,
help
=
'商品数量不能为空'
)
self
.
parser
.
add_argument
(
'user_id'
,
type
=
str
,
required
=
True
,
help
=
'用户ID不能为空'
)
self
.
parser
.
add_argument
(
'pay_method'
,
type
=
int
,
required
=
True
,
help
=
'支付方式不能为空'
)
args
=
self
.
parser
.
parse_args
()
order_service
.
CurriculumOrderService
()
.
create_order
(
args
)
return
request
.
return_success
res_info
=
request
.
stream
.
read
(
request
.
content_length
or
0
)
.
decode
()
res
=
order_service
.
alipayWxPayCheck
(
res_info
)
if
res
[
'success'
]:
order_service
.
consumeSucessAction
(
res
[
'order_no'
])
resp
=
make_response
(
res
[
'body'
])
resp
.
hearders
[
'Content-Type'
]
=
res
[
'header'
][
'Content-Type'
]
return
resp
def
put
(
self
,
id
):
"""."""
...
...
@@ -158,3 +149,29 @@ class ConsumeOrderNotify(Resource):
def
delete
(
self
,
id
):
"""."""
pass
class
AccountBalance
(
Resource
):
""""""
def
__init__
(
self
):
"""."""
self
.
parser
=
reqparse
.
RequestParser
()
def
get
(
self
):
"""."""
data
=
order_service
.
getAccountBalance
()
resp
=
request
.
return_success
resp
[
'attributes'
]
=
data
return
resp
def
post
(
self
):
"""."""
pass
def
put
(
self
,
id
):
"""."""
pass
def
delete
(
self
,
id
):
"""."""
pass
\ No newline at end of file
app/router/version1.py
View file @
cfee2007
...
...
@@ -19,3 +19,6 @@ def add_route(api):
api
.
add_resource
(
TopUpOrderNotify
,
'/tamp_order/micro_shop/topUpOrderNotify'
)
# 消费订单支付通知
api
.
add_resource
(
ConsumeOrderNotify
,
'/tamp_order/micro_shop/consumeOrderNotify'
)
# 查询探普币余额
api
.
add_resource
(
AccountBalance
,
'/tamp_order/micro_shop/accountBalance'
)
app/service/order_service.py
View file @
cfee2007
...
...
@@ -9,10 +9,17 @@
import
time
from
app.api.engine
import
tamp_pay_session
,
tamp_user_session
from
app.config.errors
import
Errors
from
app.controller.errorhandler
import
CustomFlaskErr
from
app.model.account_balance
import
AccountBalance
from
app.model.account_topup_order
import
AccountTopupOrder
from
app.model.curriculum_order
import
CurriculumOrder
from
app.model.tamp_user_models
import
CurriculumPrice
,
CurriculumColumn
,
CurriculumRes
from
xml.etree
import
cElementTree
as
etree
from
app.utils.alipay.alipayWap
import
prePay
from
app.utils.apple_pay
import
apple_pay
from
app.utils.wxpay.wx_app_pay
import
WXPay
class
TopUpOrderService
:
...
...
@@ -20,8 +27,8 @@ class TopUpOrderService:
def
__init__
(
self
):
pass
def
get_order
(
self
,
args
):
res
=
tamp_pay_session
.
query
(
AccountTopupOrder
)
.
filter
(
AccountTopupOrder
.
user_id
==
args
[
'user_id'
]
)
.
all
()
def
get_order
(
self
,
user_id
):
res
=
tamp_pay_session
.
query
(
AccountTopupOrder
)
.
filter
(
AccountTopupOrder
.
user_id
==
user_id
)
.
all
()
return
[
r
.
to_dict
()
for
r
in
res
]
...
...
@@ -29,6 +36,21 @@ class TopUpOrderService:
args
[
'order_no'
]
=
time
.
strftime
(
'
%
Y
%
m
%
d'
,
time
.
localtime
(
time
.
time
()))
+
str
(
int
(
time
.
time
()
*
100000
))
args
[
'id'
]
=
AccountTopupOrder
.
__tablename__
+
str
(
int
(
time
.
time
()
*
100000
))
args
[
'amount'
]
=
args
[
'amount'
]
*
100
args
[
'order_status'
]
=
0
subject
=
'探普币充值'
out_trade_no
=
args
[
'order_no'
]
notify_path
=
'/tamp_order/micro_shop/topUpOrderNotify'
if
args
[
'pay_method'
]
==
2
:
wx_pay
=
WXPay
(
out_trade_no
,
subject
,
args
[
'amount'
],
args
[
'remote_addr'
],
notify_path
=
notify_path
)
wx_pay
.
getReturnParams
()
elif
args
[
'pay_method'
]
==
3
:
total_amount
=
args
[
'amount'
]
/
100
res
=
prePay
(
subject
,
out_trade_no
,
total_amount
,
notify_path
=
notify_path
)
elif
args
[
'pay_method'
]
==
4
:
receipt_data
=
args
.
get
(
'receipt_data'
,
''
)
if
not
apple_pay
(
receipt_data
):
raise
CustomFlaskErr
(
Errors
.
APPLE_VOCHER_INVALID
)
args
[
'order_status'
]
=
1
order_info
=
AccountTopupOrder
(
**
args
)
tamp_pay_session
.
add
(
order_info
)
tamp_pay_session
.
commit
()
...
...
@@ -41,11 +63,11 @@ class CurriculumOrderService:
def
__init__
(
self
):
pass
def
get_order
(
self
,
args
):
def
get_order
(
self
,
user_id
):
"""."""
curriculum_column
=
tamp_user_session
.
query
(
CurriculumColumn
)
.
all
()
curriculum_res
=
tamp_user_session
.
query
(
CurriculumRes
)
.
all
()
res
=
tamp_pay_session
.
query
(
CurriculumOrder
)
.
filter
(
CurriculumOrder
.
user_id
==
args
[
'user_id'
]
)
.
all
()
res
=
tamp_pay_session
.
query
(
CurriculumOrder
)
.
filter
(
CurriculumOrder
.
user_id
==
user_id
)
.
all
()
curriculum_column
=
{
r
.
id
:
r
.
to_dict
()
for
r
in
curriculum_column
}
curriculum_res
=
{
r
.
id
:
r
.
to_dict
()
for
r
in
curriculum_res
}
orders
=
[
r
.
to_dict
()
for
r
in
res
]
...
...
@@ -105,4 +127,59 @@ def consumeSucessAction(order_no):
# 幂等校验
if
curriculum_order
.
order_status
==
1
:
return
False
# tamp_pay_session.query(CurriculumOrder).filter(CurriculumOrder.order_no == )
\ No newline at end of file
tamp_pay_session
.
query
(
CurriculumOrder
)
.
filter
(
CurriculumOrder
.
order_no
==
order_no
)
.
update
({
'order_status'
:
1
})
tamp_pay_session
.
commit
()
def
getAccountBalance
(
user_id
):
"""查询探普币余额"""
account_balance
=
tamp_pay_session
.
query
(
AccountBalance
)
.
filter
(
AccountBalance
.
user_id
==
user_id
)
.
first
()
if
not
account_balance
:
return
{
'user_id'
:
user_id
,
'android_balance'
:
0
,
'apple_balance'
:
0
}
else
:
return
account_balance
.
to_dict
()
def
xml2dict
(
content
):
"""将从微信服务器接收到的xml转为dict."""
raw
=
{}
root
=
etree
.
fromstring
(
content
)
for
child
in
root
:
raw
[
child
.
tag
]
=
child
.
text
return
raw
def
dict2xml
(
dict_
):
"""将dict转为要发送到微信服务器的xml格式."""
s
=
""
for
k
,
v
in
dict_
.
items
():
s
+=
"<{0}>{1}</{0}>"
.
format
(
k
,
v
)
s
=
"<xml>{0}</xml>"
.
format
(
s
)
return
s
.
encode
(
"utf-8"
)
def
alipayWxPayCheck
(
res_info
):
"""支付宝,微信支付异步通知"""
success
=
False
body
=
None
header
=
{
'Content-Type'
:
'application/text'
}
res
=
{}
if
'trade_status'
in
res_info
:
# 支付宝支付
res_info
=
res_info
.
split
(
'&'
)
for
ss
in
res_info
:
key
,
value
=
ss
.
split
(
'='
)
res
[
key
]
=
value
if
res
[
'trade_status'
]
==
'TRADE_SUCCESS'
:
success
=
True
body
=
'success'
.
encode
()
else
:
# 微信支付
res
=
xml2dict
(
res_info
)
if
res
[
'result_code'
]
==
'SUCCESS'
and
res
[
'return_code'
]
==
'SUCCESS'
:
success
=
True
header
=
{
'Content-Type'
:
'application/xml'
}
body
=
'<xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> </xml>'
return
{
'success'
:
success
,
'header'
:
header
,
'body'
:
body
,
'order_no'
:
res
[
'out_trade_no'
]}
app/utils/alipay/alipayWap.py
View file @
cfee2007
...
...
@@ -86,7 +86,6 @@ def prePay(subject, out_trade_no, total_amount, notify_path='/webservice/notify'
)
if
not
result
:
return
False
print
(
result
)
return
result
def
alipay_transfer
():
...
...
app/utils/apple_pay.py
View file @
cfee2007
...
...
@@ -17,19 +17,13 @@ import pickle
import
json
import
urllib
def
apple_pay
():
def
apple_pay
(
receipt_data
):
"""苹果支付"""
'''
"receipt-data":receipt_data,
"exclude-old-transactions":"true",
"password":"a1cdf6f00d3244aa9aa2c1c4a65b7ccf"
'''
data
=
request
.
get_data
()
# print(data)
# data = data.decode('utf8','replace')
data
=
eval
(
data
)
receipt_data
=
data
[
"receipt-data"
]
receipt_data
=
urllib
.
request
.
unquote
(
receipt_data
)
print
(
receipt_data
)
...
...
@@ -47,12 +41,12 @@ def apple_pay():
response
=
requests
.
post
(
AppStore_URL
[
0
],
data
=
dumped_json_string
)
if
response
.
status_code
==
200
:
if
response
.
json
()
.
get
(
"status"
)
==
21007
:
print
(
"ceshi"
)
response
=
requests
.
post
(
AppStore_URL
[
1
],
data
=
dumped_json_string
)
if
response
.
status_code
==
200
:
return
response
.
json
()
# print(response.json())
return
response
.
json
()
else
:
return
response
.
json
()
return
True
return
True
return
False
if
__name__
==
'__main__'
:
receipt_data
=
'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'
apple_pay
(
receipt_data
)
\ No newline at end of file
app/utils/wxpay/wx_app_pay.py
View file @
cfee2007
...
...
@@ -91,6 +91,7 @@ class WXPay(object):
'trade_type'
:
self
.
trade_type
,
'sign'
:
self
.
sign
}
print
(
self
.
data
)
def
dict2xml
(
self
,
dict_
):
"""将dict转为要发送到微信服务器的xml格式."""
...
...
@@ -117,15 +118,19 @@ class WXPay(object):
def
getPaySign
(
self
):
"""."""
sign_string
=
'appId={0}&nonceStr={1}&package={6}prepay_id={2}&signType={3}&timeStamp={4}&key={5}'
.
format
(
self
.
appid
,
self
.
nonce_str
,
self
.
prepay_id
,
self
.
sign_type
,
self
.
timeStamp
,
self
.
key
,
'Sign
=WXPay
'
)
self
.
appid
,
self
.
nonce_str
,
self
.
prepay_id
,
self
.
sign_type
,
self
.
timeStamp
,
self
.
key
,
'Sign'
)
self
.
paySign
=
hashlib
.
md5
(
sign_string
.
encode
(
"utf-8"
))
.
hexdigest
()
.
upper
()
def
getReturnParams
(
self
):
"""."""
params
=
{
'app_id'
:
self
.
appid
,
'noncestr'
:
self
.
nonce_str
,
'mch_id'
:
self
.
mch_id
,
'prepay_id'
:
self
.
prepay_id
,
'sign'
:
self
.
paySign
,
'timestamp'
:
self
.
timeStamp
}
return
params
if
__name__
==
'__main__'
:
out_trade_no
=
'20181210232432413413
8
'
out_trade_no
=
'20181210232432413413
9
'
body
=
'APP支付测试'
total_fee
=
0.01
remote_addr
=
'101.95.188.178'
wx
=
WXPay
(
out_trade_no
,
body
,
total_fee
,
remote_addr
)
params
=
{
'app_id'
:
wx
.
appid
,
'noncestr'
:
wx
.
nonce_str
,
'mch_id'
:
wx
.
mch_id
,
'prepay_id'
:
wx
.
prepay_id
,
'sign'
:
wx
.
paySign
,
'timestamp'
:
wx
.
timeStamp
}
print
(
params
)
print
(
wx
.
getReturnParams
())
app/utils/wxpay/wx_pay.py
deleted
100644 → 0
View file @
8fcd5db0
# -----------------------------------------------------------------------------
# File Name: wx_pay.py
# Author: X. Peng
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# Constants
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# Functions
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# Classes
# -----------------------------------------------------------------------------
import
requests
import
hashlib
import
time
from
xml.etree
import
cElementTree
as
etree
import
random
from
urllib
import
parse
def
genNonce_str
():
"""."""
sss
=
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
s
=
''
for
i
in
range
(
32
):
s
=
s
+
random
.
choice
(
sss
)
return
s
class
WXPay
(
object
):
"""微信公众号支付."""
pre_pay_prefix
=
'https://open.weixin.qq.com/connect/oauth2/authorize'
appid
=
''
redirect_uri_prefix
=
''
response_type
=
'code'
scope
=
'snsapi_base'
@
classmethod
def
prePay
(
cls
,
order_no
,
redirect_path
=
'/webservice/order'
):
pay_url
=
cls
.
pre_pay_prefix
+
'?'
+
parse
.
urlencode
({
'appid'
:
cls
.
appid
,
'redirect_uri'
:
cls
.
redirect_uri_prefix
+
redirect_path
,
'response_type'
:
cls
.
response_type
,
'scope'
:
cls
.
scope
,
'state'
:
order_no
})
+
'#wechat_redirect'
return
pay_url
def
__init__
(
self
,
code
,
out_trade_no
,
body
,
total_fee
,
remote_addr
,
notify_path
=
'/webservice/notify'
,
return_path
=
'/home/order'
):
"""."""
self
.
timeStamp
=
int
(
time
.
time
())
self
.
req_url
=
'https://api.mch.weixin.qq.com/pay/unifiedorder'
self
.
appid
=
''
self
.
secret
=
''
self
.
openid
=
None
self
.
mch_id
=
''
self
.
nonce_str
=
genNonce_str
()
self
.
sign
=
None
self
.
sign_type
=
'MD5'
self
.
body
=
body
self
.
out_trade_no
=
out_trade_no
self
.
total_fee
=
int
(
total_fee
*
100
)
self
.
spbill_create_ip
=
remote_addr
self
.
notify_url
=
self
.
redirect_uri_prefix
+
notify_path
self
.
return_url
=
self
.
redirect_uri_prefix
+
return_path
self
.
trade_type
=
'JSAPI'
self
.
key
=
''
self
.
prepay_id
=
None
self
.
getOpenid
(
code
)
self
.
getStringSign
()
self
.
getData
()
self
.
getprepay_id
()
self
.
getPaySign
()
def
getOpenid
(
self
,
code
):
"""."""
url
=
'https://api.weixin.qq.com/sns/oauth2/access_token'
params
=
{
'appid'
:
self
.
appid
,
'secret'
:
self
.
secret
,
'code'
:
code
,
'grant_type'
:
'authorization_code'
}
res
=
requests
.
get
(
url
,
params
=
params
)
self
.
openid
=
res
.
json
()[
'openid'
]
def
getStringSign
(
self
):
"""."""
self
.
string_sign_temp
=
'appid={0}&body={1}&mch_id={2}&nonce_str={3}¬ify_url={4}&openid={5}&out_trade_no={6}&sign_type={7}&spbill_create_ip={8}&total_fee={9}&trade_type={10}&key={11}'
.
format
(
self
.
appid
,
self
.
body
,
self
.
mch_id
,
self
.
nonce_str
,
self
.
notify_url
,
self
.
openid
,
self
.
out_trade_no
,
self
.
sign_type
,
self
.
spbill_create_ip
,
self
.
total_fee
,
self
.
trade_type
,
self
.
key
)
def
getData
(
self
):
"""."""
self
.
sign
=
hashlib
.
md5
(
self
.
string_sign_temp
.
encode
(
"utf-8"
))
.
hexdigest
()
.
upper
()
self
.
data
=
{
'appid'
:
self
.
appid
,
'body'
:
self
.
body
,
'mch_id'
:
self
.
mch_id
,
'nonce_str'
:
self
.
nonce_str
,
'notify_url'
:
self
.
notify_url
,
'openid'
:
self
.
openid
,
'out_trade_no'
:
self
.
out_trade_no
,
'sign_type'
:
self
.
sign_type
,
'spbill_create_ip'
:
self
.
spbill_create_ip
,
'total_fee'
:
self
.
total_fee
,
'trade_type'
:
self
.
trade_type
,
'sign'
:
self
.
sign
}
def
dict2xml
(
self
,
dict_
):
"""将dict转为要发送到微信服务器的xml格式."""
s
=
""
for
k
,
v
in
dict_
.
items
():
s
+=
"<{0}>{1}</{0}>"
.
format
(
k
,
v
)
s
=
"<xml>{0}</xml>"
.
format
(
s
)
return
s
.
encode
(
"utf-8"
)
def
xml2dict
(
self
,
content
):
"""将从微信服务器接收到的xml转为dict."""
raw
=
{}
root
=
etree
.
fromstring
(
content
)
for
child
in
root
:
raw
[
child
.
tag
]
=
child
.
text
return
raw
def
getprepay_id
(
self
):
"""."""
res
=
requests
.
post
(
self
.
req_url
,
data
=
self
.
dict2xml
(
self
.
data
))
res
=
self
.
xml2dict
(
res
.
content
)
self
.
prepay_id
=
res
[
'prepay_id'
]
def
getPaySign
(
self
):
"""."""
sign_string
=
'appId={0}&nonceStr={1}&package=prepay_id={2}&signType={3}&timeStamp={4}&key={5}'
.
format
(
self
.
appid
,
self
.
nonce_str
,
self
.
prepay_id
,
self
.
sign_type
,
self
.
timeStamp
,
self
.
key
)
self
.
paySign
=
hashlib
.
md5
(
sign_string
.
encode
(
"utf-8"
))
.
hexdigest
()
.
upper
()
def
getUI
(
self
):
"""."""
text
=
'''<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>微信支付</title>
</head>
<script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/javascript">
function onBridgeReady(){{
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {{
"appId":"{0}", //公众号名称,由商户传入
"timeStamp":"{1}", //时间戳,自1970年以来的秒数
"nonceStr":"{2}", //随机串
"package":"prepay_id={3}",
"signType":"MD5", //微信签名方式
"paySign":"{4}" //微信签名
}},
function(res){{
if(res.err_msg == "get_brand_wcpay_request:ok" ){{
window.location.href='{5}';
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
}}
}});
}}
if (typeof WeixinJSBridge == "undefined"){{
if( document.addEventListener ){{
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
}}
else if (document.attachEvent){{
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}}
}}
else{{
onBridgeReady();
}}
</script>
<body>
</body>
</html>'''
.
format
(
self
.
appid
,
self
.
timeStamp
,
self
.
nonce_str
,
self
.
prepay_id
,
self
.
paySign
,
self
.
return_url
)
return
text
logs/tamp_course_order.log
View file @
cfee2007
...
...
@@ -4388,3 +4388,20 @@ WHERE curriculum_order.user_id = %(user_id_1)s
2020-11-25 17:39:37 Wed werkzeug INFO * Restarting with stat
2020-11-25 17:39:39 Wed werkzeug WARNING * Debugger is active!
2020-11-25 17:39:39 Wed werkzeug INFO * Debugger PIN: 191-123-093
2020-11-25 17:41:11 Wed werkzeug INFO * Detected change in '/Users/pengxiong/Desktop/tamp_course_order/app/service/order_service.py', reloading
2020-11-25 17:41:11 Wed werkzeug INFO * Restarting with stat
2020-11-25 17:41:12 Wed werkzeug WARNING * Debugger is active!
2020-11-25 17:41:12 Wed werkzeug INFO * Debugger PIN: 191-123-093
2020-11-25 17:44:25 Wed werkzeug INFO * Detected change in '/Users/pengxiong/Desktop/tamp_course_order/app/router/version1.py', reloading
2020-11-25 17:44:25 Wed werkzeug INFO * Restarting with stat
2020-11-25 17:44:26 Wed werkzeug WARNING * Debugger is active!
2020-11-25 17:44:26 Wed werkzeug INFO * Debugger PIN: 191-123-093
2020-11-25 17:44:38 Wed werkzeug INFO 172.168.0.47 - - [25/Nov/2020 17:44:38] "[1m[31mGET /tamp_order/micro_shop/topUpOrder HTTP/1.1[0m" 400 -
2020-11-25 17:44:54 Wed werkzeug INFO 172.168.0.47 - - [25/Nov/2020 17:44:54] "[37mGET /tamp_order/micro_shop/topUpOrder HTTP/1.1[0m" 200 -
2020-11-25 17:44:57 Wed werkzeug INFO 172.168.0.47 - - [25/Nov/2020 17:44:57] "[1m[31mGET /tamp_order/micro_shop/topUpOrder HTTP/1.1[0m" 400 -
2020-11-25 17:45:19 Wed werkzeug INFO * Detected change in '/Users/pengxiong/Desktop/tamp_course_order/app/router/version1.py', reloading
2020-11-25 17:45:19 Wed werkzeug INFO * Restarting with stat
2020-11-25 17:45:20 Wed werkzeug WARNING * Debugger is active!
2020-11-25 17:45:20 Wed werkzeug INFO * Debugger PIN: 191-123-093
2020-11-25 17:51:48 Wed werkzeug INFO * Detected change in '/Users/pengxiong/Desktop/tamp_course_order/app/router/version1.py', reloading
2020-11-25 17:51:49 Wed werkzeug INFO * Restarting with stat
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