python-支付宝支付示例

项目演示:

1、输入金额

2、扫码支付:

3、支付完成:

一、注册账号

https://openhome.alipay.com/platform/appDaily.htm?tab=info

 

二、设置应用公钥

 

 

 

三、代码实现

1、项目结构:

        

2、把生成的     应用私钥     和    支付宝的公钥       放入keys目录下:

    注意:
支付宝公钥

商户私钥

 --- 配置商户应用私钥--copy到key目录下

            

            

--- 配置支付宝公钥--进入网页-->查看支付宝公钥-->把公钥放到key目录下

            

但是要做修改:

  1. alipay_public_2048.txt  
  2.     -----BEGIN PUBLIC KEY-----  # 加上这行  
  3.         支付宝的公钥  
  4.     -----END PUBLIC KEY-----   # 同上  
  5.   
  6. app_private_2048.txt  
  7.     -----BEGIN PUBLIC KEY-----  #同上  
  8.         应用的私钥  
  9.     -----END PUBLIC KEY-----   # 同上  

3、pay.py 这是从git上找到的支付宝支付接口(PC端支付接口) 

            

  1. in pay.py  
  2.   
  3. from datetime import datetime  
  4. from Crypto.PublicKey import RSA  
  5. from Crypto.Signature import PKCS1_v1_5  
  6. from Crypto.Hash import SHA256  
  7. from urllib.parse import quote_plus  
  8. from urllib.parse import urlparse, parse_qs  
  9. from base64 import decodebytes, encodebytes  
  10. import json  
  11.   
  12. class AliPay(object):  
  13.     """ 
  14.     支付宝支付接口(PC端支付接口) 
  15.     """  
  16.   
  17.     def __init__(self, appid, app_notify_url, app_private_key_path,  
  18.                  alipay_public_key_path, return_url, debug=False):  
  19.         self.appid = appid  
  20.         self.app_notify_url = app_notify_url  
  21.         self.app_private_key_path = app_private_key_path  
  22.         self.app_private_key = None  
  23.         self.return_url = return_url  
  24.         with open(self.app_private_key_path) as fp:  
  25.             self.app_private_key = RSA.importKey(fp.read())  
  26.         self.alipay_public_key_path = alipay_public_key_path  
  27.         with open(self.alipay_public_key_path) as fp:  
  28.             self.alipay_public_key = RSA.importKey(fp.read())  
  29.   
  30.         if debug is True:  
  31.             self.__gateway = "https://openapi.alipaydev.com/gateway.do"  
  32.         else:  
  33.             self.__gateway = "https://openapi.alipay.com/gateway.do"  
  34.   
  35.     def direct_pay(self, subject, out_trade_no, total_amount, return_url=None, **kwargs):  
  36.         biz_content = {  
  37.             "subject": subject,  
  38.             "out_trade_no": out_trade_no,  
  39.             "total_amount": total_amount,  
  40.             "product_code""FAST_INSTANT_TRADE_PAY",  
  41.             # "qr_pay_mode":4  
  42.         }  
  43.   
  44.         biz_content.update(kwargs)  
  45.         data = self.build_body("alipay.trade.page.pay", biz_content, self.return_url)  
  46.         return self.sign_data(data)  
  47.   
  48.     def build_body(self, method, biz_content, return_url=None):  
  49.         data = {  
  50.             "app_id"self.appid,  
  51.             "method": method,  
  52.             "charset""utf-8",  
  53.             "sign_type""RSA2",  
  54.             "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),  
  55.             "version""1.0",  
  56.             "biz_content": biz_content  
  57.         }  
  58.   
  59.         if return_url is not None:  
  60.             data["notify_url"] = self.app_notify_url  
  61.             data["return_url"] = self.return_url  
  62.   
  63.         return data  
  64.   
  65.     def sign_data(self, data):  
  66.         data.pop("sign"None)  
  67.         # 排序后的字符串  
  68.         unsigned_items = self.ordered_data(data)  
  69.         unsigned_string = "&".join("{0}={1}".format(k, v) for k, v in unsigned_items)  
  70.         sign = self.sign(unsigned_string.encode("utf-8"))  
  71.         # ordered_items = self.ordered_data(data)  
  72.         quoted_string = "&".join("{0}={1}".format(k, quote_plus(v)) for k, v in unsigned_items)  
  73.   
  74.         # 获得最终的订单信息字符串  
  75.         signed_string = quoted_string + "&sign=" + quote_plus(sign)  
  76.         return signed_string  
  77.   
  78.     def ordered_data(self, data):  
  79.         complex_keys = []  
  80.         for key, value in data.items():  
  81.             if isinstance(value, dict):  
  82.                 complex_keys.append(key)  
  83.   
  84.         # 将字典类型的数据dump出来  
  85.         for key in complex_keys:  
  86.             data[key] = json.dumps(data[key], separators=(','':'))  
  87.   
  88.         return sorted([(k, v) for k, v in data.items()])  
  89.   
  90.     def sign(self, unsigned_string):  
  91.         # 开始计算签名  
  92.         key = self.app_private_key  
  93.         signer = PKCS1_v1_5.new(key)  
  94.         signature = signer.sign(SHA256.new(unsigned_string))  
  95.         # base64 编码,转换为unicode表示并移除回车  
  96.         sign = encodebytes(signature).decode("utf8").replace("\n", "")  
  97.         return sign  
  98.   
  99.     def _verify(self, raw_content, signature):  
  100.         # 开始计算签名  
  101.         key = self.alipay_public_key  
  102.         signer = PKCS1_v1_5.new(key)  
  103.         digest = SHA256.new()  
  104.         digest.update(raw_content.encode("utf8"))  
  105.         if signer.verify(digest, decodebytes(signature.encode("utf8"))):  
  106.             return True  
  107.         return False  
  108.   
  109.     def verify(self, data, signature):  
  110.         if "sign_type" in data:  
  111.             sign_type = data.pop("sign_type")  
  112.         # 排序后的字符串  
  113.         unsigned_items = self.ordered_data(data)  
  114.         message = "&".join(u"{}={}".format(k, v) for k, v in unsigned_items)  
  115.         return self._verify(message, signature)  
3、路由设置
  1. in urls.py  
  2.     urlpatterns = [  
  3.         url(r'^admin/', admin.site.urls),  
  4.         url(r'^page1/', views.page1),  
  5.             url(r'^index/', views.index),  
  6.         url(r'^page2/', views.page2),  
  7.     ]  

4、视图设置

  1. in  view.py  
  2.     from django.shortcuts import render, redirect, HttpResponse  
  3.     from utils.pay import AliPay  
  4.     import json  
  5.     import time  
  6.   
  7.   
  8.     def get_ali_object():  
  9.         # 沙箱环境地址:https://openhome.alipay.com/platform/appDaily.htm?tab=info  
  10.         app_id = "2016091100486897"  #  APPID (沙箱应用)  
  11.   
  12.         # 支付完成后,支付偷偷向这里地址发送一个post请求,识别公网IP,如果是 192.168.20.13局域网IP ,支付宝找不到,def page2()   
  13.             # 接收不到这个请求  
  14.         notify_url = "http://47.94.172.250:8804/page2/"  
  15.   
  16.         # 支付完成后,跳转的地址。  
  17.         return_url = "http://47.94.172.250:8804/page2/"  
  18.   
  19.         merchant_private_key_path = "keys/app_private_2048.txt" # 应用私钥  
  20.         alipay_public_key_path = "keys/alipay_public_2048.txt"  # 支付宝公钥  
  21.   
  22.         alipay = AliPay(  
  23.             appid=app_id,  
  24.             app_notify_url=notify_url,  
  25.             return_url=return_url,  
  26.             app_private_key_path=merchant_private_key_path,  
  27.             alipay_public_key_path=alipay_public_key_path,  # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥  
  28.             debug=True,  # 默认False,  
  29.         )  
  30.         return alipay  
  31.   
  32.   def index(request):  
  33.             return render(request,'index.html')  
  34.   
  35.     def page1(request):  
  36.         # 根据当前用户的配置,生成URL,并跳转。    
  37.         money = float(request.POST.get('money'))  
  38.   
  39.         alipay = get_ali_object()  
  40.   
  41.         # 生成支付的url  
  42.         query_params = alipay.direct_pay(  
  43.             subject="充气式赵俊明",  # 商品简单描述  
  44.             out_trade_no="x2" + str(time.time()),  # 用户购买的商品订单号(每次不一样) 20180301073422891  
  45.             total_amount=money,  # 交易金额(单位: 元 保留俩位小数)  
  46.         )  
  47.   
  48.         pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(query_params)  # 支付宝网关地址(沙箱应用)  
  49.   
  50.         return redirect(pay_url)  
  51.   
  52.   
  53.     def page2(request):  
  54.         alipay = get_ali_object()  
  55.         if request.method == "POST":  
  56.             # 检测是否支付成功  
  57.             # 去请求体中获取所有返回的数据:状态/订单号  
  58.             from urllib.parse import parse_qs  
  59.             # name&age=123....  
  60.             body_str = request.body.decode('utf-8')  
  61.             post_data = parse_qs(body_str)  
  62.   
  63.             post_dict = {}  
  64.             for k, v in post_data.items():  
  65.                 post_dict[k] = v[0]  
  66.   
  67.             # post_dict有10key: 9 ,1  
  68.             sign = post_dict.pop('sign'None)  
  69.             status = alipay.verify(post_dict, sign)  
  70.             print('------------------开始------------------')  
  71.             print('POST验证', status)  
  72.             print(post_dict)  
  73.             out_trade_no = post_dict['out_trade_no']  
  74.   
  75.             # 修改订单状态  
  76.             # models.Order.objects.filter(trade_no=out_trade_no).update(status=2)  
  77.             print('------------------结束------------------')  
  78.             # 修改订单状态:获取订单号  
  79.             return HttpResponse('POST返回')  
  80.   
  81.         else:  
  82.             params = request.GET.dict()  
  83.             sign = params.pop('sign'None)  
  84.             status = alipay.verify(params, sign)  
  85.             print('==================开始==================')  
  86.             print('GET验证', status)  
  87.             print('==================结束==================')  
  88.             return HttpResponse('支付成功')  

5、模板

  1. in index.html  
  2.   
  3. <!DOCTYPE html>  
  4. <html lang="en">  
  5. <head>  
  6.     <meta charset="UTF-8">  
  7.     <title>Title</title>  
  8.     <link rel="stylesheet" href="dist/css/bootstrap.css">  
  9. </head>  
  10. <body>  
  11.     <form action="/page1/" method="POST">  
  12.         {% csrf_token %}  
  13.         <input type="text" name="money">  
  14.         <input type="submit" value="去支付" />  
  15.     </form>  
  16. <script></script>  
  17. </body>  
  18. </html>  

6、当你全部设置完,代码只需修改三个地方

git项目地址:https://github.com/zhbittt/s5alipay.git

    (1)、修改APPID

        -- 这是你账号的APPID

         

       -- in  views.py

                   def  get_ali_object():

                        app_id = 'xxxxxxx' #你的账号APPID  

================================

    (2)、换上你的支付宝公钥

    (3)、换上你的应用私钥

 

 

posted @ 2018-03-12 16:44  飞天的鱼  阅读(875)  评论(0编辑  收藏  举报