python微信支付_微信支付 python版

本文详细介绍了如何使用Python实现微信支付的功能,包括获取用户code、通过code获取openid、微信统一下单、签名算法、参数转XML、统一下单接口调用、订单查询等关键步骤,同时提到了一些可能遇到的问题和解决办法。
摘要由CSDN通过智能技术生成

需求:

微信打开商品列表页面-> 点击商品后直接显示付款页面-> 点击付款调用微信支付

说明

微信支付需要你申请了公众号(appid, key - 用于签名), 商户号(mch_id, AppSecret - 用于获取openid, 获取code)

调起微信支付的页面需要配置授权

签名校验通过时还是提示签名错误, 可能时候商户号KEY配置的问题了, 重置一下KEY, 你可以继续使用原来的KEY来重置

公众号变更时记得修改后台和前台代码中的APPID

需要的ID和KEY

# 微信配置基础数据

WPC = {

'APPID': 'wx21e25187cb87c9f0',

'APPSECRET': 'fdd177a7xxxxxxxxxxxxx856eeeb187c',

'MCHID': '14222000000',

'KEY': 'd7810713e1exxxxxxxxxxadc9617d0a6',

'GOODDESC': '商户号中的公司简称或全称-无要求的商品名字',

'NOTIFY_URL': 'https://www.xxxx.com/service/applesson/wechatordernotice',

}复制代码

流程简介

网页内调起微信支付需要一个微信统一下单生成的订单号(prepay_id)

调用微信的统一下单接口需要一个用户在商户下的唯一标示(openid)

获取openid需要code参数加上AppID和AppSecret等,通过API换取access_token(openid)

其中code又需要通过页面跳转来获取, 需要appid和重定向url(可以带有你自己的参数, 会原样返回)

那么开发思路便是一步步回朔了.

1. 获取code

用户点击按钮跳转到微信授权页, 微信处理完后重定向到redirect_uri, 并给我们加上code=xxx的参数, 这个code就是我们需要的

$('#buy').click(function() {

var param = {

appid: 'wx53c1xxxxad626eb8',

redirect_uri: 'https://www.xxxxx.com/wcpay/pay.html',

response_type: 'code',

scope: 'snsapi_base',

state: '1'

}

window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?' + $.param(param);

})复制代码

2. 获取openid

这个在后台完成, WPC中配置了你的APPSECRET, 这个不能泄露, 接口调用成功会拿到一个openid, 这里都不会有什么问题

@classmethod

def getOpenID(cls, kwargs):

param = {

'code': kwargs['code'],

'appid': WPC['APPID'],

'secret': WPC['APPSECRET'],

'grant_type': 'authorization_code',

}

# 通过code获取access_token

openIdUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token'

resp = requests.get(openIdUrl, params=param)

# {openid, accss_token, refresh_token, openid, scope, expires_in}

# openId = json.loads(resp.text)['openid']

return resp.text复制代码

3. 微信统一下单

统一下单 时参数传递需要签名(微信用我们设定的密匙对参数进行MD5加密, 通过双方的签名判断请求是否被篡改)

签名算法

@classmethod

def getSign(cls, kwargs):

# 计算签名

keys, paras = sorted(kwargs), []

paras = ['{}={}'.format(key, kwargs[key]) for key in keys if key != 'appkey']  # and kwargs[key] != '']

stringA = '&'.join(paras)

stringSignTemp = stringA + '&key=' + WPC['KEY']

sign = MD5(stringSignTemp).upper()

return sign复制代码

MD5函数

import hashlib

# 获取MD5

def MD5(str):

md5 = hashlib.md5()

md5.update(str.encode('utf-8'))

return md5.hexdigest()复制代码

参数转xml

@classmethod

def getxml(cls, kwargs):

kwargs['sign'] = Utility.getSign(kwargs)

# 生成xml

xml = ''

for key, value in kwargs.items():

xml += '{1}{0}>'.format(key, value)

xml = '{0}'.format(xml)

# print(xml)

return xml复制代码

统一下单代码

code = self.POST.get('code')

openidresp = Utility.getOpenID({'code': code})

openid = json.loads(openidresp).get('openid')

UnifieOrderRequest = {

'appid': 'wxxxxxc18f32ad626eb8',  # 公众账号ID

'body': '公司名称-商品',  # 商品描述

'mch_id': '1397xxxxxx8',  # 商户号:深圳市泽慧文化传播有限公司

'nonce_str': '',  # 随机字符串

'notify_url': 'https://service.xxxx.com/service/applesson/wechatordernotice',  # 微信支付结果异步通知地址

'openid': '',  # trade_type为JSAPI时,openid为必填参数!此参数为微信用户在商户对应appid下的唯一标识, 统一支付接口中,缺少必填参数openid!

'out_trade_no': '',  # 商户订单号

'spbill_create_ip': '',  # 终端IP

'total_fee': '',  # 标价金额

'trade_type': 'JSAPI',  # 交易类型

}

UnifieOrderRequest['nonce_str'] = Utility.getnoncestr()

UnifieOrderRequest['openid'] = openid

UnifieOrderRequest['out_trade_no'] = UnifieOrderRequest['mch_id'] + str(order.id)  # 内部订单号码

UnifieOrderRequest['spbill_create_ip'] = self.request.remote_ip

UnifieOrderRequest['total_fee'] = int(lesson.price * 100)

# 签名并生成xml

xml = Utility.getxml(UnifieOrderRequest)

resp = requests.post("https://api.mch.weixin.qq.com/pay/unifiedorder", data=xml.encode('utf-8'), headers={'Content-Type': 'text/xml'})

msg = resp.text.encode('ISO-8859-1').decode('utf-8')

xmlresp = xmltodict.parse(msg)

prepay_id = ''

if xmlresp['xml']['return_code'] == 'SUCCESS':

if xmlresp['xml']['result_code'] == 'SUCCESS':

prepay_id = xmlresp['xml']['prepay_id']

timestamp = str(int(time.time()))

data = {

"appId": xmlresp['xml']['appid'],

"nonceStr": Utility.getnoncestr(),

"package": "prepay_id=" + xmlresp['xml']['prepay_id'],

"signType": "MD5",

"timeStamp": timestamp

}

data['paySign'] = Utility.getSign(data)

data['orderid'] = order.id  # 付款后操作的订单

# 签名后返回给前端做支付参数

return JsonResponse(self, '000', data=data)

else:

msg = xmlresp['xml']['err_code_des']

return JsonResponse(self, '002', msg=msg)

else:

msg = xmlresp['xml']['return_msg']

return JsonResponse(self, '002', msg=msg)复制代码

统一下单成功返回后直接调用微信支付, 显示支付界面, 其中的paySign是我们自己的签名

try {

// statements

// 微信统一订单, 返回预支付信息

var code = query('code'),

origin = query('groupid');

// alert(code);

$.post({

url: orderurl,

data: {

origin: origin,

mobile: phone,

code: code

}

}).then(function(resp) {

if (resp.code && resp.code == "000") {

// 后台返回订单信息

var wepaydata = {

appId: resp.data.appId,

nonceStr: resp.data.nonceStr,

package: resp.data.package,

paySign: resp.data.paySign,

signType: "MD5",

timeStamp: resp.data.timeStamp

};

var orderid = resp.data.orderid || 0;

window.jsApiCall = function() {

WeixinJSBridge.invoke(

'getBrandWCPayRequest',

wepaydata,

function(res) {

WeixinJSBridge.log(res.err_msg);

// alert(res.err_code + res.err_desc + res.err_msg);

// alert(res.err_msg)

if (res.err_msg == 'get_brand_wcpay_request:ok') {

$.get(orderurl, { orderid: orderid }, function(resp) {

if (resp.code == '000') {

window.location.href = window.location.href.replace('pay.html', 'success.html');

} else {

alert(resp.msg);

// 一个code只能请求一次, 重新进入index

if (resp.code == '002') {

window.location.href = window.location.href.replace('pay.html', 'index.html');

}

}

});

} else {

// 其他支付异常微信有显示消息

// alert(res.err_msg);

}

}

);

}

window.callpay = function() {

if (typeof WeixinJSBridge == "undefined") {

if (document.addEventListener) {

document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);

} else if (document.attachEvent) {

document.attachEvent('WeixinJSBridgeReady', jsApiCall);

document.attachEvent('onWeixinJSBridgeReady', jsApiCall);

}

} else {

jsApiCall();

}

}

// 发起支付

window.callpay();

} else {

alert(resp.msg);

// alert(JSON.stringify(resp) + resp.msg);

}

}, function(resp) {

alert(resp)

alert(JSON.stringify(resp))

// alert('请求失败, 请重试');

});

} catch (e) {

// statements

alert(e)

}复制代码

4. 订单查询

订单查询 是为了确认我们的支付是成功的

# 查询微信付款情况

orderid = self.GET.get('orderid')

orderquery = {

'appid': WPC['APPID'],

'mch_id': WPC['MCHID'],

'nonce_str': Utility.getnoncestr(),

'out_trade_no': WPC['MCHID'] + orderid

}

xml = Utility.getxml(orderquery)

print(xml)

resp = requests.post("https://api.mch.weixin.qq.com/pay/orderquery", data=xml.encode('utf-8'), headers={'Content-Type': 'text/xml'})

msg = resp.text.encode('ISO-8859-1').decode('utf-8')

xmlresp = xmltodict.parse(msg)

print(xmlresp)

orderPaid = 0

if xmlresp['xml']['return_code'] == 'SUCCESS':

if xmlresp['xml']['result_code'] == 'SUCCESS':

if xmlresp['xml']['trade_state'] == 'SUCCESS':

orderPaid = 1

else:

msg = xmlresp['xml']['trade_state_desc']

return JsonResponse(self, '001', msg=smg)

else:

msg = xmlresp['xml']['err_code_des']

return JsonResponse(self, '001', msg=msg)

else:

msg = xmlresp['xml']['return_msg']

return JsonResponse(self, '001', msg=msg)复制代码

官方Demo

SDK与DEMO下载, 用python就需要自己码代码, 当时看的是PHP的

Python微信支付的Demo通常涉及到使用微信官方提供的`wxpy`库(针对个人开发者,处理基础功能)或`wechat_sdk`(用于商业场景,更全面的功能支持)与微信支付API的交互。以下是一个简化的步骤概述: 1. **安装依赖**: - 安装`requests`库用于HTTP请求,以及如上所述的微信支付SDK。 2. **注册应用**: - 在微信公众平台注册并获取AppID、AppSecret和商户号(对于企业支付)。 3. **初始化配置**: - 初始化微信支付对象,提供上述的AppID、AppSecret等信息。 4. **发起支付**: - 使用`统一下单接口`生成预订单(包含商品信息、金额等),并获取nonce_str和signature等签名参数。 5. **展示支付页面**: - 将生成的二维码或链接显示给用户,让用户通过微信客户端完成支付。 6. **验证支付结果**: - 支付完成后,用户会回调到指定URL,需要解析返回的数据(如`prepay_id`和`交易状态`),调用微信支付的`验证支付结果`接口确认交易。 ```python from wechat_sdk import WeChatPay # 初始化微信支付实例 wechat_pay = WeChatPay(appid="your_appid", mch_id="your_mch_id") # 统一下单 unified_order_info = wechat_pay.unified_order( total_fee=amount, out_trade_no=order_num, body='商品描述', notify_url='your_notify_url', # 订单通知地址 ) # 获取二维码图片数据或链接展示给用户 # ... # 验证支付结果 result = wechat_pay.verify_payment(result_data_from_user) if result['return_code'] == 'SUCCESS': print('支付成功') else: print('支付失败:', result['err_msg']) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值