一、微信小程序支付

1、微信小程序端请求支付接口

商户在小程序中先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易后调起支付。具体可以查看接口示例

接口传入参数示例:

<xml>
<appid>wx2421b1c4370ec43b</appid>
<attach>支付测试</attach>
<body>JSAPI支付测试</body>
<mch_id>10000100</mch_id>
<nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
<notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>
<openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid>
<out_trade_no>1415659990</out_trade_no>
<spbill_create_ip>14.23.150.211</spbill_create_ip>
<total_fee>1</total_fee>
<trade_type>JSAPI</trade_type>
<sign>0CB01533B8C1EF103065174F50BCA001</sign>
</xml>

接口返回示例:

<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[wx2421b1c4370ec43b]]></appid>
<mch_id><![CDATA[]]></mch_id>
<nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
<openid><![CDATA[oUpF8uMuAJO_M2pxb1Q9zNjWeS6o]]></openid>
<sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
<result_code><![CDATA[SUCCESS]]></result_code>
<prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
<trade_type><![CDATA[JSAPI]]></trade_type>
</xml>

二、接口调用(C#)

1、支付接口方法

//获取请求数据
Dictionary<string, string> strParam = new Dictionary<string, string>();
//小程序ID
strParam.Add("appid", PayInfo.appid);
//附加数据
strParam.Add("attach", PayInfo.attach);
//商品描述
strParam.Add("body", PayInfo.body);
//商户号
strParam.Add("mch_id", PayInfo.mchid);
//随机字符串
strParam.Add("nonce_str", PayInfo.nonceStr);
//通知地址 (异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。)
strParam.Add("notify_url", PayInfo.notifyUrl);
//用户标识
strParam.Add("openid", openId);
//商户订单号
strParam.Add("out_trade_no", orderNum);
//终端IP
strParam.Add("spbill_create_ip", PayInfo.addrIp);
//标价金额
strParam.Add("total_fee", Convert.ToInt32(orderTotal * ).ToString());
//交易类型
strParam.Add("trade_type", PayInfo.tradeType);
strParam.Add("sign", PayHelper.GetSignInfo(strParam, PayInfo.key));
//获取预支付ID
string preInfo = Utility.PostHttpResponse(PayInfo.orderUrl, PayHelper.CreateXmlParam(strParam));
string strCode = PayHelper.GetXmlValue(preInfo, "return_code");
string strMsg = PayHelper.GetXmlValue(preInfo, "return_msg");
if (strCode == "SUCCESS")
{
//再次签名
string nonecStr = PayInfo.nonceStr;
string timeStamp = PayInfo.timeStamp;
string package = "prepay_id=" + PayHelper.GetXmlValue(preInfo, "prepay_id");
Dictionary<string, string> singInfo = new Dictionary<string, string>();
singInfo.Add("appId", PayInfo.appid);
singInfo.Add("nonceStr", nonecStr);
singInfo.Add("package", package);
singInfo.Add("signType", PayInfo.signType);
singInfo.Add("timeStamp", timeStamp);
//返回参数
info.Msg = strMsg;
info.Code = strCode;
info.Id = orderId;
info.appId = PayInfo.appid;
info.orderGuId = orderNum;
info.Package = package;
info.TimeStamp = timeStamp;
info.NonceStr = nonecStr;
info.SignType = PayInfo.signType;
info.PaySign = PayHelper.GetSignInfo(singInfo, PayInfo.key);
listMsg.Add(info);
result = u.SuccessMsg(listMsg, "", "");
}
else
{
info.Code = strCode;
info.Msg = strMsg;
listMsg.Add(info);
result = u.FailMsg(listMsg);
}

2、支付结果通知API

/// <summary>
/// 支付结果通知API
/// </summary>
/// <returns></returns>
[HttpPost]
public string OrderNotify()
{
string strResult = string.Empty;
try
{
//1.获取微信通知的参数
string strXML = Utility.GetPostStr();
//判断是否请求成功
if (PayHelper.GetXmlValue(strXML, "return_code") == "SUCCESS")
{
//判断是否支付成功
if (PayHelper.GetXmlValue(strXML, "result_code") == "SUCCESS")
{
//获得签名
string getSign = PayHelper.GetXmlValue(strXML, "sign");
//进行签名
string sign = PayHelper.GetSignInfo(PayHelper.GetFromXml(strXML), PayInfo.key);
if (sign == getSign)
{
//校验订单信息
string wxOrderNum = PayHelper.GetXmlValue(strXML, "transaction_id"); //微信订单号
string orderNum = PayHelper.GetXmlValue(strXML, "out_trade_no"); //商户订单号
string orderTotal = PayHelper.GetXmlValue(strXML, "total_fee");
string openid = PayHelper.GetXmlValue(strXML, "openid");
//校验订单是否存在
if (true)
{
//2.更新订单的相关状态 //3.返回一个xml格式的结果给微信服务器
if (obj > )
{
strResult = PayHelper.GetReturnXml("SUCCESS", "OK");
}
else
{
strResult = PayHelper.GetReturnXml("FAIL", "订单状态更新失败");
}
}
else
{
strResult = PayHelper.GetReturnXml("FAIL", "支付结果中微信订单号数据库不存在!");
}
}
else
{
strResult = PayHelper.GetReturnXml("FAIL", "签名不一致!");
}
}
else
{
strResult = PayHelper.GetReturnXml("FAIL", "支付通知失败!");
}
}
else
{
strResult = PayHelper.GetReturnXml("FAIL", "支付通知失败!");
} #endregion
}
catch (Exception ex)
{ }
return strResult;
}

3、Utility类

/// <summary>
/// 获得Post过来的数据
/// </summary>
/// <returns></returns>
public static string GetPostStr()
{
Int32 intLen = Convert.ToInt32(HttpContext.Current.Request.InputStream.Length);
byte[] b = new byte[intLen];
HttpContext.Current.Request.InputStream.Read(b, , intLen);
return Encoding.UTF8.GetString(b);
} /// <summary>
/// 模拟POST提交
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="xmlParam">xml参数</param>
/// <returns>返回结果</returns>
public static string PostHttpResponse(string url, string xmlParam)
{
HttpWebRequest myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
myHttpWebRequest.Method = "POST";
myHttpWebRequest.ContentType = "application/x-www-form-urlencoded;charset=utf-8"; // Encode the data
byte[] encodedBytes = Encoding.UTF8.GetBytes(xmlParam);
myHttpWebRequest.ContentLength = encodedBytes.Length; // Write encoded data into request stream
Stream requestStream = myHttpWebRequest.GetRequestStream();
requestStream.Write(encodedBytes, , encodedBytes.Length);
requestStream.Close(); HttpWebResponse result; try
{
result = (HttpWebResponse)myHttpWebRequest.GetResponse();
}
catch
{
return string.Empty;
} if (result.StatusCode == HttpStatusCode.OK)
{
using (Stream mystream = result.GetResponseStream())
{
using (StreamReader reader = new StreamReader(mystream))
{
return reader.ReadToEnd();
}
}
}
return null;
}

4、PayHelper类

#region 生成签名
/// <summary>
/// 获取签名数据
///</summary>
/// <param name="strParam"></param>
/// <param name="key"></param>
/// <returns></returns>
public static string GetSignInfo(Dictionary<string, string> strParam, string key)
{
int i = ;
string sign = string.Empty;
StringBuilder sb = new StringBuilder();
try
{
foreach (KeyValuePair<string, string> temp in strParam)
{
if (temp.Value == "" || temp.Value == null || temp.Key.ToLower() == "sign")
{
continue;
}
i++;
sb.Append(temp.Key.Trim() + "=" + temp.Value.Trim() + "&");
}
sb.Append("key=" + key.Trim() + "");
sign = MD5Core.GetHashString(sb.ToString(), Encoding.UTF8).ToUpper();
}
catch (Exception ex)
{
Utility.AddLog("PayHelper", "GetSignInfo", ex.Message, ex);
}
return sign;
}
#endregion #region XML 处理
/// <summary>
/// 获取XML值
/// </summary>
/// <param name="strXml">XML字符串</param>
/// <param name="strData">字段值</param>
/// <returns></returns>
public static string GetXmlValue(string strXml, string strData)
{
string xmlValue = string.Empty;
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(strXml);
var selectSingleNode = xmlDocument.DocumentElement.SelectSingleNode(strData);
if (selectSingleNode != null)
{
xmlValue = selectSingleNode.InnerText;
}
return xmlValue;
} /// <summary>
/// 集合转换XML数据 (拼接成XML请求数据)
/// </summary>
/// <param name="strParam">参数</param>
/// <returns></returns>
public static string CreateXmlParam(Dictionary<string, string> strParam)
{
StringBuilder sb = new StringBuilder();
try
{
sb.Append("<xml>");
foreach (KeyValuePair<string, string> k in strParam)
{
if (k.Key == "attach" || k.Key == "body" || k.Key == "sign")
{
sb.Append("<" + k.Key + "><![CDATA[" + k.Value + "]]></" + k.Key + ">");
}
else
{
sb.Append("<" + k.Key + ">" + k.Value + "</" + k.Key + ">");
}
}
sb.Append("</xml>");
}
catch (Exception ex)
{
Utility.AddLog("PayHelper", "CreateXmlParam", ex.Message, ex);
} return sb.ToString();
} /// <summary>
/// XML数据转换集合(XML数据拼接成字符串)
/// </summary>
/// <param name="xmlString"></param>
/// <returns></returns>
public static Dictionary<string, string> GetFromXml(string xmlString)
{
Dictionary<string, string> sParams = new Dictionary<string, string>();
try
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlString);
XmlElement root = doc.DocumentElement;
int len = root.ChildNodes.Count;
for (int i = ; i < len; i++)
{
string name = root.ChildNodes[i].Name;
if (!sParams.ContainsKey(name))
{
sParams.Add(name.Trim(), root.ChildNodes[i].InnerText.Trim());
}
}
}
catch (Exception ex)
{
Utility.AddLog("PayHelper", "GetFromXml", ex.Message, ex);
}
return sParams;
} /// <summary>
/// 返回通知 XML
/// </summary>
/// <param name="returnCode"></param>
/// <param name="returnMsg"></param>
/// <returns></returns>
public static string GetReturnXml(string returnCode, string returnMsg)
{
StringBuilder sb = new StringBuilder();
sb.Append("<xml>");
sb.Append("<return_code><![CDATA[" + returnCode + "]]></return_code>");
sb.Append("<return_msg><![CDATA[" + returnMsg + "]]></return_msg>");
sb.Append("</xml>");
return sb.ToString();
}
#endregion

5、PayInfo类

public class PayInfo
{
/// <summary>
/// 小程序登录API
/// </summary>
public static string loginUrl = ConfigurationManager.AppSettings["loginurl"].ToString(); /// <summary>
/// 统一下单API
/// </summary>
public static string orderUrl = ConfigurationManager.AppSettings["orderurl"].ToString(); /// <summary>
/// 支付结果通知API
/// </summary>
public static string notifyUrl = ConfigurationManager.AppSettings["notifyurl"].ToString(); /// <summary>
/// 查询订单API
/// </summary>
public static string queryUrl = ConfigurationManager.AppSettings["queryurl"].ToString(); /// <summary>
/// 申请退款API
/// </summary>
public static string refundUrl = ConfigurationManager.AppSettings["refundurl"].ToString(); /// <summary>
/// 退款通知API
/// </summary>
public static string refundNotifyUrl = ConfigurationManager.AppSettings["refundnotifyurl"].ToString(); /// <summary>
/// 退款通知API
/// </summary>
public static string refundQueryUrl = ConfigurationManager.AppSettings["refundqueryurl"].ToString(); /// <summary>
/// 小程序唯一标识
/// </summary>
public static string appid = ConfigurationManager.AppSettings["appid"].ToString(); /// <summary>
/// 小程序的 app secret
/// </summary>
public static string secret = ConfigurationManager.AppSettings["secret"].ToString(); /// <summary>
/// 小程序的授权类型
/// </summary>
public static string grantType = ConfigurationManager.AppSettings["grant_type"].ToString(); /// <summary>
/// 商户号(微信支付分配的商户号)
/// </summary>
public static string mchid = ConfigurationManager.AppSettings["mch_id"].ToString(); /// <summary>
///商户平台设置的密钥key
/// </summary>
public static string key = ConfigurationManager.AppSettings["key"].ToString(); /// <summary>
/// 随机字符串不长于 32 位
/// </summary>
public static string nonceStr = PayHelper.GetNonceStr(); /// <summary>
/// 时间戳 从1970年1月1日00:00:00至今的秒数,即当前的时间
/// </summary>
public static string timeStamp = PayHelper.GetTimeStamp(); /// <summary>
/// 终端IP APP和网页支付提交用户端IP,
/// </summary>
public static string addrIp = PayHelper.GetIP; /// <summary>
/// 交易类型 小程序取值如下:JSAPI
/// </summary>
public static string tradeType = "JSAPI"; /// <summary>
/// 签名类型 默认为MD5,支持HMAC-SHA256和MD5。
/// </summary>
public static string signType = "MD5"; /// <summary>
/// 商品描述 商品简单描述,该字段请按照规范传递
/// </summary>
public static string body = "奇小爱的异想世界-支付"; /// <summary>
/// 附加数据 在查询API和支付通知中原样返回
/// </summary>
public static string attach = "微信支付信息"; /// <summary>
/// 签名,参与签名参数:appid,mch_id,transaction_id,out_trade_no,nonce_str,key
/// </summary>
public string sign = ""; /// <summary>
/// 微信订单号,优先使用
/// </summary>
public static string transactionid = ""; /// <summary>
/// 商户系统内部订单号
/// </summary>
public static string out_trade_no = ""; /// <summary>
/// 商户退款单号
/// </summary>
public static string out_refund_no = ""; /// <summary>
/// 退款金额
/// </summary>
public static decimal refundfee; /// <summary>
/// 订单金额
/// </summary>
public static decimal totalfee;
}

三、微信小程序调用

1、小程序调用方法,发起支付,具体如下:

微信小程序支付方发起微信支付

2、示例代码:

wx.requestPayment({
'timeStamp': '',
'nonceStr': '',
'package': '',
'signType': 'MD5',
'paySign': '',
'success':function(res){
},
'fail':function(res){
}
})

3、测试完成支付

优秀是一种习惯,欢迎大家关注学习 

最新文章

  1. window.open窗口关闭后刷新父窗口代码
  2. Codeforces Beta Round #69 (Div. 1 Only) C. Beavermuncher-0xFF 树上贪心
  3. python UTC,时间戳,字符串转换
  4. C#操作Excel文件(读取Excel,写入Excel)
  5. C++类继承内存布局(二)
  6. 批处理备份和恢复mysql数据库
  7. Hibernate 缓存机制(转)
  8. (转)iOS keychain API及其封装
  9. Python 第一课笔记
  10. 微信接口开发1--向微信发送请求--获取access_token
  11. VB6之断点续传
  12. JavaScript一个集合的运算类
  13. React——共享state
  14. Linux c codeblock的使用(三):使用函数库
  15. Alpha 冲刺 (2/10)
  16. phpMyadmin各版本漏洞
  17. CentOS7 loaded active exited
  18. Part 4 - Authentication(14-16)
  19. asp.net core读取appsetting.json文件
  20. Java Classloader机制解析

热门文章

  1. OC8051项目启动
  2. DC 课程内容
  3. Lecture 1
  4. LeetCode(292) Nim Game
  5. Cleaning Shifts POJ - 2376 (贪心题)
  6. debian 7 安装vagrant
  7. Linux学习-可唤醒停机期间的工作任务
  8. selenuim2模拟鼠标键盘操作
  9. MFC 中 删除一个非空文件夹
  10. python基础学习笔记——单继承