最近一段时间一直在搞微信平台开发,最近的v3.37版本微信支付接口变化贼大,所以就看着php的demo移植为
python版,为了保持一致,所以接口方法基本都没有变,这样的好处就是不用写demo了,看着微信官方的demo
照葫芦画瓢就可以了。
我已经把代码放到github了,https://github.com/Skycrab/wzhifuSDK,我主要测试了JsApi调用方式,其它的调用方式并没有测试,如果你发现了bug,请多多pull request,我将不甚感激。
方便观看,代码贴于此。
#coding:utf-8
"""
Created on 2014-11-24
@author: http://blog.youkuaiyun.com/yueguanghaidao
* 微信支付帮助库
* ====================================================
* 接口分三种类型:
* 【请求型接口】--Wxpay_client_
* 统一支付接口类--UnifiedOrder
* 订单查询接口--OrderQuery
* 退款申请接口--Refund
* 退款查询接口--RefundQuery
* 对账单接口--DownloadBill
* 短链接转换接口--ShortUrl
* 【响应型接口】--Wxpay_server_
* 通用通知接口--Notify
* Native支付——请求商家获取商品信息接口--NativeCall
* 【其他】
* 静态链接二维码--NativeLink
* JSAPI支付--JsApi
* =====================================================
* 【CommonUtil】常用工具:
* trimString(),设置参数时需要用到的字符处理函数
* createNoncestr(),产生随机字符串,不长于32位
* formatBizQueryParaMap(),格式化参数,签名过程需要用到
* getSign(),生成签名
* arrayToXml(),array转xml
* xmlToArray(),xml转 array
* postXmlCurl(),以post方式提交xml到对应的接口url
* postXmlSSLCurl(),使用证书,以post方式提交xml到对应的接口url
"""
import json
import time
import random
import urllib2
import hashlib
import threading
from urllib import quote
import xml.etree.ElementTree as ET
try:
import pycurl
from cStringIO import StringIO
except ImportError:
pycurl = None
class WxPayConf_pub(object):
"""配置账号信息"""
#=======【基本信息设置】=====================================
#微信公众号身份的唯一标识。审核通过后,在微信发送的邮件中查看
APPID = "wx8888888888888888"
#JSAPI接口中获取openid,审核后在公众平台开启开发模式后可查看
APPSECRET = "48888888888888888888888888888887"
#受理商ID,身份标识
MCHID = "18888887"
#商户支付密钥Key。审核通过后,在微信发送的邮件中查看
KEY = "48888888888888888888888888888886"
#=======【异步通知url设置】===================================
#异步通知url,商户根据实际开发过程设定
NOTIFY_URL = "http://******.com/payback"
#=======【JSAPI路径设置】===================================
#获取access_token过程中的跳转uri,通过跳转将code传入jsapi支付页面
JS_API_CALL_URL = "http://******.com/pay/?showwxpaytitle=1"
#=======【证书路径设置】=====================================
#证书路径,注意应该填写绝对路径
SSLCERT_PATH = "/******/cacert/apiclient_cert.pem"
SSLKEY_PATH = "/******/cacert/apiclient_key.pem"
#=======【curl超时设置】===================================
CURL_TIMEOUT = 30
#=======【HTTP客户端设置】===================================
HTTP_CLIENT = "CURL" # ("URLLIB", "CURL")
class Singleton(object):
"""单例模式"""
_instance_lock = threading.Lock()
def __new__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
with cls._instance_lock:
if not hasattr(cls, "_instance"):
impl = cls.configure() if hasattr(cls, "configure") else cls
instance = super(Singleton, cls).__new__(impl, *args, **kwargs)
instance.__init__(*args, **kwargs)
cls._instance = instance
return cls._instance
class UrllibClient(object):
"""使用urlib2发送请求"""
def get(self, url, second=30):
return self.postXml(None, url, second)
def postXml(self, xml, url, second=30):
"""不使用证书"""
data = urllib2.urlopen(url, xml, timeout=second).read()
return data
def postXmlSSL(self, xml, url, second=30):
"""使用证书"""
raise TypeError("please use CurlClient")
class CurlClient(object):
"""使用Curl发送请求"""
def __init__(self):
self.curl = pycurl.Curl()
self.cur