自建房外观设计网站推荐,北京最好设计公司,望野原文,南京网站开发联系南京乐识微信和支付宝H5支付
最近开发任务遇到了一个要在手机浏览器里面调起微信和支付宝去支付的开发需求#xff0c;以前都是做的扫码支付或者JSAPI都是在软件内部支付的#xff0c;没遇到过在自己浏览器内唤醒微信或者支付宝的支付这种开发在开发的过程中遇到了许多问题和坑点这里…微信和支付宝H5支付
最近开发任务遇到了一个要在手机浏览器里面调起微信和支付宝去支付的开发需求以前都是做的扫码支付或者JSAPI都是在软件内部支付的没遇到过在自己浏览器内唤醒微信或者支付宝的支付这种开发在开发的过程中遇到了许多问题和坑点这里就一一写进文章里面了
首先放上支付宝和微信支付的开发文档
支付宝手机网页支付 微信H5支付
由于是教程贴我们从一个新建的MVC项目开始 首先编写一个H5支付的页面 代码如下所示: {ViewBag.Title H5支付页;Layout null;
}
bodyscript src~/Scripts/jquery-3.4.1.js/scriptscript src~/Scripts/bootstrap.min.js/scriptlink href~/Content/bootstrap.min.css relstylesheet /script src~/Content/layer/layer.js/scriptlink href~/Content/layer/theme/default/layer.css relstylesheet /styleul li {list-style: none;font-size: 40px;margin-bottom: 20px;}input {height: 50px !important;width: 50px !important;margin-left: 5%;}.head {background-color: darkblue;height: 100px;font-size: 40px;color: white;text-align: center;}.pay {width: 50%;margin: 5% 25%;border: 3px dashed lightgray;border-radius: 15px;}.btncolor {border-radius: 25px;background-color: #1E90FF;color: white;}/styleform idalitopay action支付宝后台处理网址 onsubmitreturn sure(); methodpostdiv styletext-align:center;margin:50px 0 0 0;font-size:40px请选择支付方式/divimg src~/Images/weixin.png classpay value1 /img idzhifubao src~/Images/zhifubao.png classpay value2 /div styleposition:fixed;bottom:15%;width:100%;button classbtncolor styleheight:130px;margin:250px 5% 5% 5%;font-size:40px;width:90%;确认支付/button/div/form
/bodyscriptvar paytype ;function bordernone() {$(.pay).css(border, 3px dashed lightgray);}$(.pay).click(function () {bordernone();$(this).css(border, 5px solid #1E90FF);paytype $(this).attr(value);});function sure() {var Guid $(#Guid).val();//paytype $(input:radio:checked).val();if (paytype || paytype undefined) {layer.msg(div stylefont-size: 40px;margin-top:20px; 请选择支付方式 /div,{area: [400px, 100px]});return false;} else if (paytype 2) {//支付宝$(#alitopay).submit();return true;} else if (paytype 1) {//微信$.ajax({type: Post,url: 微信后台处理网址,data: { Guid: Guid },dataType: json,success: function (result) {if (result.id 0) {window.location.href result.result;}}});return false;}}$(document).ready(function () {$(.pay).trigger(click);})
/script
这里我们首先讲解微信支付 微信支付为了简单快捷我们用了盛派的SDK引入步骤如下 1.首先右键项目选择管理Nuget程序包 需要值得注意的是我们要安装2个dll一个Senparc.Weixin一个 Senparc.Weixin.TenPay
安装完成后我们在跟目录的web.config添加以下内容 !-- 微信支付V3 --add keyTenPayV3_MchId value你的微信商户ID /add keyTenPayV3_Key value你的微信商户密钥 /add keyTenPayV3_AppId value你的微信平台APPID /add keyTenPayV3_AppSecret value你的微信平台AppSecret /add keyTenPayV3_TenpayNotify value支付完成后回调通知地址 /配置web.config后我们还要修改Global.asax //设置全局Debug 状态var isGLobalDebug true;//全局设置参数将被储存到 Senparc.CO2NET.Config.SenparcSettingvar senparcSetting SenparcSetting.BuildFromWebConfig(isGLobalDebug);//也可以通过这种方法在程序任意位置设置全局 Debug 状态//Senparc.CO2NET.Config.IsDebug isGLobalDebug;//CO2NET 全局注册必须IRegisterService register RegisterService.Start(senparcSetting).UseSenparcGlobal();//设置微信 Debug 状态var isWeixinDebug true;//全局设置参数将被储存到 Senparc.Weixin.Config.SenparcWeixinSettingvar senparcWeixinSetting SenparcWeixinSetting.BuildFromWebConfig(isWeixinDebug);//也可以通过这种方法在程序任意位置设置微信的 Debug 状态//Senparc.Weixin.Config.IsDebug isWeixinDebug;//微信全局注册必须register.UseSenparcWeixin(senparcWeixinSetting, senparcSetting).RegisterTenpayV3(senparcWeixinSetting, XXX公众号);//记录到同一个 SenparcWeixinSettingItem 对象中此处修改完成后我们就可以动手开始写controller了
支付代码如下:
using Senparc.Weixin.Helpers;
using Senparc.Weixin.TenPay;
using Senparc.Weixin.TenPay.V3;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Mvc;namespace TestPay.Controllers
{public class WeiXinController : Controller{private static TenPayV3Info _tenPayV3Info;public static TenPayV3Info TenPayV3Info{get{if (_tenPayV3Info null){var key TenPayHelper.GetRegisterKey(Senparc.Weixin.Config.SenparcWeixinSetting);_tenPayV3Info TenPayV3InfoCollection.Data[key];}return _tenPayV3Info;}}// GET: WeiXinpublic ActionResult H5Pay(){string total_amout null;//支付价格string Guid GetSerialNumber();//系统内订单号我这里是生成的时间随机数字//注意不要超过32位否则微信会报错// 商品描述string body 测试支付;string openId ;var timeStamp TenPayV3Util.GetTimestamp();//时间戳var nonceStr TenPayV3Util.GetNoncestr();var price total_amout null ? 1 : int.Parse(total_amout) * 100;//注意微信支付单位为分所以要100 如果传1就是1分钱 传100就是1块钱//var ip Request.Params[REMOTE_ADDR];var xmlDataInfo new TenPayV3UnifiedorderRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, body, Guid, price, Request.UserHostAddress, TenPayV3Info.TenPayV3Notify, TenPayV3Type.MWEB/*此处无论传什么方法内部都会强制变为MWEB*/, openId, TenPayV3Info.Key, nonceStr);var result TenPayV3.Html5Order(xmlDataInfo);//调用统一订单接口//JsSdkUiPackage jsPackage new JsSdkUiPackage(TenPayV3Info.AppId, timeStamp, nonceStr,);var package string.Format(prepay_id{0}, result.prepay_id);//预支付订单idstring paysign TenPayV3.GetJsPaySign(TenPayV3Info.AppId, timeStamp, nonceStr, package, TenPayV3Info.Key);//签名sign//设置成功页面也可以不设置支付成功后默认返回来源地址string returnUrl ;string hosturl Request.Url.Host;returnUrl hosturl /WeiXin/PayOK;//支付成功后跳转网址var mwebUrl result.mweb_url;if (!string.IsNullOrEmpty(returnUrl)){mwebUrl string.Format(redirect_url{0}, AsUrlData(returnUrl));}return Json(new { id 1, result mwebUrl });}#region url处理public static string AsUrlData(string data){if (data null){return null;}return Uri.EscapeDataString(data);}#endregion#region 生成随机流水或private static long np1 0, np2 0, np3 1; //临时计算用。private static object orderFormNumberLock new object();//线程并行锁以保证同一时间点只有一个用户能够操作流水号。如果分多个流水号段放多个锁并行压力可以更好的解决大家自己想法子扩充吧private string strOrderNumber null;//订单号。/// summary/// 生成充值流水号格式8位日期加8位顺序号如2010030200000056。/// /summarypublic string GetSerialNumber(){DateTime now DateTime.Now;TimeSpan span now - DateTime.MinValue;long tmpDays span.Days;long seconds span.Hours * 3600 span.Seconds;StringBuilder sb new StringBuilder();Monitor.Enter(orderFormNumberLock); //锁定资源if (tmpDays ! np1){np1 tmpDays;np2 0;np3 1;}if (np2 ! seconds){np2 seconds;np3 1;}sb.Append(Convert.ToString(np1, 16).PadLeft(5, 0) Convert.ToString(np2, 16).PadLeft(5, 0) Convert.ToString(np3, 16).PadLeft(6, 0));Monitor.Exit(orderFormNumberLock); //释放资源strOrderNumber sb.ToString();return strOrderNumber;}#endregion}}完成后我们选择微信支付如下图所示
完成微信支付后我们开始支付宝的开发
同样支付宝支付我们需要一个AliPay.AopSDK的dll
我们再次将配置需要的参数写入web.config中 !--应用ID,您的APPID--add keyapp_id valuexxxxxxxxx /add keygatewayUrl valuehttps://openapi.alipay.com/gateway.do /!--商户私钥您的原始格式RSA私钥--add keyprivate_key valuexxxxxxx /!--支付宝公钥,查看地址https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。--add keyalipay_public_key valuexxxxxxx /add keysign_type valueRSA2 /add keycharset valueUTF-8 /
controller 如下所示
using Aop.Api;
using Aop.Api.Domain;
using Aop.Api.Request;
using Aop.Api.Response;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Mvc;namespace TestPay.Controllers
{public class AliPayController : Controller{// GET: AliPay[HttpPost]public void ALiPay(){string gatewayUrl ConfigurationManager.AppSettings[gatewayUrl].ToString();string app_id ConfigurationManager.AppSettings[app_id].ToString();string private_key ConfigurationManager.AppSettings[private_key].ToString();string sign_type ConfigurationManager.AppSettings[sign_type].ToString();string alipay_public_key ConfigurationManager.AppSettings[alipay_public_key].ToString();string charset ConfigurationManager.AppSettings[charset].ToString();DefaultAopClient client new DefaultAopClient(gatewayUrl, app_id,private_key, json, 1.0, sign_type, alipay_public_key, charset, false);string hosturl Request.Url.Host;// 外部订单号商户网站订单系统中唯一的订单号string out_trade_no Helper.GetSerialNumber();//系统内订单号我这里是生成的时间随机数字//注意不要超过64位否则微信会报错// 订单名称string subject 测试支付;// 付款金额string total_amout 0.01;//string total_amout 0.01;// 商品描述string body 测试支付;string quit_url ;// 支付中途退出返回商户网站地址quit_url hosturl H5pay/Index;// 组装业务参数modelAlipayTradeWapPayModel model new AlipayTradeWapPayModel();model.Body body;model.Subject subject;model.TotalAmount total_amout;model.OutTradeNo out_trade_no;model.ProductCode QUICK_WAP_WAY;model.QuitUrl quit_url;AlipayTradeWapPayRequest request new AlipayTradeWapPayRequest();// 设置支付完成同步回调地址request.SetReturnUrl(hosturl H5pay/PayOK);// 设置支付完成异步通知接收地址request.SetNotifyUrl(hosturl H5pay/Notify_url);// 将业务model载入到requestrequest.SetBizModel(model);AlipayTradeWapPayResponse response null;try{response client.pageExecute(request, null, post);Response.Write(response.Body);}catch (Exception exp){throw exp;}}}
}
完成后代码效果如下
写完支付后其实还有一步重要的步骤就是支付回调
微信支付回调
#region 微信回调方法[HttpPost]public ActionResult PayNotifyUrl(){try{ResponseHandler resHandler new ResponseHandler(null);string return_code resHandler.GetParameter(return_code);//支付结果string return_msg resHandler.GetParameter(return_msg);//支付消息bool paySuccess false;resHandler.SetKey(TenPayV3Info.Key);//验证请求是否从微信发过来安全if (resHandler.IsTenpaySign() return_code.ToUpper() SUCCESS){paySuccess true;//正确的订单处理//直到这里才能认为交易真正成功了可以进行数据库操作但是别忘了返回规定格式的消息}else{paySuccess false;//错误的订单处理}if (paySuccess){/* 这里可以进行订单处理的逻辑 *///发送支付成功的模板消息try{string appId Senparc.Weixin.Config.SenparcWeixinSetting.WeixinAppId;//与微信公众账号后台的AppId设置保持一致区分大小写。int total_fee int.Parse(resHandler.GetParameter(total_fee));//订单金额string out_trade_no resHandler.GetParameter(out_trade_no);//商户订单号string transaction_id resHandler.GetParameter(transaction_id);//商户订单号//在此处编写支付成功的逻辑}catch (Exception ex){}}string xml string.Format(xml
return_code![CDATA[{0}]]/return_code
return_msg![CDATA[{1}]]/return_msg
/xml, return_code, return_msg);return Content(xml, text/xml);}catch (Exception ex){throw;}}#endregion支付宝支付回调 #region 支付宝回调方法[HttpPost]public ActionResult Notify_url(){/* 实际验证过程建议商户添加以下校验。1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号2、判断total_amount是否确实为该订单的实际金额即商户订单创建时的金额3、校验通知中的seller_id或者seller_email) 是否为out_trade_no这笔单据的对应的操作方有的时候一个商户可能有多个seller_id/seller_email4、验证app_id是否为该商户本身。*/Dictionarystring, string sArray GetRequestPost();string gatewayUrl ConfigurationManager.AppSettings[gatewayUrl].ToString();string app_id ConfigurationManager.AppSettings[app_id].ToString();string private_key ConfigurationManager.AppSettings[private_key].ToString();string sign_type ConfigurationManager.AppSettings[sign_type].ToString();string alipay_public_key ConfigurationManager.AppSettings[alipay_public_key].ToString();string charset ConfigurationManager.AppSettings[charset].ToString();if (sArray.Count ! 0){bool flag AlipaySignature.RSACheckV1(sArray, alipay_public_key,charset, sign_type, false);if (flag){//交易状态//判断该笔订单是否在商户网站中已经做过处理//如果没有做过处理根据订单号out_trade_no在商户网站的订单系统中查到该笔订单的详细并执行商户的业务程序//请务必判断请求时的total_amount与通知时获取的total_fee为一致的//如果有做过处理不执行商户的业务程序//注意//退款日期超过可退款期限后如三个月可退款支付宝系统发送该交易状态通知string trade_status Request.Form[trade_status];//商户订单号string out_trade_no Request.Form[out_trade_no];//支付宝交易号string trade_no Request.Form[trade_no];string total_amount Request.Form[total_amount];if (trade_status TRADE_FINISHED || trade_status TRADE_SUCCESS){try{//在此处编写你的支付成功的逻辑return Json(success);}catch (Exception e){return Json(fail);}}else if (trade_status TRADE_CLOSED){return Json(fail);}return Json(success);}else{return Json(fail);}}return Json(fail);}public Dictionarystring, string GetRequestPost(){int i 0;Dictionarystring, string sArray new Dictionarystring, string();NameValueCollection coll;//coll Request.Form;coll Request.Form;String[] requestItem coll.AllKeys;for (i 0; i requestItem.Length; i){sArray.Add(requestItem[i], Request.Form[requestItem[i]]);}return sArray;}#endregion
因为很多人私信我弄不明白支付宝的参数肿么弄我这里重新在最后讲下支付宝支付参数的设置
1.下载支付宝密钥生成工具:下载地址 2.运行程序按下图所示生成密钥 配置里面的私钥就是生成的私钥 而下面的支付宝公钥需要在支付宝后台 将你生成的应用公钥复制到对应的位置确认后网页会返回给你一个支付宝公钥这个支付宝公钥就是填入配置所需的参数 最后需要源码都请扫码关注回复:H5源码 下载地址