python H5微信支付

 

# 一、定义路由:

url('ic/order/(?P<order_id>.+)/payment/', views_front.PaymentView.as_view()), # 元器件微信支付
url('ic/wechatpay/', views_front.Wxpay_Result.as_view()), # 订单支付成功回调
 
# 二、定义两个函数用来转换文本类型

def trans_dict_to_xml(data_dict):
      """
      定义字典转XML的函数
      :param data_dict:
      :return:
      """
     data_xml = []
     for k in sorted(data_dict.keys()): # 遍历字典排序后的key
          v = data_dict.get(k) # 取出字典中key对应的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转字典的函数
     :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

# 三、后台传order_id与open_id给到前台
 
import random
import string
from math import floor
from datetime import datetime, timedelta
from wechatpy.utils import timezone
 
class PaymentView(APIView):
"""微信支付"""

def get(self, request, order_id):

      open_id = request.query_params.get('openid')
      try:
           order = OrderInfo.objects.get(order_id=order_id,
                                                           pay_method=OrderInfo.PAY_METHODS_ENUM['WEXIN'],
                                                           status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'])
       except OrderInfo.DoesNotExist:
                 return Response({'message': '订单信息有误'}, status=status.HTTP_400_BAD_REQUEST)
        wechatpay = WeChatPay(
                 appid=settings.APPID,
                 api_key=settings.API_KEY,
                 mch_id=settings.MCH_ID,
                 mch_cert=os.path.join(os.path.dirname(os.path.abspath(__file__)), "../keys/apiclient_cert.pem"),
                 mch_key=os.path.join(os.path.dirname(os.path.abspath(__file__)), "../keys/apiclient_key.pem"),
                 timeout=300
       )
 
       total_fee = floor(order.total_amount * 100)
       now = datetime.fromtimestamp(time.time(), tz=timezone('Asia/Shanghai'))
       hours_later = now + timedelta(seconds=60)
       pay_data = wechatpay.order.create(
             trade_type="JSAPI",
             body='百度%s' % order_id,
             total_fee=total_fee,
             notify_url='http://www.baidu.com/ic/wechatpay/', # 微信支付成功后的回调地址,一定要能被外网访问到,                   注:“http://www.baidu.com” =》域名,“ic/wechatpay”=》接口。
             user_id=open_id,
             out_trade_no="JSAPI" + order_id,
             product_id=1,
             time_expire=hours_later
      )
      timestamp = str(int(time.time()))
      nonce_str = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(15))
      params = wechatpay.jsapi.get_jsapi_params(
             prepay_id=pay_data['prepay_id'],
             timestamp=timestamp,
             nonce_str=nonce_str,
      )
      signature = wechatpay.jsapi.get_jsapi_signature(
            prepay_id=pay_data['prepay_id'],
            timestamp=timestamp,
            nonce_str=nonce_str,
      )
      params['signature'] = signature
      return Response(params)
 


class Wxpay_Result(APIView):
          """
          微信支付结果回调通知路由
          """
         def post(self, request, *args, **kwargs):
               """
              微信支付成功后会自动回调
               """
               a = request.body.decode('utf-8')
               data_dict = trans_xml_to_dict(a) # 回调数据转字典

               wechatpay = WeChatPay(
                       appid=settings.APPID,
                       api_key=settings.API_KEY,
                       mch_id=settings.MCH_ID,
                       mch_cert=os.path.join(os.path.dirname(os.path.abspath(__file__)), "../keys/apiclient_cert.pem"),
                       mch_key=os.path.join(os.path.dirname(os.path.abspath(__file__)), "../keys/apiclient_key.pem"),
                       timeout=300
                )
               sign = wechatpay.check_signature(data_dict)
               if data_dict['return_code'] == 'SUCCESS' and sign:
                '''
                 检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成                    功。
                 '''
                     OrderInfo.objects.filter(order_id=data_dict['out_trade_no'][5:]).update(
                             status=OrderInfo.ORDER_STATUS_ENUM['UNSEND'])
                    # 处理支付成功逻辑
                    # 返回接收结果给微信,否则微信会每隔8分钟发送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'}))
 
 
# 如有错误还请指出,感谢!!!!
url('ic/order/(?P<order_id>.+)/payment/', views_front.PaymentView.as_view()), # 元器件微信支付
url('ic/wechatpay/', views_front.Wxpay_Result.as_view()), # 订单支付成功回调
 
# 二、定义两个函数用来转换文本类型

def trans_dict_to_xml(data_dict):
      """
      定义字典转XML的函数
      :param data_dict:
      :return:
      """
     data_xml = []
     for k in sorted(data_dict.keys()): # 遍历字典排序后的key
          v = data_dict.get(k) # 取出字典中key对应的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转字典的函数
     :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

# 三、后台传order_id与open_id给到前台
 
import random
import string
from math import floor
from datetime import datetime, timedelta
from wechatpy.utils import timezone
 
class PaymentView(APIView):
"""微信支付"""

def get(self, request, order_id):

      open_id = request.query_params.get('openid')
      try:
           order = OrderInfo.objects.get(order_id=order_id,
                                                           pay_method=OrderInfo.PAY_METHODS_ENUM['WEXIN'],
                                                           status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'])
       except OrderInfo.DoesNotExist:
                 return Response({'message': '订单信息有误'}, status=status.HTTP_400_BAD_REQUEST)
        wechatpay = WeChatPay(
                 appid=settings.APPID,
                 api_key=settings.API_KEY,
                 mch_id=settings.MCH_ID,
                 mch_cert=os.path.join(os.path.dirname(os.path.abspath(__file__)), "../keys/apiclient_cert.pem"),
                 mch_key=os.path.join(os.path.dirname(os.path.abspath(__file__)), "../keys/apiclient_key.pem"),
                 timeout=300
       )
 
       total_fee = floor(order.total_amount * 100)
       now = datetime.fromtimestamp(time.time(), tz=timezone('Asia/Shanghai'))
       hours_later = now + timedelta(seconds=60)
       pay_data = wechatpay.order.create(
             trade_type="JSAPI",
             body='百度%s' % order_id,
             total_fee=total_fee,
             notify_url='http://www.baidu.com/ic/wechatpay/', # 微信支付成功后的回调地址,一定要能被外网访问到,                   注:“http://www.baidu.com” =》域名,“ic/wechatpay”=》接口。
             user_id=open_id,
             out_trade_no="JSAPI" + order_id,
             product_id=1,
             time_expire=hours_later
      )
      timestamp = str(int(time.time()))
      nonce_str = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(15))
      params = wechatpay.jsapi.get_jsapi_params(
             prepay_id=pay_data['prepay_id'],
             timestamp=timestamp,
             nonce_str=nonce_str,
      )
      signature = wechatpay.jsapi.get_jsapi_signature(
            prepay_id=pay_data['prepay_id'],
            timestamp=timestamp,
            nonce_str=nonce_str,
      )
      params['signature'] = signature
      return Response(params)
 


class Wxpay_Result(APIView):
          """
          微信支付结果回调通知路由
          """
         def post(self, request, *args, **kwargs):
               """
              微信支付成功后会自动回调
               """
               a = request.body.decode('utf-8')
               data_dict = trans_xml_to_dict(a) # 回调数据转字典

               wechatpay = WeChatPay(
                       appid=settings.APPID,
                       api_key=settings.API_KEY,
                       mch_id=settings.MCH_ID,
                       mch_cert=os.path.join(os.path.dirname(os.path.abspath(__file__)), "../keys/apiclient_cert.pem"),
                       mch_key=os.path.join(os.path.dirname(os.path.abspath(__file__)), "../keys/apiclient_key.pem"),
                       timeout=300
                )
               sign = wechatpay.check_signature(data_dict)
               if data_dict['return_code'] == 'SUCCESS' and sign:
                '''
                 检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成                    功。
                 '''
                     OrderInfo.objects.filter(order_id=data_dict['out_trade_no'][5:]).update(
                             status=OrderInfo.ORDER_STATUS_ENUM['UNSEND'])
                    # 处理支付成功逻辑
                    # 返回接收结果给微信,否则微信会每隔8分钟发送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'}))
 
 
# 如有错误还请指出,感谢!!!!

猜你喜欢

转载自www.cnblogs.com/xiaohu1139168758/p/12192501.html