Login day87_11_7 small program of micro-letters, payment authorization

One. The login interface.

  Official documents https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html

  In the login interface, the following steps:

  1. wx acquired through the micro channel function code, request to the back end.

  2. Obtain appid and secret code and transmission developers to developers url

GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

        https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html

  3. session_key obtained from openid and associated database (open as the user information stored in the database, to return to the front end session_key save)

  4. In subsequent operations take openid acquiring the user, return data traffic.

 

 User view:

from rest_framework.views import APIView
from rest_framework.response import  Response
from django.core.cache import cache
from  app01 import models
import hashlib,time
from app01.wx import wx_Login
class Login(APIView):
    def post(self,request):
        param=request.data
        if param.get("code"):
            data=wx_Login.login(param.get("code"))
            if data:
                val=data['openid']+"&"+data["session_key"]
                key=str(int(time.time()))+data['openid']
                md5=hashlib.md5()
                md5.update(key.encode("utf-8"))
                key=md5.hexdigest()
                cache.set(key,val)
                has_user=models.Wxuser.objects.filter(openid=data['openid']).first()
                if not has_user:
                    models.Wxuser.objects.create(openid=data['openid'])
                return  Response({"code":200,"msg":"ok",'data':{"login_key":key}})

            else:
                return Response({"code":200,"msg":"code错误"})
        else:
            return Response({"code": 200, "msg": "缺少参数"})
view/User
import requests
from app01.wx import settings

def login(code):
    code_url = settings.code2Session.format(settings.AppId, settings.AppSecret, code)
    response = requests.get(code_url)
    json_response = response.json()
    if json_response.get('session_key'):
        return json_response
    else:
        return False
wx/wx_login
AppId=""

AppSecret=""

code2Session="https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code"
pay_mchid =''
pay_apikey = ''
wx/setting

two. Authorization process

 

   In this authorization process, session_key will expire, so to determine whether the session expired by checksession,

  To get the user's current settings, and user information through getsession and getuserinfo.

  By login session_key, encryptedData front-end transmission, iv, login_key to decrypt the personal information

import base64
import json
from Crypto.Cipher import AES
from . import settings


class WXBizDataCrypt:
    def __init__(self, appId, sessionKey):
        self.appId = appId
        self.sessionKey = sessionKey

    def decrypt(self, encryptedData, iv):
        # base64 decode
        sessionKey = base64.b64decode(self.sessionKey)
        encryptedData = base64.b64decode(encryptedData)
        iv = base64.b64decode(iv)

        cipher = AES.new(sessionKey, AES.MODE_CBC, iv)

        decrypted = json.loads(self._unpad(cipher.decrypt(encryptedData)))

        if decrypted['watermark']['appid'] != self.appId:
            raise Exception('Invalid Buffer')

        return decrypted

    def _unpad(self, s):
        return s[:-ord(s[len(s)-1:])]

    @classmethod
    def getInfo(cls,encryptedData,iv,sessionKey):
        return cls(settings.AppId, sessionKey).decrypt(encryptedData, iv)
wx/WXBizDataCrypt.py
class getInfo(APIView):
    def post(self,request,*args,**kwargs):
        param = request.data
        print(request.data)
        if param['encryptedData'] and param['iv'] and param['login_key']:
            print(cache.get(param['login_key']))
            openid,session_key = cache.get(param['login_key']).split('&')
            data = WXBizDataCrypt.WXBizDataCrypt.getInfo(param['encryptedData'],param['iv'],session_key)
            save_data = {
                "name": data['nickName'],
                "avatar": data['avatarUrl'],
                "language": data['language'],
                "province": data['province'],
                "city": data['city'],
                "country": data['country'],
            }
            models.Wxuser.objects.filter(openid=openid).update(**save_data)
            data = models.Wxuser.objects.filter(openid=openid).first()
            data = User_ser.User_ser(instance=data,many=False).data
            return Response({"code":200,"msg":"成功","data":data})
        return Response({"code":200,"msg":"缺少参数"})
views

three. Payment Process

  https://developers.weixin.qq.com/miniprogram/dev/api/open-api/payment/wx.requestPayment.html

  Data in the development of the document

 

pay:function(){
    wx.request({
      url: "http://127.0.0.1:8000/pay/",
      method: "POST",
      data:{"login_key":wx.getStorageSync("login_key")},
      header: { "content-type": "application/json" },
      success: function (e) {
        console.log(e)
        wx.requestPayment({
          'timeStamp': e.data.data.timeStamp,
          'nonceStr': e.data.data.nonceStr,
          'package': e.data.data.package,
          'signType': e.data.data.signType,
          'paySign': e.data.data.paySign,
          'success': function (res)
           {
             console.log(res,"成功")
            },
          'fail': function (res) 
          {
            console.log ( " pay for failure " , RES)
           },
        

```
    })
  }
})
```

  },
front end
 <button bind:tap="pay"> 支付</button>
import hashlib
import random
import time
from django.core.cache import cache

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
# Create your views here.
from .wx import settings
from .wx.wx_login import login as logins
from . import models
from .wx import WXBizDataCrypt
from app01.my_ser import User_ser
import requests

class test(APIView):
    def post(self,request,*args,**kwargs):
        print(request)
        return Response(data={'msg':'ok'},status='200')

class login(APIView):
    def post(self,request,*args,**kwargs):
        param = request.data
        print(param.get('code'))
        if param.get('code'):
            data = logins(param.get('code'))
            if data:
                val = data['openid'] + '&' + data['session_key']
                print("openid"+data['openid'],"session_key"+ data['session_key'])
                key = data['openid'] + str(int(time.time()))
                md5 = hashlib.md5()
                md5.update(key.encode('utf-8'))
                key = md5.hexdigest()
                cache.set(key,val)
                has_user = models.Wxuser.objects.filter(openid=data['openid']).first()
                if not has_user:
                    models.Wxuser.objects.create(openid=data['openid'])
                return Response({
                    "code": 200,
                    "msg": "ok",
                    "data": {"login_key": key}
                })
            the else :
                 return the Response ({ ' code ' : 404, ' MSG ' : ' code invalid ' })
         the else :
             return the Response ({ ' code ' : 200 is, ' MSG ' : ' no parameters ' })


class getInfo(APIView):
    def post(self,request,*args,**kwargs):
        param = request.data
        print(request.data)
        if param['encryptedData'] and param['iv'] and param['login_key']:
            print(cache.get(param['login_key']))
            openid,session_key = cache.get(param['login_key']).split('&')
            data = WXBizDataCrypt.WXBizDataCrypt.getInfo(param['encryptedData'],param['iv'],session_key)
            save_data = {
                "name": data['nickName'],
                "avatar": data['avatarUrl'],
                "language": data['language'],
                "province": data['province'],
                "city": data['city'],
                "country": data['country'],
            }
            models.Wxuser.objects.filter(openid=openid).update(**save_data)
            data = models.Wxuser.objects.filter(openid=openid).first()
            data = User_ser.User_ser(instance=data,many=False).data
            return Response({"code":200,"msg":"成功","data":data})
        return Response({"code":200,"msg":"缺少参数"})


class pay(APIView):
    def post(self,request,*args,**kwargs):
        param = request.data
        if param.get("login_key"):
            openid, session_key = cache.get(param.get("login_key")).split("&")
            self.openid = openid
            if request.META.get('HTTP_X_FORWARDED_FOR'):
                self.ip = request.META [ ' HTTP_X_FORWARDED_FOR ' ]
             the else :
                 # If no use to use Nginx REMOTE_ADDR 
                self.ip request.META = [ ' REMOTE_ADDR ' ]
            data = self.pay()
            return Response({"code":200,"msg":"ok","data":data})
        else:
            return Response({"code": 400, "msg": "缺少参数"})

    def get_str(self):
        str_all = "1234567890abcdefghijklmnopqrstuvwxyz"
        nonce_str = "".join(random.sample(str_all,20))
        return nonce_str

    def xml_to_dict(self,data):
        import xml.etree.ElementTree as ET
        xml_dict = {}
        data_dic = ET.fromstring(data)
        for item in data_dic:
            xml_dict[item.tag] = item.text
        return xml_dict



    def get_sign(self):
        data_dic = {
            "nonce_str": self.nonce_str,
            "out_trade_no": self.out_trade_no,
            "spbill_create_ip": self.ip,
            "notify_url": self.notify_url,
            "openid": self.openid,
            "body": self.body,
            "trade_type": "JSAPI",
            "appid": self.appid,
            "total_fee": self.total_fee,
            "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}"
        md5 = hashlib.md5()
        md5.update(sign_str.encode("utf-8"))
        return md5.hexdigest().upper()


    def get_order(self):
        order_id = str(time.strftime("%Y%m%d%H%M%S"))
        return order_id

    def pay(self):
        self.appid = settings.AppId
        self.mch_id = settings.pay_mchid
        self.nonce_str = self.get_str()
        self.body = "lzx"
        self.out_trade_no = self.get_order()
        self.total_fee = 1
        self.spbill_create_ip = self.ip
        self.notify_url = "http:/www.baidu.com"
        self.trade_type = "JSAPI"
        self.sign = self.get_sign()
        data = f'''
                <xml>
                       <appid>{self.appid}</appid>
                       <body>{ self.body}</body>
                       <mch_id>{self.mch_id}</mch_id>
                       <nonce_str>{self.nonce_str}</nonce_str>
                       <notify_url>{self.notify_url}</notify_url>
                       <openid>{self.openid}</openid>
                       <out_trade_no>{self.out_trade_no}</out_trade_no>
                       <spbill_create_ip>{self.spbill_create_ip}</spbill_create_ip>
                       <total_fee>{self.total_fee}</total_fee>
                       <trade_type>{self.trade_type}</trade_type>
                       <sign>{self.sign}</sign>
                </xml>
                '''
        url = "https://api.mch.weixin.qq.com/pay/unifiedorder"
        response = requests.post(url,data.encode("utf-8"),headers={"content-type":"application/xml"})
        res_data=self.xml_to_dict(response.content)
        data=self.two_sign(res_data["prepay_id"])
        return  data

    def two_sign(self, prepay_id):
        timeStamp=str(int(time.time()))
        nonceStr=self.get_str()
        data_dict={
            "appId":settings.AppId,
            "timeStamp":timeStamp,
            "nonceStr":nonceStr,
            "package":f"prepay_id={prepay_id}",
            "signType":"MD5"
        }
        sign_str = "&".join([f"{k}={data_dict[k]}" for k in sorted(data_dict)])
        sign_str = f"{sign_str}&key={settings.pay_apikey}"
        md5 = hashlib.md5()
        md5.update(sign_str.encode("utf-8"))
        sign=md5.hexdigest().upper()
        data_dict["paySign"]=sign
        data_dict.pop("appId")
        return  data_dict
view

  The need for secondary signature generation, and to submit the xml url. Also you need payid.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

Guess you like

Origin www.cnblogs.com/LZXlzmmddtm/p/11817133.html