Django之微信支付

一、在微信支付子应用创建utils.py文件并添加一下内容

import hashlib
import datetime
import random
import xml.etree.ElementTree as ET

# 配置文件导入小程序appid、商户号、商户密钥
from settings.dev import APPID, Mch_id, Mch_key


def paysign(APPID, body, mch_id, nonce_str, notify_url, openid, out_trade_no, client_ip, total_fee):
	ret = {
    	"appid": APPID,
    	"body": body,
    	"mch_id": mch_id,
    	"nonce_str": nonce_str,
    	"notify_url": notify_url,
    	"openid": openid,
    	"out_trade_no": out_trade_no,
    	"spbill_create_ip": client_ip,
    	"total_fee": total_fee,
    	"trade_type": 'JSAPI'
	}

	# 处理函数,对参数按照key=value的格式,并按照参数名ASCII字典序排序
	stringA = '&'.join(["{0}={1}".format(k, ret.get(k)) for k in sorted(ret)])
	stringSignTemp = '{0}&key={1}'.format(stringA, Mch_key)
	sign = hashlib.md5(stringSignTemp.encode("utf-8")).hexdigest()
	return sign.upper()


# 生成随机字符串
def getNonceStr():

	data = "123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP"
	nonce_str = ''.join(random.sample(data, 30))
    return nonce_str


# 生成商品订单号
def getWxPayOrdrID():
	date = datetime.datetime.now()
	# 根据当前系统时间来生成商品订单号。时间精确到微秒
	payOrdrID = date.strftime("%Y%m%d%H%M%S%f")

	return payOrdrID


# 获取全部参数信息,封装成xml
def get_bodyData(openid, client_ip, price, timeStamp, user_id, time_data):

	body = '购买质量安宝服务'  # 商品描述
	notify_url = 'https://127.0.0.1:8000/payOrder/'  # 支付成功的回调地址  可访问 不带参数
	nonce_str = getNonceStr()  # 随机字符串
	out_trade_no = getWxPayOrdrID()  # 商户订单号
	total_fee = str(price)  # 订单价格 单位是 分

	# 获取签名
	sign = paysign(APPID, body, Mch_id, nonce_str, notify_url, openid, out_trade_no, client_ip, total_fee)

	bodyData = '<xml>'
	bodyData += '<appid>' + APPID + '</appid>'  # 小程序ID
	bodyData += '<body>' + body + '</body>'  # 商品描述
	bodyData += '<mch_id>' + Mch_id + '</mch_id>'  # 商户号
	bodyData += '<nonce_str>' + nonce_str + '</nonce_str>'  # 随机字符串
	bodyData += '<notify_url>' + notify_url + '</notify_url>'  # 支付成功的回调地址
	bodyData += '<openid>' + openid + '</openid>'  # 用户标识
	bodyData += '<out_trade_no>' + out_trade_no + '</out_trade_no>'  # 商户订单号
	bodyData += '<spbill_create_ip>' + client_ip + '</spbill_create_ip>'  # 客户端终端IP
	bodyData += '<total_fee>' + total_fee + '</total_fee>'  # 总金额 单位为分
	bodyData += '<trade_type>JSAPI</trade_type>'  # 交易类型 小程序取值如下:JSAPI
	bodyData += '<sign>' + sign + '</sign>'
	bodyData += '</xml>'

	return bodyData


def xml_to_dict(xml_data):
	'''
	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


# 获取返回给小程序的paySign
def get_paysign(prepay_id, timeStamp, nonceStr):
	pay_data = {
    	'appId': APPID,
    	'nonceStr': nonceStr,
    	'package': "prepay_id=" + prepay_id,
    	'signType': 'MD5',
    	'timeStamp': timeStamp
	}
	stringA = '&'.join(["{0}={1}".format(k, pay_data.get(k)) for k in sorted(pay_data)])

	stringSignTemp = '{0}&key={1}'.format(stringA, Mch_key)

	sign = hashlib.md5(stringSignTemp.encode("utf-8")).hexdigest()
	return sign.upper()

二、视图实现一下内容

import datetime
import requests
import time

from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView

from users.models import User
from wxpay import utils


class PayViews(APIView):

	# 统一下单支付接口
	def post(self, request):

    	# 获取价格
    	price = request.data.get("price")
    	# print(price)

    	# 获取user_id
    	user_id = request.data.get("user_id")
    	# print(user_id)

    	# 获取客户端ip
    	client_ip = request.META['REMOTE_ADDR']
    	# print(client_ip)

    	# 获取小程序openid
    	openid = User.objects.get(id=user_id).openid

    	# 请求微信的url
    	url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'

    	# 获取时间戳
    	timeStamp = str(int(time.time()))
    	time_data = datetime.date.today()

    	# 拿到封装好的xml数据
    	body_data = utils.get_bodyData(openid, client_ip, price, timeStamp, user_id, time_data)

    	# 请求微信接口下单
    	respone = requests.post(url, body_data.encode("utf-8"), headers={'Content-Type': 'application/xml'})

    	# 回复数据为xml,将其转为字典
    	content = utils.xml_to_dict(respone.content)

    	if content["return_code"] == 'SUCCESS':
        	# 获取预支付交易会话标识
        	prepay_id = content.get("prepay_id")
        	# 获取随机字符串
        	nonceStr = content.get("nonce_str")

        	# 获取paySign签名,这个需要我们根据拿到的prepay_id和nonceStr进行计算签名
        	paySign = utils.get_paysign(prepay_id, timeStamp, nonceStr)

        	# 封装返回给前端的数据
        	data = {"prepay_id": prepay_id, "nonceStr": nonceStr, "paySign": paySign, "timeStamp": timeStamp}

        	return Response(data=data, status=status.HTTP_200_OK)

    	else:
        	return Response("请求支付失败")
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值