首先使用 wechatpy
库,执行以下命令进行安装
pip install wechatpy
1、 直连商户支付
import logging
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from wechatpy.pay import WeChatPay
from wechatpy.pay.api import WeChatOrder, WeChatRefund
# 假设这里有获取数据库配置的函数
from your_app.models import PaymentConfig # 请替换为实际的模型
# 获取当前模块的日志记录器,用于记录程序运行中的信息和错误
logger = logging.getLogger(__name__)
def get_payment_config():
"""
从数据库中获取直连商户的支付配置信息。
:return: 包含支付配置信息的字典,如果未找到则返回 None
"""
try:
# 假设只有一个直连商户配置,从数据库中获取
config = PaymentConfig.objects.first()
return {
'appid': config.appid, # 微信小程序的 AppID
'mch_id': config.mch_id, # 微信支付商户号
'api_key': config.api_key, # 微信支付 API 密钥
'cert_path': config.cert_path, # 商户证书路径
'key_path': config.key_path # 商户私钥路径
}
except AttributeError:
# 若未找到对应的支付配置,记录错误信息
logger.error("Payment config not found.")
return None
@require_http_methods(["POST"])
def wx_pay(request):
"""
处理微信小程序支付请求,创建预支付订单并返回支付参数。
:param request: Django 请求对象,包含 POST 请求的数据
:return: JSON 响应,包含支付结果和相关信息
"""
# 获取 POST 请求中的所有数据,并转换为字典
data = request.POST.dict()
# 获取支付配置
config = get_payment_config()
if not config:
# 若未找到支付配置,返回错误信息
return JsonResponse({'code': 400, 'msg': 'Payment config not found'})
# 根据支付配置初始化微信支付对象
wechat_pay = WeChatPay(
appid=config['appid'],
mch_id=config['mch_id'],
api_key=config['api_key'],
cert_path=config['cert_path'],
key_path=config['key_path']
)
# 创建微信订单 API 对象
order_api = WeChatOrder(wechat_pay)
try:
# 调用微信支付 API 创建预支付订单
result = order_api.create(
trade_type='JSAPI', # 交易类型,JSAPI 表示微信小程序支付
body=data.get('body'), # 商品描述
out_trade_no=data.get('out_trade_no'), # 商户订单号
total_fee=int(float(data.get('total_fee')) * 100), # 订单总金额,单位为分
notify_url=data.get('notify_url'), # 支付结果通知地址
openid=data.get('openid') # 用户的微信 openid
)
if result.get('return_code') == 'SUCCESS' and result.get('result_code') == 'SUCCESS':
# 若预支付订单创建成功,获取预支付 ID
prepay_id = result.get('prepay_id')
# 获取微信小程序支付所需的参数
pay_params = wechat_pay.jsapi.get_jsapi_params(prepay_id)
# 返回成功响应,包含支付参数
return JsonResponse({'code': 200, 'msg': 'Success', 'data': pay_params})
else:
# 若预支付订单创建失败,返回错误信息
return JsonResponse({'code': 400, 'msg': result.get('return_msg')})
except Exception as e:
# 若出现异常,记录错误信息并返回错误响应
logger.error(f"Payment error: {e}")
return JsonResponse({'code': 500, 'msg': 'Payment error'})
@require_http_methods(["POST"])
def wx_query(request):
"""
处理微信订单查询请求,返回订单的详细信息。
:param request: Django 请求对象,包含 POST 请求的数据
:return: JSON 响应,包含查询结果和相关信息
"""
# 获取 POST 请求中的所有数据,并转换为字典
data = request.POST.dict()
# 获取支付配置
config = get_payment_config()
if not config:
# 若未找到支付配置,返回错误信息
return JsonResponse({'code': 400, 'msg': 'Payment config not found'})
# 根据支付配置初始化微信支付对象
wechat_pay = WeChatPay(
appid=config['appid'],
mch_id=config['mch_id'],
api_key=config['api_key'],
cert_path=config['cert_path'],
key_path=config['key_path']
)
# 创建微信订单 API 对象
order_api = WeChatOrder(wechat_pay)
try:
# 调用微信支付 API 查询订单信息
result = order_api.query(out_trade_no=data.get('out_trade_no'))
# 返回成功响应,包含订单查询结果
return JsonResponse({'code': 200, 'msg': 'Success', 'data': result})
except Exception as e:
# 若出现异常,记录错误信息并返回错误响应
logger.error(f"Query error: {e}")
return JsonResponse({'code': 500, 'msg': 'Query error'})
@require_http_methods(["POST"])
def wx_refund(request):
"""
处理微信订单退款请求,发起退款操作并返回结果。
:param request: Django 请求对象,包含 POST 请求的数据
:return: JSON 响应,包含退款结果和相关信息
"""
# 获取 POST 请求中的所有数据,并转换为字典
data = request.POST.dict()
# 获取支付配置
config = get_payment_config()
if not config:
# 若未找到支付配置,返回错误信息
return JsonResponse({'code': 400, 'msg': 'Payment config not found'})
# 根据支付配置初始化微信支付对象
wechat_pay = WeChatPay(
appid=config['appid'],
mch_id=config['mch_id'],
api_key=config['api_key'],
cert_path=config['cert_path'],
key_path=config['key_path']
)
# 创建微信退款 API 对象
refund_api = WeChatRefund(wechat_pay)
try:
# 调用微信支付 API 发起退款操作
result = refund_api.create(
out_trade_no=data.get('out_trade_no'), # 商户订单号
out_refund_no=data.get('out_refund_no'), # 商户退款单号
total_fee=int(float(data.get('total_fee')) * 100), # 订单总金额,单位为分
refund_fee=int(float(data.get('refund_fee')) * 100) # 退款金额,单位为分
)
if result.get('return_code') == 'SUCCESS' and result.get('result_code') == 'SUCCESS':
# 若退款操作成功,返回成功响应,包含退款结果
return JsonResponse({'code': 200, 'msg': 'Success', 'data': result})
else:
# 若退款操作失败,返回错误信息
return JsonResponse({'code': 400, 'msg': result.get('return_msg')})
except Exception as e:
# 若出现异常,记录错误信息并返回错误响应
logger.error(f"Refund error: {e}")
return JsonResponse({'code': 500, 'msg': 'Refund error'})
2、有子商户的实现
import logging
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from wechatpy.pay import WeChatPay
from wechatpy.pay.api import WeChatOrder, WeChatRefund
# 假设这里有获取数据库配置的函数
from your_app.models import PaymentConfig # 请替换为实际的模型
# 获取当前模块的日志记录器,用于记录程序运行中的信息和错误
logger = logging.getLogger(__name__)
def get_payment_config(sub_mch_id):
"""
根据子商户 ID 从数据库中获取支付配置信息。
:param sub_mch_id: 子商户 ID
:return: 包含支付配置信息的字典,如果未找到则返回 None
"""
try:
# 从数据库中查找指定子商户 ID 的支付配置
config = PaymentConfig.objects.get(sub_mch_id=sub_mch_id)
return {
'appid': config.appid, # 微信小程序的 AppID
'mch_id': config.mch_id, # 微信支付商户号
'sub_mch_id': config.sub_mch_id, # 子商户号
'api_key': config.api_key, # 微信支付 API 密钥
'cert_path': config.cert_path, # 商户证书路径
'key_path': config.key_path # 商户私钥路径
}
except PaymentConfig.DoesNotExist:
# 若未找到对应的支付配置,记录错误信息
logger.error(f"Payment config not found for sub_mch_id: {sub_mch_id}")
return None
@require_http_methods(["POST"])
def wx_pay(request):
"""
处理微信小程序支付请求,创建预支付订单并返回支付参数。
:param request: Django 请求对象,包含 POST 请求的数据
:return: JSON 响应,包含支付结果和相关信息
"""
# 获取 POST 请求中的所有数据,并转换为字典
data = request.POST.dict()
# 从请求数据中获取子商户 ID
sub_mch_id = data.get('sub_mch_id')
# 根据子商户 ID 获取支付配置
config = get_payment_config(sub_mch_id)
if not config:
# 若未找到支付配置,返回错误信息
return JsonResponse({'code': 400, 'msg': 'Payment config not found'})
# 根据支付配置初始化微信支付对象
wechat_pay = WeChatPay(
appid=config['appid'],
mch_id=config['mch_id'],
sub_mch_id=config['sub_mch_id'],
api_key=config['api_key'],
cert_path=config['cert_path'],
key_path=config['key_path']
)
# 创建微信订单 API 对象
order_api = WeChatOrder(wechat_pay)
try:
# 调用微信支付 API 创建预支付订单
result = order_api.create(
trade_type='JSAPI', # 交易类型,JSAPI 表示微信小程序支付
body=data.get('body'), # 商品描述
out_trade_no=data.get('out_trade_no'), # 商户订单号
total_fee=int(float(data.get('total_fee')) * 100), # 订单总金额,单位为分
notify_url=data.get('notify_url'), # 支付结果通知地址
openid=data.get('openid') # 用户的微信 openid
)
if result.get('return_code') == 'SUCCESS' and result.get('result_code') == 'SUCCESS':
# 若预支付订单创建成功,获取预支付 ID
prepay_id = result.get('prepay_id')
# 获取微信小程序支付所需的参数
pay_params = wechat_pay.jsapi.get_jsapi_params(prepay_id)
# 返回成功响应,包含支付参数
return JsonResponse({'code': 200, 'msg': 'Success', 'data': pay_params})
else:
# 若预支付订单创建失败,返回错误信息
return JsonResponse({'code': 400, 'msg': result.get('return_msg')})
except Exception as e:
# 若出现异常,记录错误信息并返回错误响应
logger.error(f"Payment error: {e}")
return JsonResponse({'code': 500, 'msg': 'Payment error'})
@require_http_methods(["POST"])
def wx_query(request):
"""
处理微信订单查询请求,返回订单的详细信息。
:param request: Django 请求对象,包含 POST 请求的数据
:return: JSON 响应,包含查询结果和相关信息
"""
# 获取 POST 请求中的所有数据,并转换为字典
data = request.POST.dict()
# 从请求数据中获取子商户 ID
sub_mch_id = data.get('sub_mch_id')
# 根据子商户 ID 获取支付配置
config = get_payment_config(sub_mch_id)
if not config:
# 若未找到支付配置,返回错误信息
return JsonResponse({'code': 400, 'msg': 'Payment config not found'})
# 根据支付配置初始化微信支付对象
wechat_pay = WeChatPay(
appid=config['appid'],
mch_id=config['mch_id'],
sub_mch_id=config['sub_mch_id'],
api_key=config['api_key'],
cert_path=config['cert_path'],
key_path=config['key_path']
)
# 创建微信订单 API 对象
order_api = WeChatOrder(wechat_pay)
try:
# 调用微信支付 API 查询订单信息
result = order_api.query(out_trade_no=data.get('out_trade_no'))
# 返回成功响应,包含订单查询结果
return JsonResponse({'code': 200, 'msg': 'Success', 'data': result})
except Exception as e:
# 若出现异常,记录错误信息并返回错误响应
logger.error(f"Query error: {e}")
return JsonResponse({'code': 500, 'msg': 'Query error'})
@require_http_methods(["POST"])
def wx_refund(request):
"""
处理微信订单退款请求,发起退款操作并返回结果。
:param request: Django 请求对象,包含 POST 请求的数据
:return: JSON 响应,包含退款结果和相关信息
"""
# 获取 POST 请求中的所有数据,并转换为字典
data = request.POST.dict()
# 从请求数据中获取子商户 ID
sub_mch_id = data.get('sub_mch_id')
# 根据子商户 ID 获取支付配置
config = get_payment_config(sub_mch_id)
if not config:
# 若未找到支付配置,返回错误信息
return JsonResponse({'code': 400, 'msg': 'Payment config not found'})
# 根据支付配置初始化微信支付对象
wechat_pay = WeChatPay(
appid=config['appid'],
mch_id=config['mch_id'],
sub_mch_id=config['sub_mch_id'],
api_key=config['api_key'],
cert_path=config['cert_path'],
key_path=config['key_path']
)
# 创建微信退款 API 对象
refund_api = WeChatRefund(wechat_pay)
try:
# 调用微信支付 API 发起退款操作
result = refund_api.create(
out_trade_no=data.get('out_trade_no'), # 商户订单号
out_refund_no=data.get('out_refund_no'), # 商户退款单号
total_fee=int(float(data.get('total_fee')) * 100), # 订单总金额,单位为分
refund_fee=int(float(data.get('refund_fee')) * 100) # 退款金额,单位为分
)
if result.get('return_code') == 'SUCCESS' and result.get('result_code') == 'SUCCESS':
# 若退款操作成功,返回成功响应,包含退款结果
return JsonResponse({'code': 200, 'msg': 'Success', 'data': result})
else:
# 若退款操作失败,返回错误信息
return JsonResponse({'code': 400, 'msg': result.get('return_msg')})
except Exception as e:
# 若出现异常,记录错误信息并返回错误响应
logger.error(f"Refund error: {e}")
return JsonResponse({'code': 500, 'msg': 'Refund error'})