小程序微信支付
一、前置工作(微信公众平台申请 https://mp.weixin.qq.com/)要申请商户号关联APPID
1、APPID(小程序ID)
2、AppSecret(小程序密钥)
3、mch_id 商户号
4、mch_key 商户密匙 (需要设置,设置一次一定要记录,如果没记住需要重新设置。pay.weixin.qq.com中账户中心---安全中心---API秘钥---重设秘钥)
以上4个参数是必须要有的。
这一步的目的就是获取这几个必须用到的参数。
二、有了以上的参数,服务端就可以调用统一下单接口了(统一下单,说白了就是生成预支付订单,就用这个就行!)
官方文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1
小程序的微信支付需要 OpenId 支付用户唯一标识 可以通过小程序 auth.code2Session 获取
登录凭证校验:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
这个会返回 OpenId
接着说统一下单 一图顶千字
以上参数重点说一下签名 sign
看我代码的意思就是把上面的参数都拼接到一起最后加了个key(商户秘钥)再MD5加密。这是第一次签名(下面会说二次签名)。
扩展方法 粘贴直接用即可
/// <summary>
/// 把字典内的数据拼接成 url参数 例: ?par1=1&par2=2
/// </summary>
/// <param name="paraMap"></param>
/// <returns></returns>
public string FormatBizQueryParaMapForUnifiedPay(Dictionary<string, string> paraMap)
{
string buff = "";
try
{
var result = from pair in paraMap orderby pair.Key select pair;
foreach (KeyValuePair<string, string> pair in result)
{
if (pair.Key != "")
{
string key = pair.Key;
string val = pair.Value;
buff += key + "=" + val + "&";
}
}
if (buff.Length == 0 == false)
{
buff = buff.Substring(0, (buff.Length - 1) - (0));
}
}
catch (Exception e)
{
throw e;
}
return buff;
}
/// <summary>
/// MD5加密
/// </summary>
/// <param name="encypStr"></param>
/// <returns></returns>
public string GetMD5(string encypStr)
{
char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F' };
try
{
byte[] btInput = System.Text.Encoding.UTF8.GetBytes(encypStr);
// 获得MD5摘要算法的 MessageDigest 对象
MD5 mdInst = System.Security.Cryptography.MD5.Create();
// 使用指定的字节更新摘要
mdInst.ComputeHash(btInput);
// 获得密文
byte[] md = mdInst.Hash;
// 把密文转换成十六进制的字符串形式
int j = md.Length;
char[] str = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++)
{
byte byte0 = md[i];
str[k++] = hexDigits[(int)(((byte)byte0) >> 4) & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new string(str);
}
catch (Exception e)
{
Console.Error.WriteLine(e.StackTrace);
return null;
}
}
以上两个方法粘贴可用。用在sign签名签名拼接和加密。
还有那个商户订单号(out_trade_no)就是商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*且在同一个商户号下唯一。自己定义个规则就可以了。
还有随机字符串可以直接用我的这个方法:(说白了就是一个随机字符串)
/// <summary>
/// 获取微信的随机数
/// </summary>
/// <returns></returns>
public String CreateNoncestr()
{
String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
String res = "";
Random rd = new Random();
for (int i = 0; i < 16; i++)
{
res += chars[rd.Next(chars.Length - 1)];
}
return res;
}
重点就是这几个不好理解,其他的都应该好理解,再不理解,可以查查。
然后统一下单进行下一步
返回那个xml之后
这样统一下单就ok了 生成了一个微信预支付订单。很简单的逻辑
重新屡一下思路:通过参数请求统一下单的链接,返回的xml解析后,判断成功后,进行二次签名,最终返回给小程序前端。
三、小程序前端操作
首先你得有微信开发者工具,这里下载 https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
接下来就是小程序调用接口 一张图简单明了
很简单的逻辑:在这个支付的点击事件内,先调用服务端的统一下单支付接口,成功后返回的参数传给 wx.requestPayment
小程序的前端就ok了。
四、最后是关于回调的说明(notify_url)
这个需要你自己创建个回调的文件(我用的是一般处理程序ashx页面处理的,你也可以用这个),写自己的业务逻辑,这个是支付成功后要执行的地址。
比如你支付完 修改后台的订单状态,或者记录第三方信息,或者其他的业务逻辑操作都可以在这里操作。
举例代码,参考就可以了,也可以用:
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/xml"; //xml格式
var inputStream = context.Request.InputStream;//获取http实体主体的内容
if (inputStream != null)
{
var strLen = Convert.ToInt32(inputStream.Length);
var strArr = new byte[strLen];
inputStream.Read(strArr, 0, strLen);
var requestMes = Encoding.UTF8.GetString(strArr);
inputStream.Flush();
inputStream.Close();
inputStream.Dispose();
//以上这小段代码对返回参数操作,最后可以转成xml格式,这样好操作。
if (requestMes.Length > 0)
{
context.Response.Write("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>");
XmlDocument doc = new XmlDocument();
doc.XmlResolver = null;
doc.LoadXml(requestMes);
if (doc != null)
{
XmlNode xmlNode = doc["xml"];
if (xmlNode != null)
{
if (xmlNode["return_code"].InnerText.Equals("SUCCESS") && xmlNode["result_code"].InnerText.Equals("SUCCESS"))
{
//此处就可以对宁的订单状态做修改或者 其他 的 业务逻辑了!!!!!
}
}
}
}
}
} //public结尾
这样就最后一步对业务的操作ok了 就支付了。