Skip to content

Commit 67760c0

Browse files
committed
进度: notifyurl的配置未完成。
1 parent c1a1cd6 commit 67760c0

File tree

8 files changed

+624
-195
lines changed

8 files changed

+624
-195
lines changed

.gitattributes

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto
3+
4+
# Custom for Visual Studio
5+
*.cs diff=csharp
6+
7+
# Standard to msysgit
8+
*.doc diff=astextplain
9+
*.DOC diff=astextplain
10+
*.docx diff=astextplain
11+
*.DOCX diff=astextplain
12+
*.dot diff=astextplain
13+
*.DOT diff=astextplain
14+
*.pdf diff=astextplain
15+
*.PDF diff=astextplain
16+
*.rtf diff=astextplain
17+
*.RTF diff=astextplain
18+
*.js linguist-language=python
19+
*.css linguist-language=python
20+
*.html linguist-language=python

.gitignore

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Windows image file caches
2+
Thumbs.db
3+
ehthumbs.db
4+
5+
# Folder config file
6+
Desktop.ini
7+
8+
# Recycle Bin used on file shares
9+
$RECYCLE.BIN/
10+
11+
# Windows Installer files
12+
*.cab
13+
*.msi
14+
*.msm
15+
*.msp
16+
17+
# Windows shortcuts
18+
*.lnk
19+
20+
# =========================
21+
# Operating System Files
22+
# =========================
23+
24+
# OSX
25+
# =========================
26+
27+
.DS_Store
28+
.AppleDouble
29+
.LSOverride
30+
31+
# Thumbnails
32+
._*
33+
34+
# Files that might appear in the root of a volume
35+
.DocumentRevisions-V100
36+
.fseventsd
37+
.Spotlight-V100
38+
.TemporaryItems
39+
.Trashes
40+
.VolumeIcon.icns
41+
42+
# Directories potentially created on remote AFP share
43+
.AppleDB
44+
.AppleDesktop
45+
Network Trash Folder
46+
Temporary Items
47+
/VueDjangoFrameWorkShop/local_settings.py
48+
/VueDjangoFrameWorkShop/dev_settings.py

.idea/deployment.xml

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/workspace.xml

Lines changed: 225 additions & 191 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

VueDjangoFrameWorkShop/settings.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import os
1414
import sys
1515
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
16+
from past.builtins import execfile
17+
1618
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
1719
sys.path.insert(0,BASE_DIR)
1820
sys.path.insert(0,os.path.join(BASE_DIR, 'apps'))
@@ -27,7 +29,7 @@
2729
# SECURITY WARNING: don't run with debug turned on in production!
2830
DEBUG = True
2931

30-
ALLOWED_HOSTS = []
32+
ALLOWED_HOSTS = ['*']
3133

3234
# 设置邮箱和用户名和手机号均可登录
3335
AUTHENTICATION_BACKENDS = (
@@ -106,8 +108,8 @@
106108
'ENGINE': 'django.db.backends.mysql',
107109
'NAME': 'vue_shop',
108110
'USER': 'root',
109-
'PASSWORD': 'tp158917',
110-
'HOST':'127.0.0.1',
111+
'PASSWORD': '123456',
112+
'HOST': '127.0.0.1',
111113
"OPTIONS": {"init_command": "SET default_storage_engine=INNODB;"}
112114
}
113115
}
@@ -175,4 +177,17 @@
175177
REGEX_MOBILE = "^1[358]\d{9}$|^147\d{8}$|^176\d{8}$"
176178

177179
# 云片网设置
178-
APIKEY = 'd6c4ddbf50ab36611d2f52041a0b949e'
180+
APIKEY = ''
181+
182+
REMOTE_DEBUG = False
183+
PROJECT_ROOT = os.path.join(BASE_DIR, 'VueDjangoFrameWorkShop')
184+
if DEBUG:
185+
try:
186+
execfile(os.path.join(PROJECT_ROOT, 'local_settings.py'))
187+
except IOError:
188+
pass
189+
else:
190+
try:
191+
execfile(os.path.join(PROJECT_ROOT, 'dev_settings.py'))
192+
except IOError:
193+
pass

apps/trade/views.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,94 @@ def perform_create(self, serializer):
9393

9494
shop_cart.delete()
9595
return order
96+
97+
#
98+
# from rest_framework.views import APIView
99+
# from utils.alipay import AliPay
100+
# from MxShop.settings import ali_pub_key_path, private_key_path
101+
# from rest_framework.response import Response
102+
# class AlipayView(APIView):
103+
# def get(self, request):
104+
# """
105+
# 处理支付宝的return_url返回
106+
# :param request:
107+
# :return:
108+
# """
109+
# processed_dict = {}
110+
# for key, value in request.GET.items():
111+
# processed_dict[key] = value
112+
#
113+
# sign = processed_dict.pop("sign", None)
114+
#
115+
# alipay = AliPay(
116+
# appid="",
117+
# app_notify_url="http://127.0.0.1:8000/alipay/return/",
118+
# app_private_key_path=private_key_path,
119+
# alipay_public_key_path=ali_pub_key_path, # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
120+
# debug=True, # 默认False,
121+
# return_url="http://127.0.0.1:8000/alipay/return/"
122+
# )
123+
#
124+
# verify_re = alipay.verify(processed_dict, sign)
125+
#
126+
# if verify_re is True:
127+
# order_sn = processed_dict.get('out_trade_no', None)
128+
# trade_no = processed_dict.get('trade_no', None)
129+
# trade_status = processed_dict.get('trade_status', None)
130+
#
131+
# existed_orders = OrderInfo.objects.filter(order_sn=order_sn)
132+
# for existed_order in existed_orders:
133+
# existed_order.pay_status = trade_status
134+
# existed_order.trade_no = trade_no
135+
# existed_order.pay_time = datetime.now()
136+
# existed_order.save()
137+
#
138+
# response = redirect("index")
139+
# response.set_cookie("nextPath","pay", max_age=3)
140+
# return response
141+
# else:
142+
# response = redirect("index")
143+
# return response
144+
#
145+
# def post(self, request):
146+
# """
147+
# 处理支付宝的notify_url
148+
# :param request:
149+
# :return:
150+
# """
151+
# processed_dict = {}
152+
# for key, value in request.POST.items():
153+
# processed_dict[key] = value
154+
#
155+
# sign = processed_dict.pop("sign", None)
156+
#
157+
# alipay = AliPay(
158+
# appid="",
159+
# app_notify_url="http://127.0.0.1:8000/alipay/return/",
160+
# app_private_key_path=private_key_path,
161+
# alipay_public_key_path=ali_pub_key_path, # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
162+
# debug=True, # 默认False,
163+
# return_url="http://127.0.0.1:8000/alipay/return/"
164+
# )
165+
#
166+
# verify_re = alipay.verify(processed_dict, sign)
167+
#
168+
# if verify_re is True:
169+
# order_sn = processed_dict.get('out_trade_no', None)
170+
# trade_no = processed_dict.get('trade_no', None)
171+
# trade_status = processed_dict.get('trade_status', None)
172+
#
173+
# existed_orders = OrderInfo.objects.filter(order_sn=order_sn)
174+
# for existed_order in existed_orders:
175+
# order_goods = existed_order.goods.all()
176+
# for order_good in order_goods:
177+
# goods = order_good.goods
178+
# goods.sold_num += order_good.goods_num
179+
# goods.save()
180+
#
181+
# existed_order.pay_status = trade_status
182+
# existed_order.trade_no = trade_no
183+
# existed_order.pay_time = datetime.now()
184+
# existed_order.save()
185+
#
186+
# return Response("success")

apps/utils/alipay.py

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# encoding: utf-8
2+
__author__ = 'mtianyan'
3+
__date__ = '2018/3/12 0012 17:07'
4+
5+
from datetime import datetime
6+
from Crypto.PublicKey import RSA
7+
from Crypto.Signature import PKCS1_v1_5
8+
from Crypto.Hash import SHA256
9+
from base64 import b64encode, b64decode
10+
from urllib.parse import quote_plus
11+
from urllib.parse import urlparse, parse_qs
12+
from urllib.request import urlopen
13+
from base64 import decodebytes, encodebytes
14+
15+
import json
16+
17+
18+
class AliPay(object):
19+
"""
20+
支付宝支付接口
21+
"""
22+
23+
def __init__(self, appid, app_notify_url, app_private_key_path,
24+
alipay_public_key_path, return_url, debug=False):
25+
self.appid = appid
26+
self.app_notify_url = app_notify_url
27+
self.app_private_key_path = app_private_key_path
28+
self.app_private_key = None
29+
self.return_url = return_url
30+
with open(self.app_private_key_path) as fp:
31+
self.app_private_key = RSA.importKey(fp.read())
32+
33+
self.alipay_public_key_path = alipay_public_key_path
34+
with open(self.alipay_public_key_path) as fp:
35+
self.alipay_public_key = RSA.import_key(fp.read())
36+
37+
if debug is True:
38+
self.__gateway = "https://openapi.alipaydev.com/gateway.do"
39+
else:
40+
self.__gateway = "https://openapi.alipay.com/gateway.do"
41+
42+
def direct_pay(self, subject, out_trade_no, total_amount, return_url=None, **kwargs):
43+
biz_content = {
44+
"subject": subject,
45+
"out_trade_no": out_trade_no,
46+
"total_amount": total_amount,
47+
"product_code": "FAST_INSTANT_TRADE_PAY",
48+
# "qr_pay_mode":4
49+
}
50+
51+
biz_content.update(kwargs)
52+
data = self.build_body("alipay.trade.page.pay", biz_content, self.return_url)
53+
return self.sign_data(data)
54+
55+
def build_body(self, method, biz_content, return_url=None):
56+
data = {
57+
"app_id": self.appid,
58+
"method": method,
59+
"charset": "utf-8",
60+
"sign_type": "RSA2",
61+
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
62+
"version": "1.0",
63+
"biz_content": biz_content
64+
}
65+
66+
if return_url is not None:
67+
data["notify_url"] = self.app_notify_url
68+
data["return_url"] = self.return_url
69+
70+
return data
71+
72+
def sign_data(self, data):
73+
data.pop("sign", None)
74+
# 排序后的字符串
75+
unsigned_items = self.ordered_data(data)
76+
unsigned_string = "&".join("{0}={1}".format(k, v) for k, v in unsigned_items)
77+
sign = self.sign(unsigned_string.encode("utf-8"))
78+
# ordered_items = self.ordered_data(data)
79+
quoted_string = "&".join("{0}={1}".format(k, quote_plus(v)) for k, v in unsigned_items)
80+
81+
# 获得最终的订单信息字符串
82+
signed_string = quoted_string + "&sign=" + quote_plus(sign)
83+
return signed_string
84+
85+
def ordered_data(self, data):
86+
complex_keys = []
87+
for key, value in data.items():
88+
if isinstance(value, dict):
89+
complex_keys.append(key)
90+
91+
# 将字典类型的数据dump出来
92+
for key in complex_keys:
93+
data[key] = json.dumps(data[key], separators=(',', ':'))
94+
95+
return sorted([(k, v) for k, v in data.items()])
96+
97+
def sign(self, unsigned_string):
98+
# 开始计算签名
99+
key = self.app_private_key
100+
signer = PKCS1_v1_5.new(key)
101+
signature = signer.sign(SHA256.new(unsigned_string))
102+
# base64 编码,转换为unicode表示并移除回车
103+
sign = encodebytes(signature).decode("utf8").replace("\n", "")
104+
return sign
105+
106+
def _verify(self, raw_content, signature):
107+
# 开始计算签名
108+
key = self.alipay_public_key
109+
signer = PKCS1_v1_5.new(key)
110+
digest = SHA256.new()
111+
digest.update(raw_content.encode("utf8"))
112+
if signer.verify(digest, decodebytes(signature.encode("utf8"))):
113+
return True
114+
return False
115+
116+
def verify(self, data, signature):
117+
if "sign_type" in data:
118+
sign_type = data.pop("sign_type")
119+
# 排序后的字符串
120+
unsigned_items = self.ordered_data(data)
121+
message = "&".join(u"{}={}".format(k, v) for k, v in unsigned_items)
122+
return self._verify(message, signature)
123+
124+
125+
if __name__ == "__main__":
126+
# return_url = ''
127+
# o = urlparse(return_url)
128+
# query = parse_qs(o.query)
129+
# processed_query = {}
130+
# ali_sign = query.pop("sign")[0]
131+
132+
# 测试用例
133+
alipay = AliPay(
134+
# appid在沙箱环境中就可以找到
135+
appid="2016091200490210",
136+
# 这个值先不管,在与vue的联调中介绍
137+
app_notify_url="http://127.0.0.1:8000/alipay/return/",
138+
# 我们自己商户的密钥
139+
app_private_key_path="../trade/keys/private_2048.txt",
140+
# 支付宝的公钥
141+
alipay_public_key_path="../trade/keys/alipay_key_2048.txt", # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
142+
# debug为true时使用沙箱的url。如果不是用正式环境的url
143+
debug=True, # 默认False,
144+
145+
# 先不用管,后面vue解释
146+
return_url="http://127.0.0.1:8000/alipay/return/"
147+
)
148+
149+
# for key, value in query.items():
150+
# processed_query[key] = value[0]
151+
# print (alipay.verify(processed_query, ali_sign))
152+
153+
# 直接支付:生成请求的字符串。
154+
url = alipay.direct_pay(
155+
# 订单标题
156+
subject="测试订单",
157+
# 我们商户自行生成的订单号
158+
out_trade_no="20180312mtianyan002",
159+
# 订单金额
160+
total_amount=9999,
161+
return_url="http://115.159.122.64:8000/alipay/return/"
162+
)
163+
# 将生成的请求字符串拿到我们的url中进行拼接
164+
re_url = "https://openapi.alipaydev.com/gateway.do?{data}".format(data=url)
165+
166+
print(re_url)

0 commit comments

Comments
 (0)