最近刚接触微信就接到了一个微信支付的功能,连着调了四天,晚上睡觉都在想代码,也是被折腾的不轻,感觉处处都是问题,经过自己的一些探索,在此做一些总结,以便以后遇到类似的问题能及时得到解决,我觉得微信支付最大的难点和瓶颈并不是微信支付本身,而是拿到微信支付的权限,首先微信支付所面向的开发对象不是个人,设置秘钥什么的都需要管理员授权,商户平台的登录也需要管理员扫码,公司的微信号又不会随便给个人进行开发,这样就造成了不必要的麻烦。
一、开发前的准备
1、微信平台概念理解
以前没接触过微信开发,刚开始做微信都不知道要去哪个平台申请账户,自己对这三个平台也是一头雾水,所以在开发前要先理解微信这三个平台的含义,具体有什么作用,以及三个平台之间的关系,在这里要做微信服务号的支付功能,所以就只需要在微信公众平台和微信商户平台注册即可。
(1)微信开放平台
主要面对移动应用/网站应用开发者,为其提供微信登录,分享,支付等相关权限和服务,微信开放平台还提供了数据统计功能,用于开发者统计接入应用的登录,分享等数据情况。以京东APP为例,比如京东APP需要使用微信登录,分享和微信支付功能,首先注册微信开发平台-开发者账号,并按照以下流程在微信开放平台创建京东APP:审核通过后,即可获得以下的初级权限,如要获得更高如微信支付权限,需要再单独申请,具体微信支付权限申请步骤详见附件《移动应用-微信支付权限申请流程》
(2)微信公众平台
微信公众平台用于管理,开放微信公众号(包括订阅号,服务号,企业号),简单的说就是微信公众号的后台运营,管理系统。
后台功能(以服务号介绍)
<1>基础运营功能:公众号申请成功后即可获得群发功能,自动回复,自定义菜单,投票管理;
<2>高级功能:微信公众平台还提供了以下高级的功能来丰富公众号,以下权限需要二次开发;
<3>微信支付:提供公众号内微信支付能力,和移动应用一样也需要单独申请,流程和移动APP流程类似;
<4>管理:包括已关注用户管理,消息管理,素材管理
<5>推广:包括广告主(定向投向广告,精准推广自己的服务)和流量主(按月获取广告收入)
<6>统计:用户分析,图文分析,消息分析,接口分析(自定义菜单调用量)
(3)微信商户平台
无论是申请公众平台商户还是开放平台商户,申请成功后,都会拥有商户平台账号,可登录商户平台进行操作,商户平台主要是做微信支付用的,如果APP或者公众号需要接入支付能力,那么就需要在公众平台申请公众平台商户,或者在开放平台申请开放平台商户,申请成功后会分配商户平台账号。
3、官方demo下载我们用C#所以选择.net版本,不过这个官方的demo根本跑不起来
4、开发前的微信公众平台的一些配置,请务必认真检查配置
微信支付的开发配置要去微信商户平台的产品中心-->开发配置中进行设置
二、编码
做好了这些准备工作以后,就要开始编码了,我们知道微信支付有两种:1、原生态的;2、jsapi直接调用的,我项目中用到的是第二种,首先把官方的demo下载下来。
(1)下载证书
在微信商户平台的账户中心-->API安全,设置完秘钥以后,下载证书,放到自己的项目中
(2)默认的Default.aspx中的链接竟然都是链接到http://paysdk.weixin.qq.com/example/ProductPage.aspx这个如果不注意的话,也会郁闷好久,将其改成我们自己的服务器测试地址(http://haohuish.com/ProductPage.aspx)。
(3)默认它给你开启了代理服务器,如果不知道的话也会郁闷很久,如果这边不填的话,又报错:无效的URI:此URI为空。填其他也会报相同的错误,只好找到它使用代理的地方手动注释掉,在demo里的HttpService.cs里面,注意get和post方法里面都有,都要注释掉,如下图所示:
(4)配置文件Config.cs
using System;
using System.Collections.Generic;
using System.Web;
namespace WxPayAPI
{
/**
* 配置账号信息
*/
public class WxPayConfig
{
//=======【基本信息设置】=====================================
/* 微信公众号信息配置
* APPID:绑定支付的APPID(必须配置)
* MCHID:商户号(必须配置)
* KEY:商户支付密钥,参考开户邮件设置(必须配置)
* APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置)
*/
public const string APPID = "wxed7a1fbd75937abf";
public const string MCHID = "1393954302";
public const string KEY = "uDWrfN3Amn3ecoRWTczBDQIzUukJ2L5n";
public const string APPSECRET = "6420c4fc129a89f0c5e8350e0be7273d";
//=======【证书路径设置】=====================================
/* 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要)
*/
public const string SSLCERT_PATH = "cert/apiclient_cert.p12";
public const string SSLCERT_PASSWORD = "1393954302";
//=======【支付结果通知url】=====================================
/* 支付结果通知回调url,用于商户接收支付结果
*/
public const string NOTIFY_URL = "http://haohuish.com/LJWY/WX00/growing_center.aspx";
//=======【商户系统后台机器IP】=====================================
/* 此参数可手动配置也可在程序中自动获取
*/
public const string IP = "116.62.139.72";
//=======【代理服务器设置】===================================
/* 默认IP和端口号分别为0.0.0.0和0,此时不开启代理(如有需要才设置)
*/
public const string PROXY_URL = "http://10.152.18.220:8080";
//=======【上报信息配置】===================================
/* 测速上报等级,0.关闭上报; 1.仅错误时上报; 2.全量上报
*/
public const int REPORT_LEVENL = 1;
//=======【日志级别】===================================
/* 日志等级,0.不输出日志;1.只输出错误信息; 2.输出错误和正常信息; 3.输出错误信息、正常信息和调试信息
*/
public const int LOG_LEVENL = 0;
}
}
(5)demo里面ProductPage.aspx,我们不需要使用公用地址的功能,所以在后台注释掉相关的代码
protected void Page_Load(object sender, EventArgs e)
{
JsApiPay jsApiPay = new JsApiPay(this);
try
{
//调用【网页授权获取用户信息】接口获取用户的openid和access_token
jsApiPay.GetOpenidAndAccessToken();
//获取收货地址js函数入口参数
//wxEditAddrParam = jsApiPay.GetEditAddressParameters();
ViewState["openid"] = jsApiPay.openid;
}
catch (Exception ex)
{
Response.Write("<span style='color:#FF0000;font-size:20px'>" + "页面加载出错,请重试" + "</span>");
Button1.Visible = false;
Button2.Visible = false;
Label1.Visible = false;
Label2.Visible = false;
}
}
把前台aspx页面的使用地址的代码也删掉
//获取共享地址
function editAddress()
{
WeixinJSBridge.invoke(
'editAddress',
<%=wxEditAddrParam%>,//josn串
function (res)
{
//var addr1 = res.proviceFirstStageName;
//var addr2 = res.addressCitySecondStageName;
//var addr3 = res.addressCountiesThirdStageName;
//var addr4 = res.addressDetailInfo;
//var tel = res.telNumber;
//var addr = addr1 + addr2 + addr3 + addr4;
//alert(addr + ":" + tel);
}
);
}
点击按钮就可以看到预支付界面了
在这中间还有一个问题就是不能正确的执行支付结果js回调函数,看看其页面的点击事件是放在asp:Button上面的。我们知道在asp.net webform中,按钮的点击是有页面回调后台的,也就是说其实点击了以后页面是有刷新的,所以这边要是想用官方的js回调的话就要做一下修改,让它执行js的回调方法,将点击支付的按钮改成
<asp:Button ID="submit" runat="server" Text="确认支付" OnClientClick="javascript:callpay();return false;" style="width:210px; height:50px; border-radius: 15px;background-color:#ffb12b; border:0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" />
这样我们不管在支付成功和失败后都会执行我们在页面里定义好的回调函数!
总结:感觉别人能提供资源已是好的,自己也不能再说什么了,但是还是忍不住想说几句,不知道腾讯的ASP.NET工程师是怎么想的,能够把jssdk提供给大家,感觉是在做一件非常大的慈善,既然是在做慈善就要把它做好,文档写的详细一点,规范一点,大家阅读起来才不会那么模棱两可,写的这么不负责任,代码里面都能看到java的注释,个人觉得也实在太不应该了。