Django接入支付宝支付
一、 申请沙盒账号
-
进入沙盒环境
-
- 生成后,需要把应用公钥复制进去,获取支付宝公钥
- 保存好应用私钥
- 主要好支付宝公钥和应用私钥格式,以下为举例
alipay_public_key.pem
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAns4fKUa1T1dvJGJXPqESxsciOVdmC1MMvha3NIGrdYhWTXpS22klru9yPp2htIRE4TW5M2Hf/BZgsuVxj1xy/bdHGW1YyMAf0Xjcj4/UHomwC4yqrZrgAsJSrpP6RtSxPuYCfk0nNXhaJYznhm3HT7IYU7C3mdbOTdIQ/t8G4X2luQBHnZuY9kqaRf64TG+aH8121ZA5dsW+V77T3S9k0zfUFelVPHlvpsgCtPu0SGSjHSSpvLlKybZGWEnBviTa+jHtvkRYeztmjMapaYJY4F5INQaww4DzefVSkneHTYpb6KCZVNUChAmmpeUQKuObWPxGcPznF2zGwNwHptRTDwIDAQAB -----END PUBLIC KEY-----
app_private_key.pem
-----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEA6E+jr5AEmz5VHNpp4xkHhIOhA59bs5rc6glBTL34Uqj+rWxDL6EVle//LpKvuN3yU79avEBFYwSBP+BioWlq+vY1tDediGdRa060x4N3d/9/GvF8RNpZKZI+cwY9umRlm4NJbv+KZ4kHRRAbxOmL4xALvMQhgCmQwUgySL47oLXRuispzzGwqx5Eo77ei364/PxuQLwoIXxo4oWO0andXhSRNQCGTtwSPsfmdEsA11Xoa5y4uvshlIXpn9lE0BryXw9j6+k5hnPFoiXKmQJlIeYQEnYxSo2aycXJ7VyYSsGbdPFl4yNwigwIb0wnePw79Z4zV8/IQy3EylhF54ah7wIDAQABAoIBAQC1UtvvP1jpF0j1oWD+md2tR9RYcHzx/hEqNxkZ3jlBw5gtIpB6T5/6jP2/i0zO3aW0Smp2/y9pbu23PtudIxwWUDBwvuwduI7rU950z59jMTAzhoM5drgbY4OM4jUyFATe0iVyFtEfqOvcswsJskS2cSLILsn7L/ZFdqWQ87K051i+6ldp916m25+Xc+5TGKhfqFKmlgueRh4r4ZPn9v0pFCNTr2dH70LqZnrL9OMy3YLiw/K9U4vFh/P3HqNHPANvquh155/2zemGiGPZHJ5r1uaeXVxvIAEXpWL21BskpW546RObr0Do7Dmz3B0cZ6tDPsqn0mUn8kqWJSVr+htRAoGBAPoyfKqYwf2BjwBQjiqaZemFM7fbgHO1Kgf+2Bq2AbLfzM1SwUJpCA/Qlepe+rL1QvUJJJhCCrbXNS4tBgItww+cYC8z2+NdufXCtwlPOQ5D2EbiXPIUS8Jzea35lj10DoQppCkcMWp68fRAYdeyJ9Xz6iVs3SVTgELDvpk5Vl1nAoGBAO2y9Lb45+rIQkn60k6vBr8Z7zTOk5HFDK/xItt9f0r3vs6zGF6kAAFw9K/8ePNlcjHD+X46I9qKsLU1GwYwdlmzhhUhgith9sgEsoAUs05yh04eW4D1ucyRa09NpZ/7vua3xL6Y9XlPFHXnDNvFyOoiJJFyCBOF279o8mh8ubo5AoGABaKFdEIkfFUip1spGISJrwy08XscFX8LB0sSCuf2edTYg/dNKvW6nMCR38lr1AP6EhK2pEc4fo2yQOv6qqnlLsDS2b1NQn2l5ocQIEGMg2m7wTzv4vPaEPMQ1n48h/3JJejaLaLY6hECygF5MqZsh0ELEPS2tlR/GwHVlRXZgBkCgYEAziuGbp3+KnqAZMKVX4IYi/DmthrnjGwp0QGKhm6X1mKEsaxN2ujMyHM9CNgn4JWBMwEUihPLvWbGVqY1Rm0KektoZTOnQBG8h0jruoQ58jUMfwl9vKFmArWvKh3jJpyovF1w3RC2+f1JdepuEMHAvrPWnAEYWDamn6Nbfp2QSqECgYEA3Y8t+P1/zFUMZHr1FlHMXCk6UG96MUzE3KOFkFGqTfeFVXxwAVvHGhpJXGMO2um/oy+ASDVolxaHb5V6ptOn0CosXvgmipjM5n4pd2kKAhnWL0COx9ktcle4XsVvUgtxd8XbrFJuI+BpB9mKkmRlZCK5yr5y99npD2dJOig9Oh8= -----END RSA PRIVATE KEY-----
-
在沙盒环境中配置授权回调地址
-
下载沙盒钱包,账号和密码都可在沙盒账号找到
二、 编写代码
首先需要执行命令:pip install python-alipay-sdk
-
生成支付宝支付链接方法
import os import uuid from alipay import AliPay from django.http import JsonResponse from django.shortcuts import render from django.views.generic import View class OrderPayView(View): def post(self,request): #接收参数 order_id = str(uuid.uuid1()) merchant_private_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/app_private_key.pem")).read() alipay_public_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/alipay_public_key.pem")).read() # print(x,'eeeee') #业务处理:使用Python sdk调用支付宝的支付接口 alipay = AliPay( appid="2016102200736331", #APPID app_notify_url=None, # 默认回调url,可以传也可以不传 app_private_key_string=merchant_private_key_path, #私钥的路径 alipay_public_key_string=alipay_public_key_path,#支付宝公钥的路径 sign_type="RSA2", # RSA 或者 RSA2,签名的算法 debug = True # 默认False,沙箱环境改成True ) #借助alipay对象,向支付宝发起支付请求 #电脑网站支付,需要跳转到https://openapi.alipaydev.com/gateway.do?+order_string total_pay = 5 #订单总金额 order_string = alipay.api_alipay_trade_page_pay( out_trade_no=order_id, #订单id total_amount=str(total_pay), #支付宝总金额 subject="测试支付", #订单标题 return_url="http://127.0.0.1:8000/success/", notify_url=None ) #返回应答 pay_url = "https://openapi.alipaydev.com/gateway.do?"+order_string return JsonResponse({"pay_url":pay_url})
注意事项
- 问题:私钥会出现不支持的情况,解决方法:使用open读取值再传送即可。
- 问题:return_url方法为get请求回调时间,回答:当支付成功后,并且按照正常操作等待支付宝调用才会进行调用,即出现支付完成时不会快速点击关闭。
- 问题:notify_url方法为post请求回调时间,回答:当支付成功后,会直接调用这个接口。
-
回调函数方法(同步回调和异步回调)
# 处理支付宝回调 class AlipayView(APIView): def get(self, request): """ 处理支付宝的return_url返回 """ processed_dict = {} # 1. 获取GET中参数 for key, value in request.GET.items(): processed_dict[key] = value # 2. 取出sign sign = processed_dict.pop("sign", None) merchant_private_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/app_private_key.pem")).read() alipay_public_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/alipay_public_key.pem")).read() # 3. 生成ALipay对象 alipay = AliPay( appid="2016102200736331", #APPID app_notify_url=None, # 默认回调url,可以传也可以不传 app_private_key_string=merchant_private_key_path, # 应用私钥 alipay_public_key_string=alipay_public_key_path, # 支付宝公钥 sign_type="RSA2", # RSA 或者 RSA2,签名的算法 debug = True # 默认False,沙箱环境改成True ) verify_re = alipay.verify(processed_dict, sign) # 这里可以不做操作。因为不管发不发return url。notify url都会修改订单状态。 if verify_re is True: order_sn = processed_dict.get('out_trade_no', None) # 商户订单号 trade_no = processed_dict.get('trade_no', None) # 支付宝交易号 return render(request,'pay_success.html') else: return render(request,'demo.html') def post(self, request): """ 处理支付宝的notify_url """ # 1. 先将sign剔除掉 processed_dict = {} for key, value in request.POST.items(): processed_dict[key] = value sign = processed_dict.pop("sign", None) merchant_private_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/app_private_key.pem")).read() alipay_public_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/alipay_public_key.pem")).read() # 2. 生成ALipay对象 alipay = AliPay( appid="2016102200736331", #APPID app_notify_url=None, # 默认回调url,可以传也可以不传 app_private_key_string=merchant_private_key_path, #私钥的路径 alipay_public_key_string=alipay_public_key_path,#支付宝公钥的路径 sign_type="RSA2", # RSA 或者 RSA2,签名的算法 debug = True # 默认False,沙箱环境改成True ) # 3. 进行验签,确保这是支付宝给我们的 verify_re = alipay.verify(processed_dict, sign) # 如果验签成功 if verify_re is True: order_sn = processed_dict.get('out_trade_no', None) # 商户订单号 trade_no = processed_dict.get('trade_no', None) # 支付宝交易号 trade_status = processed_dict.get('trade_status', None) # 交易状态 # 将success返回给支付宝,支付宝就不会一直不停的继续发消息了。 return Response("success")
-
查询支付状态
# 查询支付状态 class CheckPayView(View): def post(self,request): # 初始化 merchant_private_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/app_private_key.pem")).read() alipay_public_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/alipay_public_key.pem")).read() # 业务处理:使用Python sdk调用支付宝的支付接口 alipay = AliPay( appid="2016102200736331", # APPID app_notify_url=None, # 默认回调url,可以传也可以不传 app_private_key_string=merchant_private_key_path, # 私钥的路径 alipay_public_key_string=alipay_public_key_path, # 支付宝公钥的路径 sign_type="RSA2", # RSA 或者 RSA2,签名的算法 debug = True # 默认False,沙箱环境改成True ) order_id = str(uuid.uuid1()) # 前端传入,目前是随机生成 while True: response = alipay.api_alipay_trade_query(out_trade_no=order_id) # out_trade_no和trade_no两个至少有一个存在 code = response.get("code") # 如果返回码为10000和交易状态为交易支付成功 if code == "10000" and response.get("trade_status") == "TRADE_SUCCESS": # 获取支付宝交易号 trade_no = response.get("trade_no") return JsonResponse({"status":"ok","message":"支付成功"}) # 返回码为40004 或 交易状态为等待买家付款 elif code == "40004" or (response.get("trade_status") == "WAIT_BUYER_PAY"): # 等待买家付款 import time time.sleep(5) continue else: # 支付出错 return JsonResponse({"status":"error","message":"支付失败"})
三、 声明
本博客仅供参考,如商用出现不可控问题,概不负责
源码: Django-Extended-App,该仓库里Alipy_WX文件夹