Erlo

前后端分离djangorestframework—— 接入支付宝支付平台

2019-03-12 15:01:47 发布   825 浏览  
页面报错/反馈
收藏 1 赞

支付宝

简介

支付宝是什么不用多说了,本次教程适合初学者

 

前提准备

话不多说,干就完了

 

1.注册开发者账号,设置公钥私钥

首先进入支付宝开发者平台:传送门 ,有账号直接登录,没账号用你平时用来付款收钱的账号登录,然后用这个账号激活注册成开发者账号就行了

登录之后点开发中心:

先用沙箱测试一下,点研发服务

 

 跳转到此页面,设置一个公钥

 

 

先点查看公钥生成:

 

 进入开发文档:传送门  根据文档步骤下载秘钥生成工具,根据说明文档运行程序

 

 

本次教程使用的是Python,所以一定要选非java,然后点击生成秘钥

 

 再点打开秘钥路径就可以看到已经生成了两个文件:

 

用这里的公钥和私钥,填入刚才那个设置页面:

如果在保存时提示什么公钥签名啥啥的,反正不成功的提示,利用秘钥生成工具重新生成一次填入即可

接着按这里的文档走就行:传送门  需要一个安卓手机下载沙箱版的支付宝作为测试

 

2.安装sdk 

 

之前使用支付宝,都要去github上download大神写的sdk,现在pyi社区已经有官方的sdk了:传送门  所以,直接pip install alipay-sdk-python 安装:

 但是到最后会报错:

 

 

然后看到说是因为安装支付宝的sdk时,由于需要安装这个库,而这个库需要依赖微软的visual c++才行,这就尴尬了,据查,要安装visual C++最好的办法是,下载visual Studio集成开发工具,注意不是visual studio code,两个是不同的软件,虽然都可以当开发工具,我的理解就是visual studio比visual studio code多了那些需要的运行库

 visual studio官方下载链接最新版   另外据网查,可以只安装visual studio 2015版就行,visual studio 2015下载链接 ,总共有几个G,解压并安装,只安装这个c++ 2015

 

等好长一会儿:

 

 然后再安装支付宝的sdk看看,还是不行

 按报错提示,那个c1.exe不被认识,所以还要设置环境变量:变量名:VCINSTALLDIR,变量值就是vc的路径

 

设置了环境变量后关闭cmd,重新打开cmd, 先使用命令设置:set CL=/FI"%VCINSTALLDIR%\INCLUDE\stdint.h" 这条命令是为了让刚才我们设置的环境变量生效

 

然后pip 安装,终于成功了

 

注:如果报错:UnicodeDecodeError: 'utf-8' codec can't decode byte... 将CMD的终端编码用“CHCP 65001”命令改为“UTF-8”后再安装即可

 

进入支付宝支付开发

 

好接着进入真正的开发阶段了,本次选用【电脑页面支付】:

 

然后进到支付宝的api文档:传送门

选用  统一收单下单支付接口  

进入的目录就不展示了,里面的参数配置就是正式的支付接口,这个就根据自己实际情况配置了,本次我们只用沙箱账号测试一下就行了,和正式的配置是一样的,因为正式的配置要认证商家才行,所以为了方便且精简的演示,就用沙箱账号了

 

在前面设置公钥私钥那个页面,把安卓版的沙箱支付宝下载安装好,使用这里的账号密码登录:

 

 准备好之后,现在进入真正的开发了。

 

1.创建一个django项目,一个简单的支付宝充值话费的

 

配置文件里导入rest_framework  app,设置url,其中pay则是一会儿要用到的测试url

html文件:

 

view,就按照pypi社区上支付宝给的案例调整代码就行:

 

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import traceback

from alipay.aop.api.AlipayClientConfig import AlipayClientConfig
from alipay.aop.api.DefaultAlipayClient import DefaultAlipayClient
from alipay.aop.api.FileItem import FileItem
from alipay.aop.api.domain.AlipayTradeAppPayModel import AlipayTradeAppPayModel
from alipay.aop.api.domain.AlipayTradePagePayModel import AlipayTradePagePayModel
from alipay.aop.api.domain.AlipayTradePayModel import AlipayTradePayModel
from alipay.aop.api.domain.GoodsDetail import GoodsDetail
from alipay.aop.api.domain.SettleDetailInfo import SettleDetailInfo
from alipay.aop.api.domain.SettleInfo import SettleInfo
from alipay.aop.api.domain.SubMerchant import SubMerchant
from alipay.aop.api.request.AlipayOfflineMaterialImageUploadRequest import AlipayOfflineMaterialImageUploadRequest
from alipay.aop.api.request.AlipayTradeAppPayRequest import AlipayTradeAppPayRequest
from alipay.aop.api.request.AlipayTradePagePayRequest import AlipayTradePagePayRequest
from alipay.aop.api.request.AlipayTradePayRequest import AlipayTradePayRequest
from alipay.aop.api.response.AlipayOfflineMaterialImageUploadResponse import AlipayOfflineMaterialImageUploadResponse
from alipay.aop.api.response.AlipayTradePayResponse import AlipayTradePayResponse

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s %(levelname)s %(message)s',
    filemode='a',)
logger = logging.getLogger('')


if __name__ == '__main__':
    """
    设置配置,包括支付宝网关地址、app_id、应用私钥、支付宝公钥等,其他配置值可以查看AlipayClientConfig的定义。
    """
    alipay_client_config = AlipayClientConfig()
    alipay_client_config.server_url = 'https://openapi.alipay.com/gateway.do'
    alipay_client_config.app_id = '[your app_id]'
    alipay_client_config.app_private_key = '[your app private key]'
    alipay_client_config.alipay_public_key = '[alipay public key]'

    """
    得到客户端对象。
    注意,一个alipay_client_config对象对应一个DefaultAlipayClient,定义DefaultAlipayClient对象后,alipay_client_config不得修改,如果想使用不同的配置,请定义不同的DefaultAlipayClient。
    logger参数用于打印日志,不传则不打印,建议传递。
    """
    client = DefaultAlipayClient(alipay_client_config=alipay_client_config, logger=logger)

    """
    系统接口示例:alipay.trade.pay
    """
    # 对照接口文档,构造请求对象
    model = AlipayTradePayModel()
    model.auth_code = "282877775259787048"
    model.body = "Iphone6 16G"
    goods_list = list()
    goods1 = GoodsDetail()
    goods1.goods_id = "apple-01"
    goods1.goods_name = "ipad"
    goods1.price = 10
    goods1.quantity = 1
    goods_list.append(goods1)
    model.goods_detail = goods_list
    model.operator_id = "yx_001"
    model.out_trade_no = "20180510AB014"
    model.product_code = "FACE_TO_FACE_PAYMENT"
    model.scene = "bar_code"
    model.store_id = ""
    model.subject = "huabeitest"
    model.timeout_express = "90m"
    model.total_amount = 1
    request = AlipayTradePayRequest(biz_model=model)
    # 如果有auth_token、app_auth_token等其他公共参数,放在udf_params中
    # udf_params = dict()
    # from alipay.aop.api.constant.ParamConstants import *
    # udf_params[P_APP_AUTH_TOKEN] = "xxxxxxx"
    # request.udf_params = udf_params
    # 执行请求,执行过程中如果发生异常,会抛出,请打印异常栈
    response_content = None
    try:
        response_content = client.execute(request)
    except Exception as e:
        print(traceback.format_exc())
    if not response_content:
        print("failed execute")
    else:
        response = AlipayTradePayResponse()
        # 解析响应结果
        response.parse_response_content(response_content)
        print(response.body)
        if response.is_success():
            # 如果业务成功,则通过respnse属性获取需要的值
            print("get response trade_no:" + response.trade_no)
        else:
            # 如果业务失败,则从错误码中可以得知错误情况,具体错误码信息可以查看接口文档
            print(response.code + "," + response.msg + "," + response.sub_code + "," + response.sub_msg)


    """
    带文件的系统接口示例:alipay.offline.material.image.upload
    """
    # 如果没有找到对应Model类,则直接使用Request类,属性在Request类中
    request = AlipayOfflineMaterialImageUploadRequest()
    request.image_name = "我的店"
    request.image_type = "jpg"
    # 设置文件参数
    f = open("/Users/foo/Downloads/IMG.jpg", "rb")
    request.image_content = FileItem(file_name="IMG.jpg", file_content=f.read())
    f.close()
    response_content = None
    try:
        response_content = client.execute(request)
    except Exception as e:
        print(traceback.format_exc())
    if not response_content:
        print("failed execute")
    else:
        response = AlipayOfflineMaterialImageUploadResponse()
        response.parse_response_content(response_content)
        if response.is_success():
            print("get response image_url:" + response.image_url)
        else:
            print(response.code + "," + response.msg + "," + response.sub_code + "," + response.sub_msg)


    """
    页面接口示例:alipay.trade.page.pay
    """
    # 对照接口文档,构造请求对象
    model = AlipayTradePagePayModel()
    model.out_trade_no = "pay201805020000226"
    model.total_amount = 50
    model.subject = "测试"
    model.body = "支付宝测试"
    model.product_code = "FAST_INSTANT_TRADE_PAY"
    settle_detail_info = SettleDetailInfo()
    settle_detail_info.amount = 50
    settle_detail_info.trans_in_type = "userId"
    settle_detail_info.trans_in = "2088302300165604"
    settle_detail_infos = list()
    settle_detail_infos.append(settle_detail_info)
    settle_info = SettleInfo()
    settle_info.settle_detail_infos = settle_detail_infos
    model.settle_info = settle_info
    sub_merchant = SubMerchant()
    sub_merchant.merchant_id = "2088301300153242"
    model.sub_merchant = sub_merchant
    request = AlipayTradePagePayRequest(biz_model=model)
    # 得到构造的请求,如果http_method是GET,则是一个带完成请求参数的url,如果http_method是POST,则是一段HTML表单片段
    response = client.page_execute(request, http_method="GET")
    print("alipay.trade.page.pay response:" + response)


    """
    构造唤起支付宝客户端支付时传递的请求串示例:alipay.trade.app.pay
    """
    model = AlipayTradeAppPayModel()
    model.timeout_express = "90m"
    model.total_amount = "9.00"
    model.seller_id = "2088301194649043"
    model.product_code = "QUICK_MSECURITY_PAY"
    model.body = "Iphone6 16G"
    model.subject = "iphone"
    model.out_trade_no = "201800000001201"
    request = AlipayTradeAppPayRequest(biz_model=model)
    response = client.sdk_execute(request)
    print("alipay.trade.app.pay response:" + response)
pypi社区上支付宝官方案例

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from alipay.aop.api.AlipayClientConfig import AlipayClientConfig
from alipay.aop.api.DefaultAlipayClient import DefaultAlipayClient
from alipay.aop.api.domain.AlipayTradePagePayModel import AlipayTradePagePayModel
from alipay.aop.api.request.AlipayTradePagePayRequest import AlipayTradePagePayRequest
from rest_framework.views import APIView
from rest_framework.response import Response
from django.shortcuts import render, redirect, HttpResponse


def alipayclient():
    """
    设置配置,包括支付宝网关地址、app_id、应用私钥、支付宝公钥等,其他配置值可以查看AlipayClientConfig的定义。
    """
    alipay_client_config = AlipayClientConfig()
    alipay_client_config.server_url = 'https://openapi.alipay.com/gateway.do'
    alipay_client_config.app_id = '您的app_Id'
    with open("keys/private_key.txt") as f:
        alipay_client_config.app_private_key = f.read()
    # 阿里的公钥
    with open("keys/public_key.txt") as f:
        alipay_client_config.alipay_public_key = f.read()

    """
    得到客户端对象。
    注意,一个alipay_client_config对象对应一个DefaultAlipayClient,定义DefaultAlipayClient对象后,alipay_client_config不得修改,如果想使用不同的配置,请定义不同的DefaultAlipayClient。
    logger参数用于打印日志,不传则不打印,建议传递。
    """
    client = DefaultAlipayClient(alipay_client_config=alipay_client_config)
    return client


"""
系统接口示例:alipay.trade.pay
"""


class AlipayView(APIView):
    def get(self, request):
        return render(request, 'pay.html')

    def post(self, request):
        money = request.data.get('money')
        if not money.isdigit():
            return Response('错误,只能是数字')
        money = int(money)
        client = alipayclient()

        """
        页面接口示例:alipay.trade.page.pay
        """
        # 对照接口文档,构造请求对象
        model = AlipayTradePagePayModel()
        import time
        model.out_trade_no = 'pay201805020000226'
        model.total_amount = money
        model.subject = "测试"
        model.body = "支付宝测试"
        model.product_code = "FAST_INSTANT_TRADE_PAY"
        request = AlipayTradePagePayRequest(biz_model=model)
        # 得到构造的请求,如果http_method是GET,则是一个带完成请求参数的url,如果http_method是POST,则是一段HTML表单片段
        response = client.page_execute(request, http_method="GET")
        print("alipay.trade.page.pay response:" + response)
        return redirect(response)
views

 

from django.contrib import admin
from django.urls import path
from app.views import AlipayView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('pay/',AlipayView.as_view()),
]
urls

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>支付宝电脑端支付-话费充值</title>
</head>
<body>

<form method="post">
    {% csrf_token %}
    <label for="money">金额:</label>
    <input type="
登录查看全部

参与评论

评论留言

游客
2019-08-08 16:28

游客
2019-09-05 15:32

123

浏览 2966.56 万次 点击这里给我发消息

手机查看

返回顶部

给这篇文章打个标签吧~

棒极了 糟糕透顶 好文章 PHP JAVA JS 小程序 Python SEO MySql 确认