【24.0】支付相关

发布时间 2023-08-19 17:25:38作者: Chimengmeng

【一】支付课程功能

  • 购买课程,付款

    • 在购买课程时,用户可以选择不同的支付方式进行付款,如支付宝支付、微信支付或者银联支付。
  • 支付宝支付(即便没有账号,也可以测试)

    • 支付宝支付是一种方便快捷的支付方式,用户可以使用支付宝账号或者通过扫描二维码等方式完成支付。
    • 对于没有支付宝账号的用户,我们可以提供游客支付功能,允许用户以游客身份进行支付并完成购买。
  • 微信支付(需要用营业执照申请商家帐号)

    • 微信支付是一种广泛使用的支付方式,用户可以通过微信账号进行支付。
    • 然而,为了接入微信支付功能,您需要拥有一个营业执照并申请微信商家帐号。
    • 一旦获得商家帐号,我们将嵌入微信支付功能,让用户能够使用微信进行支付。
  • 银联支付

    • 银联支付是指用户通过银联借记卡、信用卡等银联渠道进行支付的方式。
    • 我们可以集成银联支付接口,使用户能够使用银联支付完成课程购买。
  • 通过以上支付方式的完善,您的平台将能够提供多样化的支付选择,让用户在购买课程时更加便捷和灵活。

【二】支付宝支付官方文档

【三】集成支付宝流程

【1】后端

  • 我们自己的网站:点击购买按钮
  • 向我们后端发送请求
  • 携带购买商品信息
  • 生成订单,入库,订单是未支付状态
  • 生成支付宝支付链接
  • 返回给前端
  • 用户在我们的网站点击购买按钮。
  • 前端将购买商品信息通过向后端发送请求进行传递。
  • 后端接收到请求后,生成一个未支付状态的订单,并将订单信息存入数据库。
  • 后端向支付宝发起请求,生成支付宝支付链接,并将该链接返回给前端。

【2】前端

  • 前端拿到支付链接
  • get请求打开
  • 咱们的前端就来到了支付宝的页面
  • 用户掏出手机扫描支付
  • 付款完成
  • 支付宝收到了钱
  • get回调(咱们配置回调地址)
  • 跳回我们自己的网页
  • 支付宝还会发送post请求给我们后端
  • 我们要验签,通过后,把订单状态改为已支付状态
  • 前端接收到支付宝支付链接后,在浏览器中通过GET请求打开该链接,进入支付宝页面。
  • 用户使用支付宝客户端扫描二维码或者进行其他授权登录的方式完成付款操作。
  • 支付宝收到用户的付款后,会进行相应的处理,并向事先配置好的回调地址发送POST请求。
  • 后端根据支付宝的回调请求,验证支付结果的真实性,并确保未被篡改。
  • 验签通过后,后端将对应的订单状态改为已支付,并进行相应的业务逻辑处理,如生成课程访问权限等。
  • 最后,后端向支付宝返回一个成功响应,以确认支付宝已经成功收到了回调信息。

【四】使用第三方sdk

【1】安装SDK:

  • 通过运行以下命令安装支付宝SDK。
pip install python-alipay-sdk --upgrade
  • 要使用支付宝:
    • 需要营业执照注册,咱们没有,咱们使用沙箱环境测试
    • 测试通过,后期只要换成公司的商户号和支付宝公钥私钥即可

【2】沙箱环境:

  • 可以下载沙盒版支付宝

【3】生成公钥私钥

  • 需要生成公钥私钥:非对称加密(公钥加密,私钥解密)
  • https://opendocs.alipay.com/common/02kipl
    • 生成公钥私钥:按照支付宝提供的文档说明,生成自己的公钥和私钥对。
    • 可以参考非对称加密
  • 生成公钥和私钥
  • 把你的公钥,配置在支付宝账号里,生成支付宝公钥
    • 写支付,需要用支付宝公钥和私钥
  • 下载客户端

  • 一路下一步安装

  • 生成公钥和私钥

  • 打开文件位置,将公钥私钥文件复制到指定位置

【4】上传公钥

  • 上传公钥至支付宝开放平台
    • 公钥模式

  • 上传成功后会生成支付宝公钥(我们使用支付宝公钥)

【5】使用生成的公私钥

  • 支付宝公钥(PUBLIC KEY)
    • 网页上获取
    • 注意格式
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAptkXVjUkA21vOW+h7FrW
68sooGwRqZCT3c8zcP7WLwwvKzwpiU5l+oX7yMoEes9qa7TCZd6YySxoYAdi1u9R
6Bi5YOeWCKGfh5ijbaWU9vH5k/qgWzCkWMSu0ZDyV0rMnQHigrnlEWGNOdMxglTJ
EeuiIGLi7i/3loFUjwCfXq8bkEcylTMMGiXGh88qevG0SbVA8RBNO37tHsRtSD/M
U1hIcjTDMH5+yiLGKVx1OjdOlX0nrjTivM0i9uQn0NZaBBVT7SVT/CykmpSLxX5P
tTJ+I56uRUpeQyRd+vaeTdqrmTFmpG3Nd0nUJV0wWespzOBgg+fYG9Sd7yoEb8g2
JwIDAQAB
-----END PUBLIC KEY-----
  • 支付宝私钥
    • 客户端生成的私钥
    • 注意格式
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAptkXVjUkA21vOW+h7FrW68sooGwRqZCT3c8zcP7WLwwvKzwp
iU5l+oX7yMoEes9qa7TCZd6YySxoYAdi1u9R6Bi5YOeWCKGfh5ijbaWU9vH5k/qg
WzCkWMSu0ZDyV0rMnQHigrnlEWGNOdMxglTJEeuiIGLi7i/3loFUjwCfXq8bkEcy
lTMMGiXGh88qevG0SbVA8RBNO37tHsRtSD/MU1hIcjTDMH5+yiLGKVx1OjdOlX0n
rjTivM0i9uQn0NZaBBVT7SVT/CykmpSLxX5PtTJ+I56uRUpeQyRd+vaeTdqrmTFm
pG3Nd0nUJV0wWespzOBgg+fYG9Sd7yoEb8g2JwIDAQABAoIBAAHQsNFOSLME2MXu
MfvJTTdJgYqlQlfu67zpCS08iIYAgu7ce7MzuCZOmNupXv0bDpRXZhoHnu/pXMVW
rzuZZPG6eyHTwy0a3QpznauOtp0tKsLyYhY75D3W/fPnuMs8VBeNMrKrZROYVRoA
8zPwyjM4tg3WJZPjz7TCeXII1rMH/ivumSwMuM5ZI1G+lnga6wnicC7XcpoRqBGb
5IHti9g65E1/Al1NwfIfvubppoM1IkrFSW1vIBBwJ/xIBBMR3eCCpNzMzYLf01Kf
qcLqtNHPCKu3h/DS8+8Ldmbo2Gmk/rF4EM2ON2ctqnh35VnfYNbkdLtVRKN/I3Y3
5fwWv7kCgYEA1ZAs5MYoWyg2CVDoYTMeDPK4eauUp9j/PkW8CKhe2zqL/aYWRnON
w/ssYVzIezGu2Y28U0lancNJlPLvPDQTAU3njkK9qOCFoP6RfaO1iIqbra4pUdCL
ozJsreIsFxyDUn7UuaO1RQCfLvijC2qHTMrVRmDRDS+wGLdlO10yGhMCgYEAyACL
Xbuw+z4TC4dcegqmXLqhjnEPafTlmkltmi/WQIbCxAQEr5w5Kt+W4MrxiPwX5XIu
oG61G9dTSluQQniFQCk+31uI8qyWEXNx3LwBmhnEPbLIbHxSvqgXwHq40bLPgd4g
+fmIb4wvQmOHlWZU4wO7h1zlQSIUYNN3KJVf9h0CgYAVTUk9FIrn9M3XBgv3zgp8
TiWadUPhriJfisMjte+oPGHETjHAmzwTxVT67S9OInmHV7zmLdXtEJKhWc4FGkif
A69KIFwcoTCTC3Flr9Omp/S5UTrr3zpeb+QpP/sX3w82RlJfpfWpyVMXc1OICvst
7LlzSKrxfsU44eomDri1owKBgBbikQ/hqSeme7FnBLrmOxEDPfc5kqTyI8+atVLe
RGrPwLuDJjId8yCnwvDn5+lfxzA294TeBhUwd1Rb0873UW/9CDewlqQGAYnvpsi2
Loy+hAj3Sx22wBUW0NjycfF0v2/Bxg40clspNEMpdlsvAWmUhMHBbG4egyxtJgZb
yUY1AoGAEGobZAoEpc6Px2tDJx7p0ePrs6857Ge2+2yeiYY4xPTrF8xsD732V7rY
jJW2V7ETn9LKXPAlFdZUv0OQ0JYD3sHnyz7puVV5xEqPB+rXVCAypVCdWZoQKJ+a
N4mQ0bHgc2JgO5EMu1GYa2uIEobWpaiMR+1qIIaq/ok/FCajtHA=
-----END RSA PRIVATE KEY-----

【五】模拟简单的支付流程

# -*-coding: Utf-8 -*-
# @File : pay .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/8/13


from alipay import AliPay, DCAliPay, ISVAliPay
from alipay.utils import AliPayConfig

# 私钥和支付宝公钥 需要去支付宝官网申请
# 只能使用测试环境:沙箱环境
app_private_key_string = open("pem/private.key").read()
alipay_public_key_string = open("pem/alipayPublic.key").read()

alipay = AliPay(
    appid="9021000125626535",  # 支付宝页面上复制,沙箱环境---》公司有人会给你
    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)  # 可选,请求超时时间
)

# 订单标题
subject = '兰博基尼'

# 订单号(唯一)
order_string = alipay.api_alipay_trade_page_pay(
    out_trade_no="201102102102102102",
    total_amount=644491.03,
    subject=subject,
    return_url="https://example.com",
    notify_url="https://example.com/notify"  # 可选,不填则使用默认 notify url
)

# https://openapi.alipaydev.com/gateway.do? : 支付宝网关
print('https://openapi.alipaydev.com/gateway.do?' + order_string)
  • 运行程序生成链接
https://openapi-sandbox.dl.alipaydev.com/gateway.do?app_id=9021000125626535&biz_content=%7B%22subject%22%3A%22%5Cu5170%5Cu535a%5Cu57fa%5Cu5c3c%22%2C%22out_trade_no%22%3A%22201102102102102102%22%2C%22total_amount%22%3A644491.03%2C%22product_code%22%3A%22FAST_INSTANT_TRADE_PAY%22%7D&charset=utf-8&method=alipay.trade.page.pay&notify_url=https%3A%2F%2Fexample.com%2Fnotify&return_url=https%3A%2F%2Fexample.com&sign_type=RSA2&timestamp=2023-08-13+18%3A17%3A45&version=1.0&sign=ZDN1pYlK3x%2BQorh7LI5F3fKTUz2ZH5A3JbBW7Ash4a1VsGDdhF9ApsC2TzqVebH9STuRtuZGdx%2Ft3MnsICYZeiVfznupuVTX7AJyKWE9YTyoUTzq%2F%2FnQHCGRTK0ipAOIuwERWJ43A8VPfcgUnJz0eCzHSZZT263MdX5%2Fsc4fsVhxYsxbBNymG8qjfqd9Z6eqnjyti93do1ZLoA8onP5xBeYAWck9TJpvOK8CyGQKFDoNcU7w6vUaBC8Zpv9fPbOR8X9L7Jb0NXcpmNdtYKQ2vi1TTC%2BNwuaFC0RK%2F8SHF8CG9MGoa%2FecnWiXW589A9xe6JaDhkvSTKIJAfBqESErkw%3D%3D
  • 打开链接

  • 可以选择平台提供的账号进行付款,也可以选择app

  • 付款完成

【六】aliapy二次封装包

【1】GitHub开源框架

【2】依赖

pip install python-alipay-sdk --upgrade
  • 如果抛ssl相关错误,代表缺失该包
pip install pyopenssl

【3】结构树

libs
    ├── iPay  							# aliapy二次封装包
    │   ├── __init__.py 				# 包文件
    │   ├── pem							# 公钥私钥文件夹
    │   │   ├── alipay_public_key.pem	# 支付宝公钥文件
    │   │   ├── app_private_key.pem		# 应用私钥文件
    │   ├── pay.py						# 支付文件
    └── └── settings.py  				# 应用配置  

【4】封包

  • __init__ .py
# -*-coding: Utf-8 -*-
# @File : __init__ .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/8/13

from .pay import ALiPay
  • pay .py
# -*-coding: Utf-8 -*-
# @File : pay .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/8/13
from alipay import AliPay, DCAliPay, ISVAliPay
from alipay.utils import AliPayConfig
from . import settings


class ALiPay():
    def __init__(self):
        '''

        :param appid: 支付宝页面上复制,沙箱环境---》公司有人会给你
        :param app_notify_url: 默认回调 url
        :param app_private_key_string: 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
        :param alipay_public_key_string: 支付宝的私钥
        :param sign_type: 加密方式 RSA 或者 RSA2
        :param debug: 调试模式
        :param verbose: 输出调试数据
        :param config: 可选,请求超时时间
        '''

        # 生成支付对象
        self.alipay = AliPay(
            appid=settings.APP_ID,
            app_notify_url=None,
            app_private_key_string=settings.APP_PRIVATE_KEY_STRING,
            alipay_public_key_string=settings.ALIPAY_PUBLIC_KEY_STRING,
            sign_type=settings.SIGN,
            debug=settings.DEBUG,
            verbose=False,
            config=AliPayConfig(timeout=15)
        )
        # 支付网关
        self.gateway = settings.GATEWAY

    def create_order_url(self, order_id, total_amount, order_name, return_url="https://example.com", notify_url="https://example.com/notify"):
        '''

        :param order_id: 订单ID号
        :param total_amount: 订单总金额
        :param subject: 订单名称
        :param return_url: 回调 url
        :param notify_url: 可选,不填则使用默认 notify url
        :return:
        '''
        order_string = self.alipay.api_alipay_trade_page_pay(
            out_trade_no=order_id,
            total_amount=total_amount,
            subject=order_name,
            return_url=return_url,
            notify_url=notify_url
        )

        return self.gateway + order_string
  • settings .py
# -*-coding: Utf-8 -*-
# @File : settings .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/8/13
import os

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

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

# 应用ID
APP_ID = '9021000125626535'

# 加密方式
SIGN = 'RSA2'

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

# 支付网关
GATEWAY = 'https://openapi-sandbox.dl.alipaydev.com/gateway.do?' if DEBUG else 'https://openapi.alipay.com/gateway.do?'
  • 使用
# 导入支付包
from luffyCity.libs.ALiPaySDK import ALiPay

# 生成支付对象
pay = ALiPay()
# 订单号
order_id = "201102102102102150"
# 订单总价
total_amount = 644491.03
# 订单名称
order_name = '兰博基尼'
# 生成付款链接
order_url = pay.create_order_url(order_id=order_id, total_amount=total_amount, order_name=order_name)