官方文档:[http://codepay.fateqq.com/apiword/r1YwqrOte.html]
C#代码如下
-
数据结构
public class RequestInfo { /// <summary> /// 商户秘钥 /// </summary> public string paykey { get; set; } /// <summary> /// 请求地址 /// </summary> public string req_uri { get; set; } /// <summary> /// 商户订单号 /// </summary> public string out_trade_no { get; set; } /// <summary> /// 商品描述 /// </summary> public string body { get; set; } /// <summary> /// 总金额 /// </summary> public int total_fee { get; set; } /// <summary> /// 订单生成时间 /// </summary> public string time_start { get; set; } /// <summary> /// 商户号 /// </summary> public string mch_id { get; set; } /// <summary> /// 通知回调地址 /// </summary> public string notify_url { get; set; } /// <summary> /// 签名方式 /// </summary> public string sign_type { get; set; } }
2.发起请求
public void SendPay(RequestInfo resInfo) { var dic = new Dictionary<string, string> { {"id",resInfo.mch_id},//个人支付Id {"pay_id", resInfo.out_trade_no},//唯一标识,可以是用户ID,用户名,session_id(),订单ID,ip 付款后返回 {"type","1"},//1支付宝支付 3微信支付 2QQ钱包 {"price",price.ToString()},//总金额 {"notify_url",resInfo.notify_url},//通知回调地址,商户需改为自己的,且保证外网能POST发送数据请求成功. {"return_url",""},//跳转地址 {"page","4"} }; var query = GetOtherSignString(dic, resInfo.paykey); Encoding en = Encoding.GetEncoding("UTF-8"); HttpWebResponse response = CreatePostHttpResponse(resInfo.req_uri, query, en); Stream stream = response.GetResponseStream(); //获取响应的字符串流 StreamReader sr = new StreamReader(stream); //创建一个stream读取流 string html = sr.ReadToEnd(); //从头读到尾,放到字符串html JavaScriptSerializer serializer = new JavaScriptSerializer(); Dictionary<string, object> json = (Dictionary<string, object>)serializer.DeserializeObject(html); string status = ""; string code_url = ""; string code_img_url = ""; logger.Error(json); foreach (var item in json) { if (item.Key == "status") { status = item.Value.ToString(); } if (item.Key == "qrcode") { code_img_url = item.Value.ToString(); } if (item.Key == "qr") { code_url = item.Value.ToString(); } } //发起支付 if (status != "" && status =="0") { imgCpdehUrl = code_img_url; errmsg = "码支付本地订单(" + HttpUtility.HtmlEncode(tradeno) + ")处理成功."; logger.Error(errmsg); } else { errmsg = "JSAPI码支付发起支付(" + HttpUtility.HtmlEncode(tradeno) + ")发生错误."; logger.Error(errmsg); return Content("<span style=‘color:#FF0000;font-size:20px‘>" + "抱歉,支付订单处理失败" + "</span><p>" + errmsg + "</p>"); } }
3.扩展方法:处理请求参数
public static string GetOtherSignString(Dictionary<string, string> dic, string key) { var newDic = dic.Where(p => p.Key != "sign").OrderBy(p => p.Key); string sign = ""; string urls = ""; foreach (var item in newDic) { if (item.Value == "" || item.Key == "sign") continue;//跳过不需要的参数名 //追加&拼接URL if (sign != "") { sign += "&"; urls += "&"; } sign += item.Key + "=" + item.Value; urls += item.Key + "=" + HttpUtility.UrlEncode(item.Value); } sign = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sign += key, "MD5");//md5加密 return urls + "&sign=" + sign; }
4.通知回调处理
private static bool doNotifyProcess_shpayAliMA(string appid, string orderid, string srContent, out string resultValue, StringBuilder errorMsgs) { resultValue = ""; string _msg; var str = srContent.Split(‘&‘);//分割回调字符串 string status = ""; string out_trade_no = ""; string price = ""; foreach (var item in str) { if (item.IndexOf("status") > -1) { status = item.Split(‘=‘)[1];//订单状态 } if (item.IndexOf("pay_id") > -1) { out_trade_no = item.Split(‘=‘)[1];//订单号 } if (item.IndexOf("money") > -1) { price = item.Split(‘=‘)[1];//价格 } } if (status != "" && Convert.ToInt32(status) == 0) { // 充值支付核心处理(回调信息写入 + 充值处理) if (ServiceHelper.WriteAndFillOrderPay_ShAliMA(out_trade_no,decimal.Parse(price), "Post", out _msg)) { // 商户成功接收到支付结果通知之后,返回http包体数据为SUCCESS。若返回数据非SUCCESS,则视为失败 resultValue = _SH_SUCCESS; errorMsgs.Append("[MA成功](" + out_trade_no + ")" + resultValue); return true; } else { // 回写订单发货失败 resultValue = _SH_ERROR; errorMsgs.Append("[MA支付失败](" + out_trade_no + ")" + resultValue + _msg); } } else { // 签名和数据解析失败 resultValue = _SH_ERROR; errorMsgs.Append("[MA成功](" + out_trade_no + ")"); } return false; }