python怎么实现微信小程序的多种支付方式
发表于:2024-11-23 作者:千家信息网编辑
千家信息网最后更新 2024年11月23日,本篇内容主要讲解"python怎么实现微信小程序的多种支付方式",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"python怎么实现微信小程序的多种支付方式"
千家信息网最后更新 2024年11月23日python怎么实现微信小程序的多种支付方式
本篇内容主要讲解"python怎么实现微信小程序的多种支付方式",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"python怎么实现微信小程序的多种支付方式"吧!
多支付
原理
1.利用鸭子类型。规定前台传过来支付方式。pay_methon2.再支付方式里面实现pay(名字统一)方法3.回调函数,在支付方式里面写notify(名字统一)统一方法,返回的data统一格式。 eg: data={"statu":'success',"order_id":notity_data['order_id'],"print":"0000"} 这样的的牛逼之处:我们在修改、添加支付方式的时候,只需要按照鸭子类型,命名一样的函数名,写好自己的支付方式即可。不需要改其他的代码
多支付接口代码
urls.py:
path("order/create",order.Creat.as_view()),path("order/notify/<paymethod>",order.Notify.as_view())
# 这里所有的支付都是走的小程序微信支付:import importlibclass Creat(APIView): ...伪代码 pay_methon = "Wxpay" # 如果是PC端,可以前台传过来支付方式 try: #pay_file是对象 pay_file = importlib.import_module(f"app01.Pay.{pay_methon}") # 调用对应的支付方式 pay_class = getattr(pay_file, pay_methon) # 反射机制 order_data['open_id'] = openid # 传的参数 order_data['ip'] = host_ip # 传的参数 data = pay_class().pay(order_data) # 调用支付 except: return Response({"code":201,"msg":"未知支付方式"})# 异步回调的class Notify(APIView): def post(self,request,paymethod): pay_file = importlib.import_module(f"app01.Pay.{paymethod}") pay_class = getattr(pay_file,paymethod) data = pay_class().notify(request.data) # 调用异步回调 # 判断data数据中属性,然后修改订单 if data["statu"] == "success": models.Order.objects.filter(order_id =data['order_id']).update(pay_status =1) return Response(data["print"])
支付方式代码
Alipay支付
# Alipay支付class Alipay: def pay(self,order_data): #统一下单方法 pass def notify(self,notity_data): if notity_data['success'] : #notity_data['order_id']表示商城订单号 data={"statu":'success',"order_id":notity_data['order_id'],"print":"0000"} return data
YLpay支付方式
# YLpay支付方式class YLpay: def pay(self,order_data): pass def notify(self,request_data): #验签 #数据处理 pass
Wxpay支付方式
import timefrom app01.wx import settingsclass Wxpay: def pay(self,order_data): self.order_id = order_data["order_id"] self.open_id = order_data['open_id'] self.ip = order_data['ip'] data_body = self.get_body_data() import requests url = "https://api.mch.weixin.qq.com/pay/unifiedorder" response = requests.post(url, data_body.encode("utf-8"), headers={'content-type': "application/xml"}) res_dict = self.xml_to_dic(response.content) timeStamp = str(int(time.time())) paySign = self.get_pay_sign(res_dict, timeStamp) data_dic = { 'timeStamp': timeStamp, 'nonceStr': res_dict['nonce_str'], 'package': f"prepay_id={res_dict['prepay_id']}", 'signType': 'MD5', "paySign": paySign, } return data_dic def get_pay_sign(self, res_dict, timeStamp): data_dic = { 'appId': res_dict['appid'], 'timeStamp': timeStamp, 'nonceStr': res_dict['nonce_str'], 'package': f"prepay_id={res_dict['prepay_id']}", "signType": "MD5" } sign_str = "&".join([f"{k}={data_dic[k]}" for k in sorted(data_dic)]) sign_str = f"{sign_str}&key={settings.pay_apikey}" import hashlib md5 = hashlib.md5() md5.update(sign_str.encode("utf-8")) sign = md5.hexdigest() return sign.upper() def xml_to_dic(self, xml_data): import xml.etree.ElementTree as ET ''' xml to dict :param xml_data: :return: ''' xml_dict = {} root = ET.fromstring(xml_data) for child in root: xml_dict[child.tag] = child.text return xml_dict def get_random(self): import random data = "123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP" nonce_str = "".join(random.sample(data, 30)) return nonce_str def get_sign(self): data_dic = { "nonce_str": self.nonce_str, "out_trade_no": self.out_trade_no, "spbill_create_ip": self.spbill_create_ip, "notify_url": self.notify_url, "openid": self.open_id, "body": self.body, "trade_type": "JSAPI", "appid": self.appid, "total_fee": "1", "mch_id": self.mch_id } sign_str = "&".join([f"{k}={data_dic[k]}" for k in sorted(data_dic)]) sign_str = f"{sign_str}&key={settings.pay_apikey}" import hashlib md5 = hashlib.md5() md5.update(sign_str.encode("utf-8")) sign = md5.hexdigest() return sign.upper() def get_body_data(self): self.appid = settings.AppId # openid=self.open_id self.mch_id = str(settings.pay_mchid) self.nonce_str = self.get_random() self.out_trade_no = self.order_id self.spbill_create_ip = self.ip self.notify_url = "https://www.test.com" self.body = "老男孩学费" self.sign = self.get_sign() body_data = f""" <xml> <appid>{self.appid}</appid> <mch_id>{self.mch_id}</mch_id> <nonce_str>{self.nonce_str}</nonce_str> <sign>{self.sign}</sign> <body>{self.body}</body> <out_trade_no>{self.out_trade_no}</out_trade_no> <total_fee>1</total_fee> <spbill_create_ip>{ self.spbill_create_ip}</spbill_create_ip> <notify_url>{self.notify_url}</notify_url> <openid>{self.open_id}</openid> <trade_type>JSAPI</trade_type> </xml>""" return body_data
Creat下订单
from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom app01.wx import wx_loginimport hashlib ,timefrom app01 import modelsfrom django.core.cache import cachefrom django.db import transactionfrom app01.func import function_toolimport importlibclass Creat(APIView): @transaction.atomic def post(self,request): #小程序提交给我们的数据 ''' {'token': '0bb2aa1102ca9c8306133b2539c3508b', 'remark': '', 'province': '广东省', 'city': '广州市', 'county': '海珠区', 'address': '新港中路397号', 'phone': '020-81167888', 'name': '张三', 'buy_list': {'2': 1}} ''' param = request.data if param.get("token") and param.get("buy_list"): user_cache = cache.get(param["token"]) if user_cache: # 获取ip if request.META.get("HTTP_X_FORWARDED_FOR"): host_ip = request.META["HTTP_X_FROWARDED_FOR"] else: host_ip = request.META["REMOTE_ADDR"] openid = user_cache.split("&")[0] #data['openid']+"&"+data["session_key"] user_data = models.Wxuser.objects.filter(openid=openid).first() order_data = { "consignee_mobile": param['phone'], 'consignee_name': param['name'], 'wxuser_id': user_data.id, "memo": param['remark'], "consignee_area": f"{param['province']},{param['city']},{param['county']}", "consignee_address": param['address'], "order_id": function_tool.get_order_id(), "order_total": 0 } # 1 上面的order_data 出来上面的数据,有些是需要通过购买上面列表做累加才能获得到 # 2 order_item 是通过buy_list里面的商品列表,一个键值对就是一条记入'buy_list': {'2': 1,"1":2} # 3 再每一次增加一个order_item的时候,我们都需要校验库存。如果有一个商品的库存不足,我们就应该不然用户下单 # 4 由于第三步中进行多次增加,如果再后面的的商品库存有问题,我们不让他下单,但是前面的数据已经插入。 # 所有我们要用数据库的事务管理数据的统一。就算order_item没有问题,order_data,插入的时候,也可能出错,所以也要用事务 # 5 由于并发问题,所有的用户都会对数据的库存进行加减,所以我们这里再校验库存的时候要用锁。 buy_list = param.get("buy_list") # 获取到buy_list是没有商品信息只有有id,我们先把buy_list中的所有商品查出来 goods_key = list(buy_list.keys()) all_product = models.Product.objects.filter(product_id__in = goods_key) #用for循环添加order_item sid = transaction.savepoint() for product in all_product: # 将product.product_id 转字符串,为了通过product.product_id在buy_list获取商品的购买数量 product.product_id = str(product.product_id) # 获取订单总金额 order_data['order_total'] += product.price* buy_list[product.product_id] for i in range(3): #先查库存,重新查库的 stock = product.stock.quantity #当前的库存的库存数量,减去购买数量,是否大于0 new_stock = stock-buy_list[product.product_id] if new_stock < 0 : #库存不足,回滚 transaction.savepoint_rollback(sid) return Response({"code":201,"msg": f"{product.name}库存不足"}) #乐观锁 res = models.Stock.objects.filter(quantity= stock,stock_id =product.stock.stock_id).update(quantity = new_stock) if not res: if i == 2: transaction.savepoint_rollback(sid) return Response({"code":201,"msg": "创建订单失败"}) else: continue else: break #获取购买数量 new_buy_cout = product.buy_count + buy_list[product.product_id] models.Product.objects.filter(product_id=product.product_id).update(buy_count =new_buy_cout) #组织order_item的数据 order_item_data = { 'order_id': order_data['order_id'], 'product_id': product.product_id, "name": product.name, "image": product.image, "price": product.price, "nums": buy_list[product.product_id], "brief": product.brief } models.Order_items.objects.create(**order_item_data) models.Order.objects.create(**order_data) transaction.savepoint_commit(sid) #所有的支付都是走的小程序微信支付: pay_methon = "Wxpay" try: #pay_file是对象 pay_file = importlib.import_module(f"app01.Pay.{pay_methon}") pay_class = getattr(pay_file, pay_methon) order_data['open_id'] = openid order_data['ip'] = host_ip data = pay_class().pay(order_data) except: return Response({"code":201,"msg":"未知支付方式"}) # 1对接小程序支付 # 2 我们要用celery去定时检查,该订单在指定时间内用没有支付,没有支付,取消订单,回滚库存 function_tool.pay_status(order_data['order_id']) return Response({"code":200,"msg":"ok","data":data}) else: return Response({"code": 201, "msg": "无效的token"}) else: return Response({"code":202,"msg":"缺少参数"})class Notify(APIView): def post(self,request,paymethod): pay_file = importlib.import_module(f"app01.Pay.{paymethod}") pay_class = getattr(pay_file,paymethod) data = pay_class().notify(request.data) # 判断data数据中属性,然后修改订单 if data["statu"] == "success": models.Order.objects.filter(order_id =data['order_id']).update(pay_status =1) return Response(data["print"])
到此,相信大家对"python怎么实现微信小程序的多种支付方式"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
支付
方式
库存
数据
订单
程序
商品
统一
代码
数量
方法
时候
多种
参数
问题
utf-8
事务
内容
函数
前台
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
上海暴雪软件开发有限公司上班
系统管理员删除数据库
速达ERP数据库
数据库窗体视图有哪几个节
集成及软件开发合同管理制度
软件测试技术 软件开发
淘宝上的服务器找不到
手机经常显示没法连接服务器
访问云数据库
常用的数据库应用开发工具
网络安全法停机处理
安卓访问服务器数据库
江苏常规网络技术咨询商家
在网络安全会议的发言
dell服务器蓝色灯不亮
中国邮政软件开发面试题
数据库在医学上应用
临沂微企邦网络技术服务怎么样
政府网络安全办公室职责
h3c服务器直流电源
微信文件服务器保留吗
水尚网络技术
大数据软件开发正规平台
吉林新一代软件开发五星服务
网络安全法停机处理
泰州智能化服务器技术指导
数据库是显示所有电脑数据吗
苹果链接苹果服务器出问题
wind数据库搜索视频
网络安全周例会发言