微信支付 django

微信支付有条件,必须申请公众号为服务号

settings配置
# 商户id
WEIXIN_SHANG_ID = "xxxx"

微信支付,获取二维码

from PIL import Image,ImageOps
from users.models import UserProfile
from datetime import datetime, timedelta
import qrcode
from io import BytesIO
from .PayToolUtil import *
from django import http
from django.views.decorators.csrf import csrf_exempt

def getWeChatQRCode(request):
    order_id = request.GET.get("order_id")
    order = OrderInfo.objects.filter(o_id=order_id).first()

    if order:
        # 获取充值类型
        if order.o_type == "vip":
            tishi = "开通/续费VIP"
        else:
            tishi = "积分充值"
        #   获取客户端生成的订单号
        goodsName = tishi  # 获取商品信息
        goodsPrice = int(order.o_total_price) * 100 # 获取价格,单位是分,需要是整数
        # goodsPrice = 1

        toolUtil = PayToolUtil()
        code_url = toolUtil.getPayUrl(order_id, goodsName, goodsPrice)  # 调用统一下单方法,获得支付订单的url链接
        # result = toolUtil.getPayUrl(order_id, goodsName, goodsPrice)
        # if result:
        #     code_url = result[0]

        if code_url:
            res_info = code_url

        # 如果成功获得支付链接,则写入一条订单记录
        # todo:自己的后台逻辑

        else:
            res_info = "二维码失效"  # 获取url失败,则二维码信息为失效

        # 根据res_info生成二维码,使用qrcode模块
        qr = qrcode.QRCode(
            version=1,
            error_correction=qrcode.constants.ERROR_CORRECT_H,
            box_size=10,
            border=1
        )
        qr.add_data(res_info)  # 二维码所含信息
        img = qr.make_image()  # 生成二维码图片
        img = img.convert("RGBA")
        # 添加logo
        icon = Image.open('/home/pythonProjects/media/logo/logo.png')
        # icon = Image.open('D://Users/Administrator/Desktop/项目文件/前后端分离Django/ucasonline/media/logo/logo.png')
        w, h = img.size
        # 可调节logo大小
        factor = 3
        size_w = int(w / factor)
        size_h = int(h / factor)
        icon_w, icon_h = icon.size
        if icon_w > size_w:
            icon_w = size_w
        if icon_h > size_h:
            icon_h = size_h
        icon = icon.resize((icon_w, icon_h), Image.ANTIALIAS)
        w = int((w - icon_w) / 2)
        h = int((h - icon_h) / 2)
        icon = icon.convert("RGBA")

        img.paste(icon, (w, h), icon)

        byte_io = BytesIO()
        img.save(byte_io, 'PNG')  # 存入字节流
        byte_io.seek(0)

        response = http.HttpResponse(byte_io, content_type="image/png")
        return response

支付回调

from rest_framework import status
# 微信支付回调
@csrf_exempt
def weChatQRCodeNotify(request):
    order_result_xml = request.body  # 从请求流提取数据
    order_result_xml = str(order_result_xml,encoding="utf-8")
    doc = xmltodict.parse(order_result_xml)  # 解析得到的xml字符串,转为dict
    out_trade_no = doc['xml']['out_trade_no']  # 提取返回数据中的订单号
    total_fee = doc['xml']['total_fee']

    # todo:提取签名、支付金额等,验证签名是否正确、金额是否正确


    # 思路:在前面获取二维码时,生成了一条订单记录,订单应该保存下订单号、签名、金额等信息。在这里,根据回传的订单号查询数据库,得到对应的签名、金额进行验证即可
    order = OrderInfo.objects.filter(o_id=out_trade_no).first()
    if order:
        user = UserProfile.objects.filter(id=order.user.id).first()
        if user:
                # if int(order.o_total_price) == int(total_fee) * 100:
                if int(total_fee)  ==  1:
                    # 判断支付状态
                    if order.o_pay == False:
                       # 写入支付完成的逻辑 
                    order.o_pay = True
                    order.save()

                    # 最后,别忘了应答微信支付平台,防止重复发送数据

                    return http.HttpResponse('''
                        <xml>
                        <return_code><![CDATA[SUCCESS]]></return_code>
                        <return_msg><![CDATA[OK]]></return_msg>
                        </xml>
                        ''',status=status.HTTP_200_OK )
                    # return http.HttpResponse({"return_code":"SUCCESS","return_msg":"OK"})
                else:
                    return http.HttpResponse('''<xml><return_code><![CDATA[FAIL]]></return_code></xml>''', status=status.HTTP_400_BAD_REQUEST)
        else:
            return http.HttpResponse('''<xml><return_code><![CDATA[FAIL]]></return_code></xml>''',status=status.HTTP_400_BAD_REQUEST)
    else:
        return http.HttpResponse('''<xml><return_code><![CDATA[FAIL]]></return_code></xml>''',status=status.HTTP_400_BAD_REQUEST)

前端调接口:支付结果轮询

def weChatQRCodeHadPay(request):
    order_id = request.GET.get('order_id')  # 获取订单号
    # todo:根据订单号查询对应的订单记录状态,返回支付结果
    order = OrderInfo.objects.filter(o_id=order_id).first()
    if order:
        if order.o_pay == True:
            return http.JsonResponse({"type": "object","msg": "success","status": "0", "data": { "error": "订单支付成功"}})
        else:
            return http.JsonResponse({"type": "object", "msg": "success", "status": "1", "data": {"error": "未成功"}})
    else:
        return http.JsonResponse({"type": "object","msg": "success","status": "1", "data": { "error": "订单不存在"}})

另需:

import socket
import random
import json
import hashlib
import xmltodict
import sys

class PayToolUtil(object):

    # ========支付相关配置信息===========
    _APP_ID = "XXXXX";  # 公众账号appid
    _MCH_ID = "XXXX";  # 商户号
    _API_KEY = "XXXXX";  # key设置路径:微信商户平台(pay.weixin.qq.com) -->账户设置 -->API安全 -->密钥设置

    # 有关url
    _host_name = socket.gethostname()
    _ip_address = socket.gethostbyname(_host_name)
    _CREATE_IP = _ip_address;  # 发起支付的ip

    _UFDODER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    _NOTIFY_URL = "http://www.XXXX/vuser/wei/checkpay";  # 微信支付结果回调的处理方法


    def getPayUrl(self,orderid,goodsName,goodsPrice,**kwargs):
        '''
        向微信支付端发出请求,获取url
        '''

        appid = self._APP_ID
        mch_id = self._MCH_ID
        key = self._API_KEY

        nonce_str = str(int(round(time.time() * 1000)))+str(random.randint(1,999))+"".join(random.sample(['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'], 5)).replace(" ","") #生成随机字符串
        spbill_create_ip = self._CREATE_IP
        notify_url = self._NOTIFY_URL
        trade_type = "NATIVE"

        params = {}
        params['appid'] = appid
        params['mch_id'] = mch_id
        params['nonce_str'] = nonce_str
        params['out_trade_no'] = orderid
        # params['out_trade_no'] = orderid.encode('utf-8')    #客户端生成并传过来,参数必须用utf8编码,否则报错
        params['total_fee'] = goodsPrice   #单位是分,必须是整数
        params['spbill_create_ip'] = spbill_create_ip
        params['notify_url'] = notify_url
        params['body'] = goodsName
        # params['body'] = goodsName.encode('utf-8')   #中文必须用utf-8编码,否则xml格式错误
        params['trade_type'] = trade_type

        #生成签名
        ret = []
        for k in sorted(params.keys()):
            if (k != 'sign') and (k != '') and (params[k] is not None):
                ret.append('%s=%s' % (k, params[k]))
        params_str = '&'.join(ret)
        params_str = '%(params_str)s&key=%(partner_key)s'%{'params_str': params_str, 'partner_key': key}

        params_str = hashlib.md5(params_str.encode('utf-8')).hexdigest()
        sign = params_str.upper()
        params['sign'] = sign


        #拼接参数的xml字符串
        request_xml_str = '<xml>'
        for key, value in params.items():
            if isinstance(value,str):
            # if isinstance(value, basestring):
                request_xml_str = '%s<%s><![CDATA[%s]]></%s>' % (request_xml_str, key, value, key, )
            else:
                request_xml_str = '%s<%s>%s</%s>' % (request_xml_str, key, value, key, )
        request_xml_str = '%s</xml>' % request_xml_str

        #向微信支付发出请求,并提取回传数据
        res = urllib.request.Request(self._UFDODER_URL, data=request_xml_str.encode("utf-8"))
        res_data = urllib.request.urlopen(res)
        res_read = res_data.read()
        doc = xmltodict.parse(res_read)
        return_code = doc['xml']['return_code']
        if return_code=="SUCCESS":
            result_code = doc['xml']['result_code']
            if result_code=="SUCCESS":
                code_url = doc['xml']['code_url']
                return code_url
            else:
                err_des = doc['xml']['err_code_des']
                print("errdes==========="+err_des)
        else:
            fail_des = doc['xml']['return_msg']
            print("fail des============="+fail_des)

感谢大佬资源分享,仅作记录

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现微信支付v3的django库有很多,其中比较常用的是wechatpy和weixin-pay,下面分别介绍一下。 1. wechatpy wechatpy是一个Python的微信开发库,支持微信公众号、小程序、企业号等平台的开发,同时也支持微信支付v3。使用wechatpy可以方便地实现微信支付v3的接口调用和签名验证等功能。 首先,需要在微信商户平台上创建商户号,并获取商户证书,包括apiclient_key.pem、apiclient_cert.pem、wechat_pay_cert.pem三个文件。将这三个文件放置在django项目的某个目录下,然后在settings.py文件中添加以下配置: ``` WECHAT_PAY = { 'appid': '微信公众平台appid', 'mch_id': '商户号', 'mch_key': '商户支付密钥', 'apiclient_key_path': 'apiclient_key.pem证书路径', 'apiclient_cert_path': 'apiclient_cert.pem证书路径', 'wechat_pay_cert_path': 'wechat_pay_cert.pem证书路径', 'notify_url': '微信支付结果通知地址', } ``` 接下来,可以在views.py中实现微信支付的业务逻辑,比如创建微信支付订单、查询订单状态等。具体实现方式可以参考wechatpy的官方文档。 2. weixin-pay weixin-pay是另一个支持微信支付v3的Python库,使用方法与wechatpy类似。使用weixin-pay需要在微信商户平台上创建商户号,并获取商户密钥和证书。将商户证书放置在django项目的某个目录下,然后在settings.py文件中添加以下配置: ``` WEIXIN_PAY = { 'appid': '微信公众平台appid', 'mch_id': '商户号', 'mch_key': '商户支付密钥', 'cert_path': 'apiclient_cert.pem证书路径', 'key_path': 'apiclient_key.pem证书路径', 'notify_url': '微信支付结果通知地址', } ``` 接下来,可以在views.py中实现微信支付的业务逻辑,具体实现方式可以参考weixin-pay的官方文档。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值