-
安装包
# 安装python-alipay-sdk # --upgrade 是你之前安装了pycrypto, 加它是升级, 一次都没安装的用户, 直接pip install python-alipay-sdk pip install python-alipay-sdk --upgrade
-
生成密钥文件
# openssl window上没有, linux下和mac上都带这个命令 openssl OpenSSL> genrsa -out app_private_key.pem 2048 # 私钥 OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem # 导出公钥 OpenSSL> exit
-
把支付宝公钥填写到沙箱环境
-
把私钥放在项目里
-
查看支付宝的公钥
-
把支付宝公钥复制粘贴到你项目的alipay_public_key.pem文件夹里, 记得在头加上
将-----BEGIN PUBLIC KEY-----添加到支付宝公钥的头部 将-----END PUBLIC KEY-----添加到支付宝的尾部
-
初始化
from alipay import AliPay alipay = AliPay( appid="", # 沙箱appid 或 线上appid app_notify_url=None, # 默认回调url 不写的话这里用None app_private_key_path="", # 私钥 alipay_public_key_path="", # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥, sign_type="RSA", # RSA 或者 RSA2 debug=False # 默认False 沙箱环境把这里设置为True )
-
根据对象发送请求
5.1 电脑网站支付 alipay.trade.page.pay# 如果你是Python 2用户(考虑考虑升级到Python 3吧),请确保非ascii的字符串为utf8编码: subject = u"测试订单".encode("utf8") # 如果你是 Python 3的用户,使用默认的字符串即可 subject = "测试订单" # 电脑网站支付,需要跳转到https://openapi.alipay.com/gateway.do? + order_string 这是线上环境 # 电脑网站支付, 需要跳转到https://openapi.alipaydev.com/gateway.do? + order_string 这是沙箱环境 order_string = alipay.api_alipay_trade_page_pay( out_trade_no="20161112", # 订单编号 total_amount="0.01", # 总金额 subject=subject, # 订单标题 随便写个字符串 return_url="https://example.com", # 返回的链接地址 notify_url="https://example.com/notify" # 可选, 不填则使用默认notify url 不填这里写None )
5.2 手机网站支付 alipay.trade.wap.pay
# 手机网站支付,需要跳转到https://openapi.alipay.com/gateway.do? + order_string 这是线上环境 # 手机网站支付, 需要跳转到https://openapi.alipaydev.com/gateway.do? + order_string 这是沙箱环境 order_string = alipay.api_alipay_trade_wap_pay( out_trade_no="20161112", # 订单编号 total_amount="0.01", # 总金额 subject=subject, # 订单标题 随便写个字符串 return_url="https://example.com", # 返回的链接地址 notify_url="https://example.com/notify" # 可选, 不填则使用默认notify url 不填这里写None )
5.3 App支付 alipay.trade.app.pay
# App支付,将order_string返回给app即可 order_string = alipay.api_alipay_trade_app_pay( out_trade_no="20161112", # 订单id total_amount=0.01, # 总金额 subject=subject, # 订单标题 随便写个字符串 notify_url="https://example.com/notify" # 可选, 不填则使用默认notify url 不填这里写None )
-
基于flask的简单验证
from flask import Flask from flask import request app = Flask(__name__) @app.route('/', methods=["GET", "POST"]) def hello_world(): data = request.form.to_dict() # sign 不能参与签名验证 signature = data.pop("sign") print(json.dumps(data)) print(signature) # verify success = alipay.verify(data, signature) if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED" ): print("trade succeed")
-
列子
-
支付宝付款接口链接返回给前端
from . import api from ihome.models import Order from ihome.utils.commons import login_required from flask import g, current_app, jsonify from ihome.utils.response_code import RET from ihome import constants from alipay import AliPay import os @api.route("/orders/<int:order_id>/payment", methods=["POST"]) @login_required def order_pay(order_id): """ 订单支付 :param order_id: 订单的id :return: 支付宝支付的链接地址 格式json """ # 接收用户id user_id = g.user_id # 校验参数 # 根据order_id查询数据库, order_id是否存在, 订单是否属于该用户, 订单是否是待支付状态 try: order = Order.query.filter(Order.id == order_id, Order.user_id == user_id, Order.status == "WAIT_PAYMENT").first() except Exception as e: current_app.logger.error(e) return jsonify(errnum=RET.DBERR, errmsg=u"获取订单信息失败") if order is None: return jsonify(errnum=RET.NODATA, errmsg=u"订单信息不存在") # 业务处理 # 创建支付宝sdk的工具对象 alipay_client = AliPay( appid="2016092500596768", # 沙箱appid 或 线上appid app_notify_url=None, # 默认回调url 不写的话这里用None # os.path.dirname(__file__): 获取当前文件所在目录的路径 app_private_key_path=os.path.join(os.path.dirname(__file__), "keys/app_private_key.pem"), # 私钥 alipay_public_key_path=os.path.join(os.path.dirname(__file__), "keys/alipay_public_key.pem"), # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥, sign_type="RSA2", # RSA 或者 RSA2 debug=False # 默认False 沙箱环境把这里设置为True ) # 手机网站支付,需要跳转到https://openapi.alipay.com/gateway.do? + order_string 这是线上环境 # 手机网站支付, 需要跳转到https://openapi.alipaydev.com/gateway.do? + order_string 这是沙箱环境 order_string = alipay_client.api_alipay_trade_wap_pay( out_trade_no=order.id, # 订单编号 total_amount=str(order.amount/100.0), # 总金额 subject=u"订单编号 %s" % order.id, # 订单标题 随便写个字符串 return_url="http://172.16.66.238:5000/orders.html", # 返回的链接地址 notify_url=None # 可选, 不填则使用默认notify url 不填这里写None ) # 构造让用户跳转的支付链接地址 这里用的是沙箱环境 pay_url = constants.ALIPAY_URL_PREFIX + order_string # 返回应答 return jsonify(errnum=RET.OK, errmsg=u"ok", data={"pay_url": pay_url})
-
前端回跳的参数
-
验证是否是支付宝发送过来的
@api.route("/order/payment", methods=["PUT"]) def save_order_payment_result(): """保存订单支付结果""" # 接收参数 # 将form表单数据转换成字典 alipay_dict = request.form.to_dict() # 对支付宝的数据进行分离 提取出支付宝的签名参数sign 和剩下的其他数据 alipay_sign = alipay_dict.pop("sign") # 业务处理 # 创建支付宝sdk的工具对象 alipay_client = AliPay( appid="2016092500596768", # 沙箱appid 或 线上appid app_notify_url=None, # 默认回调url 不写的话这里用None # os.path.dirname(__file__): 获取当前文件所在目录的路径 app_private_key_path=os.path.join(os.path.dirname(__file__), "keys/app_private_key.pem"), # 私钥 alipay_public_key_path=os.path.join(os.path.dirname(__file__), "keys/alipay_public_key.pem"), # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥, sign_type="RSA2", # RSA 或者 RSA2 debug=False # 默认False 沙箱环境把这里设置为True ) # 借助工具验证参数的合法性 # 如果确定参数是支付宝的, 返回True, 否则返回False result = alipay_client.verify(alipay_dict, alipay_sign) if result: # 获取订单id order_id = alipay_dict.get("out_trade_no") # 获取支付宝交易号 trade_no = alipay_dict.get("trade_no") try: # 这里是根据订单id查询这个订单, 并且更新订单里的status和trade_no着两个字段 Order.query.filter_by(id=order_id).update({"status": "WAIT_COMMENT", "trade_no": trade_no}) # 保存到数据库中 db.session.commit() except Exception as e: # 有异常记录log日志 current_app.logger.error(e) # 回滚到提交前 db.session.commit() # 返回应答 return jsonify(errnum=RET.OK, errmsg=u"ok")
-
-
线上环境就是把沙箱的appid换成线上的appid, 访问的域名用线上的域名.
来源:CSDN
作者:程序使我快乐
链接:https://blog.csdn.net/zsx1314lovezyf/article/details/90677788