页面按钮显示:
<!--支付确认按钮--> <article class="btn-group"> <a href="javascript:void(0);" click=‘wx_pay()‘ class="btn btn-w100 f28"> 下一步 </a> </article>
点击支付:
var wx_pay = function(){ var ordernum=$("#hid_ordernum").val(); var ip=$("#hid_ip").val(); var ra=$(‘input:radio[name="pay-type"]:checked‘).val(); if(ra=="weixin"){ var open_id = "{{open_id}}"; if(open_id.length <= 0 ){ //如果用户还没有微信给的open_id 就去获取一个 这个是静默授权获取 $.get("/wechat/weixin_snsapi_base/"+ordernum,{},function(data){ window.location.href = data.wx_redirect_url; }) }else{ $.ajax({ type: "POST", url: "/wechat/unified_order", data: {‘ordernum‘:ordernum,"ip":ip}, success:function (data) { if(data["code"]=="SUCCESS"){ //调起微信支付 onBridgeReady(data["dict"]); }else{ $("#div_box_message").html(data[‘msg‘]); $("#div_show_box").show(); }; } }); } }else { $("#div_box_message").html("请选择你支付方式!"); $("#div_show_box").show(); return false; } }
支付的首先调用微信统一下单接口,微信那边创建预支付订单:
@wechat.route(‘/unified_order‘, methods=[‘POST‘]) def unified_order(): ‘‘‘统一下单接口 price, time_start, time_out,artwork_id‘‘‘ ip = request.form.get("ip") if request.form.get( "ip") else webutil.request_ip() ordernum = request.form.get("ordernum") if not ordernum: return jsonify({"code": -1}) open_id = webutil.session_get_user_open_id(ordernum) # print ‘1----‘, open_id # if not open_id: # # 用户没有微信授权先授权获取open_id # url = open_weixin_snsapi_base(ordernum, ip) # return redirect(url) # print ‘2----‘, open_id # print ‘3----‘, open_id # print ‘4----‘, open_id order = Orders.query.filter_by(ordernum=ordernum).first() price = order.order_price time_start = order.created_on time_out = order.created_on artwork_id = order.artwork_id res = _unified_order(ordernum, price, ip, time_start, time_out, artwork_id, open_id) # 组装返回值 code = "FAIL" msg = res[‘return_msg‘] dict = {} if res["return_code"] == "SUCCESS" and res[‘result_code‘] == "SUCCESS": dict[‘appId‘] = res[‘appid‘] dict[‘timeStamp‘] = ‘{}‘.format(int(time.time())) dict[‘nonceStr‘] = uuid.uuid4().hex dict[‘package‘] = "prepay_id=%s" % res[‘prepay_id‘] dict[‘signType‘] = "MD5" dict[‘paySign‘] = __get_sign(dict) code = "SUCCESS" elif res["return_code"] == "SUCCESS": msg = res[‘err_code_des‘] print dict return jsonify({"code": code, "msg": msg, "dict": dict})
def _unified_order(ordernum, price, ip, time_start, time_out, artwork_id, openid): """统一下单接口 公众账号ID appid 是 String(32) wxd678efh567hg6787 微信支付分配的公众账号ID(企业号corpid即为此appId) 商户号 mch_id 是 String(32) 1230000109 微信支付分配的商户号 设备号 device_info 否 String(32) 013467007045764 自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB" 随机字符串 nonce_str 是 String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,长度要求在32位以内。推荐随机数生成算法 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 通过签名算法计算得出的签名值,详见签名生成算法 签名类型 sign_type 否 String(32) HMAC-SHA256 签名类型,默认为MD5,支持HMAC-SHA256和MD5。 商品描述 body 是 String(128) 腾讯充值中心-QQ会员充值 商品简单描述,该字段请按照规范传递,具体请见参数规定 商品详情 detail 否 String(6000) 附加数据 attach 否 String(127) 深圳分店 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用。 商户订单号 out_trade_no 是 String(32) 20150806125346 商户系统内部订单号,要求32个字符内、且在同一个商户号下唯一。 详见商户订单号 标价币种 fee_type 否 String(16) CNY 符合ISO 4217标准的三位字母代码,默认人民币:CNY,详细列表请参见货币类型 标价金额 total_fee 是 Int 88 订单总金额,单位为分,详见支付金额 终端IP spbill_create_ip 是 String(16) 123.12.12.123 APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。 交易起始时间 time_start 否 String(14) 20091225091010 订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则 交易结束时间 time_expire 否 String(14) 20091227091010 订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则 注意:最短失效时间间隔必须大于5分钟 商品标记 goods_tag 否 String(32) WXG 商品标记,使用代金券或立减优惠功能时需要的参数,说明详见代金券或立减优惠 通知地址 notify_url 是 String(256) http://www.weixin.qq.com/wxpay/pay.php 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。 交易类型 trade_type 是 String(16) JSAPI 取值如下:JSAPI,NATIVE,APP等,说明详见参数规定 商品ID product_id 否 String(32) 12235413214070356458058 trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。 指定支付方式 limit_pay 否 String(32) no_credit 上传此参数no_credit--可限制用户不能使用信用卡支付 用户标识 openid 否 String(128) oUpF8uMuAJO_M2pxb1Q9zNjWeS6o trade_type=JSAPI时(即公众号支付),此参数必传,此参数为微信用户在商户对应appid下的唯一标识。openid如何获取,可参考【获取openid】。企业号请使用【企业号OAuth2.0接口】获取企业号内成员userid,再调用【企业号userid转openid接口】进行转换 ‘device_info‘: ‘WEB‘, "sign_type": "MD5", """ return_url = os.path.join("http://", DOMAIN_NAME, "wechat/wx_notify") dict = { ‘appid‘: appid, ‘mch_id‘: "1435556302", "nonce_str": uuid.uuid4().hex, "body": "诗艺-艺术品", "out_trade_no": ordernum, "total_fee": int(price * 100), "spbill_create_ip": ip, "notify_url": return_url, "trade_type": "JSAPI", "openid": openid } # if time_out and time_start: # dict["time_start"] = time_start # dict["time_out"] = time_start + timedelta(minutes=30) if artwork_id: dict["product_id"] = artwork_id # 生成签名 dict[‘sign‘] = __get_sign(dict) print dict, ‘-----‘ # dict转换为xml格式 xml = __json_to_xml(dict) url = "https://api.mch.weixin.qq.com/pay/unifiedorder" req = urllib2.Request( url=url, headers={‘Content-Type‘: ‘text/xml‘}, data=str(xml)) f = urllib2.urlopen(req) res = f.read() res = __xml_to_json(res) return res.get("xml")
统一下单完成之后调起微信支付:
//jsapi微信支付 function onBridgeReady(data){ WeixinJSBridge.invoke( ‘getBrandWCPayRequest‘, data, function(res){ if(res.err_msg == "get_brand_wcpay_request:ok") {
//跳转到支付成功界面 window.location.href="/order/pay_finish"; } // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。 else{ //alert(res.err_msg); } } ); }
微信支付就完成了,基本会成功,但是这里说不保证绝对可靠,所以需要调用微信另一个用来查询订单支付是否成功接口。