tenpay.dll:javascript
MD5Util.cs前端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
namespace tenpay
{
public class MD5Util
{
public MD5Util()
{
//
// TODO: 在此處添加構造函數邏輯
//
}
/** 獲取大寫的MD5簽名結果 */
public static string GetMD5(string encypStr, string charset)
{
string retStr;
MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();
//建立md5對象
byte[] inputBye;
byte[] outputBye;
//使用GB2312編碼方式把字符串轉化爲字節數組.
try
{
inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr);
}
catch (Exception ex)
{
inputBye = Encoding.GetEncoding("GB2312").GetBytes(encypStr);
}
outputBye = m5.ComputeHash(inputBye);
retStr = System.BitConverter.ToString(outputBye);
retStr = retStr.Replace("-", "").ToUpper();
return retStr;
}
}
}
OrderDetail.csjava
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace tenpay
{
/// <summary>
/// 微信訂單明細實體對象
/// </summary>
[Serializable]
public class OrderDetail
{
/// <summary>
/// 返回狀態碼,SUCCESS/FAIL 此字段是通訊標識,非交易標識,交易是否成功須要查看trade_state來判斷
/// </summary>
public string return_code = "";
/// <summary>
/// 返回信息返回信息,如非空,爲錯誤緣由 簽名失敗 參數格式校驗錯誤
/// </summary>
public string return_msg = "";
/// <summary>
/// 公共號ID(微信分配的公衆帳號 ID)
/// </summary>
public string appid = "";
/// <summary>
/// 商戶號(微信支付分配的商戶號)
/// </summary>
public string mch_id = "";
/// <summary>
/// 隨機字符串,不長於32位
/// </summary>
public string nonce_str = "";
/// <summary>
/// 簽名
/// </summary>
public string sign = "";
/// <summary>
/// 業務結果,SUCCESS/FAIL
/// </summary>
public string result_code = "";
/// <summary>
/// 錯誤代碼
/// </summary>
public string err_code = "";
/// <summary>
/// 錯誤代碼描述
/// </summary>
public string err_code_des = "";
/// <summary>
/// 交易狀態
///SUCCESS—支付成功
///REFUND—轉入退款
///NOTPAY—未支付
///CLOSED—已關閉
///REVOKED—已撤銷
///USERPAYING--用戶支付中
///NOPAY--未支付(輸入密碼或確認支付超時) PAYERROR--支付失敗(其餘緣由,如銀行返回失敗)
/// </summary>
public string trade_state = "";
/// <summary>
/// 微信支付分配的終端設備號
/// </summary>
public string device_info = "";
/// <summary>
/// 用戶在商戶appid下的惟一標識
/// </summary>
public string openid = "";
/// <summary>
/// 用戶是否關注公衆帳號,Y-關注,N-未關注,僅在公衆帳號類型支付有效
/// </summary>
public string is_subscribe = "";
/// <summary>
/// 交易類型,JSAPI、NATIVE、MICROPAY、APP
/// </summary>
public string trade_type = "";
/// <summary>
/// 銀行類型,採用字符串類型的銀行標識
/// </summary>
public string bank_type = "";
/// <summary>
/// 訂單總金額,單位爲分
/// </summary>
public string total_fee = "";
/// <summary>
/// 現金券支付金額<=訂單總金額,訂單總金額-現金券金額爲現金支付金額
/// </summary>
public string coupon_fee = "";
/// <summary>
/// 貨幣類型,符合ISO 4217標準的三位字母代碼,默認人民幣:CNY
/// </summary>
public string fee_type = "";
/// <summary>
/// 微信支付訂單號
/// </summary>
public string transaction_id = "";
/// <summary>
/// 商戶系統的訂單號,與請求一致。
/// </summary>
public string out_trade_no = "";
/// <summary>
/// 商家數據包,原樣返回
/// </summary>
public string attach = "";
/// <summary>
/// 支付完成時間,格式爲yyyyMMddhhmmss,如2009年12月27日9點10分10秒錶示爲20091227091010。
/// 時區爲GMT+8 beijing。該時間取自微信支付服務器
/// </summary>
public string time_end = "";
}
}
QueryOrder.csajax
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace tenpay
{
/// <summary>
/// 微信訂單查詢接口請求實體對象
/// </summary>
[Serializable]
public class QueryOrder
{
/// <summary>
/// 公共號ID(微信分配的公衆帳號 ID)
/// </summary>
public string appid = "";
/// <summary>
/// 商戶號(微信支付分配的商戶號)
/// </summary>
public string mch_id = "";
/// <summary>
/// 微信訂單號,優先使用
/// </summary>
public string transaction_id = "";
/// <summary>
/// 商戶系統內部訂單號
/// </summary>
public string out_trade_no = "";
/// <summary>
/// 隨機字符串,不長於 32 位
/// </summary>
public string nonce_str = "";
/// <summary>
/// 簽名,參與簽名參數:appid,mch_id,transaction_id,out_trade_no,nonce_str,key
/// </summary>
public string sign = "";
}
}
UnifiedOrder.csjson
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace tenpay
{
/// <summary>
/// 微信統一接口請求實體對象
/// </summary>
[Serializable]
public class UnifiedOrder
{
/// <summary>
/// 公共號ID(微信分配的公衆帳號 ID)
/// </summary>
public string appid = "";
/// <summary>
/// 商戶號(微信支付分配的商戶號)
/// </summary>
public string mch_id = "";
/// <summary>
/// 微信支付分配的終端設備號
/// </summary>
public string device_info = "";
/// <summary>
/// 隨機字符串,不長於 32 位
/// </summary>
public string nonce_str = "";
/// <summary>
/// 簽名
/// </summary>
public string sign = "";
/// <summary>
/// 商品描述
/// </summary>
public string body = "";
/// <summary>
/// 附加數據,原樣返回
/// </summary>
public string attach = "";
/// <summary>
/// 商戶系統內部的訂單號,32個字符內、可包含字母,確保在商戶系統惟一,詳細說明
/// </summary>
public string out_trade_no = "";
/// <summary>
/// 訂單總金額,單位爲分,不能帶小數點
/// </summary>
public int total_fee = 0;
/// <summary>
/// 終端IP
/// </summary>
public string spbill_create_ip = "";
/// <summary>
/// 訂 單 生 成 時 間 , 格 式 爲yyyyMMddHHmmss,如 2009 年12 月 25 日 9 點 10 分 10 秒錶示爲 20091225091010。時區爲 GMT+8 beijing。該時間取自商戶服務器
/// </summary>
public string time_start = "";
/// <summary>
/// 交易結束時間
/// </summary>
public string time_expire = "";
/// <summary>
/// 商品標記 商品標記,該字段不能隨便填,不使用請填空,使用說明詳見第 5 節
/// </summary>
public string goods_tag = "";
/// <summary>
/// 接收微信支付成功通知
/// </summary>
public string notify_url = "";
/// <summary>
/// JSAPI、NATIVE、APP
/// </summary>
public string trade_type = "";
/// <summary>
/// 用戶標識 trade_type 爲 JSAPI時,此參數必傳
/// </summary>
public string openid = "";
/// <summary>
/// 只在 trade_type 爲 NATIVE時須要填寫。
/// </summary>
public string product_id = "";
}
}
TenpayUtil.csapi
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
namespace tenpay
{
public class TenpayUtil
{
/// <summary>
/// 統一支付接口
/// </summary>
const string UnifiedPayUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
/// <summary>
/// 網頁受權接口
/// </summary>
const string access_tokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";
/// <summary>
/// 微信訂單查詢接口
/// </summary>
const string OrderQueryUrl = "https://api.mch.weixin.qq.com/pay/orderquery";
/// <summary>
/// 隨機串
/// </summary>
public static string getNoncestr()
{
Random random = new Random();
return MD5Util.GetMD5(random.Next(1000).ToString(), "GBK").ToLower().Replace("s", "S");
}
/// <summary>
/// 時間截,自1970年以來的秒數
/// </summary>
public static string getTimestamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
/// <summary>
/// 網頁受權接口
/// </summary>
public static string getAccess_tokenUrl()
{
return access_tokenUrl;
}
/// <summary>
/// 獲取微信簽名
/// </summary>
/// <param name="sParams"></param>
/// <returns></returns>
public string getsign(SortedDictionary<string, string> sParams, string key)
{
int i = 0;
string sign = string.Empty;
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> temp in sParams)
{
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() + "");
string signkey = sb.ToString();
sign = MD5Util.GetMD5(signkey, "utf-8");
return sign;
}
/// <summary>
/// post數據到指定接口並返回數據
/// </summary>
public string PostXmlToUrl(string url, string postData)
{
string returnmsg = "";
using (System.Net.WebClient wc = new System.Net.WebClient())
{
returnmsg = wc.UploadString(url, "POST", postData);
}
return returnmsg;
}
/// <summary>
/// 獲取prepay_id
/// </summary>
public string getPrepay_id(UnifiedOrder order, string key)
{
string prepay_id = "";
string post_data = getUnifiedOrderXml(order, key);
string request_data = PostXmlToUrl(UnifiedPayUrl, post_data);
SortedDictionary<string, string> requestXML = GetInfoFromXml(request_data);
foreach (KeyValuePair<string, string> k in requestXML)
{
if (k.Key == "prepay_id")
{
prepay_id = k.Value;
break;
}
}
return prepay_id;
}
/// <summary>
/// 獲取微信訂單明細
/// </summary>
public OrderDetail getOrderDetail(QueryOrder queryorder, string key)
{
string post_data = getQueryOrderXml(queryorder, key);
string request_data = PostXmlToUrl(OrderQueryUrl, post_data);
OrderDetail orderdetail = new OrderDetail();
SortedDictionary<string, string> requestXML = GetInfoFromXml(request_data);
foreach (KeyValuePair<string, string> k in requestXML)
{
switch (k.Key)
{
case "retuen_code":
orderdetail.result_code = k.Value;
break;
case "return_msg":
orderdetail.return_msg = k.Value;
break;
case "appid":
orderdetail.appid = k.Value;
break;
case "mch_id":
orderdetail.mch_id = k.Value;
break;
case "nonce_str":
orderdetail.nonce_str = k.Value;
break;
case "sign":
orderdetail.sign = k.Value;
break;
case "result_code":
orderdetail.result_code = k.Value;
break;
case "err_code":
orderdetail.err_code = k.Value;
break;
case "err_code_des":
orderdetail.err_code_des = k.Value;
break;
case "trade_state":
orderdetail.trade_state = k.Value;
break;
case "device_info":
orderdetail.device_info = k.Value;
break;
case "openid":
orderdetail.openid = k.Value;
break;
case "is_subscribe":
orderdetail.is_subscribe = k.Value;
break;
case "trade_type":
orderdetail.trade_type = k.Value;
break;
case "bank_type":
orderdetail.bank_type = k.Value;
break;
case "total_fee":
orderdetail.total_fee = k.Value;
break;
case "coupon_fee":
orderdetail.coupon_fee = k.Value;
break;
case "fee_type":
orderdetail.fee_type = k.Value;
break;
case "transaction_id":
orderdetail.transaction_id = k.Value;
break;
case "out_trade_no":
orderdetail.out_trade_no = k.Value;
break;
case "attach":
orderdetail.attach = k.Value;
break;
case "time_end":
orderdetail.time_end = k.Value;
break;
default:
break;
}
}
return orderdetail;
}
/// <summary>
/// 把XML數據轉換爲SortedDictionary<string, string>集合
/// </summary>
/// <param name="strxml"></param>
/// <returns></returns>
protected SortedDictionary<string, string> GetInfoFromXml(string xmlstring)
{
SortedDictionary<string, string> sParams = new SortedDictionary<string, string>();
try
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlstring);
XmlElement root = doc.DocumentElement;
int len = root.ChildNodes.Count;
for (int i = 0; i < len; i++)
{
string name = root.ChildNodes[i].Name;
if (!sParams.ContainsKey(name))
{
sParams.Add(name.Trim(), root.ChildNodes[i].InnerText.Trim());
}
}
}
catch { }
return sParams;
}
/// <summary>
/// 微信統一下單接口xml參數整理
/// </summary>
/// <param name="order">微信支付參數實例</param>
/// <param name="key">密鑰</param>
/// <returns></returns>
protected string getUnifiedOrderXml(UnifiedOrder order, string key)
{
string return_string = string.Empty;
SortedDictionary<string, string> sParams = new SortedDictionary<string, string>();
sParams.Add("appid", order.appid);
sParams.Add("attach", order.attach);
sParams.Add("body", order.body);
sParams.Add("device_info", order.device_info);
sParams.Add("mch_id", order.mch_id);
sParams.Add("nonce_str", order.nonce_str);
sParams.Add("notify_url", order.notify_url);
sParams.Add("openid", order.openid);
sParams.Add("out_trade_no", order.out_trade_no);
sParams.Add("spbill_create_ip", order.spbill_create_ip);
sParams.Add("total_fee", order.total_fee.ToString());
sParams.Add("trade_type", order.trade_type);
order.sign = getsign(sParams, key);
sParams.Add("sign", order.sign);
//拼接成XML請求數據
StringBuilder sbPay = new StringBuilder();
foreach (KeyValuePair<string, string> k in sParams)
{
if (k.Key == "attach" || k.Key == "body" || k.Key == "sign")
{
sbPay.Append("<" + k.Key + "><![CDATA[" + k.Value + "]]></" + k.Key + ">");
}
else
{
sbPay.Append("<" + k.Key + ">" + k.Value + "</" + k.Key + ">");
}
}
return_string = string.Format("<xml>{0}</xml>", sbPay.ToString());
byte[] byteArray = Encoding.UTF8.GetBytes(return_string);
return_string = Encoding.GetEncoding("GBK").GetString(byteArray);
return return_string;
}
/// <summary>
/// 微信訂單查詢接口XML參數整理
/// </summary>
/// <param name="queryorder">微信訂單查詢參數實例</param>
/// <param name="key">密鑰</param>
/// <returns></returns>
protected string getQueryOrderXml(QueryOrder queryorder, string key)
{
string return_string = string.Empty;
SortedDictionary<string, string> sParams = new SortedDictionary<string, string>();
sParams.Add("appid", queryorder.appid);
sParams.Add("mch_id", queryorder.mch_id);
sParams.Add("transaction_id", queryorder.transaction_id);
sParams.Add("out_trade_no", queryorder.out_trade_no);
sParams.Add("nonce_str", queryorder.nonce_str);
queryorder.sign = getsign(sParams, key);
sParams.Add("sign", queryorder.sign);
//拼接成XML請求數據
StringBuilder sbPay = new StringBuilder();
foreach (KeyValuePair<string, string> k in sParams)
{
if (k.Key == "attach" || k.Key == "body" || k.Key == "sign")
{
sbPay.Append("<" + k.Key + "><![CDATA[" + k.Value + "]]></" + k.Key + ">");
}
else
{
sbPay.Append("<" + k.Key + ">" + k.Value + "</" + k.Key + ">");
}
}
return_string = string.Format("<xml>{0}</xml>", sbPay.ToString().TrimEnd(','));
return return_string;
}
}
}
看官網例子:數組
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();
}
主要是prepay_id和paySign的獲取。類庫tenpay.dll的做用就是獲取這兩個東西的。服務器
大體流程:獲取公衆號的code——》獲取預約單號的openid——》獲取prepay_id。微信
1.根據本身的業務邏輯生成內部訂單app
protected void btnPay_Click(object sender, EventArgs e)
{
if (Fetch.GetUserCookie() == null)
{
Response.Redirect("/App/Login.aspx?url=/App/indexPay.aspx");
return;
}
int salePrice = Utility.StrToInt(OrderAmount, 0);
OnLineOrder onlineOrder = new OnLineOrder();
onlineOrder.ShareID = 13;
onlineOrder.OrderID = PayHelper.GetOrderIDByPrefix("WX");
#region 訂單處理
if (Fetch.GetUserCookie() == null)
{
onlineOrder.OperUserID = 0;
}
else
{
onlineOrder.OperUserID = Fetch.GetUserCookie().UserID;
}
onlineOrder.Accounts = Fetch.GetUserCookie().Accounts;
onlineOrder.CardTotal = 1;
onlineOrder.CardTypeID = salePrice / 10; //< 30 ? 1 : salePrice < 60 ? 2 : salePrice < 120 ? 3 : 4;
onlineOrder.OrderAmount = salePrice;
onlineOrder.IPAddress = GameRequest.GetUserIP();
//生成訂單
Message umsg = treasureFacade.RequestOrder(onlineOrder);
if (!umsg.Success)
{
RenderAlertInfo(true, umsg.Content, 2);
return;
}
#endregion
//發起微信支付
Response.Redirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的公衆號appid&redirect_uri=http://你的網站/App/Pay/PayOrder.aspx?showwxpaytitle=1&response_type=code&scope=snsapi_base&state=" + OrderAmount + "_" + onlineOrder.OrderID + "#wechat_redirect");
}
2.進入公衆號配置網頁受權獲取用戶基本信息
這樣配置後就能夠調用微信的接口獲取到公衆號的code
Response.Redirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的公衆號appid&redirect_uri=http://你的網站/App/Pay/PayOrder.aspx?showwxpaytitle=1&response_type=code&scope=snsapi_base&state=" + OrderAmount + "_" + onlineOrder.OrderID + "#wechat_redirect");
訪問https://open.weixin.qq.com/connect/oauth2/authorize接口,成功後會跳轉到設置的redirect_uri頁面,其中會包含code參數,接下來就到redirect_uri頁面(我這裏就是PayOrder.aspx了)簡單的獲取code參數:
上面一句
protected string code = GameRequest.GetQueryString("code");
就獲取到了傳過來的code參數。
而後調用網頁受權接口https://api.weixin.qq.com/sns/oauth2/access_token 獲取openid
這個接口返回的數據是json類型的,使用JavaScriptSerializer類和結構體把openid取出:
public struct authorization
{
public string access_token { get; set; } //屬性的名字,必須與json格式字符串中的"key"值同樣。
public string expires_in { get; set; }
public string refresh_token { get; set; }
public string openid { get; set; }
public string scope { get; set; }
}
TenpayUtil tenpay = new TenpayUtil();
string paySignKey = ConfigurationManager.AppSettings["paySignKey"].ToString();
string AppSecret = ConfigurationManager.AppSettings["AppSecret"].ToString();
string mch_id = ConfigurationManager.AppSettings["mch_id"].ToString();
appId = ConfigurationManager.AppSettings["AppId"].ToString();
string post_data = "appid=" + appId + "&secret=" + AppSecret + "&code=" + code + "&grant_type=authorization_code";
string requestData = tenpay.PostXmlToUrl(TenpayUtil.getAccess_tokenUrl(), post_data);
JavaScriptSerializer js = new JavaScriptSerializer(); //實例化一個可以序列化數據的類
authorization auth = js.Deserialize<authorization>(requestData); //將json數據轉化爲對象類型並賦值給auth
AppId和AppSecret是公衆號裏面給的,mch_id是經過微信支付申請後微信發郵件給的,paySignKey是本身設置的證書密陰
TenpayUtil.getAccess_tokenUrl()="https://api.weixin.qq.com/sns/oauth2/access_token"
這樣轉化後就能夠獲得openid
order.openid = auth.openid;
終於到重頭戲獲取prepay_id了
UnifiedOrder order = new UnifiedOrder();
order.appid = appId;
order.attach = "vinson";
order.body = OrderAmount + "拍幣";
order.device_info = "";
order.mch_id = mch_id;
order.nonce_str = TenpayUtil.getNoncestr();
order.notify_url = "http://你的網站/App/Shop/pay.aspx";
order.openid = auth.openid;
order.out_trade_no = OrderID;
order.trade_type = "JSAPI";
order.spbill_create_ip = Page.Request.UserHostAddress;
order.total_fee = int.Parse(OrderAmount) * 100;
//order.total_fee = 1;
prepay_id = tenpay.getPrepay_id(order, paySignKey);
對象類型UnifiedOrder方便把多個參數融合一個對象中,看看tenpay.getPrepay_id(order, paySignKey)方法:
/// <summary>
/// 獲取prepay_id
/// </summary>
public string getPrepay_id(UnifiedOrder order, string key)
{
string prepay_id = "";
string post_data = getUnifiedOrderXml(order, key);
string request_data = PostXmlToUrl(UnifiedPayUrl, post_data);
SortedDictionary<string, string> requestXML = GetInfoFromXml(request_data);
foreach (KeyValuePair<string, string> k in requestXML)
{
if (k.Key == "prepay_id")
{
prepay_id = k.Value;
break;
}
}
return prepay_id;
}
接口UnifiedPayUrl="https://api.mch.weixin.qq.com/pay/unifiedorder"
這個接口的參數是xml格式的,返回來的數據也是xml格式的
/// <summary>
/// 微信統一下單接口xml參數整理
/// </summary>
/// <param name="order">微信支付參數實例</param>
/// <param name="key">密鑰</param>
/// <returns></returns>
protected string getUnifiedOrderXml(UnifiedOrder order, string key)
{
string return_string = string.Empty;
SortedDictionary<string, string> sParams = new SortedDictionary<string, string>();
sParams.Add("appid", order.appid);
sParams.Add("attach", order.attach);
sParams.Add("body", order.body);
sParams.Add("device_info", order.device_info);
sParams.Add("mch_id", order.mch_id);
sParams.Add("nonce_str", order.nonce_str);
sParams.Add("notify_url", order.notify_url);
sParams.Add("openid", order.openid);
sParams.Add("out_trade_no", order.out_trade_no);
sParams.Add("spbill_create_ip", order.spbill_create_ip);
sParams.Add("total_fee", order.total_fee.ToString());
sParams.Add("trade_type", order.trade_type);
order.sign = getsign(sParams, key);
sParams.Add("sign", order.sign);
//拼接成XML請求數據
StringBuilder sbPay = new StringBuilder();
foreach (KeyValuePair<string, string> k in sParams)
{
if (k.Key == "attach" || k.Key == "body" || k.Key == "sign")
{
sbPay.Append("<" + k.Key + "><![CDATA[" + k.Value + "]]></" + k.Key + ">");
}
else
{
sbPay.Append("<" + k.Key + ">" + k.Value + "</" + k.Key + ">");
}
}
return_string = string.Format("<xml>{0}</xml>", sbPay.ToString());
byte[] byteArray = Encoding.UTF8.GetBytes(return_string);
return_string = Encoding.GetEncoding("GBK").GetString(byteArray);
return return_string;
}
全部參數準備完畢,就剩下最後的微信簽名paySign了:
prepay_id = tenpay.getPrepay_id(order, paySignKey);
timeStamp = TenpayUtil.getTimestamp();
nonceStr = TenpayUtil.getNoncestr();
SortedDictionary<string, string> sParams = new SortedDictionary<string, string>();
sParams.Add("appId", appId);
sParams.Add("timeStamp", timeStamp);
sParams.Add("nonceStr", nonceStr);
sParams.Add("package", "prepay_id=" + prepay_id);
sParams.Add("signType", "MD5");
paySign = tenpay.getsign(sParams, paySignKey);
這裏要注意了:appId這些參數的大小寫必定要和js那邊的參數大小寫一致!稍微有所不一樣都會提示「商戶簽名錯誤」。
<script type="text/javascript">
var appId = "<%=appId %>";
var timeStamp = "<%=timeStamp %>";
var nonceStr = "<%=nonceStr %>";
var prepay_id = "<%=prepay_id %>";
var paySign = "<%=paySign %>";
var OrderID="<%=OrderID %>";
//alert("appId:" + appId + ",timeStamp:" + timeStamp + ",nonceStr:" + nonceStr + ",prepay_id:" + prepay_id + ",paySign:" + paySign);
//return;
function onBridgeReady() {
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId": appId, //公衆號名稱,由商戶傳入
"timeStamp": timeStamp, //時間戳,自1970年以來的秒數
"nonceStr": nonceStr, //隨機串
"package": "prepay_id=" + prepay_id,
"signType": "MD5", //微信簽名方式:
"paySign": paySign //微信簽名
},
function (res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
$(function () {
$.ajax({
contentType: "application/json",
url: "/WS/vinson.asmx/payWeiXin",
data: "{OrderID:'" + OrderID + "'}",
type: "POST",
dataType: "json",
success: function (json) {
json = eval("(" + json.d + ")");
if (json.success == "success") {
$("#tip").text("支付成功,正在跳轉......");
window.location = "http://你的網站/App/Shop/successful.aspx";
}
else {
$("#tip").text(json.msg);
alert(json.msg);
window.location = "http://你的網站/App/indexPay.aspx";
}
},
error: function (err, ex) {
alert(err.responseText);
}
});
})
} // 使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功後返回 ok,但並不保證它絕對可靠。
else {
alert("交易取消");
window.location="http://www.你的網站.cn/App/indexPay.aspx";
}
}
);
}
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();
}
</script>
要發起微信支付,還要到公衆號設置支付受權目錄:
一切準備就緒,就能夠真正的發起微信支付了: