支付宝第三方接口对接
支付宝介绍
在学习搭建网站需要对接支付宝支付的接口,支付宝有专门用于研发的沙箱接口,只需要有支付宝账号即可
支付宝开放平台入口
https://open.alipay.com/platform/home.htm
登陆进去后,界面如下:
点击开发服务==》研发服务 进入沙箱,需要配置公钥私钥
生成公钥私钥
$ openssl
$ OpenSSL> genrsa -out app_private_key.pem 2048 # 制作私钥RSA2
$ OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem # 导出公钥
$ OpenSSL> exit
支付宝SDK配置参数
ALIPAY_APPID = 'appod' #沙箱环境中的appid
ALIPAY_DEBUG = True
ALIPAY_URL = 'https://openapi.alipaydev.com/gateway.do'
ALIPAY_RETURN_URL = 'return url' # 支付成功后返回的地址
对接支付宝接口
class PaymentView(LoginRequiredJsonMixin, View):
"""对接支付宝的对接接口"""
def get(self, request, order_id):
# 查询要支付的订单
user = request.user
try:
order = OrderInfo.objects.get(order_id=order_id, user=user, status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'])
except OrderInfo.DoesNotExist:
return http.HttpResponseForbidden('订单信息错误')
# 创建支付宝支付对象,
# SDK对象对接支付宝支付的接口,得到登陆页的地址
# 拼接完整的登陆页地址
app_private_key_string = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/app_private_key.pem")).read(),
# print(app_private_key_string[0])
alipay_public_key_string = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/alipay_public_key.pem")).read(),
alipay = AliPay(
appid=settings.ALIPAY_APPID, # 应用id
app_notify_url=None, # 默认回调url,如果采用同步通知就不传
# 应用的私钥和支付宝的公钥路径
app_private_key_string=app_private_key_string[0],
alipay_public_key_string=alipay_public_key_string[0],
sign_type="RSA2", # 加密标准
debug=True, # 指定是否是开发环境
)
# 生成登录支付宝连接
order_string = alipay.api_alipay_trade_page_pay(
out_trade_no=order_id, # 订单编号
total_amount=str(order.total_amount), # 支付金额
subject="美多商城%s" % order_id, # 订单标题
return_url=settings.ALIPAY_RETURN_URL, # 同步通知的回调地址
)
# 响应登录支付宝连接
# 真实环境电脑网站支付网关:https://openapi.alipay.com/gateway.do? + order_string
# 沙箱环境电脑网站支付网关:https://openapi.alipaydev.com/gateway.do? + order_string
alipay_url = settings.ALIPAY_URL + "?" + order_string
return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'alipay_url': alipay_url})
返回网站保存订单状态
class PaymentStatusView(LoginRequiredJsonMixin, View):
"""保存订单的状态"""
def get(self, request):
# 获取到所有的查询字符串
query_str = request.GET
# 转成字典类型
query_dict = query_str.dict()
# 提取出sign
signature = query_dict.pop('sign')
# 使用sdk对象调用通知认证接口函数,验证
app_private_key_string = open(
os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/app_private_key.pem")).read(),
# print(app_private_key_string[0])
alipay_public_key_string = open(
os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/alipay_public_key.pem")).read(),
alipay = AliPay(
appid=settings.ALIPAY_APPID, # 应用id
app_notify_url=None, # 默认回调url,如果采用同步通知就不传
# 应用的私钥和支付宝的公钥路径
app_private_key_string=app_private_key_string[0],
alipay_public_key_string=alipay_public_key_string[0],
sign_type="RSA2", # 加密标准
debug=True, # 指定是否是开发环境
)
success = alipay.verify(query_dict, signature)
# 验证通过,支付宝的支付状态处理
order_id = query_dict['out_trade_no'],
trade_id = query_dict['trade_no'],
if success:
Payment.objects.create(
order_id=order_id,
trade_id=trade_id,
)
# 修改订单状态,由待支付变成待评价
OrderInfo.objects.filter(order_id=order_id, status=OrderInfo.ORDER_STATUS_ENUM['UNPAID']).update(
status=OrderInfo.ORDER_STATUS_ENUM['UNCOMMENT'])
else:
return http.HttpResponseForbidden('非法请求')
context = {
'trade_id': trade_id,
}
return render(request, 'pay_success.html', context=context)