微信JSAPI 公众号支付 H5支付以及APP支付 WEBAPI接口开发测试

统一下单入口 调用该方法入口:

public void WxPayAPI()
{ //string PayPrice ="99.9";
////订单号
//string Payorder =GenerateOutTradeNo(); //支付金额
string PayPrice = Request.GetString("payprice").ToString("filtersql");
//支付单号
string Payorder = Request.GetString("payorder").ToString("filtersql");
//公众号jsapi支付 H5支付传参数
string Openid =Request.GetString("openid").ToString("filtersql");
string data = "";
try
{ WechatPayHelper wxpay = new WechatPayHelper();
int total_fee = (Convert.ToInt32(decimal.Parse(PayPrice) * )); ;
////////////////////////////////////////////////////////////////////////////////////////////
//发起统一下单请求APP支付
// string return_response = wxpay.GetUnifiedOrderResult(Payorder, total_fee, "财政专费");
////////////////////////////////////////////////////////////////////////////////////////////
//发起统一下单请求JASPI H5支付 传递参数 订单号 金额 body说明 公众号ID
string return_response = wxpay.GetUnifiedOrderResultJSAPI(Payorder, total_fee, "财政专费", "rsR8y885552oooo8DH0"); //写日志
Utils.WriteLog("统一下单:" + return_response, "微信下单日志");
//读取返回xml文件信息
XmlDocument doc = new XmlDocument();
doc.LoadXml(return_response);//读取xml字符串
XmlElement root = doc.DocumentElement;
//转化类
WeUnifiedorder weun = GetExmlMsg(root); if (null!=weun)
{
if (weun.return_code.Trim().ToLower() == "fail")
{
//签名失败 接口问题
Utils.WriteLogFile("[WechatPay]签名失败:", "异常日志");
ReturnData(API.ReturnStatus.失败, "SYSTEMERROR", "系统超时", "");
}
else if (weun.result_code.Trim().ToLower() == "fail")
{
string error = ErrorCode(weun.err_code);
Utils.WriteLog("[WechatPay]" + weun.err_code + ":" + error + "", "异常日志");
ReturnData(API.ReturnStatus.失败, weun.err_code, error, "");
}
else
{
//统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP或者公众号客户端。
//参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。
//注意:package的值格式为Sign=WXPay
string noncestr = WechatPayHelper.StrRodamNo();
string timestamp = Common.TimeSpanValue.getTimestamp();
//把请求参数打包成数组
Dictionary<string, string> sParaTempToken = new Dictionary<string, string>();
sParaTempToken.Add("appid", weun.appid);
sParaTempToken.Add("partnerid", weun.mch_id);
sParaTempToken.Add("noncestr", noncestr);
sParaTempToken.Add("prepayid", weun.prepay_id);
sParaTempToken.Add("package", "Sign=WXPay");
sParaTempToken.Add("timestamp", timestamp);
//请求参数体
string strRequestData = "";
//加密
string strSign = wxpay.MakeSignData(sParaTempToken, ref strRequestData); data = "{\"appid\":\"" + weun.appid + "\",\"partnerid\":\"" + weun.mch_id + "\",\"noncestr\":\"" + noncestr + "\",\"sign\":\"" + strSign + "\",\"Package\":\"Sign=WXPay\",\"prepayid\":\"" + weun.prepay_id + "\",\"timestamp\":\"" + timestamp + "\"}"; ReturnData(API.ReturnStatus.成功, "success", "下单支付成功", data);
}
} else
{
ReturnData(API.ReturnStatus.失败, "error", "下单支付失败", "");
} }
catch (System.Threading.ThreadAbortException) { }
catch (Exception e)
{
Utils.WriteLog("统一下单:" + e.Message, "异常日志");
ReturnData(API.ReturnStatus.失败, "error", "下单支付失败", data);
} } /// <summary>
/// 统一下单返回类
/// </summary>
/// <param name="root"></param>
/// <returns></returns>
public WeUnifiedorder GetExmlMsg(XmlElement root)
{
WeUnifiedorder xmlMsg = new WeUnifiedorder()
{
return_code = root.SelectSingleNode("return_code").InnerText
};
//返回状态码为SUCCESS
if (xmlMsg.return_code.Trim().ToLower() == "fail")
{
xmlMsg.return_msg = root.SelectSingleNode("return_msg").InnerText;
}
else
{
xmlMsg.appid = root.SelectSingleNode("appid").InnerText;
xmlMsg.mch_id = root.SelectSingleNode("mch_id").InnerText; xmlMsg.nonce_str = root.SelectSingleNode("nonce_str").InnerText;
xmlMsg.sign = root.SelectSingleNode("sign").InnerText;
xmlMsg.result_code = root.SelectSingleNode("result_code").InnerText;
//业务结果
if (xmlMsg.result_code.Trim().ToLower() == "fail")
{
xmlMsg.err_code = root.SelectSingleNode("err_code").InnerText;
xmlMsg.err_code_des = root.SelectSingleNode("err_code_des").InnerText;
}
else
{
xmlMsg.trade_type = root.SelectSingleNode("trade_type").InnerText;
xmlMsg.prepay_id = root.SelectSingleNode("prepay_id").InnerText;
}
}
return xmlMsg;
} /// <summary>
/// 统一下单返回错误码
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
public string ErrorCode(string code)
{
string message = "错误信息:"; switch (code)
{
case "NOAUTH":
message += "商户未开通此接口权限";
break;
case "NOTENOUGH":
message += "用户帐号余额不足";
break;
case "ORDERPAID":
message += "商户订单已支付";
break;
case "ORDERCLOSED":
message += "当前订单已关闭,无法支付";
break;
case "SYSTEMERROR":
message += "系统超时";
break;
case "APPID_NOT_EXIST":
message += "请检查APPID是否正确";
break;
case "MCHID_NOT_EXIST":
message += "请检查MCHID是否正确";
break;
case "APPID_MCHID_NOT_MATCH":
message += "appid和mch_id不匹配";
break;
case "LACK_PARAMS":
message += "缺少必要的请求参数";
break;
case "OUT_TRADE_NO_USED":
message += "商户订单号重复";
break;
case "SIGNERROR":
message += "签名错误";
break;
case "XML_FORMAT_ERROR":
message += "XML格式错误";
break;
case "REQUIRE_POST_METHOD":
message += "未使用post传递参数 ";
break;
case "POST_DATA_EMPTY":
message += "post数据不能为空";
break;
case "NOT_UTF8":
message += "编码格式错误";
break;
}
return message;
}

WechatPayHelper 代码:

public class WechatPayHelper
{
private string RequestUrl = "";//接口调用地址
//交易安全检验码,由数字和字母组成的32位字符串
private string key = "";
private string appid = "";//应用ID
private string mch_id = "";//商户号
private string nonce_str = "";//随机字符串
private string sign = "";//签名
private string spbill_create_ip = "";//终端IP
private string notify_url = "";//通知地址
private string trade_type = "";//交易类型
private string pay_url = "";
//字符编码格式 目前支持 utf-8
private string input_charset = "utf-8";
//签名方式RSA MD5
private string sign_type = "MD5";
public WechatPayHelper()
{
HttpContext Context = System.Web.HttpContext.Current;
DataTable dt = null;
//////////////////////////////////////////////////////
//APP支付配置 读取配置文件XML
/////////////////////////////////////////////////////
// string strXML = "Wechat_Pay_APP.xml";
/////////////////////////////////////////////////
//jsapi h5支付配置 读取配置XML文件 string strXML = "Wechat_Pay_JSAPI.xml";
object objValue =GetCache(strXML);
if (objValue == null)
{
dt = GetConfigXml("//Config//PayConfig/" + strXML);
SetCache(strXML, dt);
}
else
{
dt = (DataTable)objValue;
}
if (dt != null)
{
appid = dt.Rows[]["appid"].ToString();
mch_id = dt.Rows[]["mch_id"].ToString();
notify_url = dt.Rows[]["notify_url"].ToString();
pay_url = dt.Rows[]["pay_url"].ToString();
spbill_create_ip = GetUserIp();
nonce_str=StrRodamNo();
trade_type = dt.Rows[]["trade_type"].ToString();
key = dt.Rows[]["key"].ToString();
}
}
/// <summary>
/// 调用统一下单,获得下单结果 APP
/// </summary>
/// <param name="out_trade_no"></param>
/// <param name="total_fee"></param>
/// <param name="body"></param>
/// <returns></returns>
public string GetUnifiedOrderResult(string out_trade_no, int total_fee, string body)
{
//请求业务参数详细
StringBuilder sb = new StringBuilder();
sb.AppendFormat("<xml><appid>{0}</appid><mch_id>{1}</mch_id> <body>{2}</body><nonce_str>{3}</nonce_str>", appid, mch_id, body, nonce_str);
sb.AppendFormat("<out_trade_no>{0}</out_trade_no><total_fee>{1}</total_fee> <spbill_create_ip>{2}</spbill_create_ip><trade_type>{3}</trade_type>", out_trade_no, total_fee.ToString(), spbill_create_ip, trade_type);
sb.AppendFormat("<notify_url>{0}</notify_url>", notify_url);
//把请求参数打包成数组
Dictionary<string, string> softdic = new Dictionary<string, string>();
softdic.Add("appid", appid);
softdic.Add("mch_id", mch_id);
softdic.Add("nonce_str", nonce_str);
softdic.Add("body", body);
softdic.Add("out_trade_no", out_trade_no);
softdic.Add("total_fee", total_fee.ToString());
softdic.Add("spbill_create_ip", spbill_create_ip);
softdic.Add("trade_type", trade_type);
softdic.Add("notify_url", notify_url); //请求参数体
string strRequest = ""; //加密签名
string strSign = MakeSignData(softdic, ref strRequest); strRequest += "&sign=" + strSign; //打包xml
sb.AppendFormat("<sign>{0}</sign></xml>", strSign); //发送请求
string strResponse = RequestWechatpay(sb.ToString()); //URLDECODE返回的信息
Encoding code = Encoding.GetEncoding(input_charset);
strResponse = HttpUtility.UrlDecode(strResponse, code); return strResponse;
} /// <summary>
/// 调用统一下单,获得下单结果 JSAPI
/// </summary>
/// <param name="out_trade_no"></param>
/// <param name="total_fee"></param>
/// <param name="body"></param>
/// <returns></returns>
public string GetUnifiedOrderResultJSAPI(string out_trade_no, int total_fee, string body, string openid)
{
//请求业务参数详细
StringBuilder sb = new StringBuilder();
sb.AppendFormat("<xml><appid>{0}</appid><mch_id>{1}</mch_id> <body>{2}</body><nonce_str>{3}</nonce_str>", appid, mch_id, body, nonce_str);
sb.AppendFormat("<out_trade_no>{0}</out_trade_no><total_fee>{1}</total_fee> <spbill_create_ip>{2}</spbill_create_ip><trade_type>{3}</trade_type>", out_trade_no, total_fee.ToString(), spbill_create_ip, trade_type);
sb.AppendFormat("<notify_url>{0}</notify_url>", notify_url);
sb.AppendFormat("<openid>{0}</openid>", openid); //把请求参数打包成数组
Dictionary<string, string> softdic = new Dictionary<string, string>();
softdic.Add("appid", appid);
softdic.Add("mch_id", mch_id);
softdic.Add("nonce_str", nonce_str);
softdic.Add("body", body);
softdic.Add("out_trade_no", out_trade_no);
softdic.Add("total_fee", total_fee.ToString());
softdic.Add("spbill_create_ip", spbill_create_ip);
softdic.Add("trade_type", trade_type);
softdic.Add("notify_url", notify_url);
softdic.Add("openid", openid); //请求参数体
string strRequest = ""; //加密签名
string strSign = MakeSignData(softdic, ref strRequest); strRequest += "&sign=" + strSign; //打包xml
sb.AppendFormat("<sign>{0}</sign></xml>", strSign); //发送请求
string strResponse = RequestWechatpay(sb.ToString()); //URLDECODE返回的信息
Encoding code = Encoding.GetEncoding(input_charset);
strResponse = HttpUtility.UrlDecode(strResponse, code); return strResponse;
} /// <summary>
  /// 设置当前应用程序指定CacheKey的Cache值
  /// </summary>
  /// <param name="CacheKey"></param>
  /// <param name="objObject"></param>
  public static void SetCache(string CacheKey, object objObject)
  {
   System.Web.Caching.Cache objCache = HttpRuntime.Cache;
            if (objObject!=null)
                objCache.Insert(CacheKey, objObject, null, DateTime.UtcNow.AddDays(7), TimeSpan.Zero);
  }
/// <summary>
  /// 获取当前应用程序指定CacheKey的Cache值
  /// </summary>
  /// <param name="CacheKey"></param>
  /// <returns></returns>
  public static object GetCache(string CacheKey)
  {
   System.Web.Caching.Cache objCache = HttpRuntime.Cache;
   return objCache[CacheKey];
  }
/// <summary>
/// 签名原始串
/// </summary>
/// <param name="dicParm">所有非空参数</param>
/// <param name="strQueryString">请求串</param>
/// <returns>签名串</returns>
public string MakeSignData(Dictionary<string, string> dicParm, ref string strQueryString)
{ //先排序
Dictionary<string, string> dicSort = dicParm.OrderBy(o => o.Key).ToDictionary(o => o.Key, p => p.Value);
StringBuilder sb = new StringBuilder();
//再转换成URL字符串
foreach (KeyValuePair<string, string> kvParm in dicSort)
{
if (null != kvParm.Value && "".CompareTo(kvParm.Value) !=
&& "sign".CompareTo(kvParm.Key) != && "key".CompareTo(kvParm.Key) != && "sign_type".CompareTo(kvParm.Key) != )
{
if (sb.Length > )
{
sb.Append("&");
strQueryString += "&";
}
sb.Append(kvParm.Key + "=" + HttpUtility.UrlDecode(kvParm.Value));
strQueryString += kvParm.Key + "=" + HttpUtility.UrlEncode(kvParm.Value);
}
}
//再和key拼装成字符串
sb.Append("&key=" + key);
//再进行MD5加密转成大写
return MD5Create(sb.ToString(), input_charset).ToUpper(); } public static string MD5Create(string str, string charset)
{
string retStr;
MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider(); //创建md5对象
byte[] inputBye;
byte[] outputBye; //使用GB2312编码方式把字符串转化为字节数组.
try
{
inputBye = Encoding.GetEncoding(charset).GetBytes(str);
}
catch (Exception ex)
{
inputBye = Encoding.GetEncoding("GB2312").GetBytes(str);
}
outputBye = m5.ComputeHash(inputBye); retStr = System.BitConverter.ToString(outputBye);
retStr = retStr.Replace("-", "");
return retStr;
} /// <summary>
///把请求参数信息打包发送请求微信支付地址
/// </summary>
/// <param name="strRequestData">请求参数字符串(QueryString)</param>
/// <returns></returns>
private string RequestWechatpay(string strRequestData)
{
Encoding code = Encoding.GetEncoding(input_charset); //把数组转换成流中所需字节数组类型
byte[] bytesRequestData = code.GetBytes(strRequestData); //请求远程HTTP
string strResult = "";
try
{
//设置HttpWebRequest基本信息
HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(pay_url);
myReq.Method = "post";
myReq.ContentType = "text/xml"; //填充POST数据
myReq.ContentLength = bytesRequestData.Length;
Stream requestStream = myReq.GetRequestStream();
requestStream.Write(bytesRequestData, , bytesRequestData.Length);
requestStream.Close(); //发送POST数据请求服务器
HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
Stream myStream = HttpWResp.GetResponseStream(); //获取服务器返回信息
StreamReader reader = new StreamReader(myStream, code);
StringBuilder responseData = new StringBuilder();
String line;
while ((line = reader.ReadLine()) != null)
{
responseData.Append(line);
} //释放
myStream.Close(); strResult = responseData.ToString();
}
catch (Exception exp)
{
strResult = "报错:" + exp.Message;
} return strResult;
} /// <summary>
/// 获得客户端的IP
/// </summary>
/// <returns>当前页面客户端的IP</returns>
public static string GetUserIp()
{ string userHostAddress = HttpContext.Current.Request.UserHostAddress; if (string.IsNullOrEmpty(userHostAddress))
{
userHostAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
} //最后判断获取是否成功,并检查IP地址的格式(检查其格式非常重要)
if (!string.IsNullOrEmpty(userHostAddress) && IsIP(userHostAddress))
{
return userHostAddress;
}
return "127.0.0.1"; } /// <summary>
/// 检查IP地址格式
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public static bool IsIP(string ip)
{
return System.Text.RegularExpressions.Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
} /// <summary>
/// 生成随机字母与数字
/// </summary>
/// <param name="IntStr">生成长度</param>
/// <returns></returns>
public static string StrRodamNo(int Length)
{
return StrRodam(Length, false);
} /// <summary>
/// 生成随机字母与数字
/// </summary>
/// <param name="Length">生成长度</param>
/// <param name="Sleep">是否要在生成前将当前线程阻止以避免重复</param>
/// <returns></returns>
public static string StrRodam(int Length, bool Sleep)
{
if (Sleep)
System.Threading.Thread.Sleep();
char[] Pattern = new char[] { '', '', '', '', '', '', '', '', '', '', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
string result = "";
int n = Pattern.Length;
System.Random random = new Random(~unchecked((int)DateTime.Now.Ticks));
for (int i = ; i < Length; i++)
{
int rnd = random.Next(, n);
result += Pattern[rnd];
}
return result;
} #region 读取xml中的指定节点的值
/// <summary>
/// 读取xml中的指定节点的值
/// </summary>
private string ReadXmlNode(string filename)
{
string result = "调用微信服务异常";
XmlDocument xmlDoc = new XmlDocument();
try
{
xmlDoc.LoadXml(filename); XmlNode root = xmlDoc.SelectSingleNode("xml");
if (root != null)
result = (root.SelectSingleNode("code_url")).InnerText; }
catch (Exception e)
{
SZRPP.Common.Utils.WriteLogFile("ReadXmlNode:" + e.Message,"");
}
return result;
} #endregion
}

微信返回结果异步通知地址

wechatpay_notify.aspx

 protected void Page_Load(object sender, EventArgs e)
{ StreamReader reader = new StreamReader(Request.InputStream);
String xmlData = reader.ReadToEnd();
Utils.WriteLog("微信异步回调:" + xmlData, "微信异步回调");
//序列化xml
Dictionary<string, string> dicParam = GetInfoFromXml(xmlData);
string data = ""; try
{
//当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。 if (dicParam.ContainsKey("return_code") && dicParam["return_code"] == "SUCCESS")
{
//通讯成功
WechatPayHelper wcHelper = new WechatPayHelper();
string strRequestData = "";
//计算加密
string strSign = wcHelper.MakeSignData(dicParam, ref strRequestData);
//判断签名
if (strSign == dicParam["sign"])
{
//判断业务结果
if ("SUCCESS" == dicParam["result_code"])
{
//判断业务是否处理过
string out_trade_no = dicParam["out_trade_no"];//订单编号 if (out_trade_no != null)
{
OrderPayment payment = payBll.Query(out_trade_no,""); if (payment != null)
{//商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致,防止数据泄漏导致出现“假通知”,造成资金损失。
if (payment.PayPrice.Equals(decimal.Parse(dicParam["total_fee"])/))
{
data = "<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[金额不一致]]></return_msg></xml>";
Response.Write(data);
}
if (payment.PayStatus == )
{
//已经支付 视为处理过 直接返回
data = "<xml><return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg></xml>";
Response.Write(data);
}
else
{
//修改支付状态
if (payBll.UpdatePayStatus(out_trade_no, "",) > )
{ data = "<xml><return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg></xml>";
Response.Write(data);
}
}
} else
{
data = "<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[系统调用超时]]></return_msg></xml>";
Response.Write(data);
}
}
}
else
{
//错误信息
string error = dicParam["err_code"] + ":" + dicParam["err_code_des"];
data = "<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[系统调用超时]]></return_msg></xml>";
Response.Write(data);
}
}
else
{
data="<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[系统调用超时]]></return_msg></xml>";
Response.Write(data);
}
} }
catch (Exception ex)
{
Utils.WriteLog("微信异步回调异常:" + ex.Message, "异常日志");
data = "<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[系统调用超时]]></return_msg></xml>";
Response.Write(data);
} } /// <summary>
/// 把XML数据转换为Sorted<string, string>集合
/// </summary>
/// <param name="strxml"></param>
/// <returns></returns>
public Dictionary<string, string> GetInfoFromXml(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)
{ }
return sParams;
}

xml配置文件: Wechat_Pay_JSAPI.xml

<?xml version="1.0" encoding="utf-8" ?>
<data>
<!--接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数-->
<notify_url>http://8.20.7.8:300/PayNotifyPage/PayNotify/wechatpay_notify.aspx</notify_url>
<pay_url>https://api.mch.weixin.qq.com/pay/unifiedorder</pay_url>
<!--微信开放平台审核通过的应用APPID-->
<appid>wxf99999999999</appid>
<!--微信支付分配的商户号-->
<mch_id>148888888882</mch_id>
<key>16ce9ghjjjjjj5555552ee19d</key>
<subject>财政专费</subject>
<trade_type>JSAPI</trade_type>
</data>

Wechat_Pay_APP.xml


<?xml version="1.0" encoding="utf-8" ?>
<data>
<!--接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数-->
<notify_url>http://8.20.7.8:300/PayNotifyPage/PayNotify/wechatpay_notify.aspx</notify_url>
<pay_url>https://api.mch.weixin.qq.com/pay/unifiedorder</pay_url>
<!--微信开放平台审核通过的应用APPID-->
<appid>wxf99999999999</appid>
<!--微信支付分配的商户号-->
<mch_id>148888888882</mch_id>
<key>16ce9ghjjjjjj5555552ee19d</key>
<subject>财政专费</subject>
<trade_type>APP</trade_type>
</data>
</data>

稍加对接口的调整 加一个参数类型 直接使用一个接口即可完成对APP 公众号 jsapi H5 的统一调用即可   当哪一个渠道发起支付请求就唤起哪一个渠道的支付
至此进行传递参数进行发起下单既可完成整个支付请求了。在这里分开写 主要起到一个牵针引线的作用

上一篇:微信商户/H5支付申请 被拒原因:网站存在不实内容或不安全信息


下一篇:支付宝开发之手机网站支付(H5支付)