[DEMO]支付宝网页支付及微信网页扫码支付
34-支付宝支付

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 才会失效。
php实现微信和支付宝支付的示例代码

php实现微信和⽀付宝⽀付的⽰例代码php实现微信⽀付在php下实现微信⽀付,这⾥我使⽤了EasyWeChat这⾥我是在Yii框架实现的,安装EasyWeChat插件composer require jianyan74/yii2-easy-wechat⼀:配置EasyWeChat1:在config/main.php 的 component中添加EasyWeChat的SDK'components' => [// ...'wechat' => ['class' => 'jianyan\easywechat\Wechat','userOptions' => [], // ⽤户⾝份类参数'sessionParam' => 'wechatUser', // 微信⽤户信息将存储在会话在这个密钥'returnUrlParam' => '_wechatReturnUrl', // returnUrl 存储在会话中'rebinds' => [ // ⾃定义服务模块// 'cache' => 'common\components\Cache',]],// ...]2:在config/params.php中设置基础配置信息和微信⽀付信息// 微信配置具体可参考EasyWechat'wechatConfig' => [],// 微信⽀付配置具体可参考EasyWechat'wechatPaymentConfig' => [],// 微信⼩程序配置具体可参考EasyWechat'wechatMiniProgramConfig' => [],// 微信开放平台第三⽅平台配置具体可参考EasyWechat'wechatOpenPlatformConfig' => [],// 微信企业微信配置具体可参考EasyWechat'wechatWorkConfig' => [],// 微信企业微信开放平台具体可参考EasyWechat'wechatOpenWorkConfig' => [],// 微信⼩微商户具体可参考EasyWechat'wechatMicroMerchantConfig' => [],⼆:实现微信⽀付1:微信⽀付api$data = ['body' => '',//⽀付描述'out_trade_no' => '',//订单号'total_fee' => '',//⽀付⾦额'notify_url' => '', // ⽀付结果通知⽹址,如果不设置则会使⽤配置⾥的默认地址'trade_type' => 'JSAPI',//⽀付⽅式'openid' => '',//⽤户openid];// ⽣成⽀付配置$payment = Yii::$app->wechat->payment;$result = $payment->order->unify($data);if ($result['return_code'] == 'SUCCESS') {$prepayId = $result['prepay_id'];$config = $payment->jssdk->sdkConfig($prepayId);} else {throw new yii\base\ErrorException('微信⽀付异常, 请稍后再试');}return $this->render('wxpay', ['jssdk' => $payment->jssdk, // $app通过上⾯的获取实例来获取'config' => $config]);2:在wxpay.php⽂件中发起⽀付<script src="/open/js/jweixin-1.4.0.js" type="text/javascript" charset="utf-8"></script><script type="text/javascript" charset="utf-8">//数组内为jssdk授权可⽤的⽅法,按需添加,详细查看微信jssdk的⽅法wx.config(<?php echo $jssdk->buildConfig(array('chooseWXPay'), true) ?>);function onBridgeReady(){// 发起⽀付wx.chooseWXPay({timestamp: <?= $config['timestamp'] ?>,nonceStr: '<?= $config['nonceStr'] ?>',package: '<?= $config['package'] ?>',signType: '<?= $config['signType'] ?>',paySign: '<?= $config['paySign'] ?>', // ⽀付签名success: function (res) {// ⽀付成功后的回调函数},cancel: function(r) {//⽀付取消后的回调函数},});}if (typeof WeixinJSBridge == "undefined"){if( document.addEventListener ){document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);}else if (document.attachEvent){document.attachEvent('WeixinJSBridgeReady', onBridgeReady);document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);}}else{onBridgeReady();}</script>在异步回调地址中获取微信⽀付回调只需要使⽤如下⽅法即可:$payment = Yii::$app->wechat->payment;$response = $payment->handlePaidNotify(function($message, $fail) {//⽀付结果逻辑,只有在函数⾥ return true; 才代表处理完成});$response->send();根据如上步骤就可以实现微信⽀付php实现⽀付宝⽀付⼀:在php中安装⽀付宝插件composer require alipaysdk/easysdk⼆:php实现⽀付宝⽀付1:配置⽀付宝/*** ⽀付宝配置*/public static function getOptions(){$options = new Config();$options->protocol = 'https';$options->gatewayHost = '';$options->signType = 'RSA2';$options->appId = '<-- 请填写您的AppId,例如:2019022663440152 -->';// 为避免私钥随源码泄露,推荐从⽂件中读取私钥字符串⽽不是写⼊源码中$options->merchantPrivateKey = '<-- 请填写您的应⽤私钥,例如:MIIEvQIBADANB ... ... -->';$options->alipayCertPath = '<-- 请填写您的⽀付宝公钥证书⽂件路径,例如:/foo/alipayCertPublicKey\_RSA2.crt -->';$options->alipayRootCertPath = '<-- 请填写您的⽀付宝根证书⽂件路径,例如:/foo/alipayRootCert.crt" -->';$options->merchantCertPath = '<-- 请填写您的应⽤公钥证书⽂件路径,例如:/foo/appCertPublicKey\_2019051064521003.crt -->'; //注:如果采⽤⾮证书模式,则⽆需赋值上⾯的三个证书路径,改为赋值如下的⽀付宝公钥字符串即可// $options->alipayPublicKey = '<-- 请填写您的⽀付宝公钥,例如:MIIBIjANBg... -->';//可设置异步通知接收服务地址(可选)$options->notifyUrl = "<-- 请填写您的⽀付类接⼝异步通知接收服务地址,例如:https:///callback -->";//可设置AES密钥,调⽤AES加解密相关接⼝时需要(可选)//$options->encryptKey = "<-- 请填写您的AES密钥,例如:aa4BtZ4tspm2wnXLb1ThQA== -->";return $options;}2:实现⽀付宝⽀付//加载⽀付宝配置Factory::setOptions(self::getOptions());try {//发起API调⽤$result = Factory::payment()->wap()->pay('订单标题', '商户订单号', '订单总⾦额', '⽤户付款中途退出返回商户⽹站的地址', '⽀付回调地址');$responseChecker = new ResponseChecker();//处理响应或异常if ($responseChecker->success($result)) {//调⽤成功return $result->body;} else {//调⽤失败$errorMsg = $result->msg . $result->subMsg;throw new yii\\base\\ErrorException($errorMsg);}} catch (\\Exception $e) {throw new yii\\base\\ErrorException($e->getMessage());}根据如上就可以实现⽀付宝⽀付到此这篇关于php实现微信和⽀付宝⽀付的⽰例代码的⽂章就介绍到这了,更多相关php实现微信和⽀付宝⽀付内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。
微信支付解决方案

微信支付七种支付通道今天带来的是微信支付7种常见的支付通道,市面上最常见的七种微信支付通道如下所示:JSAPI支付、APP支付、付款码支付、Native支付、微信收款商业版、小程序、H5支付。
在微信支付以外,还有支付宝支付、银联支付等一些其他支付渠道,但是都没有微信支付这7种支付渠道使用的范围广。
接下来根据开发技术的难度、最适合商家的两个方面来划分这七种支付渠道的优先级。
一、划分支付通道优先级1、按技术层次划分:Native支付-> APP支付-> 小程序支付-> H5支付-> JSAPI支付-> 付款码支付->微信收款商业版(1) Native支付:优先级最高。
Native支付是指在移动应用中使用微信SDK进行支付,用户体验较好,支付成功率高。
但需要对接微信SDK,开发成本较高。
(2) APP支付:优先级较高。
APP支付是指在手机上通过微信客户端进行支付,相比H5支付更加稳定可靠。
但需要用户下载并安装微信客户端。
(3) 小程序支付:也是优先级较高。
小程序支付是指在微信小程序内部进行支付,可以提升用户体验及转化率。
但需要开发微信小程序,并通过微信审核。
(4) H5支付:优先级次之。
H5支付是指在手机浏览器中打开链接进行支付,用户体验较差,但不需要用户下载客户端,支持跨平台使用。
(5) JSAPI支付:优先级次于H5支付。
JSAPI支付是指在网页上嵌入微信支付功能,在微信内部完成支付。
但需要用户在微信中打开网页,不能跨平台使用。
(6) 付款码支付:优先级较低。
付款码支付是指商户收款时由用户出示自己的微信支付二维码进行扫码支付。
但需要用户主动出示二维码,适用范围有限。
(7) 微信收款商业版:优先级最低。
微信收款商业版是指商户通过微信官方提供的工具进行收款,可支持多种支付方式。
但需要服务费用,并且功能相比其他支付方式较为受限制。
2、按照最适合商家来划分:JSAPI支付H5支付-> APP支付和Native支付-> 微信收款商业版和付款码支付-> 小程序支付(1)微信支付JSAPI支付和H5支付:适用于网页和移动端应用内支付,方便用户快速完成支付,且接口简单易用,两者之间无明显差别,开发成本可观,是商家朋友的不二之选。
支付宝和微信支付流程和技术说明

支付宝和微信支付流程和技术说明
1.1微信支付
1.1.1JSAPI网页支付
JSAPI网页支付即前文说的公众号支付,可在微信公众号、朋友圈、聊天会话中点击页面链接,或者用微信“扫一扫”扫描页面地址二维码在微
信中打开商户HTML5页面,在页面内下单完成支付。
1.1.2Native原生支付
Native原生支付即前文说的扫码支付,商户根据微信支付协议格式生成的二维码,用户通过微信“扫一扫”扫描二维码后即进入付款确认界面,输入密码即完成支付。
1.1.3接入方式
微信支付系统是指完成微信支付流程中涉及的
API接口、后台业务处理系统、账务系统、回调通知等系统的总称。
微信支付分为公众号支付,App支付,扫码支付(包括PC 网站),刷卡支付(设备扫描用户手
机)
本项目主要适用扫码支付。
接通扫码支付流程:
注册公众帐号申请微信
认证
申请微信
支付
商户平台
进行验证
在线签署
协议
启动设计
和开发
用户扫描商户展示在各种场景的二维码进行支付。
步骤1:商户根据微信支付的规则,为不同商品生成不同的二维码,展示在各种场景,用于用户扫描购买。
步骤2:用户使用微信“扫一扫”扫描二维码后,获取商品支付信息,引导用户完成支付。
步骤(3):用户确认支付,输入支付密码。
步骤(4):支付完成后会提示用户支付成功,商户后台得到支付成功的通知,然后进行发货处理。
开发步骤:。
前端h5调起支付宝扫码付款,附上启动支付宝常用命令

前端h5调起⽀付宝扫码付款,附上启动⽀付宝常⽤命令在开发⼀些⽀付宝相关功能的⽹页时,有些情况需要直接调起⽀付宝APP的某个功能,那么在前端直接⽤⼀段简单的命令来调起是最⽅便的。
⽤法也简单,直接⽤⼀个a标签来跳转就可以。
举个例⼦,⽐如我项⽬中使⽤的调起⽀付宝扫码付款——<a href='alipays://platformapi/startapp?appId=20000067&url=⽀付宝收款码⽀付地址'> 跳转⽀付宝⽀付</a>然后,有的时候这样也没办法成功调起,那么再加个前缀转化⼀下。
https:///p/s/i?scheme=PS:注意要把等号后⾯这串地址urlencode编码转化。
下⾯是⼀些常⽤的唤醒⽀付宝某项功能的命令mes = “alipayqr://platformapi/startapp?saId=10000003”;⼿机充值mes = “alipayqr://platformapi/startapp?saId=10000007”;扫⼀扫mes = “alipayqr://platformapi/startapp?saId=10000009”;爱⼼捐赠mes = “alipayqr://platformapi/startapp?saId=100000011”;彩票⾸页mes = “alipayqr://platformapi/startapp?saId=100000033”;话费卡转让mes = “alipayqr://platformapi/startapp?saId=10000110”;关于mes = “alipayqr://platformapi/startapp?saId=10000112”;服务授权mes = “alipayqr://platformapi/startapp?saId=20000116”;转账mes = “alipayqr://platformapi/startapp?saId=20000056”;付款码mes = alipays://platformapi/startapp?appId=20000003;账单mes = alipays://platformapi/startapp?appId=20000076;账单mes = “alipays://platformapi/startapp?appId=20000006”;切换账户mes = “alipays://platformapi/startapp?appId=20000008”;⽀付宝登出mes = “alipays://platformapi/startapp?appId=20000009”;⼿机号注册mes = “alipays://platformapi/startapp?appId=20000010”;绑定⼿机mes = “alipays://platformapi/startapp?appId=20000011”;客服帮助mes = “alipays://platformapi/startapp?appId=20000013”;修改⽀付密码mes = “alipays://platformapi/startapp?appId=20000014”;我的银⾏卡mes = “alipays://platformapi/startapp?appId=20000015”;找回登录密码mes = “alipays://platformapi/startapp?appId=20000017”;修改登录密码mes = “alipays://platformapi/startapp?appId=20000019”;余额mes = “alipays://platformapi/startapp?appId=20000020”;卡包mes = “alipays://platformapi/startapp?appId=20000024”;⽀付宝设置mes = “alipays://platformapi/startapp?appId=20000027”;账号切换mes = “alipays://platformapi/startapp?appId=20000031”;设置个⼈头像mes = “alipays://platformapi/startapp?appId=20000032”;余额宝mes = “alipays://platformapi/startapp?appId=20000033”;提现mes = “alipays://platformapi/startapp?appId=20000038”;⾝份验证mes = “alipays://platformapi/startapp?appId=20000048”;添加⽣活好mes = “alipays://platformapi/startapp?appId=20000049”;意见反馈mes = “alipays://platformapi/startapp?appId=20000050”;打开地图mes = “alipays://platformapi/startapp?appId=20000057”;账号管理mes = “alipays://platformapi/startapp?appId=20000068”;快速挂失mes = “alipays://platformapi/startapp?appId=20000068”;安全中⼼mes = “alipays://platformapi/startapp?appId=20000071”;城市⼀卡通mes = “alipays://platformapi/startapp?appId=20000078”;上银汇款mes = “alipays://platformapi/startapp?appId=20000081”;更多mes = “alipays://platformapi/startapp?appId=20000122”;⾸页活动mes = “alipays://platformapi/startapp?appId=20000123”;收钱mes = “alipayqr://platformapi/startapp?appId=68687017”;年度账单mes = “alipayqr://platformapi/startapp?appId=20000101”;⽣活号mes = “alipayqr://platformapi/startapp?appId=20000102”;打开nfcmes = “alipayqr://platformapi/startapp?appId=20000107”;出境mes = “alipayqr://platformapi/startapp?appId=20000108”;挂号就诊mes = “alipayqr://platformapi/startapp?appId=20000110”;我的保障mes = “alipayqr://platformapi/startapp?appId=20000115”;设备管理mes = “alipayqr://platformapi/startapp?appId=20000119”;阿⾥游戏mes = “alipayqr://platformapi/startapp?appId=20000118”;芝⿇信⽤mes = “alipayqr://platformapi/startapp?appId=20000120”;饿了么mes = “alipayqr://platformapi/startapp?appId=20000123”;收钱mes = “alipayqr://platformapi/startapp?appId=20000125”;⾸页mes = “alipayqr://platformapi/startapp?appId=20000126”;免费wifimes = “alipayqr://platformapi/startapp?appId=20000130”;滴滴mes = “alipayqr://platformapi/startapp?appId=20000132”;亲情号mes = “alipayqr://platformapi/startapp?appId=20000134”;股票⾃选mes = “alipayqr://platformapi/startapp?appId=20000135”;⽕车票mes = “alipayqr://platformapi/startapp?appId=20000136”;游戏充值mes = “alipayqr://platformapi/startapp?appId=20000139”;酒店搜索mes = “alipayqr://platformapi/startapp?appId=20000141”;修改昵称mes = “alipayqr://platformapi/startapp?appId=20000142”;娱乐宝mes = “alipayqr://platformapi/startapp?appId=20000143”;⽕车票汽车票预定mes = “alipayqr://platformapi/startapp?appId=20000146”;我的淘宝mes = “alipayqr://platformapi/startapp?appId=20000150”;汇率换算mes = “alipayqr://platformapi/startapp?appId=20000153”;游戏中⼼mes = “alipayqr://platformapi/startapp?appId=20000155”;飞猪mes = “alipayqr://platformapi/startapp?appId=20000157”;国际机票查询mes = “alipayqr://platformapi/startapp?appId=20000160”;蚂蚁会员mes = “alipayqr://platformapi/startapp?appId=20000161”;理财⼩⼯具mes = “alipayqr://platformapi/startapp?appId=20000162”;⽺城通mes = “alipayqr://platformapi/startapp?appId=20000165”;定期理财mes = “alipayqr://platformapi/startapp?appId=20000161”;指纹⼿势解锁mes = “alipayqr://platformapi/startapp?appId=20000168”;年度账单mes = “alipayqr://platformapi/startapp?appId=20000176”;红包mes = “alipayqr://platformapi/startapp?appId=20000183”;设置⼿势密码mes = “alipayqr://platformapi/startapp?appId=20000161”;指纹⼿势解锁设定界⾯mes = “alipayqr://platformapi/startapp?appId=20000186”;通讯录mes = “alipayqr://platformapi/startapp?appId=20000161”;绑定智能⼿环mes = “alipayqr://platformapi/startapp?appId=20000197”;⾸页-热门游戏mes = “alipayqr://platformapi/startapp?appId=20000199”;花呗mes = “alipayqr://platformapi/startapp?appId=20000205”;亲情圈mes = “alipayqr://platformapi/startapp?appId=20000218”;黄⾦mes = “alipayqr://platformapi/startapp?appId=20000225”;借条mes = “alipayqr://platformapi/startapp?appId=20000227”;卡包mes = “alipayqr://platformapi/startapp?appId=20000234”;刷脸mes = “alipayqr://platformapi/startapp?appId=20000235”;服务提醒mes = “alipayqr://platformapi/startapp?appId=20000241”;车险服务mes = “alipayqr://platformapi/startapp?appId=20000243”;总资产mes = “alipayqr://platformapi/startapp?appId=20000248”;个性签名mes = “alipayqr://platformapi/startapp?appId=20000252”;朋友模块mes = “alipayqr://platformapi/startapp?appId=20000255”;账户充值mes = “alipayqr://platformapi/startapp?appId=20000266”;邮箱账单mes = “alipayqr://platformapi/startapp?appId=20000288”;聊天室mes = “alipayqr://platformapi/startapp?appId=20000290”;可能认识的⼈mes = “alipayqr://platformapi/startapp?appId=20000298”;证书管理mes = “alipayqr://platformapi/startapp?appId=20000301”;多设备管理mes = “alipayqr://platformapi/startapp?appId=20000305”;⽀付宝内付款码声波付mes = “alipayqr://platformapi/startapp?appId=20000307”;暗号还有其他的欢迎评论分享⼀下~。
扫码支付方案

扫码支付方案扫码支付已成为当代社会中非常常见的支付方式之一。
通过扫描二维码,用户可以快速便捷地完成支付操作。
在这篇文章中,我将为您介绍几种常见的扫码支付方案,并分析它们的优缺点。
同时,我也将讨论扫码支付在未来的发展趋势。
一、支付宝扫码支付支付宝扫码支付是目前国内最常见的扫码支付方案之一。
用户只需要打开支付宝应用,选择“扫一扫”功能,然后对准商家提供的二维码进行扫描即可完成支付。
支付宝扫码支付具有以下优点:首先,支付宝用户众多,几乎每个人都可以使用;其次,支付宝的支付流程简便快捷,省时省力;再次,支付宝对用户的资金安全有很好的保障机制。
然而,支付宝扫码支付也存在一些问题,例如对于没有安装支付宝应用的用户来说,使用起来就不太方便。
二、微信扫码支付微信扫码支付是另一种主流的扫码支付方案。
与支付宝扫码支付类似,用户打开微信应用后选择“扫一扫”功能,并对准商家提供的二维码进行扫描即可完成支付。
微信扫码支付的优点如下:首先,微信拥有庞大的用户基础,用户数量多;其次,微信扫码支付相对便捷,使用起来简单;再次,微信支付也有很好的资金安全机制。
然而,与支付宝扫码支付一样,微信扫码支付也存在应用未安装的用户无法使用的问题。
三、银联云闪付银联云闪付是银联推出的一种扫码支付方案。
用户只需打开银联云闪付应用,选择“扫码支付”功能后对准商家二维码扫描即可完成支付。
银联云闪付的优点在于:首先,银联云闪付与多家银行合作,用户数量庞大;其次,银联作为国内主要支付网关,对用户资金的安全性保障较高。
不过,使用银联云闪付进行扫码支付也需要安装相应的应用。
四、苹果支付苹果支付是苹果公司推出的扫码支付解决方案。
用户在iPhone或者iPad等苹果设备上添加银行卡,然后选择“扫码支付”功能完成支付。
苹果支付的优点如下:首先,苹果拥有庞大的用户群体,用户数量众多;其次,苹果支付的安全性较高,用户的资金相对较为安全。
但是,苹果支付只适用于苹果设备用户,而且对于部分老款设备可能不支持。
php面试题简述微信支付的流程(3篇)

第1篇一、微信支付简介微信支付是腾讯公司推出的一款便捷的移动支付产品,用户可以通过微信客户端进行线上支付、线下支付等多种支付场景。
微信支付具有安全性高、便捷性强、用户量大等特点,广泛应用于电子商务、O2O、线下零售等多个领域。
二、微信支付流程1. 订单创建(1)商户在后台创建订单,订单信息包括商品名称、订单号、订单金额等。
(2)商户将订单信息发送至微信支付平台。
2. 统一下单(1)微信支付平台收到商户订单信息后,进行订单验证。
(2)验证通过后,微信支付平台生成支付参数,包括订单号、金额、签名等。
(3)微信支付平台将支付参数发送给商户。
3. 发起支付(1)商户将支付参数传递给前端页面。
(2)前端页面根据支付参数生成支付界面,用户进行支付操作。
4. 支付通知(1)用户完成支付后,微信支付平台发送支付通知给商户。
(2)商户接收支付通知,验证通知签名。
(3)验证通过后,商户处理支付结果,如修改订单状态、发送通知给用户等。
5. 退款(1)用户或商户发起退款请求。
(2)商户验证退款请求,将退款信息发送至微信支付平台。
(3)微信支付平台处理退款请求,将退款金额返还给用户。
三、PHP面试题1. 请简述微信支付的基本流程。
答:微信支付的基本流程包括订单创建、统一下单、发起支付、支付通知和退款。
2. 微信支付中,商户需要提供哪些订单信息?答:商户需要提供订单号、商品名称、订单金额等信息。
3. 微信支付中,如何生成支付参数?答:商户可以使用微信支付平台提供的API接口,根据订单信息和商户账号生成支付参数。
4. 在微信支付流程中,支付通知的作用是什么?答:支付通知是微信支付平台通知商户支付结果的一种方式,商户可以通过支付通知处理支付结果,如修改订单状态、发送通知给用户等。
5. 请简述微信支付退款流程。
答:微信支付退款流程包括用户或商户发起退款请求、商户验证退款请求、将退款信息发送至微信支付平台、微信支付平台处理退款请求、退款金额返还给用户。
微信支付demo

微信⽀付demo这⾥开发时使⽤的是thinkphp5.11.直接唤起微信⽀付<?phpnamespace app\index\controller;use wechatpay\lib\WxPayApi;use wechatpay\lib\WxPayUnifiedOrder;use wechatpay\example\JsApiPay;use wechatpay\example\WxPayConfig;use think\facade\Env;class Pay{/*1、交易⾦额交易⾦额默认为⼈民币交易,接⼝中参数⽀付⾦额单位为【分】,参数值不能带⼩数。
对账单中的交易⾦额单位为【元】。
外币交易的⽀付⾦额精确到币种的最⼩单位,参数值不能带⼩数点。
2、交易类型JSAPI--公众号⽀付、NATIVE--原⽣扫码⽀付、APP--app⽀付,统⼀下单接⼝trade_type的传参可参考这⾥MICROPAY--刷卡⽀付,刷卡⽀付有单独的⽀付接⼝,不调⽤统⼀下单接⼝3、货币类型货币类型的取值列表:CNY:⼈民币4、时间标准北京时间,时区为东⼋区;如果商户的系统时间为⾮标准北京时间。
参数值必须根据商户系统所在时区先换算成标准北京时间,例如商户所在地为0时区的伦敦,当地时间为2014年11⽉11⽇0时0分0秒,换算成北京时间为2014年11⽉11⽇8时 5、时间戳标准北京时间,时区为东⼋区,⾃1970年1⽉1⽇ 0点0分0秒以来的秒数。
注意:部分系统取到的值为毫秒级,需要转换成秒(10位数字)。
6、商户订单号商户⽀付的订单号由商户⾃定义⽣成,仅⽀持使⽤字母、数字、中划线-、下划线_、竖线|、星号*这些英⽂半⾓字符的组合,请勿使⽤汉字或全⾓等特殊字符。
微信⽀付要求商户订单号保持唯⼀性(建议根据当前系统时间加随机序列来⽣成订单号) *//*** 微信⽀付调⽤* @author ffx* @param int $userId ⽤户id* @param float $money ⾦额* @param int $type ⽀付类型(1充值,2订单⽀付)* @param string $body 显⽰title,提⽰头信息* @param string $backUrl 回调地址(/index/pay/wxPayBack)* @param string $addition 附加参数(微信回调时原样返回)* @return bool|mixed*/public function wxPay($userId,$money,$type,$body,$backUrl,$addition = ''){$out_trade_no = self::getOrderNo();$wxchid = config('wechat.wxmchid');$wxAppId = config('wechat.paywxAppId');//微信⽀付sdk中的⽂件include_once EXTEND_PATH."wechatpay/lib/WxPay.Api.php";include_once EXTEND_PATH."wechatpay/example/WxPay.JsApiPay.php";$total_money = floor(sprintf("%0.3f",$money)*100);if(!$total_money || $total_money <= 0){return ['code'=>100001,'message'=>"⽀付⾦额⼩于0"];}if($_SERVER["REQUEST_SCHEME"] == "http"){$notify_url = 'http://'.$_SERVER['HTTP_HOST'].$backUrl;}else{$notify_url = 'https://'.$_SERVER['HTTP_HOST'].$backUrl;}//此处查询的是登录时存起来的openid$openid = Db::name('member')->where('id',$userId)->value('openid');$input = new \WxPayUnifiedOrder();$input->SetAppid($wxAppId);$input->SetMch_id($wxchid); //商户号$input->SetAttach($addition); //附加参数$nonceStr = self::createNonceStr();$input->SetNonce_str($nonceStr);//⾃定义随机字符串$input->SetBody($body);//$input->SetOut_trade_no($out_trade_no);//订单号,⾃⼰建$input->SetTotal_fee($total_money);//⾦钱$input->SetSpbill_create_ip($this->getIP());//客户端ip$input->SetTime_start(date("YmdHis"));$input->SetTime_expire(date("YmdHis", time() + 600));//过期时间$input->SetNotify_url($notify_url);//回调的接⼝地址$input->SetTrade_type("JSAPI");//⽀付类型$input->SetOpenid($openid);//此处两个是微信⽀付的sdk的类$WxPayApi = new WxPayApi();$config = new WxPayConfig();$response = $WxPayApi->unifiedOrder($config,$input);//预创建订单//写⼊⽀付记录表(业务逻辑处理)$res = $this->insertWxPayLog($userId,$out_trade_no,$money,$type,0);if(!$res){return false;}if($response['result_code']=='SUCCESS' && $response['return_code']=='SUCCESS' && $response['return_msg']=='OK') {$tools = new JsApiPay();$response['nonce_str'] = $nonceStr;$jsApiParameters = $tools->GetJsApiParameters($response);return json_decode($jsApiParameters);//$jsApiParameters⽰例//{"appId":"wx194a1075c8bca3d9","nonceStr":"4tmc7nttscu5w6u6cqbxlgvum4qs6p8y","package":"prepay_id=wx05155440194924091e0efc912670185750","signType":"MD5","timeStamp":"1541404480","paySign":"CD4DE57A6B5B2B5418 //输出直接唤起⽀付// $str = "<html><body></body></html>";//// $str .='<html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><title>微信⽀付</title></head><body>';//// $str .= "<script>function onBridgeReady(){WeixinJSBridge.invoke('getBrandWCPayRequest',$jsApiParameters)}if(typeof WeixinJSBridge=='undefined'){if(document.addEventListener){document.addEventListener('WeixinJSBridgeReady',o//// echo $str;exit;}else{return false;}}/*** 余额⽀付回调* @author ffx**/function amountPayBack(){$xml = file_get_contents('php://input');$xmlJson = json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA));$arr = json_decode($xmlJson, true);//此处注释暂未⽤到/* //⽤户http_build_query()将数据转成URL键值对形式$sign = http_build_query($arr);//md5处理$sign = md5($sign);//转⼤写$sign = strtoupper($sign);//验签名。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
[DEMO] 支付宝网页支付及微信网页扫码支付
DEMO 包含支付宝网页支付以及微信扫码支付功能,相对于手机端支付,完善支付场景,使PC 端与移动端都能实现支付需要。
摘要:
DEMO 已经将支付宝及微信支付需要的配置信息独立化,导入,配置,即可使用。
对于各平台应用前置配置要求,接口各参数意义及用途,请参阅:支付宝网页支付官方文档微信扫码支付(模式二)官方文档
XPZ 下载:
Demo_PCPayment_20180102-114.1.zip (1.04 MB, 下载次数: 1)Note:修复支付宝支付成功页面PaySuccess验签参数SDT 错误
XPZ 下载:
Demo_PCPaymen-t114.2.zip (1.04 MB, 下载次数: 1)另:此xpz 中使用了支付宝服务端sdk,现只实现了.Net 环境的封装,java 环境之后补充。
说明:
导入xpz,配置数据库连接信息,编译运行。
导入module 结构如下:打开访问pcpayment.main.aspx页面
点击“加载配置”按钮可以加载默认配置
按照文档说明配置各参数,点击“保存配置”按钮保存修改
页面下方是用户信息及各用户的支付记录,默认初始化了三个用户用于测试
点击“支付宝支付”按钮,进入支付宝支付页面
默认填入了商品信息及金额,点击页面下方确认支付”按钮进行支付
正常情况下会返回一个form 表单的字符串,及支付宝返回的订单信息
点击“访问上面的返回form 支付”按钮,触发表单中自动提交事件,打开支付宝网页支付页面
完成支付后,将跳转到支付成功页面
返回main 页面查看用户支付记录
可以查看到支付时间,同步返回及异步通知的信息。
可以看到,支付状态一栏中显示了接收到同步及异步信息的先后顺序,且用户关闭支付宝页面后将无法跳转到成功提示页面,及没有同步返回消息,因此,务必按照官方推荐,在异步通知中处理支付成功逻辑。
点击“微信支付 ”按钮,进入微信扫码支付页面
默认填入了订单信息及金额,点击 “确认支付 ”按钮调用微信统一下单 API ,获取 返回参数。
注意微信的金额单位是 “分”,与支付宝 “元”为单位不同。
且此参数不支持小数点, 只能是整数,及 1为最小金额, 0.01元。
正常情况下可以获取到微信支付 url ,点击 “将支付 url
转为二维码进行扫码支付
按钮,获取二维码图片以进行扫码支付
支付完成后返回main 页面查看用户支付记录
可以看到微信没有同步返回参数,依赖于异步通知,业务逻辑同样在异步通知时处理。