支付宝收款流程图
- 格式:pdf
- 大小:952.29 KB
- 文档页数:1
实例解析:收银台支付流程介绍本文主要以app端的聚合收银台为例进行介绍(大家可以直接用京东app的收银台为例子进行理解),来看看收银台的支付流程到底是怎样的。
一、收银台及支付方式介绍(1)收银台收银台俗称付款处,是顾客交易付款的地方。
线下支付的时候用户是在商店柜台处选择现金、刷卡等支付方式进行结账,移动支付发展之后用户在线上支付,在收银台处选择支付方式进行付款,收银台是顾客在“商店”最后停留的地方。
(2)支付方式介绍账户支付:基于支付公司的账户体系建立起来的支付方式,是通过账户间转账来完成资金转移的支付方式。
前提是需要用户要在支付公司开立个人支付账户,并且在账户充值才可使用。
举例:微信支付的零钱账户、支付宝的余额账户就是此类。
银行卡支付:银行卡支付分为借记卡和信用卡支付,目前收银台大多是基于协议支付产品从用户银行卡进行资金转移。
微信支付:从收银台跳转至微信app进行支付,包括微信零钱、在微信绑定的银行卡等方式。
支付宝支付:从收银台跳转至支付宝app进行支付,包括支付宝余额、花呗、在支付宝绑定的银行卡等方式。
其他支付方式:例如京东的白条、钢镚、小金库等支付方式二、收银台支付流程(1)收银台支付流程注:用户选择已有支付方式进行支付时,若未设置支付密码,则走下发验证码流程,此流程同绑卡支付发短信流程。
(2)用户操作路径此流程需要注意的几个点:订单有效时间:订单有效时常设置,超时未支付,收银台主动关单。
验证码发送次数限制:同一手机号某一时段发送次数限制,设置风控规则。
验证码预填功能:提升用户体验。
用户收不到验证码的处理逻辑:给用户准备收不到验证码这种异常case的处理提示。
支付成功/失败跳转逻辑:支付成功/失败后跳转URL,一般由下单方接口上送。
注:忘记密码流程图省略三、收银台功能介绍1. 功能(1)支付方式展示1)支付方式分类聚合收银台汇集了多种支付渠道的支付方式,从品牌上来分主要分为自品牌支付和其他三方支付。
海外旗舰店操作指南海外旗舰店操作指南1. 注册与登录1.1 注册一个账号1.2 完善账号信息1.3 并安装方式应用1.4 登录账号2. 绑定银行卡2.1 打开应用2.2 进入“我的”页面2.3 “银行卡管理”2.4 “添加银行卡”2.5 输入银行卡信息2.6 验证银行卡2.7 设置支付密码3. 充值与提现3.1 充值账户3.1.1 选择充值方式3.1.2 输入充值金额3.1.3 确认充值信息3.1.4 完成充值3.2 提现账户3.2.1 进入“我的”页面 3.2.2 “余额提现”3.2.3 输入提现金额3.2.4 选择提现到银行卡 3.2.5 输入银行卡密码 3.2.6 确认提现信息3.2.7 完成提现4. 支付与转账4.1 使用二维码进行支付4.1.1 扫描商家的二维码 4.1.2 输入支付金额4.1.3 确认支付信息4.1.4 输入支付密码4.1.5 完成支付4.2 转账给他人4.2.1 进入“转账”页面4.2.2 输入对方账号或者方式号 4.2.3 输入转账金额4.2.4 确认转账信息4.2.5 输入支付密码4.2.6 完成转账5. 账户安全与设置5.1 设置支付密码5.2 设置登录密码5.3 开启指纹或者面部识别5.4 绑定方式号5.5 设置支付限额5.6 实名认证5.7 关联其他社交账号6. 附件本文档涉及的附件包括:- 方式应用- 用户注册流程图- 账户安全设置指南7. 法律名词及注释- :是由中国著名的电子商务公司阿里巴巴集团旗下的网络技术有限公司推出的一种第三方支付工具。
- 银行卡:银行出具的具有存款、支付等功能的卡片,用于个人或者企业进行金融交易。
- 充值:向账户中添加资金的过程。
- 提现:从账户中将资金转到绑定的银行卡上的过程。
- 二维码支付:通过扫描商家展示的二维码完成支付的方式。
- 转账:将账户中的资金转移到他人账户的过程。
- 实名认证:对账户进行实名身份验证的过程,提高账户的安全性。
34-⽀付宝⽀付⽀付宝⽀付⼀、快速连接通道1. ⽀付宝<1>. ⽀付宝API:六⼤接⼝<2>. ⽀付宝⼯作流程<3>. ⽀付宝8次异步通知机制(⽀付宝对我们的服务器发送POST请求,索要success7个字符)2. 沙箱环境<1>. 在沙箱环境下实名认证<2>. 电脑⽹站⽀付API<3>. 完成RSA秘钥⽣成<4>. 在开发中⼼的沙箱应⽤下设置应⽤公钥填⼊⽣成的公钥⽂件中的内容<5>. Python⽀付宝开源框架pip install python-alipay-sdk --upgrade<6>. 公钥私钥设置"""# alipay_public_key.pem-----BEGIN PUBLIC KEY-----⽀付宝公钥-----END PUBLIC KEY-----# app_private_key.pem-----BEGIN RSA PRIVATE KEY-----⽤户私钥-----END RSA PRIVATE KEY-----"""<7>. ⽀付宝回调连接⼆、⽀付流程图三、⽀付宝介⼊⼊门1. 流程'''# ⽀付宝开放平台1. 服务范围(⾃研开发服务) -> 实名认证2. 控制台 -> 我的应⽤ -> 创建应⽤ -> ⽹页&移动应⽤ -> ⽀付接⼊ -> 应⽤名称 -> 应⽤图标 ->1) 移动应⽤ -> 应⽤平台 -> Bundle ID ...2) ⽹页应⽤ (不成功. 需要使⽤营业执照) -> ⽹址url -> 简介注意: 先选择功能再审核能⼒列表:添加能⼒ -> ⽀付能⼒ -> 电脑⽹站⽀付 开发设置:加签管理 -> 公钥 -⽀付宝⽹关应⽤⽹关授权回调地址3. ⽂档 -> ⽹页 & 移动应⽤接⼝⽂档能⼒列表1) 开放能⼒:⽀付能⼒ -> 电脑⽹站⽀付2) 产品介绍:注意: 会跳到⽀付宝的页⾯, ⽀付宝会有⼀个get页⾯回调, post数据返回后端回调费率: 0.6%3) 快速接⼊:SDK快速接⼊: python没有, 只能使⽤API开发⽀付流程: 下单 -> 商户系统 -> ⽀付宝 -> 回调(get显⽰订单结果, post修改订单状态)4) ⽀付API:公共请求参数请求参数订单号 out_trade_no总⾦额 total_amount订单标题 subjet公共响应参数⽀付宝交易号 trade_no我们的订单号 out_trade_no5) GitHub开源SDKpip install python-alipay-sdk# ⽀付宝沙箱环境1. 沙箱环境地址: https:///platform/appDaily.htm2. 沙箱应⽤:APPID⽀付宝⽹关: 地址中带dev表⽰沙箱环境, 不带表⽰正式环境加密⽅式: 使⽤⽀付宝提供的密钥⽣成(⽀付宝开放平台组助⼿).之前是xx.jar包, 现在变成xx.exe软件. 需要⽣成公钥和私钥将⾃⼰的公钥配置在⽀付宝中, ⽀付宝会⽣成⼀个⽀付宝的公钥.3. 项⽬中使⽤:注释 .read这⾥是操作⽂件的app_private_key_string 配置⾃⼰的私钥alipay_public_key_string 配置⽀付宝的公钥注意: 不能有空格AliPay类中的参数配置:APPID配置沙箱环境的APPIDsign_type 配置⾃⼰的 RSA2debug=False测试环境, True正式环境alipay.api_alipay_trade_page_pay中的参数配置:return_url 回调地址 (注意: 需要使⽤公⽹地址)notify_url 回调地址⽀付宝⽹关 + order_string => ⽣成连接地址提⽰: ⽣成连接地址打开会出现钓鱼⽹站异常4. 解决提⽰钓鱼问题: 浏览器⾥⾯有多个窗⼝沙箱环境存在的问题, 如果出现问题, 开⽆痕窗⼝即可, 付完之后会回调到之前配置的return_url中配置的⽹页⽀付宝沙箱环境充值:控制台 -> 沙箱账号 -> 账户余额# ⽀付宝公私密钥⽣成, sdk使⽤⽀付宝开放平台组助⼿使⽤: ⽣成公私钥⽀付宝开放平台下载:https:///ide/getPluginUrl.htm?clientType=assistant&platform=win&channelType=WEB密钥长度: RSA2密钥格式: PKCS1⽣成即可GitHub开源SDK:⽀付宝开源框架地址: https:///fzlee/alipaypip install python-alipay-sdk# 拓展:xx.apk 如果apk使⽤QQ 或者微信传送, 它会改名, 再后⾯加个.1 -> xx.apk.1. ⽬的就是防⽌恶意软件.如果你需要安装, 只需要将后缀名修改过来即可'''2. 测试⽬录结构3. t_alipay.pyfrom alipay import AliPayapp_private_key_string = """-----BEGIN rsa2 PRIVATE KEY-----MIIEowIBAAKCAQEAr6my/KRUtoPcQzuBt8TZtxLvLtwI8Rf/ETubH6dfi143yuiHd0SnfTctD+ZTmGyRHxuqNwwTNV4CN0d58wuI2F3hky4Tm8ocp8n0tzjlYxDvoh1b4d4ksxXCM0yhSzywdIK+K+Y9VP74uU4mlT47oBFUs6TBK9AAlMfZfoPTUAUjSDF -----END rsa2 PRIVATE KEY-----"""alipay_public_key_string = """-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCqAQEAgvXw19HTUH0t1thzkoq8KBhDBwFCoDqRJyBYnpN/KOTxTuSoUR0+pLK3vJbeQ0w5GJ/tiHpLh38hc88LNSR5nk26IBXX8WuNmxxC56d/A4/AaqiO3xgs9jKZjvYs0xuaFkwLswMuD8vm3 -----END PUBLIC KEY-----"""alipay = AliPay(appid="2021000117620642",app_notify_url=None, # 默认回调urlapp_private_key_string=app_private_key_string,# ⽀付宝的公钥,验证⽀付宝回传消息使⽤,不是你⾃⼰的公钥,alipay_public_key_string=alipay_public_key_string,sign_type="RSA2", # rsa2 或者 RSA2debug=False # 默认False)# 如果你是 Python 3的⽤户,使⽤默认的字符串即可subject = "测试订单"# 电脑⽹站⽀付,需要跳转到https:///gateway.do? + order_stringalipay_url = 'https:///gateway.do?'order_string = alipay.api_alipay_trade_page_pay(out_trade_no="20161112", # 订单号, 必须唯⼀total_amount=10, # 总⾦额subject=subject, # 订单标题return_url="http://139.196.184.91/", # 同步回调(⽀付成功)notify_url="http://139.196.184.91/" # 异步回调(订单状态) 可选, 不填则使⽤默认notify url)print(alipay_url + order_string)4. 注意事项from alipay import AliPayapp_private_key_string = """-----BEGIN rsa2 PRIVATE KEY-----MIIEowIBAAKCAQEAr6my/KRUtoPcQzuBt8TZtxLvLtwI8Rf/ETubH6dfi143yuiHd0SnfTctD+ZTmGyRHxuqNwwTNV4CN0d58wuI2F3hky4Tm8ocp8n0tzjlYxDvoh1b4d4ksxXCM0yhSzywdIK+K+Y9VP74uU4mlT47oBFUs6TBK9AAlMfZfoPTUAUjSDF -----END rsa2 PRIVATE KEY-----"""alipay_public_key_string = """-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgvXw19HTUH0t1thzkoq8KBhDBwFCoDqRJyBYnpN/KOTxTuSoUR0+pLK3vJbeQ0w5GJ/tiHpLh38hc88LNSR5nk26IBXX8WuNmxxC56d/A4/AaqiO3xgs9jKZjvYs0xuaFkwLswMuD8vm3x -----END PUBLIC KEY-----"""alipay = AliPay(appid="2021000117620642",app_notify_url=None, # 默认回调urlapp_private_key_string=app_private_key_string,# ⽀付宝的公钥,验证⽀付宝回传消息使⽤,不是你⾃⼰的公钥,alipay_public_key_string=alipay_public_key_string,sign_type="RSA2", # rsa2 或者 RSA2debug=False # 默认False)# 如果你是 Python 3的⽤户,使⽤默认的字符串即可subject = "测试订单"# 电脑⽹站⽀付,需要跳转到https:///gateway.do? + order_stringalipay_url = 'https:///gateway.do?'order_string = alipay.api_alipay_trade_page_pay(out_trade_no="20161112", # 订单号, 必须唯⼀total_amount=10, # 总⾦额subject=subject, # 订单标题return_url="http://139.196.184.91/", # 同步回调(⽀付成功)notify_url="http://139.196.184.91/" # 异步回调(订单状态) 可选, 不填则使⽤默认notify url)print(alipay_url + order_string)四、⽀付宝⼆次封装1. GitHub开源框架参考https:///fzlee/alipay2. 调⽤⽀付宝⽀付SDKpip install python-alipay-sdk --upgrade3. 流程'''1. libs中新建⽂件, ⽂件中新建__init__.py, 新建.py⽂件2. 将之前写死的 app...string 等, 修改成从⽂件中读取 open().read()3. 新建⽂件夹存放⽀付宝公钥和⾃⼰的私钥⽤于被第⼆步读取公钥私钥存放的⽂件格式是:-----xxx-----公钥或者私钥-----xxx-----4. 新建settings.py⽂件存放⼀些常量5. debug 配置成和 setting.py中的debug⼀直性6. 使⽤三元运算配置⽀付宝的⽀付⽹关7. 使⽤__init__.py优化导⼊的层级注意: ⽹站⽀付alipay.api_alipay_trade_page_pay放到外⾯书写和订单⼀起.'''4. ⽬录结构libs├── al_alipay # aliapy⼆次封装包│├── __init__.py # 包⽂件│├── pem # 公钥私钥⽂件夹││├── alipay_public_key.pem # ⽀付宝公钥⽂件││├── app_private_key.pem # 应⽤私钥⽂件│├── pay.py # ⽀付⽂件└──└── settings.py # 应⽤配置5. pem/alipay_public_key.pem-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt99Bp0XLP1Zu2WdRu74CMB/tVx1/2thIo8t3oAo8eD8smku1e76PfeOw4iqYMHU32Vq1Fg7BLa9oPMw7Ro+kNjX4jTDz4wC3LA6dUI5OeGxYd9+tkpsBwyg+buVNhhogppQn5rcCzkRFTx0D -----END PUBLIC KEY-----6. pem/app_private_key.pem-----BEGIN RSA PRIVATE KEY-----MIIEowIBAAKCAQEAj91mUtyrPlFFkfoLB+66lYcwexzXzEt6SlJuxsj3lW6+8pqla4YKqiUf98DeuBpX+USFm+baYFPqP5FWKyAUmGSDU8T4xD9BwLc+gm7rjeEjE5LzdyMInoEjW0QKXnn6S5y4gGPwI2WjOhg9vfr2R0GTDMTqn4i7zDB/u+wTksX5e -----END RSA PRIVATE KEY-----7. __init__.pyfrom .alipay_task import alipay, alipay_gateway8. pay.pyfrom alipay import AliPayfrom . import settingsalipay = AliPay(appid=settings.APPID,app_notify_url=None,app_private_key_string=settings.APP_PRIVATE_KEY_SIRING,alipay_public_key_string=settings.ALIPAY_PUBLIC_KEY_SIRING,sign_type=settings.SIGN_TYPE,debug=settings.DEBUG,)gateway = settings.GATEWAY9. settings.pyimport osAPPID = '2021000117613064'# 默认回调APP_NOTIFY_URL = None# ⾃⼰私钥APP_PRIVATE_KEY_SIRING = open(os.path.join(os.path.dirname(__file__), 'pem', 'app_private_kay.pem')).read()# 阿⾥公钥ALIPAY_PUBLIC_KEY_SIRING = open(os.path.join(os.path.dirname(__file__), 'pem', 'alipay_public_key.pem')).read()# 标签加密类型SIGN_TYPE = 'RSA2'# True表⽰测试沙箱环境DEBUG = True# 阿⾥⽹关GATEWAY = 'https:///gateway.do?' if DEBUG else 'https:///gateway.do?'10. 配置⽂件中配置⽀付宝替换接⼝:settings.py|开发⼈员# 后台基URLBASE_URL = 'http://139.196.184.91:8000' # 注意: 这⾥的8000上线以后指定的nginx的8000端⼝, 由nginx的8000端⼝发送到nginx配置内部的uwsgi的端⼝中# 前台基URLLUFFY_URL = 'http://139.196.184.91' # 注意: 这⾥没有写端⼝默认就是80端⼝.# ⽀付宝同步异步回调接⼝配置# 后台: ⽀付宝异步回调的接⼝NOTIFY_URL = BASE_URL + "/order/success/"# 前台: ⽀付宝同步回调接⼝,没有 / 结尾RETURN_URL = LUFFY_URL + "/pay/success"五、后台-⽀付接⼝1. 订单模块表<1>. 流程'''1. 新建订单app, 注册, ⼦路由urls, 总路由分发,2. 表分析订单表:订单标题, 总价格, 订单id(⾃⼰的), 流⽔号(⽀付宝), 订单状态, ⽀付⽅式, ⽀付时间, 订单⽤户(注意: 导⼊⽤户表路径尽量⼩), 创建时间, 更新时间订单⼀对多外键, 课程⼀对多外键(级联删除改为Set_NULL, null=True), 原价格, 实价str的健壮性校验订单和订单详情表关系分析: ⼀对多订单详情是多的⼀⽅⼀个订单可以有多个订单详情, ⼀个订单详情不可以同时属于多个订单.订单表和课程表关系分析: 多对多⼀个订单可以包含多个课程, ⼀个课程可以属于多个订单重点: 但是我们这⾥不着不过对订单表与课程表建⽴多对多的关系,⽽是通过订单详情表与课程表建⽴关系.订单详情表和课程表关系分析: ⼀对多订单详情是多的⼀⽅订单详情多的⼀⽅⼀个订单详情不可以属于多个课程, ⽽⼀个课程可以属于多个订单详情订单表和⽤户表关系分析: ⼀对多订单是多的⼀⽅⼀个⽤户可以下多个订单, ⼀个订单不能属于多个⽤户on_delete -> DO_NOTHINGdb_constraint=False提⽰: 不继承BaseModel表. is_show, orders没有必要存在3. 数据迁移'''<2>. order/models.py"""class Order(models.Model):# 主键、总⾦额、订单名、订单号、订单状态、创建时间、⽀付时间、流⽔号、⽀付⽅式、⽀付⼈(外键) - 优惠劵(外键,可为空)passclass OrderDetail(models.Model):# 订单号(外键)、商品(外键)、实价、成交价 - 商品数量pass"""from django.db import modelsfrom user.models import Userfrom course.models import Courseimport utilsclass Order(models.Model):"""订单模型"""status_choices = ((0, '未⽀付'),(1, '已⽀付'),(2, '已取消'),(3, '超时取消'),)pay_choices = ((1, '⽀付宝'),(2, '微信⽀付'),)subject = models.CharField(max_length=150, verbose_name="订单标题")total_amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="订单总价", default=0)out_trade_no = models.CharField(max_length=64, verbose_name="订单号", unique=True)trade_no = models.CharField(max_length=64, null=True, verbose_name="流⽔号")order_status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="订单状态")pay_type = models.SmallIntegerField(choices=pay_choices, default=1, verbose_name="⽀付⽅式")pay_time = models.DateTimeField(null=True, verbose_name="⽀付时间")created_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')updated_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')# 订单表和⽤户表关系分析: ⼀对多订单是多的⼀⽅⼀个⽤户可以下多个订单, ⼀个订单不能属于多个⽤户user = models.ForeignKey(User, related_name='order_user', on_delete=models.DO_NOTHING, db_constraint=False,verbose_name="下单⽤户")class Meta:db_table = "luffy_order"verbose_name = "订单记录"verbose_name_plural = "订单记录"def __str__(self):return "%s - ¥%s" % (self.subject, self.total_amount)@propertydef courses(self):data_list = []for item in self.order_courses.all():data_list.append({"id": item.id,"course_name": ,"real_price": item.real_price,})return data_listclass OrderDetail(models.Model):"""订单详情"""price = models.DecimalField(max_digits=6, decimal_places=2, verbose_name="课程原价")real_price = models.DecimalField(max_digits=6, decimal_places=2, verbose_name="课程实价")# 订单和订单详情表关系分析: ⼀对多订单详情是多的⼀⽅⼀个订单可以有多个订单详情, ⼀个订单详情不可以同时属于多个订单.order = models.ForeignKey(Order, related_name='order_courses', on_delete=models.CASCADE, db_constraint=False,verbose_name="订单")# 订单详情表和课程表关系分析: ⼀对多订单详情是多的⼀⽅订单详情多的⼀⽅⼀个订单详情不可以属于多个课程, ⽽⼀个课程可以属于多个订单详情 '''订单表和课程表关系分析: 多对多⼀个订单可以包含多个课程, ⼀个课程可以属于多个订单重点: 但是我们这⾥不着不过对订单表与课程表建⽴多对多的关系,⽽是通过订单详情表与课程表建⽴关系.'''course = models.ForeignKey(Course, related_name='course_orders', on_delete=models.SET_NULL, null=True,db_constraint=False,verbose_name="课程")class Meta:db_table = "luffy_order_detail"verbose_name = "订单详情"verbose_name_plural = "订单详情"def __str__(self):"""str的健壮性校验"""try:return "%s的订单:%s" % (, self.order.out_trade_no)except Exception as e:utils.log.error(str(e))return super().__str__()2. 订单模块接⼝之⽀付接⼝<1>. 流程'''1. ⽀付接⼝: ⽣成订单, ⽣成⽀付连接, 返回⽀付连接1) 新建路由pay, payView2) 新建视图payVieworder表和orderdetail表插⼊数据, 重写create⽅法.⽣成订单号 uuid登录后才能⽀付 jwt认证当前登录⽤户就是下单⽤户, 存到order表中订单价格校验. 如: 下了三个课程, 总价格100, 前端提交的价格是99# 实现继承 C, G新建序列化类 OrderModelSeriailzer注意: 这是⼀个反序列化的表# 传输的数据格式{course: [1, 2, 3], total_amount: 100, subject: 商品名, pay_type: 1}# 控制字段fields=['total_amount', 'subject', 'pay_type', 'course_list']# 可以再局部钩⼦中把course=[1, 2, 3]⽣成course=[obj1, obj2, obj3] 或者使⽤ PrimayKeyRElatedFieldcourse=serialisers.CharField()# 校验1. 校验订单总价格: 获取总价格, 获取课程对象列表从总价格列表中获取每个价格叠加与总价格对⽐ (注意: 需要返回总价格)2. ⽣成订单号: str(uuid).replace('-', '')3. 获取⽀付⽤户: 视图中重写create⽅法借助self.context传将request对象传给序列化类4. ⽣成⽀付连接: 导⼊alipay, alipay_gateway. 拷贝, 将post, get2个回调的地址存放到配置⽂件中(配置到django的配置⽂件中), 拼接地址返回即可!5. ⼊库(订单, 订单详情): 将user对象存⼊attrs中, 把订单号存⼊attrs中, 将pay_url存⼊self.context中6. create⽅法. 先pop出课程列表对象, 存order表. for循环存⼊课程详情视图中: Response返回给前端的, 前端只需要⼀个连接, 那么序列化校验的第五步, 在self.context中将它存⼊, 将它返回给前端3) 配置jwt认证对PayView类进⾏限制. 使⽤内置限制(认证 + 权限)内置认证类: JSONWebTokenAUthentication内置权限类: isAuthenticated4) 序列化中让所有的fields中的字段必填. 有默认值的字段, 就不是必填的. required=True5) 出现错误: ⽀付宝⽀付的时候pay_total_amount是⼀个decimal类型, 需要转换成float类型. (提⽰: decimal累加可以)提⽰: ⽀付⽅式⽬前只写了⽀付宝的⽀付⽅式因此pay_type=1, 3个课程⼀起买⼀共1382. ⽀付宝异步回调的post接⼝: 验签, 修改订单状态3. 当⽀付宝get回调前端, vue组件⼀创建, ⽴马向后端你发⼀个get请求.(⽐较绕)'''<2>. order/views.pyfrom rest_framework.viewsets import GenericViewSetfrom rest_framework.mixins import CreateModelMixinfrom rest_framework import statusfrom rest_framework_jwt.authentication import JSONWebTokenAuthenticationfrom rest_framework.permissions import IsAuthenticatedimport utilsfrom . import modelsfrom . import serializerclass PayView(CreateModelMixin, GenericViewSet):# 对PayView类进⾏限制. 使⽤内置限制(认证 + 权限)authentication_classes = [JSONWebTokenAuthentication]permission_classes = [IsAuthenticated]queryset = models.Order.objects.all()serializer_class = serializer.OrderModelSeriailzerdef create(self, request, *args, **kwargs):# 视图中重写create⽅法借助self.context传将request对象传给序列化类serializer = self.get_serializer(data=request.data, context={'request': request})serializer.is_valid(raise_exception=True)self.perform_create(serializer)headers = self.get_success_headers(serializer.data)# 视图中: Response返回给前端的, 前端只需要⼀个连接, 那么序列化校验的第五步, 在self.context中将它存⼊, 将它返回给前端return utils.APIResponse(serializer.context['pay_link'], status=status.HTTP_201_CREATED, headers=headers)<3>. order/serializer.pyimport uuidfrom rest_framework import serializersfrom rest_framework.exceptions import ValidationErrorfrom django.conf import settingsfrom . import modelsfrom libs.alipay_sdk import alipay, alipay_gatewayclass OrderModelSeriailzer(serializers.ModelSerializer):# 可以再局部钩⼦中把course_list=[1, 2, 3]⽣成course_list=[obj1, obj2, obj3] 或者使⽤ PrimayKeyRElatedFieldcourse_list = serializers.PrimaryKeyRelatedField(write_only=True, many=True, queryset=models.Course.objects.all())class Meta:model = models.Orderfields = ['subject', 'total_amount', 'pay_type', 'course_list']extra_kwargs = {# 序列化中让所有的fields中的字段必填. 有默认值的字段, 就不是必填的. required=True'total_amount': {'required': True},'pay_type': {'required': True},}@staticmethoddef _verify_amount(attrs):total_amount = attrs.get('total_amount')course_list = attrs.get('course_list')course_amount = 0for course in course_list:course_amount += course.priceif course_amount == total_amount:return total_amountraise ValidationError("订单总价错误!")@staticmethoddef _order_number():return str(uuid.uuid1()).replace('-', '')def _pay_user(self):return self.context['request'].userdef _pay_link(self, out_trade_no, total_amount, subject):# print('total_amount:', total_amount, type(total_amount)) # total_amount: 138.00 <class 'decimal.Decimal'>order_string = alipay.api_alipay_trade_page_pay(out_trade_no=out_trade_no, # 订单号, 必须唯⼀# ⽀付宝⽀付的时候pay_total_amount是⼀个decimal类型, 需要转换成float类型. (提⽰: decimal累加可以)total_amount=float(total_amount), # 总⾦额subject=subject, # 订单标题return_url=settings.RETURN_URL, # 同步回调(⽀付成功)notify_url=settings.NOTIFY_URL # 异步回调(订单状态) 可选, 不填则使⽤默认notify url)return alipay_gateway + order_stringdef _before_create(self, attrs, out_trade_no, user, pay_link):attrs['out_trade_no'] = out_trade_noattrs['user'] = userself.context['pay_link'] = pay_linkdef validate(self, attrs):"""1. 校验订单总价格: 获取总价格, 获取课程对象列表从总价格列表中获取每个价格叠加与总价格对⽐ (注意: 需要返回总价格)2. ⽣成订单号: str(uuid).replace('-', '')3. 获取⽀付⽤户: 视图中重写create⽅法借助self.context传将request对象传给序列化类4. ⽣成⽀付连接: 导⼊alipay, alipay_gateway. 拷贝, 将post, get2个回调的地址存放到配置⽂件中(配置到django的配置⽂件中), 拼接地址返回即可!5. ⼊库(订单, 订单详情): 将user对象存⼊attrs中, 将pay_link存⼊self.context中"""# 1. 校验订单总价格total_amount = self._verify_amount(attrs)# 2. ⽣成订单号order_number = self._order_number()# 3. 获取⽀付⽤户user = self._pay_user()# 4. ⽣成⽀付连接pay_link = self._pay_link(out_trade_no=order_number, total_amount=total_amount, subject=attrs.get('subject'))# 5. ⼊库(订单, 订单详情)self._before_create(attrs=attrs, out_trade_no=order_number, user=user, pay_link=pay_link)return attrsdef create(self, validated_data):course_list = validated_data.pop('course_list')order = models.Order.objects.create(**validated_data)for course in course_list:models.OrderDetail.objects.create(course=course, price=course.price, real_price=course.price, order=order)return order<4>. settings/dev.py# 后台基URLBASE_URL = 'http://139.196.184.91'# 前台基URLLUFFY_URL = 'http://139.196.184.91'# ⽀付宝同步异步回调接⼝配置# 后台异步回调接⼝NOTIFY_URL = BASE_URL + "/order/success/"# 前台同步回调接⼝,没有 / 结尾RETURN_URL = LUFFY_URL + "/pay/success"<5>. luffyapi/urls.pypath('order/',include('order.urls')),<6>. order/urls.py⼦路由from django.urls import path, re_path, includefrom . import viewsfrom rest_framework.routers import SimpleRouterrouter = SimpleRouter()router.register('pay', views.PayView, 'pay')urlpatterns = [path('', include(router.urls)),]六、前台-⽀付⽣成页⾯1. 前端跳转到⽀付宝⽀付<1>. 流程'''提⽰: ⼀共三个地⽅都有⽴即购买操作1. FreeCourse.vue1) 定义buy_now()点击触发事件的⽅法从this.$cookies中获取token判断如果没有token那么触发this.$message发送ajax的post请求, this.$settings.base_url + /order/pay/, headers需要携带认证 Authorization, data需要携带对着数据. 使⽤另⼀种⽤法{}获取到pay_link, 前端发送get请求window.open(pay_link, '_self')2) 付款成功以后需要跳转到/order/success页⾯, 前端需要success组件. 后端需要success接⼝'''<2>. FreeCoourse.vue# template<span class="buy-now" @click="buy_now(course)">⽴即购买</span># scriptmethods: {buy_now(course) {// 获取token, 校验⽤户是否登录let token = this.$cookies.get('token');if (!token) {this.$message({message: "请先登录!",type: 'warning',});return false;}// 发送axiosthis.$axios({method: 'post',url: `${this.$settings.base_url}/order/pay/`,data: {"subject": ,// "total_amount": 11,"total_amount": course.price,"pay_type": 1,"course_list": [course.id,},headers: {Authorization: `jwt ${this.$cookies.get('token')}`},}).then(response => {console.log(response.data);if (response.data.code) {open(response.data.data, '_self');} else {this.$message({message: '订单处理失败!',type: 'warning',})}}).catch(error => {this.$message({message: "未知错误!",type: 'warning',})})},...}2. ⽀付成功前端页⾯<1>. 流程'''1. 新建PaySuccess.vue组件2. 配置路由 path: '/pay/success'注意: 回调以后会在你的url地址中, 携带者很多东西3. 拷贝PaySuccess页⾯提⽰: 页⾯只有⽀付宝回调回来才有数据, 直接查看是没有的4. create⾥⾯有⼀种特殊⽤法5. 同步回调参数trade_no ⽀付宝的流⽔号auth_app_id 商家流⽔号app_id 我们的id号页⾯需要的参数: 订单号, 交易号, 付款时间'''<2>. routere/index.jsimport PaySuccess from '../views/PaySuccess.vue'const routes = [...{path: '/pay/success',name: 'PaySuccess',component: PaySuccess},];<3>. ⽀付宝返回参数charset=utf-8&out_trade_no=7f7c7d12d57d45b693e1b49a6b01e1dd& # ⾃⼰的订单号method=alipay.trade.page.pay.return&total_amount=39.00&sign=FUmceqiNMWvxcD%2BUPCHiOTaEwlJ%2FXIXL5UwZWOSI1TwRjPIZVzjRLB4j2G5CQpn472JO8X%2BwMx04dHqjLxqLcY3TRu0XurQ%2FwKTNpyfDrtNuNv0rfGPuVHw52y3blbS7%2FKFVsWryw4%2BBuF2fCrJ4qWH8Zg14Rct7qoMbu73N trade_no=2020030722001464020500585462& # ⽀付宝的流⽔号auth_app_id=2016093000631831&version=1.0&app_id=2016093000631831&sign_type=RSA2&seller_id=2088102177958114×tamp=2020-03-07%2014%3A47%3A48 # 付款时间`// 同步回调没与订单状态<4>. views/PaySuccess.vue<template><div class="pay-success"><!--如果是单独的页⾯,就没必要展⽰导航栏(带有登录的⽤户)--><Header/><div class="main"><div class="title"><div class="success-tips"><p class="tips">您已成功购买 1 门课程!</p></div></div><div class="order-info"><p class="info"><b>订单号:</b><span>{{ result.out_trade_no }}</span></p><p class="info"><b>交易号:</b><span>{{ result.trade_no }}</span></p><p class="info"><b>付款时间:</b><span><span>{{ result.timestamp }}</span></span></p></div><div class="study"><span>⽴即学习</span></div></div></div></template><script>import Header from "@/components/Header"export default {name: "Success",data() {return {result: {},};},// console.log(location.search);// 解析⽀付宝回调的url参数let params = location.search.substring(1); // 去除? => a=1&b=2 let items = params.length ? params.split('&') : []; // ['a=1', 'b=2']//逐个将每⼀项添加到args对象中for (let i = 0; i < items.length; i++) { // 第⼀次循环a=1,第⼆次b=2 let k_v = items[i].split('='); // ['a', '1']//解码操作,因为查询字符串经过编码的if (k_v.length >= 2) {// url编码反解let k = decodeURIComponent(k_v[0]);this.result[k] = decodeURIComponent(k_v[1]);// 没有url编码反解// this.result[k_v[0]] = k_v[1];}}// 解析后的结果// console.log(this.result);// 把地址栏上⾯的⽀付结果,再get请求转发给后端this.$axios({url: this.$settings.base_url + '/order/success/' + location.search, method: 'get',}).then(response => {console.log(response.data);}).catch(() => {console.log('⽀付结果同步失败');})},components: {Header,}}</script><style scoped>.main {padding: 60px 0;margin: 0 auto;width: 1200px;background: #fff;}.main .title {display: flex;-ms-flex-align: center;align-items: center;padding: 25px 40px;border-bottom: 1px solid #f2f2f2;}.main .title .success-tips {box-sizing: border-box;}.title img {vertical-align: middle;width: 60px;height: 60px;margin-right: 40px;}.title .success-tips {box-sizing: border-box;}.title .tips {font-size: 26px;color: #000;}.info span {color: #ec6730;}.order-info {padding: 25px 48px;padding-bottom: 15px;border-bottom: 1px solid #f2f2f2;}.order-info p {display: -ms-flexbox;display: flex;margin-bottom: 10px;font-size: 16px;}.order-info p b {font-weight: 400;color: #9d9d9d;white-space: nowrap;}.study {padding: 25px 40px;}.study span {display: block;width: 140px;height: 42px;text-align: center;line-height: 42px;cursor: pointer;background: #ffc210;border-radius: 6px;font-size: 16px;color: #fff;}</style>七、后台-⽀付成功的备选接⼝1. 流程优化: 后端序列化中判断⽤户⽀付⾦额是否是0, 是0那么就直接修改订单状态, 也不⽤发送pay_link了# 前端: created分析1. localtion.search就可以获取⽀付好?号后⾯的参数获取到(包括问号), 使⽤.substring(1), 取出左边的?号2. 使⽤三元表达式, 对params进⾏split. 以及后⾯将这种参数进⾏处理3. decodeURICompontent,4. 把地址栏上⾯的⽀付结果, 再get请求发给后端this.$settings.base_url + '/order/success/' + localtion.search# 后端1. 路由: success/ SuccessView2. 视图: 继承APIView 因为不和序列化类有关系, 和数据库有点关系# get:获取前端传递过来的 out_trade_no, 去数据库中查取, 判断订单 order_status 的订单状态是否成功.最后返回响应中通过code=0或者code=1返回给前端即可# post: ⽀付宝回调回调地址: https:///fzlee/alipay/blob/master/README.zh-hans.md#alipay.fund.trans.toaccount.transfer回调参数: https:///open/270/105902/注意: 必须data内容返回 successrequest.data可能有2种情况. 如果是json格式是字典, 如果是QuseryDict需要注意失败了之后需要记录⽇志成功了之后需要记录⽇志, 并且修改订单状态, 使⽤ out_trade_no 作为过来标志, order_status 修改为1, 交易⽀付时间pay_time=gmt_payment'''2. 同步理论参数charset=utf-8&out_trade_no=7f7c7d12d57d45b693e1b49a6b01e1dd&method=alipay.trade.page.pay.return&total_amount=39.00&sign=FUmceqiNMWvxcD%2BUPCHiOTaEwlJ%2FXIXL5UwZWOSI1TwRjPIZVzjRLB4j2G5CQpn472JO8X%2BwMx04dHqjLxqLcY3TRu0XurQ%2FwKTNpyfDrtNuNv0rfGPuVHw52y3blbS7%2FKFVsWryw4%2BBuF2fCrJ4qWH8Zg14Rct7qoMbu73N trade_no=2020030722001464020500585462&auth_app_id=2016093000631831&version=1.0&app_id=2016093000631831&sign_type=RSA2&seller_id=2088102177958114×tamp=2020-03-07%2014%3A47%3A48`// 同步回调没与订单状态3. order/urls.pypath('success/',views.successView.as_view()),4. order/views.pyfrom rest_framework.views import APIViewfrom libs.alipay_sdk import alipayclass SuccessView(APIView):def get(self, request, *args, **kwargs):"""获取前端传递过来的 out_trade_no, 去数据库中查取, 判断订单 order_status 的订单状态是否成功.最后返回响应中通过code=0或者code=1返回给前端即可"""out_trade_no = request.query_params.get('out_trade_no')order = models.Order.objects.filter(out_trade_no=out_trade_no).first()# order.order_status值为1表⽰订单成功if order.order_status == 1:return utils.APIResponse()return utils.APIResponse(code=0, msg='失败')def post(self, request, *args, **kwargs):"""回调地址: https:///fzlee/alipay/blob/master/README.zh-hans.md#alipay.fund.trans.toaccount.transfer回调参数: https:///open/270/105902/注意: 必须data内容返回 successrequest.data可能有2种情况. 如果是json格式是字典, 如果是QuseryDict需要注意失败了之后需要记录⽇志成功了之后需要记录⽇志, 并且修改订单状态, 使⽤ out_trade_no 作为过来标志, order_status修改为1, 交易⽀付时间pay_time=gmt_payment"""# request.data类型判断data = request.data.dict()utils.log(f'data: {data}')signature = data.pop("sign")out_trade_no = data.get('out_trade_no')gmt_payment = data.get('gmt_payment')# 校验success = alipay.verify(data, signature)if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):# 修改订单状态models.Order.objects.filter(out_trade_no=out_trade_no).update(order_status=1, pay_time=gmt_payment)(f'{out_trade_no}订单⽀付成功!')# 注意: 服务器异步通知页⾯特性'''当商户收到服务器异步通知并打印出 success 时,服务器异步通知参数 notify_id 才会失效。
支付宝新企业版签约产品介绍及应用说明目录1、支付宝收款产品..........................................1)、担保交易收款.......................................2)、即时到账收款.......................................3)、网银支付...........................................4)、COD货到付款平台 ...................................5)、移动支付...........................................6)、手机网站支付.......................................7)、扫码即时到账收款...................................8)、扫码担保交易收款...................................2、商家付款产品............................................1、批量付款到支付宝账户(银行卡账户)..................3、平台商产品..............................................1)、平台商担保交易收款.................................4、增值服务................................................1)、数据罗盘...........................................2)、集分宝批量自助发...................................3)、快捷登录........................................... 二、普通网站接口收费标准.......................................1、收款产品................................................1)、担保交易、即时到帐.................................2)、网银支付...........................................3)、COD货到付款 .......................................4)、快捷支付、手机网站支付.............................5)、扫码即时到账收款、扫码担保交易收款.................6)、平台商担保交易收款.................................2、付款产品(可批量)........................................1)、转账到支付宝账户...................................3、增值产品................................................三、支付宝后台交易对账系统解释.................................四、支付宝商户案例.............................................1、联通网上营业厅..........................................2、大众点评网..............................................3、一号店.................................................. 附表一:储蓄卡快捷支付限额总表(电脑端、无线端)...............一、支付宝签约产品简介1、支付宝收款产品1)、担保交易收款2)、即时到账收款3)、网银支付4)、COD货到付款平台5)、移动支付6)、手机网站支付7)、扫码即时到账收款8)、扫码担保交易收款2、商家付款产品1、批量付款到支付宝账户(银行卡账户)支付宝已升级新企业版,转账额度已提高。
甘肃农业大学校园统一缴费平台使用流程图特别说明:1.登录用户名:本科新生为考生号,研究生新生和往届生为学号;密码:身份证号后六位(末尾字母大写)。
2.校园统一缴费平台支持微信和支付宝支付方式。
3.请在浏览器地址栏手动输入缴费网址,不要通过搜索引擎搜索,以免搜到钓鱼网站。
登录“校园统一缴费平台”核对个人信息及缴费信息点击“学费缴费”点击“非税项目缴费”缴纳学费和住宿费点击“代收费项目”缴纳医保费和体检费核对缴费金额,点击“下一步”选择缴费方式,点击“确定缴费”打开手机微信或支付宝,扫码完成缴费点击“交易查询”,查询“银行交易记录”和“已缴费信息”到学院领取缴费票据缴费平台网址:或打开学校计划财务处网页点击“缴费平台”用手机微信或支付宝扫描“缴费平台”二维码登录“今日校园”APP ,选择“缴费平台”4.该流程为网页端缴费流程,移动端缴费流程参照该流程。
附件1甘肃农业大学校园统一缴费平台使用说明(网页端)1.系统简介甘肃农业大学校园统一缴费平台是针对在校生、老师及外校人员进行网上缴费的一个收费系统。
在校生、教师以及校外人员能随时随地通过本系统缴纳学费以及其他的学校各种零星费用,并能够实时查询项目欠费和已缴费情况。
b5E2RGbC2.系统功能缴费平台主要功能:个人信息管理、欠费查询、学费缴费、其他缴费、生活缴费、缴费记录查询、已缴费信息查询。
p1EanqFD3.系统使用说明3.1系统登陆在浏览器地址栏输入/,如图3.1-1所示。
登陆之后显示个人欠费信息,如图 3.1-2所示。
DXDiTa9E图 3.1-1 统一支付平台登陆界面图 3.1-2 统一支付平台登陆后页面A.登录用户名:新生本科为考生号,新生研究生和往届生为学号;密码:身份证号后6位(末尾大写)。
B.其他用户登陆时,用户名、密码为对应的用户编号、密码。
C.通过报名缴费的非在校生初始登陆时,点击新用户注册,报名之后再登陆。
D.忘记密码请点击“忘记密码”连接,在打开的窗口中验证密保后重新设置密码。
支付宝钱包使用指南目录一、新手入门 (2)二、转账 (5)A. 转到支付宝账号 (5)B. 转账到银行卡 (7)三、信用卡还款 (9)四、生活缴费 (11)五、查询账单 (15)六、当面付—声波支付 (16)七、当面付—条码支付 (19)八、一起AA (20)九、余额宝 (23)十、公众服务平台 (26)十一、信用卡账单导入 (28)十二、支付宝钱包新的支付与密码设计 (29)一、新手入门1.下载并打开支付宝钱包,用手机号注册为你的支付宝账号2.填写收到的校验码,并设置一个6位数的手机支付密码(此密码不影响支付宝在电脑上的登陆和支付密码,仅作为支付宝在手机上的支付密码)3.设置一个打开支付宝钱包的手势密码(在无网络情况下依然可以快捷的打开钱包)4.添加银行卡信息(可以手动输入卡号,或者拍下银行卡正面。
)5.输入收到的短信验证码,绑卡成功。
二、转账A. 转到支付宝账号1.打开支付宝钱包后,选择“转账”,怎么转都免费!2.从通讯录好友、或“转到支付宝账号”查找你要转账的人3.捎句话、选择表情,带上祝福转账。
4.跟每个转账好友的资金往来都可查看,并可在查看窗口快速付款。
B. 转账到银行卡正常版1.选择“转到银行卡”填写收款银行卡信息。
2.确认转账信息、输入6位数手机支付密码,转账成功。
对方会收到短信通知。
转账到卡—超级版对方没有支付宝,你也不知道对方银行卡,输入手机号就能转账!1.在转账时,选择“向通讯录的好友转账”,被提示对方没有支付宝账户,选择“继续”,输入金额和收款方真实姓名。
2.显示到账说明,对方按短信提示输入相关信息,完成转账。
三、信用卡还款1.打开支付宝钱包,选择“信用卡还款”2.添加要还款的信用卡信息,老用户直接跳至第三步。
输入卡号或拍下银行卡正面,设置一个还款提醒日,你会在提醒日收到支付宝的还款短信提醒)3.输入还款金额(框红:立即还款、还款金额、确认还款、金额栏的小放大镜,并备注:点这里可以查询你当月需要还款的金额)4.确认还款四、生活缴费1.打开支付宝钱包,选择“我的生活”进入“生活缴费”!2.选择你要缴纳的费用3.支付宝钱包会自动定位你所在的城市,你也可以手动选择需要缴费的城市(身在异地,可帮父母缴费)4. 第一次缴纳,需要选择缴费机构、填写户号,查看欠费5. 输入6位数手机支付密码完成缴费。