zoukankan      html  css  js  c++  java
  • 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(" ", "")  
    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)、换上你的应用私钥

  • 相关阅读:
    461. Hamming Distance
    342. Power of Four
    326. Power of Three
    368. Largest Divisible Subset java solutions
    95. Unique Binary Search Trees II java solutions
    303. Range Sum Query
    160. Intersection of Two Linked Lists java solutions
    88. Merge Sorted Array java solutions
    67. Add Binary java solutions
    14. Longest Common Prefix java solutions
  • 原文地址:https://www.cnblogs.com/zhangningyang/p/8550138.html
Copyright © 2011-2022 走看看