python实现支付宝支付

支付宝支付基本使用

第一步:测试用支付宝的沙箱环境:支付宝开放平台 (alipay.com)

第二步:生成公钥私钥:生成密钥 - 支付宝文档中心 (alipay.com)

第三步:配置公钥私钥

image

image

image

第三步:安装模块

pip install python-alipay-sdk

第四步:基本使用

from alipay import AliPay
from alipay.utils import AliPayConfig

app_private_key_string = open("./应用私钥2048.txt").read()
alipay_public_key_string = open("./支付宝公钥.txt").read()

# 应用私钥格式
"""
-----BEGIN RSA PRIVATE KEY-----
base64 encoded content
-----END RSA PRIVATE KEY-----
"""
# 支付宝公钥格式
"""
-----BEGIN PUBLIC KEY-----
base64 encoded content
-----END PUBLIC KEY-----
"""

alipay = AliPay(
    appid="2021000121627616",
    app_notify_url=None,  # 默认回调 url
    app_private_key_string=app_private_key_string,
    # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
    alipay_public_key_string=alipay_public_key_string,
    sign_type="RSA2",  # RSA 或者 RSA2
    debug=False,  # 默认 False
    verbose=False,  # 输出调试数据
    config=AliPayConfig(timeout=15)  # 可选,请求超时时间
)

res = alipay.api_alipay_trade_page_pay(
    out_trade_no='1000101',  # 订单号
    total_amount=float(999),  # 价格
    subject='气球',  # 名称
    return_url='http://127.0.0.1:8080/pay/success/',  # 支付成功后会跳转的页面
    notify_url='http://127.0.0.1:8000/order/',  # 回调地址,支付成功后支付宝会向这个地址发送post请求
)

gataway = 'https://openapi.alipaydev.com/gateway.do?'
# 支付链接
pay_url = gataway + res
print(pay_url)

访问支付链接,用沙箱账户登录支付

image

支付成功后,会跳转到代码中写的地址(http://127.0.0.1:8080/pay/success/),完整链接:

http://127.0.0.1:8080/pay/success/?charset=utf-8&out_trade_no=b61383d0-b804-45a6-a4f6-f8e3864d5f72&method=alipay.trade.page.pay.return&total_amount=299.00&sign=WSiaf7RiET4dGrfZ%2FbkhzOIHfv%2FxhX93lvBBpzV7iRUv6rqJsSycAze6UYPX0tA0EniC55UfOeYBLQbmrap4B1m%2FhnINaJRlh%2FNjno00wwHa434l6XxeNCaxSMiRk%2FKURe6KVMJI9Yhutdr23XwusshZ0CGIVSzT16ce8bclDIyL9t7HCjN%2Bm3GCSGHSDJxTogsCor0DhLV%2Fzaqivy3RtTYkZty4imILU2X%2BKyT7Jdjs2bHeV4Nc535q0g6juvFmw1NSHFmEafxuc%2B7apa4y3zAoCqa2ONUk9KgTMwhZAZf4rmBTOdql6nVHAFqsOjdEVE0A90HQCu8bazT1lYg1Ug%3D%3D&trade_no=2022072022001488050501648873&auth_app_id=2021000121627616&version=1.0&app_id=1000101&sign_type=RSA2&seller_id=2088621987720703&timestamp=2022-07-20%2017%3A19%3A44

比较有用的参数:

out_trade_no=64d01b38-fa0d-4cb9-98d6-e425475022c1  # 订单号
total_amount=299.00   #订单价格
trade_no=2022072022001479300501762515  # 支付宝流水号
timestamp=2022-07-20%2009%3A33%3A47  # 支付时间

回调地址

支付宝支付成功后,会向我们写的地址,也就是上面写的参数

notify_url='http://127.0.0.1:8000/order/'

但是要注意,支付宝是无法向我们的http://127.0.0.1:8000发送请求的,这是只有我们自己才能访问的地址,所以这里需要填公网ip,也就是需要租一台服务器,让支付宝可以向这个服务器发送请求。

class PaySuccessView(ViewSet):
    # 给前端做二次校验用
    def list(self, request):
        out_trade_no = request.query_params.get('out_trade_no')
        order = models.Order.objects.filter(out_trade_no=out_trade_no, order_status=1).first()
        if order:
            return Response({'code': 100, 'msg': '支付成功'})
        else:
            return Response({'code': 99, 'msg': '暂时还没收到你的付款'})

    # 给支付宝用的--->必须把项目部署在公网上才能回调成功
    def create(self, request):
        try:
            # post提交的数据(支付宝回调格式:urlencoded,QueryDic)
            # 把QueryDic对象转成真正的dict对象
            result_data = request.data.dict()
            # 我们的订单号
            out_trade_no = result_data.get('out_trade_no')
            # 支付宝的签名
            signature = result_data.pop('sign')
            # 导入alipay对象
            from libs.ali_pay import alipay
            # 固定格式
            result = alipay.verify(result_data, signature)
            if result and result_data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
                # 完成订单修改:订单状态、流水号、支付时间
                models.Order.objects.filter(out_trade_no=out_trade_no).update(order_status=1)
                # 完成日志记录
                logger.warning('%s订单支付成功' % out_trade_no)
                # 支付宝要的格式就这个格式
                return Response('success')
            else:
                logger.error('%s订单支付失败' % out_trade_no)
        except:
            pass
        return Response('failed')

流程图

image

二次封装

二次封装方便项目使用

包目录结构:

包名
├── __init__.py
├── pem -- 存放公钥私钥文件夹
├    ├── alipay_public_key.pem -- 支付宝公钥
├    └── app_private_key.pem -- 应用私钥
├── pay.py -- 生成一个alipay对象
└── settings.py -- 配置文件

__init.py__

from .pay import alipay
from .settings import GATEWAY

settings.py

import os

# 应用私钥
APP_PRIVATE_KEY_STRING = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'pem', 'app_private_key.pem')).read()

# 支付宝公钥
ALIPAY_PUBLIC_KEY_STRING = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'pem', 'alipay_public_key.pem')).read()

# 应用ID
APP_ID = '100'

# 加密方式
SIGN = 'RSA2'

# 是否是支付宝测试环境(沙箱环境),如果采用真是支付宝环境,配置False
DEBUG = True

# 支付网关
GATEWAY = 'https://openapi.alipaydev.com/gateway.do?' if DEBUG else 'https://openapi.alipay.com/gateway.do?'

pay.py

from alipay import AliPay
from alipay.utils import AliPayConfig

from . import settings
alipay = AliPay(
    appid=settings.APP_ID,
    app_notify_url=None,  # 默认回调 url
    app_private_key_string=settings.APP_PRIVATE_KEY_STRING,
    # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
    alipay_public_key_string=settings.ALIPAY_PUBLIC_KEY_STRING,
    sign_type=settings.SIGN,  # RSA 或者 RSA2
    debug=settings.DEBUG,  # 默认 False
    verbose=False,  # 输出调试数据
    config=AliPayConfig(timeout=15)  # 可选,请求超时时间
)

项目中使用:

# 导入包中的alipay对象和GATEWAY网关接口
res = alipay.api_alipay_trade_page_pay(
    out_trade_no='1000101',  # 订单号
    total_amount=float(999),  # 价格
    subject='气球',  # 名称
    return_url='http://127.0.0.1:8000',
    notify_url='http://127.0.0.1:8000',
)

pay_url = GATEWAY + res
print(pay_url)
posted @ 2022-07-19 18:43  Yume_Minami  阅读(1404)  评论(0编辑  收藏  举报