微信JSAPI支付结果通知(代码详解)
支付结果通知官方文档
## 应用场景
支付完成后,微信会把相关支付结果及用户信息通过数据流的形式发送给商户,商户需要接收处理,并按文档规范返回应答。
注意:
1、同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。
2、后台通知交互时,如果微信收到商户的应答不符合规范或超时,微信会判定本次通知失败,重新发送通知,直到成功为止(在通知一直不成功的情况下,微信总共会发起多次通知,通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h
- 总计 24h4m),但微信不保证通知最终一定能成功。
3、在订单状态不明或者没有收到微信支付结果通知的情况下,建议商户主动调用微信支付【查询订单API】确认订单状态。
特别提醒:
1、商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致,防止数据泄漏导致出现“假通知”,造成资金损失。
2、当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
接口链接
我们在统一下单接口中设置的notify_url,当用户支付成功后,微信将把支付结果及一些用户数据和交易数据发送到这个借口,而我们后台就必须正确的接收处理这些数据,并按文档规范返回应答.
相应的通知参数请各位移步到官方文档观看,我在这就不啰嗦了
直接贴上我的代码:
class WechatNotifyUrl(View):'''支付完成后,微信会把相关支付结果及用户信息通过数据流的形式发送给商户,商户需要接收处理,并按文档规范返回应答。详情参考:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7&index=8发给商户的参数:1 返回给微信的参数 '''def post(self,request):return_data = ''' '''# 获取到微信发送过来的数据result = request.body.decode()ret = dict_parse_from_xml(result)# 如果return_code返回的是FAIL,说明返回通信标识失败return_code = ret.get('return_code','FAIL')if return_code == 'FAIL':# 将数据转换成为xml,返回logger.info('微信支付礼物结果通知商户,返回的标识信息为FAIL')return_msg = ret['return_msg']msg = {'return_code':'FAIL','return_msg':return_msg}return_data = return_data.format(**msg)return HttpResponse(return_data,content_type="text/xml")# 支付的结果result_code = ret.get('result_code','FAIL')logger.info('pay result is {}'.format(result_code))if return_code == 'SUCCESS' and result_code == 'SUCCESS':# 支付完成的情况# 获取到商户的订单号,查找到当前的预支付对象(记录)out_trade_no = ret.get('out_trade_no')try:order = PaymentOrder.objects.get(charge_id=out_trade_no)# 签名验证,并校验返回的订单金额是否与商户侧的订单金额一致wechart_sign = ret.get('sign',None)# 计算签名时,签名不能计算在内del ret['sign']sign,_ = get_sign(ret,pay_sign_key=settings.WECHAT_API_KEY)money = ret.get('total_fee')total_fee = float(int(money)/100)amount = float(order.amount)if sign != wechart_sign and amount != total_fee:logger.info("签名或金额不对应")raise Exception('签名或金额不对应')except:logger.info('没有此预付订单')return HttpResponse('没有此预付订单')else:# 当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。pay_status = order.statuslogger.info('pay_status is {}'.format(pay_status))if pay_status == PAYMENT_ORDER_STATUS_FINISHED:logger.info("Order {} already {}".format(order.charge_id, order.status))if pay_status == PAYMENT_ORDER_STATUS_PENDING:# transaction_id 微信支付订单号transaction_id = ret.get('transaction_id')order.status = PAYMENT_ORDER_STATUS_PAIDorder.transaction_id = transaction_idorder.save()# 源头账户为微信支付主账户source_account = get_wechat_account()# 目的地账户为关联到预支付订单的账户destination_account = order.account# 资金从源头账户转移到目的地账户logger.info("Transfer of {} from account {} to account {}".format(order.amount, source_account, destination_account))merchant = settings.ACCOUNT_MERCHANT_WECHAT_PREFIXtransfer = Transfer.objects.create(source_account, destination_account, order.amount,order.user, merchant, order.description)order.transfer = transferorder.status = PAYMENT_ORDER_STATUS_FINISHEDorder.save()# 购买课程信息/打赏红包/礼物等信息存储入库charge(order.charge_id, order, destination_account)return_msg = {'return_code':'SUCCESS','return_msg':'ok'}return_data = return_data.format(**return_msg)logger.info('回复微信支付通知成功')return HttpResponse(return_data,content_type="text/xml")else:# result_code 为FAIL时返回错误码err_code_des = ret.get('err_code_des')logger.info('支付失败的原因是:{}'.format(err_code_des))err_code = ret.get('err_code')return_msg = {'return_code':'FAIL','return_msg':err_code}return_data = return_data.format(**return_msg)return HttpResponse(return_data,content_type="text/xml")
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
