微信小程序微信支付实现,微信小程序实现微信支付功能

  微信小程序微信支付实现,微信小程序实现微信支付功能

  本文主要介绍python对微信小程序各种支付方式的实现实例。有需要的朋友可以借鉴一下,希望能有所帮助。祝大家进步很大,早日升职加薪。

  00-1010多支付原则多支付接口代码支付方式代码支付宝支付YLpay支付方式Wxpay支付方式创建下单

  

目录

  

多支付

  1.利用鸭子类型。从前台指定付款方式。支付方式

  2.支付(名称统一)方法在重新支付方法中实现。

  3.回调函数,其中写了notify(名称统一)的统一方法,返回的数据是统一格式的。

  eg : data={ statu : success , order _ id : notity _ data[ order _ id ], print:0000}

  这就牛逼了:我们在修改或者添加支付方式的时候,只需要根据鸭子类型来命名相同的功能名称,并编写自己的支付方式。不需要改变其他代码。

  

原理

  urls.py:

  路径(订单/创建,订单。Creat.as_view()),

  路径( order/notify/paymethod),顺序。Notify.as_view())

  #这里所有支付都是小程序微信支付:

  导入导入库

  类创建(APIView):

  .伪代码。

  Pay_methon=Wxpay #如果是PC,可以送到前台付款。

  尝试:

  #pay_file是一个对象。

  pay _ file=import lib . import _ module(f app 01 . 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) #调用付款

  例外:

  返回响应({code 3360201, msg 3360 未知付款方式 })

  异步回调的次数

  类别通知(APIView):

  定义过帐(自身、请求、支付方法):

  pay _ file=import lib . import _ module(f app 01 . pay . { pay method } )

  pay_class=getattr(支付文件,支付方法)

  Data=pay _ class()。notify (request.data) #调用异步回调

  #判断数据data中的属性,然后修改顺序。

  如果数据[状态]=成功 :

  模特。order . objects . filter(order _ id=data[ order _ id ])。更新(pay_status=1)

  返回响应(数据[打印])

  

多支付接口代码

  

支付方式代码

  #支付宝支付

  支付宝类别:

  延期付款(自身,订单_数据):

  #统一订购方法

  及格

  定义通知(选择

  f,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 time

  from app01.wx import settings

  class 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 APIView

  from rest_framework.response import Response

  from app01.wx import wx_login

  import hashlib ,time

  from app01 import models

  from django.core.cache import cache

  from django.db import transaction

  from app01.func import function_tool

  import importlib

  class 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实现微信小程序的多种支付方式的详细内容,更多关于python微信支付方式的资料请关注盛行IT软件开发工作室其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: