# -*- coding: utf-8 -*- import json import logging import os from random import sample from string import ascii_letters, digits from flask import Flask, jsonify, request from wechatpayv3 import SignType, WeChatPay, WeChatPayType from flask_redis import FlaskRedis import time import uuid # 微信支付商户号(直连模式)或服务商商户号(服务商模式,即sp_mchid) MCHID = '123123123' # 商户证书私钥 with open('./path_to_key/apiclient_key.pem') as f: PRIVATE_KEY = f.read() # 商户证书序列号 CERT_SERIAL_NO = '123123123' # API v3密钥, https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay3_2.shtml APIV3_KEY = '123123123' # APPID,应用ID或服务商模式下的sp_appid APPID = '123123123' # 回调地址,也可以在调用接口的时候覆盖 NOTIFY_URL = '' # 微信支付平台证书缓存目录,减少证书下载调用次数,首次使用确保此目录为空目录. # 初始调试时可不设置,调试通过后再设置,示例值:'./cert' CERT_DIR = None # 日志记录器,记录web请求和回调细节 logging.basicConfig(filename=os.path.join(os.getcwd(), 'demo.log'), level=logging.DEBUG, filemode='a', format='%(asctime)s - %(process)s - %(levelname)s: %(message)s') LOGGER = logging.getLogger("demo") # 接入模式:False=直连商户模式,True=服务商模式 PARTNER_MODE = False # 代理设置,None或者{"https": "http://10.10.1.10:1080"},详细格式参见https://docs.python-requests.org/zh_CN/latest/user/advanced.html PROXY = None # 初始化 wxpay = WeChatPay( wechatpay_type=WeChatPayType.JSAPI, mchid=MCHID, private_key=PRIVATE_KEY, cert_serial_no=CERT_SERIAL_NO, apiv3_key=APIV3_KEY, appid=APPID, notify_url=NOTIFY_URL, cert_dir=CERT_DIR, logger=LOGGER, partner_mode=PARTNER_MODE, proxy=PROXY) app = Flask(__name__) @app.route('/game/wxcallback', methods=['POST']) def wxcallback(): result = wxpay.callback(request.headers, request.data) if result and result.get('event_type') == 'TRANSACTION.SUCCESS': print("result = ", result) resp = result.get('resource') print("resp = ", resp) print("out_trade_no = ", resp["out_trade_no"]) # appid = resp.get('appid') # mchid = resp.get('mchid') # out_trade_no = resp.get('out_trade_no') # transaction_id = resp.get('transaction_id') # trade_type = resp.get('trade_type') # trade_state = resp.get('trade_state') # trade_state_desc = resp.get('trade_state_desc') # bank_type = resp.get('bank_type') # attach = resp.get('attach') # success_time = resp.get('success_time') # payer = resp.get('payer') # amount = resp.get('amount').get('total') # TODO: 根据返回参数进行必要的业务处理,处理完后返回200或204 return jsonify({'code': 'SUCCESS', 'message': '成功', 'data': resp}) else: return jsonify({'code': 'FAILED', 'message': '失败'}) @app.route('/game/h5pay', methods=['POST']) def h5pay(): body = request.get_json() print("body = ", body) code, resp_str = wxpay.pay(description=body["description"], out_trade_no=body["order_no"], amount={'total': int(body["payment"])}, payer={'openid': body["openid"]}, pay_type=WeChatPayType.JSAPI) if code == 200: resp = json.loads(resp_str) prepay_id = resp["prepay_id"] timestamp = int(time.time()) nonceStr = "".join(str(uuid.uuid4()).split('-')).upper() package = f"prepay_id={prepay_id}" data = [APPID, str(timestamp), nonceStr, package] paySign = wxpay.sign(data) resp["timestamp"] = str(timestamp) resp["nonceStr"] = nonceStr resp["prepay_id"] = prepay_id resp["package"] = package resp["paySign"] = paySign return jsonify({'code': code, 'data': resp}) return jsonify({'code': code}) if __name__ == '__main__': app.run()