• 支付宝支付接入流程


    一、 接入准备

    支付宝支付流程没有微信那么复杂,而且支付宝支持沙箱。登录支付宝开放平台控制台

    在这里插入图片描述

    点击开发工具中的沙箱

    在这里插入图片描述
    接口加密方式,我这里使用的是自定义密钥。生成密钥的方式

    1. 使用支付宝官方提供的密钥工具,唯一要注意的是支付宝密钥工具生成的是 txt 格式的,也就是不包含头部和尾部标识的
      -----BEGIN PUBLIC KEY-----
      
      -----END PUBLIC KEY-----
      
      • 1
      • 2
      • 3
    2. 使用 openssl 命令自己生成。
      openssl
      OpenSSL> genrsa -out app_private_key.pem 2048  #  私钥
      OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem  #  导出公钥
      OpenSSL> exit
      
      • 1
      • 2
      • 3
      • 4

    我们需要的东西基本都有了。调试的使用可以下载工具支付宝客户端沙箱版 ,用沙箱账号进行支付。

    二、支付方式

    支付宝支持的支付方式有如下几种:
    在这里插入图片描述
    我这边使用的是手机网站支付电脑网站支付APP 支付当面付
    这里重点提一下开通当面付,当面付是需要提供店铺材料的。需要做微信支付、支付宝支付二码合一的时候会用这个。其他几个上架应用之后开通问题都不大

    三、流程图

    在这里插入图片描述

    四、代码

    import logging
    from enum import Enum
    
    from Cryptodome.PublicKey import RSA
    from alipay import AliPay, AliPayConfig
    
    """
    支付宝支付接入
    SDK 文档:https://gitee.com/yqmc/alipay/blob/master/README.zh-hans.md
    pip install python-alipay-sdk --upgrade
    """
    
    
    class AlipayType(Enum):
        WEB = 'web'  # 电脑网站支付
        WAP = 'wap'  # 手机网站支付
        APP = 'app'  # app支付
        MINI = 'mini'  # 小程序支付
    
    
    class AliPayClient:
        def __init__(self, appid, app_private_key_path, alipay_public_key_path, is_sandbox=False, default_notify_url=None,
                     return_url=None):
            """
            初始化数据
            :param appid: APP ID
            :param app_private_key_path: 应用私钥路径
            :param alipay_public_key_path: 支付宝公钥路经
            :param is_sandbox:  是否是沙箱模式
            :param default_notify_url:  默认通知地址
            """
            self.appid = appid
            self.default_notify_url = default_notify_url
            self.return_url = return_url
            self.sandbox = is_sandbox
            self.alipay_gateway_url = 'https://openapi.alipay.com/gateway.do?' if not self.sandbox else 'https://openapi-sandbox.dl.alipaydev.com/gateway.do?'
            self.app_private_key_string = self.read_secret(app_private_key_path)
            self.alipay_public_key_string = self.read_secret(alipay_public_key_path)
            self.alipay = AliPay(
                appid=self.appid,
                app_notify_url=self.default_notify_url,
                app_private_key_string=self.app_private_key_string,
                alipay_public_key_string=self.alipay_public_key_string,
                sign_type="RSA2",
                debug=self.sandbox,
                verbose=True,  # 输出调试数据
                config=AliPayConfig(timeout=15)  # 可选,请求超时时间
            )
            if self.sandbox:
                logging.debug('当前为沙箱环境')
    
        @staticmethod
        def read_secret(secret_path, import_key=False):
            """
            从文件加载秘钥
            :param secret_path:
            :param import_key: 是否需要导入秘钥
            :return:
            """
            with open(secret_path, "r") as fp:
                return RSA.importKey(fp.read()) if import_key else fp.read()
    
        def create_order(self, out_trade_no, amount, subject, notify_url=None, return_url=None,
                         pay_type=AlipayType.WEB.value):
            """
             创建支付订单
            :param out_trade_no: 订单号
            :param amount: 金额
            :param subject: 订单备注
            :param notify_url: 通知地址
            :param return_url: 回调地址
            :param pay_type: AlipayType支付类型
            :return: order_string
            """
            trade_client = {
                AlipayType.WEB.value: self.alipay.api_alipay_trade_page_pay,
                AlipayType.WAP.value: self.alipay.api_alipay_trade_wap_pay,
                AlipayType.APP.value: self.alipay.api_alipay_trade_app_pay,
                AlipayType.MINI.value: self.alipay.api_alipay_trade_create
            }
            kwargs = dict(
                out_trade_no=out_trade_no,
                total_amount=amount,
                subject=subject,
                notify_url=notify_url
            )
            pay_type in [AlipayType.WEB.value, AlipayType.WAP.value] and kwargs.update(return_url=return_url)
            order_string = trade_client[pay_type](**kwargs)
            return self.alipay_gateway_url + order_string
    
        def create_pre_order(self, subject, out_trade_no, amount, notify_url=None):
            """
            交易预创建(扫码支付)
            :param subject: 订单备注
            :param out_trade_no: 订单号
            :param amount: 金额
            :param notify_url: 通知地址
            return {'code': '10000', 'msg': 'Success', 'out_trade_no': '2023102401', 'qr_code': 'https://qr.alipay.com/bax01636yklunuyxijpc002f'}
            """
            resp = self.alipay.api_alipay_trade_precreate(
                subject=subject,
                out_trade_no=out_trade_no,
                total_amount=amount,
                notify_url=notify_url
            )
            return resp
    
        def refund(self, out_trade_no, refund_amount):
            result = self.alipay.api_alipay_trade_refund(out_trade_no=out_trade_no, refund_amount=refund_amount)
            return True if result.get("code") == "10000" else False
    
        def notify_verify(self, data):
            """
            验证回调通知:验证 alipay 的异步通知
             :param data:  来自支付宝回调 POST 给你的 data,字典格式。
                            data = {
                                 "subject": "测试订单",
                                 "gmt_payment": "2016-11-16 11:42:19",
                                 "charset": "utf-8",
                                 "seller_id": "xxxx",
                                 "trade_status": "TRADE_SUCCESS",
                                 "buyer_id": "xxxx",
                                 "auth_app_id": "xxxx",
                                 "buyer_pay_amount": "0.01",
                                 "version": "1.0",
                                 "gmt_create": "2016-11-16 11:42:18",
                                 "trade_no": "xxxx",
                                 "fund_bill_list": "[{\"amount\":\"0.01\",\"fundChannel\":\"ALIPAYACCOUNT\"}]",
                                 "app_id": "xxxx",
                                 "notify_time": "2016-11-16 11:42:19",
                                 "point_amount": "0.00",
                                 "total_amount": "0.01",
                                 "notify_type": "trade_status_sync",
                                 "out_trade_no": "xxxx",
                                 "buyer_logon_id": "xxxx",
                                 "notify_id": "xxxx",
                                 "seller_email": "xxxx",
                                 "receipt_amount": "0.01",
                                 "invoice_amount": "0.01",
                                 "sign": "xxx"
                            }
            """
            signature = data.pop("sign")
    
            # verification
            success = self.alipay.verify(data, signature)
            return success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
  • 相关阅读:
    7.zigbee开发,低功耗,通信加密开发
    python-文件操作常用功能-2
    【算法与数据结构】491、LeetCode递增子序列
    【NLP的Python库(04/4)】:Flair
    机器学习模型评价指标
    掌握这十个Linux命令,秒变Linux老手
    数据结构与算法(C语言版)P8---树、二叉树、森林
    【Go学习之 go mod】gomod小白入门,在github上发布自己的项目(项目初始化、项目发布、项目版本升级等)
    FPGA的通用FIFO设计verilog,1024*8bit仿真,源码和视频
    抖音seo短视频矩阵SaaS源码部署--开源搭建(一)
  • 原文地址:https://blog.csdn.net/weixin_44777680/article/details/134057795