本文时间为2017年04月16日,如果微信支付官方文档有变化请注意。

h5页面用JS调起支付。

文档里面的参数一定要分清楚大小写!有些地方是大写,有些小写,有些又是下划线。真的巨坑

noncestr nonce_str nonceStr

timestamp timeStamp

1.微信JS SDK

文档地址

有一个坑,因为我是在微信服务号中调用的,有一步需要获取用户的openid,导致最后的url变化为/?code=xxxx&state=xxx。

函数说明:

create_noncestr 生成16位随机字符串

create_timestamp 生成10位时间戳

get_jsapi_ticket 根据 access_token 获取jsapi_ticket

js_url 为当前的url!即调用该JS页面的完整url

noncestr = create_noncestr()
timestamp = create_timestamp()
jsapi = get_jsapi_ticket()
js_url = JSAPI_URL + '?code={code}&state={state}'.format(code=code, state=state)

开启debug:true,如果提示 “errMsg”:”config ok” 则表示JSSDK初始化成功。(成功提示居然是errMsg。。)

2.统一下单

文档地址

坑一:按照文档的步骤走,但是有一点需要注意,文档里面没有timeStamp这一项,需要自己加!

坑二:spbill_create_ip

这个参数表示客服端ip,由于我是用Django进行开发,Nginx反向代理,所以这里如果用 request.META[‘REMOTE_ADDR’] 为127.0.0.1

应该使用 request.META[‘HTTP_X_FORWARDED_FOR’].split(‘,’)[0]

坑三:openid 为必填(JS SDK支付为必填)

坑四:openssl 给微信服务器发送xml数据的地址是https,Linux下需要安装一些东西。

sudo apt-get install openssl
sudo apt-get install libssl-dev

拿到 perpay_id 后,里面同时有个sign,注意这个sign不是前端所需要的paySign

这句话在JS SDK文档里面:

paySign 采用统一的微信支付 Sign 签名生成方法,注意这里 appId 也要参与签名,appId 与 config 中传入的 appId 一致,即最后参与签名的参数有appId, timeStamp, nonceStr, package, signType。

用同样的签名方式

# 拿到prepay_id后继续获取前端所需要的 paySign
d1 = {
    'appId': APP_ID,
    'timeStamp': 2步骤发送的timestamp,
    'nonceStr': 2步骤返回的nonce_str,
    'package': 'prepay_id='+ 2步骤返回的perpay_id,
    'signType': 'MD5',
}
s_d1 = '&'.join(['%s=%s' % (key, d1[key]) for key in sorted(d1)])
# 这里注意必须在最后加上 &key=商户key(在微信支付商户设置里面设置的32位随机字符串)
s_d1 += '&key={key}'.format(key=API_KEY)
paySign = hashlib.md5(s_d1.encode('utf-8')).hexdigest().upper()

3.前端调用

真的无语,微信官方有两套方法。微信支付有一套,JSSDK里面又有一种。最后用的微信支付文档里面的方法

文档地址


function onBridgeReady () {
    WeixinJSBridge.invoke(
        'getBrandWCPayRequest', {
            "appId":"wx2421b1c4370ec43b",     //公众号名称,由商户传入     
            "timeStamp":"1395712654",         //时间戳,自1970年以来的秒数     
            "nonceStr":"e61463f8efa94090b1f366cccfbbb444", //随机串     
            "package":"prepay_id=u802345jgfjsdfgsdg888",     
            "signType":"MD5",         //微信签名方式:     
            "paySign":"70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 
        },
        function (res) {     
            if(res.err_msg == "get_brand_wcpay_request:ok" ) {}     // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。 
        }
    ); 
}

if (typeof WeixinJSBridge == "undefined") {
    if (document.addEventListener) {
            document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
        } else if (document.attachEvent) {
            document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
            document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
        }
    } else {
        onBridgeReady();
    }

4.notify地址返回success或者fail

2017年05月26日补充:这里和之前一样,拿到request.body xml解析后操作,返回也是xml格式。

付款成功后的操作就在这里进行。

##5.需要用到的key/id

1.公众账号ID APPID

2.商户号 mch_id

3.商户key (商户平台后台设置的32位随机字符串)