亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python實現(xiàn)的微信支付方式總結(jié)【三種方式】

 更新時間:2019年04月13日 13:53:27   作者:微信1257309054  
這篇文章主要介紹了Python實現(xiàn)的微信支付方式,結(jié)合實例形式總結(jié)分析了Python實現(xiàn)的三種微信支付方式及相關(guān)操作步驟、原理、注意事項,需要的朋友可以參考下

本文實例講述了Python實現(xiàn)的微信支付方式。分享給大家供大家參考,具體如下:

一、準備環(huán)境

1、要有微信公眾號,商戶平臺賬號

https://pay.weixin.qq.com/wiki/doc/api/index.html

2、支持的支付方式有

3、備案域名

選擇掃碼支付,如果使用模式二則不需要域名,只需要可訪問的ip地址就行。

4、建一個Django項目。

一、掃碼支付

點擊“掃碼支付”按官方文檔配置好回調(diào)url(具體如何配置看官網(wǎng))
先從公眾號上獲取APP_IDAPP_SECRECT,從商戶平臺上獲取MCH_ID,API_KEY

1、使用模式一生成支付二維碼

這個二維碼是沒有時間限制的。

create_qrcode.html

創(chuàng)建二維碼頁面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>生成掃碼支付二維碼</title>
</head>
<body>
<form method="post" action="/wxpay/QRcode/" >
輸入手機號:<input name="phone"/>
<input id="submit" type="submit" value="生成二維碼">
  <br>
  {% if img_url %}
    <img src="{{ img_url }}" style="width: 200px;height: 200px"/>
  {% endif %}
<br>
{{ url }}
</form>
</body>
</html>

pay_settings.py

#微信支付配置
# ========支付相關(guān)配置信息===========
import random
import time
import hashlib
from random import Random
import qrcode
from bs4 import BeautifulSoup
APP_ID = "xxx" # 你公眾賬號上的appid
MCH_ID = "xxx" # 你的商戶號
API_KEY = "xxx" # 微信商戶平臺(pay.weixin.qq.com) -->賬戶設(shè)置 -->API安全 -->密鑰設(shè)置,設(shè)置完成后把密鑰復(fù)制到這里
APP_SECRECT = "xxx"
UFDODER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder" # 該url是微信下單api
NOTIFY_URL = "http://xxx/" # 微信支付結(jié)果回調(diào)接口,需要改為你的服務(wù)器上處理結(jié)果回調(diào)的方法路徑
CREATE_IP = 'xxx' # 你服務(wù)器的IP
def random_str(randomlength=8):
  """
  生成隨機字符串
  :param randomlength: 字符串長度
  :return:
  """
  str = ''
  chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
  length = len(chars) - 1
  random = Random()
  for i in range(randomlength):
    str+=chars[random.randint(0, length)]
  return str
def order_num(phone):
  """
  生成掃碼付款訂單號
  :param phone: 手機號
  :return:
  """
  local_time = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
  result = phone + 'T' + local_time + random_str(5)
  return result
def get_sign(data_dict, key):
  # 簽名函數(shù),參數(shù)為簽名的數(shù)據(jù)和密鑰
  params_list = sorted(data_dict.items(), key=lambda e: e[0], reverse=False) # 參數(shù)字典倒排序為列表
  params_str = "&".join(u"{}={}".format(k, v) for k, v in params_list) + '&key=' + key
  # 組織參數(shù)字符串并在末尾添加商戶交易密鑰
  md5 = hashlib.md5() # 使用MD5加密模式
  md5.update(params_str.encode('utf-8')) # 將參數(shù)字符串傳入
  sign = md5.hexdigest().upper() # 完成加密并轉(zhuǎn)為大寫
  return sign
def trans_dict_to_xml(data_dict): # 定義字典轉(zhuǎn)XML的函數(shù)
  data_xml = []
  for k in sorted(data_dict.keys()): # 遍歷字典排序后的key
    v = data_dict.get(k) # 取出字典中key對應(yīng)的value
    if k == 'detail' and not v.startswith('<![CDATA['): # 添加XML標記
      v = '<![CDATA[{}]]>'.format(v)
    data_xml.append('<{key}>{value}</{key}>'.format(key=k, value=v))
  return '<xml>{}</xml>'.format(''.join(data_xml)).encode('utf-8') # 返回XML,并轉(zhuǎn)成utf-8,解決中文的問題
def trans_xml_to_dict(data_xml):
  soup = BeautifulSoup(data_xml, features='xml')
  xml = soup.find('xml') # 解析XML
  if not xml:
    return {}
  data_dict = dict([(item.name, item.text) for item in xml.find_all()])
  return data_dict
def wx_pay_unifiedorde(detail):
  """
  訪問微信支付統(tǒng)一下單接口
  :param detail:
  :return:
  """
  detail['sign'] = get_sign(detail, API_KEY)
  # print(detail)
  xml = trans_dict_to_xml(detail) # 轉(zhuǎn)換字典為XML
  response = requests.request('post', UFDODER_URL, data=xml) # 以POST方式向微信公眾平臺服務(wù)器發(fā)起請求
  # data_dict = trans_xml_to_dict(response.content) # 將請求返回的數(shù)據(jù)轉(zhuǎn)為字典
  return response.content
def pay_fail(err_msg):
  """
  微信支付失敗
  :param err_msg: 失敗原因
  :return:
  """
  data_dict = {'return_msg': err_msg, 'return_code': 'FAIL'}
  return trans_dict_to_xml(data_dict)
def create_qrcode(phone,url):
  """
  生成掃碼支付二維碼
  :param phone: 手機號
  :param url: 支付路由
  :return:
  """
  img = qrcode.make(url) # 創(chuàng)建支付二維碼片
  # 你存放二維碼的地址
  img_url = r'media/QRcode' + '/' + phone + '.png'
  img.save(img_url)
  return img_url

views.py

from django.shortcuts import render
from django.http import HttpResponse
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from pay_settings.py import *
class Wxpay_QRccode(View):
  """
  生成微信支付二維碼
  """
  def get(self, request, *args, **kwargs):
    return render(request, 'create_qrcode.html')
  def post(self, request, *args, **kwargs):
    """
    # 生成可掃碼支付的二維碼
    :param request:
    :param args:
    :param kwargs:
    :return:
    """
    phone = request.data.get('phone', None)
    if not phone:
      return HttpResponse('手機號獲取失敗')
    paydict = {
      'appid': APP_ID,
      'mch_id': MCH_ID,
      'nonce_str': random_str(phone),
      'product_id': phone, # 商品id,可自定義
      'time_stamp': int(time.time()),
    }
    paydict['sign'] = get_sign(paydict, API_KEY)
    url = "weixin://wxpay/bizpayurl?appid=%s&mch_id=%s&nonce_str=%s&product_id=%s&time_stamp=%s&sign=%s" \
       % (paydict['appid'], paydict['mch_id'], paydict['nonce_str'], paydict['product_id'], paydict['time_stamp'], paydict['sign'])
    # 可以直接在微信中點擊該url,如果有錯誤,微信會彈出提示框,如果是掃碼,如果失敗,什么提示都沒有,不利于調(diào)試
    print(url)
    # 創(chuàng)建二維碼
    img_url = create_qrcode(url)
    return render(request, 'create_qrcode.html', context={'img_url': img_url})
@method_decorator(csrf_exempt, name='dispatch')
class Wxpay_ModelOne_pay(View):
  """
  使用微信掃一掃掃描二維碼,微信系統(tǒng)會自動回調(diào)此路由,Post請求
  """
  def post(self, request, *args, **kwargs):
    """
    掃描二維碼后,微信系統(tǒng)回調(diào)的地址處理
    微信傳來的參數(shù)格式經(jīng)trans_xml_to_dict()轉(zhuǎn)成字典
    {'openid': 'xxx',
     'is_subscribe': 'Y',
     'mch_id': 'xxx',
     'nonce_str': 'xxx',
     'sign': 'xxx',
     'product_id': 'xxx',
     'appid': 'xxx'}
    :param request:
    :param args:
    :param kwargs:
    :return:
    """
    data_dict = trans_xml_to_dict(request.body) # 回調(diào)數(shù)據(jù)轉(zhuǎn)字典
    sign = data_dict.pop('sign') # 取出簽名
    key = API_KEY # 商戶交易密鑰
    back_sign = get_sign(data_dict, key) # 計算簽名
    if sign == back_sign: # 驗證簽名是否與回調(diào)簽名相同
      total_fee = 1 # 付款金額,單位是分,必須是整數(shù)
      params = {
        'appid': APP_ID, # APPID
        'mch_id': MCH_ID, # 商戶號
        'nonce_str': random_str(16), # 隨機字符串
        'out_trade_no': order_num(data_dict['product_id']), # 訂單編號
        'total_fee': total_fee, # 訂單總金額
        'spbill_create_ip': CREATE_IP, # 發(fā)送請求服務(wù)器的IP地址
        'notify_url': NOTIFY_URL,
        'body': 'xxx公司',  # 商品描述
        'detail': 'xxx商品', # 商品詳情
        'trade_type': 'NATIVE', # 掃碼支付類型
      }
      # 調(diào)用微信統(tǒng)一下單支付接口url
      notify_result = wx_pay_unifiedorde(params)
      #print(trans_xml_to_dict(notify_result))
      return HttpResponse(notify_result)
    return HttpResponse(pay_fail('交易信息有誤,請重新掃碼'))

2、使用模式二生成支付二維碼

這個二維碼是有時間限制的。

模式二與模式一相比,流程更為簡單,不依賴設(shè)置的回調(diào)支付URL。商戶后臺系統(tǒng)先調(diào)用微信支付的統(tǒng)一下單接口,微信后臺系統(tǒng)返回鏈接參數(shù)code_url,商戶后臺系統(tǒng)將code_url值生成二維碼圖片,用戶使用微信客戶端掃碼后發(fā)起支付。注意:code_url有效期為2小時,過期后掃碼不能再發(fā)起支付。具體流程看微信公眾號。

主體代碼:

pay_settings.py

#微信支付配置
# ========支付相關(guān)配置信息===========
import random
import time
import hashlib
from random import Random
from bs4 import BeautifulSoup
APP_ID = "xxx" # 你公眾賬號上的appid
MCH_ID = "xxx" # 你的商戶號
API_KEY = "xxx" # 微信商戶平臺(pay.weixin.qq.com) -->賬戶設(shè)置 -->API安全 -->密鑰設(shè)置,設(shè)置完成后把密鑰復(fù)制到這里
APP_SECRECT = "xxx"
UFDODER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder" # 該url是微信下單api
NOTIFY_URL = "http://xxx/" # 微信支付結(jié)果回調(diào)接口,需要改為你的服務(wù)器上處理結(jié)果回調(diào)的方法路徑
CREATE_IP = 'xxx' # 你服務(wù)器的IP
def get_sign(data_dict, key): 
  """
  簽名函數(shù)
  :param data_dict: 需要簽名的參數(shù),格式為字典
  :param key: 密鑰 ,即上面的API_KEY
  :return: 字符串
  """
  params_list = sorted(data_dict.items(), key=lambda e: e[0], reverse=False) # 參數(shù)字典倒排序為列表
  params_str = "&".join(u"{}={}".format(k, v) for k, v in params_list) + '&key=' + key
  # 組織參數(shù)字符串并在末尾添加商戶交易密鑰
  md5 = hashlib.md5() # 使用MD5加密模式
  md5.update(params_str.encode('utf-8')) # 將參數(shù)字符串傳入
  sign = md5.hexdigest().upper() # 完成加密并轉(zhuǎn)為大寫
  return sign
def order_num(phone):
  """
  生成掃碼付款訂單號
  :param phone: 手機號
  :return:
  """
  local_time = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
  result = phone + 'T' + local_time + random_str(5)
  return result
def random_str(randomlength=8):
  """
  生成隨機字符串
  :param randomlength: 字符串長度
  :return: 
  """
  strs = ''
  chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
  length = len(chars) - 1
  random = Random()
  for i in range(randomlength):
    strs += chars[random.randint(0, length)]
  return strs
def trans_dict_to_xml(data_dict):
  """
  定義字典轉(zhuǎn)XML的函數(shù)
  :param data_dict: 
  :return: 
  """
  data_xml = []
  for k in sorted(data_dict.keys()): # 遍歷字典排序后的key
    v = data_dict.get(k) # 取出字典中key對應(yīng)的value
    if k == 'detail' and not v.startswith('<![CDATA['): # 添加XML標記
      v = '<![CDATA[{}]]>'.format(v)
    data_xml.append('<{key}>{value}</{key}>'.format(key=k, value=v))
  return '<xml>{}</xml>'.format(''.join(data_xml)) # 返回XML
def trans_xml_to_dict(data_xml):
  """
  定義XML轉(zhuǎn)字典的函數(shù)
  :param data_xml: 
  :return: 
  """
  soup = BeautifulSoup(data_xml, features='xml')
  xml = soup.find('xml') # 解析XML
  if not xml:
    return {}
  data_dict = dict([(item.name, item.text) for item in xml.find_all()])
  return data_dict

views.py

import qrcode
from django.shortcuts import render
from pay_settings import *
from django.http import HttpResponse
from django.views import View
class WXPayView(View):
  def get(self,request):
    # 在info.html有一個按鈕,點擊后跳轉(zhuǎn)到這個類的post()中,具體urls.py設(shè)置不詳述
    return render(request, 'info.html')
  def post(self,request):
    phone = request.POST.get('phone','')
    if not phone:
      return render(request, 'info.html', {'err_msg': '獲取手機號失敗'})
    data_dict = wxpay(phone)
    if data_dict.get('return_code') == 'SUCCESS': # 如果請求成功
      qrcode_name = phone + '.png' # 二維碼圖片名稱
      img = qrcode.make(data_dict.get('code_url')) # 創(chuàng)建支付二維碼片
      img.save(r'static' + '/' + qrcode_name) 
      return render(request, 'qrcode.html', {'qrcode_img': qrcode_name})
    return render(request, 'info.html', {'err_msg': '獲取微信的code_url失敗'})
def wxpay(phone):
  nonce_str = random_str() # 拼接出隨機的字符串即可,我這里是用 時間+隨機數(shù)字+5個隨機字母
  total_fee = 1 # 付款金額,單位是分,必須是整數(shù)
  params = {
    'appid': APP_ID, # APPID
    'mch_id': MCH_ID, # 商戶號
    'nonce_str': nonce_str,  # 隨機字符串
    'out_trade_no': order_num(phone), # 訂單編號,可自定義
    'total_fee': total_fee, # 訂單總金額
    'spbill_create_ip': CREATE_IP, # 自己服務(wù)器的IP地址
    'notify_url': NOTIFY_URL, # 回調(diào)地址,微信支付成功后會回調(diào)這個url,告知商戶支付結(jié)果
    'body': 'xxx公司', # 商品描述
    'detail': 'xxx商品', # 商品描述
    'trade_type': 'NATIVE', # 掃碼支付類型
  }
  sign = get_sign(params,API_KEY) # 獲取簽名
  params['sign'] = sign # 添加簽名到參數(shù)字典
  # print(params)
  xml = trans_dict_to_xml(params) # 轉(zhuǎn)換字典為XML
  response = requests.request('post', settings._UFDODER_URL, data=xml) # 以POST方式向微信公眾平臺服務(wù)器發(fā)起請求
  data_dict = trans_xml_to_dict(response.content) # 將請求返回的數(shù)據(jù)轉(zhuǎn)為字典
  return data_dict
class Wxpay_Result(View):
  """
  微信支付結(jié)果回調(diào)通知路由
  """
  def get(self, request, *args, **kwargs):
    machine_code = request.GET.get('machine_code', '獲取機器編號失敗')
    # 返回支付成功頁面,可自定義
    return render(request, 'zfcg.html', {'machine': {'machine_code': machine_code}})
  def post(self, request, *args, **kwargs):
    """
    微信支付成功后會自動回調(diào)
    返回參數(shù)為:
    {'mch_id': '',
    'time_end': '',
    'nonce_str': '',
    'out_trade_no': '',
    'trade_type': '',
    'openid': '',
     'return_code': '',
     'sign': '',
     'bank_type': '',
     'appid': '',
     'transaction_id': '',
     'cash_fee': '',
     'total_fee': '',
     'fee_type': '', '
     is_subscribe': '',
     'result_code': 'SUCCESS'}
    :param request:
    :param args:
    :param kwargs:
    :return:
    """
    data_dict = trans_xml_to_dict(request.body) # 回調(diào)數(shù)據(jù)轉(zhuǎn)字典
    # print('支付回調(diào)結(jié)果', data_dict)
    sign = data_dict.pop('sign') # 取出簽名
    back_sign = get_sign(data_dict, API_KEY) # 計算簽名
    # 驗證簽名是否與回調(diào)簽名相同
    if sign == back_sign and data_dict['return_code'] == 'SUCCESS':
      '''
      檢查對應(yīng)業(yè)務(wù)數(shù)據(jù)的狀態(tài),判斷該通知是否已經(jīng)處理過,如果沒有處理過再進行處理,如果處理過直接返回結(jié)果成功。
      '''
      print('微信支付成功會回調(diào)!')
      # 處理支付成功邏輯
      # 返回接收結(jié)果給微信,否則微信會每隔8分鐘發(fā)送post請求
      return HttpResponse(trans_dict_to_xml({'return_code': 'SUCCESS', 'return_msg': 'OK'}))
    return HttpResponse(trans_dict_to_xml({'return_code': 'FAIL', 'return_msg': 'SIGNERROR'}))

二、使用JsAPI發(fā)起微信支付

在微信公眾號中左下角 設(shè)置->公眾號設(shè)置->功能設(shè)置,把業(yè)務(wù)域名,js接口安全域名,網(wǎng)頁授權(quán)域名設(shè)置好。

用戶在微信中點擊一個路由Url(可把這個url封裝成二維碼).在后臺中的views.py中的WxJsAPIPay類中使用get()函數(shù)處理用戶的請求,先獲取用戶的openid,然后調(diào)用微信統(tǒng)一下單接口,獲取prepay_id,具體看官網(wǎng)。

wx_js_pay.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" id="vp"/>
{#    <script type="text/javascript" src="/static/js/rem.js"></script>#}
{#    <link rel="stylesheet" type="text/css" href="/static/css/base.css" rel="external nofollow" />#}
{#    <link rel="stylesheet" type="text/css" href="/static/css/index.css" rel="external nofollow" />#}
  </head>
  <body>
    <div class="bigbox">
      <div class="top">
        <span>訂單詳情</span>
      </div>
      <div class="zhong">
      </div>
      <div class="zhifu">
        <button class="btn" type="button" onclick="javascript:callpay();return false;">立即支付</button>
      </div>
    </div>
<script src="https://cdn.bootcss.com/jquery/1.12.1/jquery.js"></script>
<script type="text/javascript">
  //調(diào)用微信JS api 支付
  function onBridgeReady() {
    WeixinJSBridge.invoke(
      'getBrandWCPayRequest',
      {
        appId: "{{ params.appid }}",    //公眾號名稱,由商戶傳入
        timeStamp: "{{ params.timeStamp }}", //時間戳,自1970年以來的秒數(shù)
        nonceStr: "{{ params.nonceStr }}", //隨機串
        package: "prepay_id={{ params.prepay_id }}", //預(yù)支付id
        signType: "MD5", //微信簽名方式
        paySign: "{{ params.sign }}"   //微信簽名
      },
      function (res) {
        //支付成功后返回 get_brand_wcpay_request:ok
        if (res.err_msg == "get_brand_wcpay_request:ok") {
          // 跳轉(zhuǎn)到支付成功的頁面
          window.location.href = '#';
          {#alert('支付成功');#}
        } else if (res.err_msg == "get_brand_wcpay_request:cancel") {
          alert("您已取消支付!");
          {#alert({{ params.machine_code }});#}
          {#window.location.href = '';#}
        } else if (res.err_msg == "get_brand_wcpay_request:fail") {
          $.each(res, function(key,value){
            alert(value);
            });
          alert("支付失敗!");
        }
      }
    );
  }
  function callpay() {
    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>
  </body>
</html>

pay_settings.py

# encoding: utf-8
import hashlib
import time
import requests
from collections import OrderedDict
from random import Random
from bs4 import BeautifulSoup
APP_ID = "xxx" # 公眾賬號appid
MCH_ID = "xxx" # 商戶號
API_KEY = "xxx" # 微信商戶平臺(pay.weixin.qq.com) -->賬戶設(shè)置 -->API安全 -->密鑰設(shè)置,設(shè)置完成后把密鑰復(fù)制到這里
APP_SECRECT = "xxx"
UFDODER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder" # url是微信下單api
NOTIFY_URL = "http://xxx/wxpay/pay_result/" # 微信支付結(jié)果回調(diào)接口,需要你自定義
CREATE_IP = 'xxx' # 你服務(wù)器上的ip
# 生成隨機字符串
def random_str(randomlength=8):
  """
  生成隨機字符串
  :param randomlength: 字符串長度
  :return:
  """
  str = ''
  chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
  length = len(chars) - 1
  random = Random()
  for i in range(randomlength):
    str+=chars[random.randint(0, length)]
  return str
def order_num(phone):
  """
  生成掃碼付款訂單,
  :param phone: 
  :return:
  """
  local_time = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
  result = phone + 'T' + local_time + random_str(5)
  return result
def get_sign(data_dict, key):
  # 簽名函數(shù),參數(shù)為簽名的數(shù)據(jù)和密鑰
  params_list = sorted(data_dict.items(), key=lambda e: e[0], reverse=False) # 參數(shù)字典倒排序為列表
  params_str = "&".join(u"{}={}".format(k, v) for k, v in params_list) + '&key=' + key
  # 組織參數(shù)字符串并在末尾添加商戶交易密鑰
  md5 = hashlib.md5() # 使用MD5加密模式
  md5.update(params_str.encode('utf-8')) # 將參數(shù)字符串傳入
  sign = md5.hexdigest().upper() # 完成加密并轉(zhuǎn)為大寫
  return sign
def trans_dict_to_xml(data_dict): # 定義字典轉(zhuǎn)XML的函數(shù)
  data_xml = []
  for k in sorted(data_dict.keys()): # 遍歷字典排序后的key
    v = data_dict.get(k) # 取出字典中key對應(yīng)的value
    if k == 'detail' and not v.startswith('<![CDATA['): # 添加XML標記
      v = '<![CDATA[{}]]>'.format(v)
    data_xml.append('<{key}>{value}</{key}>'.format(key=k, value=v))
  return '<xml>{}</xml>'.format(''.join(data_xml)).encode('utf-8') # 返回XML,并轉(zhuǎn)成utf-8,解決中文的問題
def trans_xml_to_dict(data_xml):
  soup = BeautifulSoup(data_xml, features='xml')
  xml = soup.find('xml') # 解析XML
  if not xml:
    return {}
  data_dict = dict([(item.name, item.text) for item in xml.find_all()])
  return data_dict
def wx_pay_unifiedorde(detail):
  """
  訪問微信支付統(tǒng)一下單接口
  :param detail:
  :return:
  """
  detail['sign'] = get_sign(detail, API_KEY)
  # print(detail)
  xml = trans_dict_to_xml(detail) # 轉(zhuǎn)換字典為XML
  response = requests.request('post', UFDODER_URL, data=xml) # 以POST方式向微信公眾平臺服務(wù)器發(fā)起請求
  # data_dict = trans_xml_to_dict(response.content) # 將請求返回的數(shù)據(jù)轉(zhuǎn)為字典
  return response.content
def get_redirect_url():
  """
  獲取微信返回的重定向的url
  :return: url,其中攜帶code
  """
  WeChatcode = 'https://open.weixin.qq.com/connect/oauth2/authorize'
  urlinfo = OrderedDict()
  urlinfo['appid'] = APP_ID
  urlinfo['redirect_uri'] = 'http://xxx/wxjsapipay/?getInfo=yes' # 設(shè)置重定向路由
  urlinfo['response_type'] = 'code'
  urlinfo['scope'] = 'snsapi_base' # 只獲取基本信息
  urlinfo['state'] = 'mywxpay'  # 自定義的狀態(tài)碼
  info = requests.get(url=WeChatcode, params=urlinfo)
  return info.url
def get_openid(code,state):
  """
  獲取微信的openid
  :param code:
  :param state:
  :return:
  """
  if code and state and state == 'mywxpay':
    WeChatcode = 'https://api.weixin.qq.com/sns/oauth2/access_token'
    urlinfo = OrderedDict()
    urlinfo['appid'] = APP_ID
    urlinfo['secret'] = APP_SECRECT
    urlinfo['code'] = code
    urlinfo['grant_type'] = 'authorization_code'
    info = requests.get(url=WeChatcode, params=urlinfo)
    info_dict = eval(info.content.decode('utf-8'))
    return info_dict['openid']
  return None
def get_jsapi_params(openid):
  """
  獲取微信的Jsapi支付需要的參數(shù)
  :param openid: 用戶的openid
  :return:
  """
  total_fee = 1 # 付款金額,單位是分,必須是整數(shù)
  params = {
    'appid': APP_ID, # APPID
    'mch_id': MCH_ID, # 商戶號
    'nonce_str': random_str(16), # 隨機字符串
    'out_trade_no': order_num('123'), # 訂單編號,可自定義
    'total_fee': total_fee, # 訂單總金額
    'spbill_create_ip': CREATE_IP, # 發(fā)送請求服務(wù)器的IP地址
    'openid': openid,
    'notify_url': NOTIFY_URL, # 支付成功后微信回調(diào)路由
    'body': 'xxx公司', # 商品描述
    'trade_type': 'JSAPI', # 公眾號支付類型
  }
  # print(params)
  # 調(diào)用微信統(tǒng)一下單支付接口url
  notify_result = wx_pay_unifiedorde(params)
  params['prepay_id'] = trans_xml_to_dict(notify_result)['prepay_id']
  params['timeStamp'] = int(time.time())
  params['nonceStr'] = random_str(16)
  params['sign'] = get_sign({'appId': APP_ID,
                "timeStamp": params['timeStamp'],
                'nonceStr': params['nonceStr'],
                'package': 'prepay_id=' + params['prepay_id'],
                'signType': 'MD5',
                },
               API_KEY)
  return params

views.py

from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render
from django.views import View
from pay_settings import *
class WxJsAPIPay(View):
  def get(self, request, *args, **kwargs):
    """
    用戶點擊一個路由或者掃碼進入這個views.py中的函數(shù),首先獲取用戶的openid,
    使用jsapi方式支付需要此參數(shù)
    :param self:
    :param request:
    :param args:
    :param kwargs:
    :return:
    """
    getInfo = request.GET.get('getInfo', None)
    openid = request.COOKIES.get('openid', '')
    if not openid:
      if getInfo != 'yes':
      # 構(gòu)造一個url,攜帶一個重定向的路由參數(shù),
      # 然后訪問微信的一個url,微信會回調(diào)你設(shè)置的重定向路由,并攜帶code參數(shù)
        return HttpResponseRedirect(get_redirect_url())
      elif getInfo == 'yes':
   # 我設(shè)置的重定向路由還是回到這個函數(shù)中,其中設(shè)置了一個getInfo=yes的參數(shù)
      # 獲取用戶的openid
        openid = get_openid(request.GET.get('code'), request.GET.get('state', ''))
        if not openid:
          return HttpResponse('獲取用戶openid失敗')
        response = render_to_response('wx_js_pay.html', context={'params': get_jsapi_params(openid)})
        response.set_cookie('openid', openid, expires=60 * 60 * 24 *30)
        return response
      else:
        return HttpResponse('獲取機器編碼失敗')
    else:
      return render(request, 'wx_js_pay.html', context={'params': get_jsapi_params(openid)})

更多關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Python數(shù)學(xué)運算技巧總結(jié)》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》、《Python入門與進階經(jīng)典教程》及《Python文件與目錄操作技巧匯總

希望本文所述對大家Python程序設(shè)計有所幫助。

相關(guān)文章

  • 實例介紹Python中整型

    實例介紹Python中整型

    在本篇內(nèi)容中我們通過實例分享了關(guān)于Python中整型的相關(guān)知識點內(nèi)容,有興趣的朋友們學(xué)習(xí)下。
    2019-02-02
  • python tarfile壓縮包操作保姆級教程

    python tarfile壓縮包操作保姆級教程

    TarFile類就是tar壓縮包,其由member塊組成, member塊則包括header塊和data塊. 每個member以TarInfo對象形式描述. 所以TarFile就是TarInfo的序列
    2023-02-02
  • 關(guān)于pycharm 切換 python3.9 報錯 ‘HTMLParser‘ object has no attribute ‘unescape‘ 的問題

    關(guān)于pycharm 切換 python3.9 報錯 ‘HTMLParser‘ object has no attribu

    這篇文章主要介紹了pycharm 切換 python3.9 報錯 ‘HTMLParser‘ object has no attribute ‘unescape‘ 解決,需要的朋友可以參考下
    2020-11-11
  • python+opencv實現(xiàn)車道線檢測

    python+opencv實現(xiàn)車道線檢測

    這篇文章主要為大家詳細介紹了python+opencv實現(xiàn)車道線檢測,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-02-02
  • Python實現(xiàn)各種郵件發(fā)送

    Python實現(xiàn)各種郵件發(fā)送

    這篇文章主要介紹了Python實現(xiàn)各種郵件發(fā)送,Python內(nèi)置對SMTP的支持,可以發(fā)送純文本郵件、HTML郵件以及帶附件的郵件,下文詳細實現(xiàn)過程需要的小伙伴可以參考一下
    2022-05-05
  • python3.4 將16進制轉(zhuǎn)成字符串的實例

    python3.4 將16進制轉(zhuǎn)成字符串的實例

    今天小編就為大家分享一篇python3.4 將16進制轉(zhuǎn)成字符串的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-06-06
  • PyTorch模型容器與AlexNet構(gòu)建示例詳解

    PyTorch模型容器與AlexNet構(gòu)建示例詳解

    這篇文章主要為大家介紹了PyTorch模型容器與AlexNet構(gòu)建示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • Python實現(xiàn)的文本對比報告生成工具示例

    Python實現(xiàn)的文本對比報告生成工具示例

    這篇文章主要介紹了Python實現(xiàn)的文本對比報告生成工具,涉及Python基于difflib模塊實現(xiàn)對文本內(nèi)容進行對比的相關(guān)操作技巧,需要的朋友可以參考下
    2018-05-05
  • Python基礎(chǔ)之?dāng)?shù)據(jù)結(jié)構(gòu)詳解

    Python基礎(chǔ)之?dāng)?shù)據(jù)結(jié)構(gòu)詳解

    這篇文章主要介紹了Python基礎(chǔ)之?dāng)?shù)據(jù)結(jié)構(gòu)詳解,文中有非常詳細的代碼示例,對正在學(xué)習(xí)python基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Django多個app urls配置代碼實例

    Django多個app urls配置代碼實例

    這篇文章主要介紹了Django多個app urls配置代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11

最新評論