python micro-channel public pay


# First, define the routing:
url ( 'ic / order / (? P <order_id>. +) / payment /', views_front.PaymentView.as_view ()), # micro-channel payment Component
url ( 'ic / wechatpay /', views_front.Wxpay_Result.as_view ()), # order payment success callback
 
# Two, define two functions used to convert text type

trans_dict_to_xml DEF (data_dict):
"" "
dictionary definition XML transfer function
: param data_dict:
: return:
" ""
data_xml = []
for K in the sorted (data_dict.keys ()): After traversing the dictionary ordering # Key
V = data_dict.get (k) # remove key dictionary corresponding value
IF K == 'Detail' and Not v.startswith ( '<[CDATA [!'): # add XML tags
v = '<[CDATA [{ }! ]]> '. the format (V)
data_xml.append (' <{Key}> {value} </} {Key> '. the format (Key = K, V = value))
return' <XML> {} </ xml> '. format (' ' . join (data_xml)) # returns 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

 

# Third, the backstage pass to the front desk to order_id and open_id
 
class PaymentView(APIView):
"" "Micro-channel pay." ""

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': 'incorrect order information', "enmessage": "Error"}, status = status.HTTP_400_BAD_REQUEST)
wechatpay = WeChatPay (
appid=settings.APPID,
# sub_appid=settings.sub_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,
# sandbox=True,
)
from math import floor
total_fee = floor(order.total_amount * 100)
from datetime import datetime, timedelta
from wechatpy.utils import timezone
now = datetime.fromtimestamp(time.time(), tz=timezone('Asia/Shanghai'))
hours_later = now + timedelta(seconds=60)
import random
import string
import json
pay_data = wechatpay.order.create(
trade_type="JSAPI",
body = 'smart cube% s'% order_id,
total_fee=total_fee,
notify_url = 'http: //www.baidu.com/ic/wechatpay/', # micro-channel pay after the success callback address, must be accessible to the external network, note: "http://www.baidu.com" = "domain name," ic / wechatpay "=" interface.
user_id=open_id,
out_trade_no=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):
"""
Micro-channel pay callback notification routing results
"""
def post(self, request, *args, **kwargs):
"""
After the success of micro-channel payment will automatically callback
Return parameters are:
{ '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:
"""
a = request.body.decode('utf-8')
data_dict = trans_xml_to_dict (a) # transfer data dictionary callback

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:
'''
Check the state of the corresponding service data, it determines whether the notification has been treated, if not dealt with further processing, if processed directly return successful results.
'''
OrderInfo.objects.filter(order_id=data_dict['out_trade_no']).update(
status=OrderInfo.ORDER_STATUS_ENUM['UNSEND'])
# Successful payment processing logic
# Return result to the micro-channel receiver, or micro-channel will be transmitted every 8 minutes post request
return HttpResponse(trans_dict_to_xml({'return_code': 'SUCCESS', 'return_msg': 'OK'}))
return HttpResponse(trans_dict_to_xml({'return_code': 'FAIL', 'return_msg': 'SIGNERROR'}))
 
 
# Please also indicate if wrong, thanks! ! ! !

Guess you like

Origin www.cnblogs.com/xiaohu1139168758/p/11314006.html