Django对接支付宝沙箱环境(2024年9月新测有效)

1、申请沙箱环境
bash 复制代码
#需要填一些个人信息
https://opendocs.alipay.com/

2、使用支付宝登入,并进入控制台,进入'开发者工具推荐'-->'沙箱'

3、获取基本信息

主要是APPID,和支付宝网关地址

4、生成应用私钥和应用公钥和支付宝公钥

上面的接口加签方式选择系统默认密钥

注:这里有个坑,如果选择自定密钥,后面回调验签会不成功。

点击查看,可以看到应用私钥和应用公钥和支付宝公钥

6、沙箱账号

这里用商家和买家的账号信息,也可以进行充值

7、下载支付宝沙箱APP
8、在手机上用买家账号和密码登入登入支付宝沙箱APP
9、下载并安装支付宝SDK
bash 复制代码
pip3 install alipay-sdk-python
10、生成支付链接

在视图函数中调用止函数即可生成支付链接。

python 复制代码
import logging
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

def alpay_page(order_id,total_amount,subject,return_url,notify_url):
	"""
        功能:网页生成支付宝支付页面
        :param order_id:订单号(str)
        :param total_amount:订单金额(float)
        :param subject:订单标题
        :param return_url:同步回调地址
        :param notify_url:异步回调地址
    """
 
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s %(levelname)s %(message)s',
        filemode='a', )
    logger = logging.getLogger('')


    """
        设置配置,包括支付宝网关地址、app_id、应用私钥、支付宝公钥等,其他配置值可以查看AlipayClientConfig的定义。
        """
    alipay_client_config = AlipayClientConfig()        #创建用户对象配置文件         
    alipay_client_config.server_url = project1.settings.gateway     #支付宝网关
    alipay_client_config.app_id = project1.settings.APPID           #支付宝APPID
    alipay_client_config.app_private_key = project1.settings.private_key   #应用私钥
    alipay_client_config.alipay_public_key = project1.settings.public_key  #支付宝公钥
    alipay_client_config.charset = 'utf-8'   

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

    model = AlipayTradePagePayModel()
    model.out_trade_no = order_id
    model.total_amount = total_amount
    model.subject = 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 = "2088721043828344"
    # model.sub_merchant = sub_merchant
    request = AlipayTradePagePayRequest(biz_model=model)
    request.notify_url = notify_url  # 异步通知回调地址
    request.return_url = return_url  # 同步回调地址
    # 得到构造的请求,如果http_method是GET,则是一个带完成请求参数的url,如果http_method是POST,则是一段HTML表单片段
    response = client.page_execute(request, http_method="GET")
    print("alipay.trade.page.pay response:" + response)
    return response             #返回支付页面url
11、支付宝回调
python 复制代码
@csrf_exempt
def pay_callback(req):
    #支付宝回调函数
    #verify_with_rsa用于验签
    from alipay.aop.api.util.SignatureUtils import verify_with_rsa

    log_file = os.path.join(settings.BASE_DIR, 'uwsgi/uwsgi.log')
    logging.basicConfig(filename=log_file, level=logging.DEBUG,
                        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')


    def visa(data_dict):
        #验签函数
        # 获取并删除sign
        sign = data_dict.pop('sign')
        # 获取并删除sign_type
        sign_type = data_dict.pop('sign_type')
        # 将回传参数排序(按ascii码升序排序)并组合成字符串
        unsigned_str = '&'.join('{}={}'.format(key, data_dict[key]) for key in sorted(data_dict))
        # 将参数字符串编码
        message = unsigned_str.encode('utf-8')
        # 获取支付宝公钥
        public_key = project1.settings.public_key
        # 支付宝回调验签
        try:
            status = verify_with_rsa(public_key, message, sign)
            if status:
                return True
            else:
                return False
        except BaseException as e:
            print(e)
            return False


        if req.method=='POST':
            #异步回调
            logging.debug('异步回调')
            data_dict=req.POST.dict()

            print('data',data_dict)
            if data_dict.get('trade_status')=='TRADE_SUCCESS':
                #判断支付是否成功
                result = visa(data_dict)          #调用验签函数验签
                print('异步回签字结果', result)
                if result:
                    #如果验签成功,则更新订单信息
                    #这里写上你自己的更新订单代码 
                    #验签成功后必须返回'sucess',否则支付宝会一直通过POST方式发送验签信息
                    return HttpResponse('success')
                return HttpResponse('unsuccess')
            return HttpResponse('unsuccess')

    elif req.method=='GET':
        #同步验签
        #获取支付宝回传参数(字典)        
        data_dict=req.GET.dict()
        result=visa(data_dict)                  #调用验签函数验签
        print('同步回签字结果',result)
        if result==True:
            #验签成功则更新订单信息
            #这里写上你自己的更新订单代码 

            context={
                #返回给用户的信息,可自定义                
                'status':True,
                'order':data_dict.get('out_trade_no'),        #订单号                
                'total_amount':data_dict.get('total_amount'), #订单金额
                'trade_no':data_dict.get('trade_no')          #交易流水号


            }


            return render(req,'web/pay_success.html',context)
        else:
            return JsonResponse({'status':False})
相关推荐
这个DBA有点耶3 天前
MVCC深入:Read View、版本链与快照读——InnoDB并发控制的内核
数据库·mysql·架构
DBA_G3 天前
从地面到云霄:GBase数据库在民航三大场景的落地实践
数据库
自由能燃气设备3 天前
商用全预混低氮冷凝锅炉免费方案vs付费方案对比+选型避坑指南
大数据·数据库·人工智能
科创致远3 天前
科创致远 ESOP 系统核心效能与实战价值展示
大数据·数据库·人工智能·精益工程
kybs19913 天前
全球灾害数据分析可视化 毕业设计-附源码66794
vue.js·spring boot·mysql·安全·django·c#·asp.net
2601_962218613 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法
张洛闻Eren3 天前
k8s云原生【第十课】:水平 Pod 自动扩缩容
运维·数据库·云原生·kubernetes·github
醇氧3 天前
Python`__pycache__` 被 Git 跟踪的排查与解决
python·django
于平安3 天前
MySQL-触发器
数据库·mysql
白远山3 天前
上海24小时自助健身房解决方案实战指南与经验分享
java·数据库·架构·需求分析