本节文档下载地址:https://download.youkuaiyun.com/download/geek_xiong/11615541
目录
蚂蚁金服--支付宝的使用
蚂蚁金服的链接地址:https://open.alipay.com/platform/manageHome.htm
使用沙箱账号做开发与测试
开发文档:https://openhome.alipay.com/developmentDocument.htm
使用python开发工具包:https://github.com/fzlee/alipay/blob/master/README.zh-hans.md
以上具体的可参考文档(自行下载)
订单支付
在我的订单界面显示房客预定过的订单,其中包括“待结单”、“去支付”、“发表评论”、“已完成”等,本节要完成的是“去支付”。
点击“去支付”按钮,调起支付宝接口,进入支付宝支付界面,需要自定义要展示的参数(标题、金额等)
前后端代码编写
URL:127.0.0.1:5000/api/v1.0/orders/<orderId>/payment
请求方式:POST
参数:订单编号
大致流程:
- 获取用户的编号
- 判断该订单的状态
- 配置支付宝接口
- 生成支付宝链接
- 返回结果
# POST 127.0.0.1:5000/api/v1.0/orders/<orderId>/payment
@api.route("/orders/<int:order_id>/payment", methods=['POST'])
@login_required
def order_pay(order_id):
"""发起支付宝支付"""
# 获取用户的id
user_id = g.user_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.errer(e)
return jsonify(errno=RET.DBERR, errmsg='数据库异常')
if order is None:
return jsonify(errno=RET.NODATA, errmsg='订单数据有误')
# 创建支付宝sdk的工具对象
alipay_client = AliPay(
appid="2016101000651363",
app_notify_url=None,
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",
debug=True
)
# 手机网站支付,需要跳转到https://openapi.alipay.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='爱家租房 %s' % order.id,
return_url="http://127.0.0.1:5000/payComplete.html",
notify_url=None # 可选, 不填则使用默认notify url
)
# 构建让用户跳转的支付链接地址
pay_url = constants.ALIPAY_URL_PREFIX + order_string
return jsonify(errno=RET.OK, errmsg="OK", data={"pay_url": pay_url})
# 支付宝的网关地址(支付宝的域名)
ALIPAY_URL_PREFIX = "https://openapi.alipaydev.com/gateway.do?"
支付成功后会返回结果,url如:
url如:http://127.0.0.1:5000/payComplete.html
?charset=utf-8
&out_trade_no=3
&method=alipay.trade.wap.pay.return
&total_amount=4500.00
&sign=Givnobw%2FNN832970v....FNN8329
&trade_no=2019082622001498191000030983
&auth_app_id=2016101000651363
&version=1.0
&app_id=2016101000651363
&sign_type=RSA2
&seller_id=2088102178900710
×tamp=2019-08-26+17%3A41%3A35
我们并不想带着 这个结果回到订单页面,所以设置了一个过渡界面payComplete.html
<div class="container">
<div class="top-bar">
<div class="nav-bar">
<h3 class="page-title">支付完成</h3>
<a class="nav-btn fl" href="/my.html"><span><i class="fa fa-angle-left fa-2x"></i></span></a>
</div>
</div>
<div class="orders-con">
<p> 支付已完成 </p>
<a href="/orders.html">回到我的订单</a>
</div>
<div class="footer">
<p><span><i class="fa fa-copyright"></i></span>爱家租房 享受家的温馨</p>
</div>
</div>
<script type="text/javascript">
function getCookie(name) {
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : undefined;
}
var alipayData = document.location.search.substr(1);
$.ajax({
url: "/api/v1.0/order/payment",
type: "put",
data: alipayData,
headers: {
"X-CSRFToken": getCookie("csrf_token")
}
})
</script>
当点击“回到我的订单”链接时,发送ajax请求,
后端根据url中的参数订单编号,将订单状态改为“发表评论”,即已支付完成
# put 127.0.0.1:5000/api/v1.0/order/payment
@api.route("/order/payment", methods=['PUT'])
@login_required
def save_order_payment_result():
"""保存支付订单结果"""
alipay_dict = request.form.to_dict()
# # 对支付宝的数据进行分离 提取出支付宝的签名参数sign 和剩下的其他数据
alipay_sign = alipay_dict.pop("sign")
# 创建支付宝sdk的工具对象
alipay_client = AliPay(
appid="2016101000651363",
app_notify_url=None,
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",
debug=True
)
# 借助工具验证参数的合法性
# 如果确定参数是支付宝的,返回True,否则返回false
result = alipay_client.verify(alipay_dict, alipay_sign)
if result:
# 修改数据库的订单状态信息
order_id = alipay_dict.get("out_trade_no")
trade_no = alipay_dict.get("trade_no") # 支付宝交易的流水号
try:
Order.query.filter_by(id=order_id).update({"status": "WAIT_COMMENT", "trade_no": trade_no})
db.session.commit()
except Exception as e:
current_app.logger.error(e)
db.session.rollback()
return jsonify(error=RET.OK, errmsg='OK')
# models.py
class Order(...):
...
trade_no = db.Column(db.String(80)) # 交易的流水号 支付宝的
重新迁移一下数据库
python manage.py db init
python manage.py db migrate -m 'db tables'
python manage.py db upgrade
测试
重新启动一下项目