最近对接了安卓开发,涉及到了微信支付,需要调取微信 app 支付相关的接口,目前我们项目中使用的是微信普通商户版的。我们开发的安卓 APP 调用微信提供的SDK调用微信支付模块,安卓 APP 会跳转到微信中完成支付,支付完后跳回到安卓APP内,最后展示支付结果。我们后端涉及到的接口主要是统一下单接口、调起支付接口,支付结果通知接口。
首先按照统微信统一下单接口文档,把所有必填参数发送给统一下单接口在微信支付服务后台生成预支付交易单,如果成功统一下单接口会返回给你一个prepayid(这个很重要),然后再按照微信支付接口文档要求,把必填的字段以及之前返回给你的 prepay_id 发送给安卓 app 端,安卓 app 会调取微信支付接口。微信会根据你之前在统一下单接口中传递的 notify_url 字段,回调你的接口(这个接口必须是线上环境,外界可以访问的),通知你支付是否成功,参考支付结果通知。微信 app 支付的流程大体是这样的。需要注意的是签名的生成,必须要把参数按照 ASCII 码进行排序。
import datetime
import logging
import time
import uuid
from decimal import Decimal
import requests
from django.db import transaction
from 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_1
本文分享自 pythonista的日常 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有