微信支付接口对接

2021年09月15日 阅读数:1
这篇文章主要向大家介绍微信支付接口对接,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

最近对接了安卓开发,涉及到了微信支付,须要调取微信 app 支付相关的接口,目前咱们项目中使用的是微信普通商户版的。咱们开发的安卓 APP 调用微信提供的SDK调用微信支付模块,安卓 APP 会跳转到微信中完成支付,支付完后跳回到安卓APP内,最后展现支付结果。咱们后端涉及到的接口主要是统一下单接口、调起支付接口,支付结果通知接口。php

首先按照统微信统一下单接口文档,把全部必填参数发送给统一下单接口在微信支付服务后台生成预支付交易单,若是成功统一下单接口会返回给你一个prepayid(这个很重要),而后再按照微信支付接口文档要求,把必填的字段以及以前返回给你的 prepay_id 发送给安卓 app 端,安卓 app 会调取微信支付接口。微信会根据你以前在统一下单接口中传递的 notify_url 字段,回调你的接口(这个接口必须是线上环境,外界能够访问的),通知你支付是否成功,参考支付结果通知。微信 app 支付的流程大致是这样的。须要注意的是签名的生成,必需要把参数按照 ASCII 码进行排序。python

import datetimeimport loggingimport timeimport uuidfrom decimal import Decimal
import requestsfrom django.db import transactionfrom wechatpy.pay.utils import calculate_signature

def order_wx_app_pay(main_order): """ 订单微信APP支付 :param main_order: :return: """ unpaid_amount = main_order.get_unpaid_amount() if unpaid_amount <= 0: return False, ErrorCode.NOT_TO_PAY_ORDER # company = main_order.company # account = company.wx_account # sub_mch_id = account.mchid # if not sub_mch_id: # return False, ErrorCode.NOT_COMPANY_MCH_ID # ip = self.request.headers.get('X-Real-Ip', 0) or self.request.remote_ip ip = "127.0.0.1" nonce_str = uuid.uuid1().hex.upper() notify_url = WxConfig.NOTIFY_URL body = "商品名称" req_args = { "appid": WxConfig.WX_PAY_APP_ID_OFFICAL, # 商户的APPID "mch_id": WxConfig.MCH_ID, # 商户号 "nonce_str": nonce_str, # 随机字符串 "body": body.encode("utf-8"), # 商品描述 "out_trade_no": main_order.order_number, # 商户订单号 "total_fee": int(unpaid_amount * 100), # 总金额 "spbill_create_ip": ip, # 终端IP "notify_url": notify_url, # 通知地址 "trade_type": "APP" # 交易类型 } # 生成签名 req_sign = calculate_signature(req_args, WxConfig.WX_PAY_API_KEY) req_args['sign'] = req_sign req_xml = trans_dict_to_xml(req_args) # 定义返回信息 return_code, return_msg, result_code = None, None, None prepay_id = None # 调用微信统一下单接口,正常返回prepay_id try: response = requests.post(url=WxConfig.URL_PAY_WX_MP, data=req_xml) response.encoding = "utf8" result = response.text result = trans_xml_to_dict(result) return_code = result['return_code'] return_msg = result['return_msg'] if return_code == "SUCCESS": result_code = result['result_code'] if result_code == 'SUCCESS': prepay_id = result.get('prepay_id') else: err_code_des = result.get("err_code_des", ErrorCode.NOT_PREPAY_ID[1]) return False, (99999, err_code_des) else: return False, (99999, return_msg)
except Exception as e: log_service.exception(e)
log_service.info('PayResult ReturnCode:%s ReturnMSG:%s ResultCode:%s PrePayID:%s', return_code, return_msg, result_code, prepay_id)
if not prepay_id: return False, ErrorCode.NOT_PREPAY_ID ts_str = str(int(time.time())) _nonce_str = uuid.uuid1().hex.upper() app_sign_args = { 'appid': WxConfig.WX_PAY_APP_ID_OFFICAL, # 子商户在微信开放平台上申请的APPID 'noncestr': _nonce_str, # 随机字符串 'package': 'Sign=WXPay', # 扩展字段 'partnerid': WxConfig.MCH_ID, # 子商户的商户号 "prepayid": prepay_id, # 微信返回的支付交易会话ID 'timestamp': ts_str, # 时间戳 } app_sign = calculate_signature(app_sign_args, WxConfig.WX_PAY_API_KEY) app_sign_args['sign'] = app_sign return True, app_sign_args

def wx_pay_notify(request): """订单微信支付回调""" return_code = "FAIL" log_service.info(request.data) try: notify_data = trans_xml_to_dict(request.data) except: return_msg = ErrorCode.FORMAT_ERROR_PAY_NOTIFY return trans_dict_to_xml({"return_code": return_code, "return_msg": return_msg}) wx_sign = notify_data.pop("sign", "") app_sign = calculate_signature(notify_data, WxConfig.WX_PAY_API_KEY) if wx_sign != app_sign: return_msg = ErrorCode.BAD_SIGN return trans_dict_to_xml({"return_code": return_code, "return_msg": return_msg}) if notify_data["return_code"] != "SUCCESS": return_msg = notify_data["err_code_des"] return trans_dict_to_xml({"return_code": return_code, "return_msg": return_msg}) transaction_id = notify_data.get("transaction_id", "") # 微信支付订单号 out_trade_no = notify_data.get("out_trade_no", "") # 商户订单号 total_fee = notify_data.get("total_fee", "") # 订单总金额,单位为分 pay_time_str = notify_data.get("pay_time", "") # 支付完成时间 try: pay_time = datetime.datetime.strptime(pay_time_str, "%Y%m%d%H%M%S") except: pay_time = datetime.datetime.now() if not OrderPay.objects.filter(transaction_id=transaction_id).exists(): main_order = MainOrder.objects.get(orderno=out_trade_no) data = { "main_order": main_order, "amount": Decimal(total_fee) / 100, "pay_time": pay_time, "pay_method": MainOrderPayMethod.wx, "confirm_time": datetime.datetime.now(), "status": OrderPayLogStatus.had_pay, } with transaction.atomic(): order_pay = OrderPay.objects.create(**data) order_pay.gene_order_number() flow_main_order.update_main_order_paid_amount_status(main_order=main_order) # 更新订单的支付金额和支付状态 return_code = "SUCCESS" return_msg = "ok" return trans_dict_to_xml({"return_code": return_code, "return_msg": return_msg}

微信支付文档https://pay.weixin.qq.com/wiki/doc/api/app/app_sl.php?chapter=9_1django

本文分享自微信公众号 - pythonista的平常(gh_fc70d5d98d3f)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。后端