首先介绍一下我在调用微信支付接口使用的是 weixin.senparc SDK,非常方便好用开源的一个微信开发SDK。
先去下载下来Senparc.Weixin SDK。
在调起支付接口之前,需要先要调用统一下单接口,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再在APP里面调起支付。
微信 JsApi支付 在这个目录下 Senparc.Weixin.MP.Sample.Controllers 找到JsApi支付。
{
//这里的state其实是会暴露给客户端的,验证能力很弱,这里只是演示一下
//实际上可以存任何想传递的数据,比如用户ID,并且需要结合例如下面的Session["OAuthAccessToken"]进行验证
return Content("验证失败!请从正规途径进入!1001");
}
try
{
//获取产品信息
var stateData = state.Split('|');
int productId = 0;
ProductModel product = null;
if (int.TryParse(stateData[0],out productId))
{
int hc = 0;
if (int.TryParse(stateData[1],out hc))
{
var products = ProductModel.GetFakeProductList();
product = products.FirstOrDefault(z => z.Id == productId);
if (product == null || product.GetHashCode() != hc)
{
return Content("商品信息不存在,或非法进入!1002");
}
ViewData["product"] = product;
}
}
//通过,用code换取access_token
var openIdResult = OAuthApi.GetAccessToken(TenPayV3Info.AppId,TenPayV3Info.AppSecret,code);
if (openIdResult.errcode != ReturnCode.请求成功)
{
return Content("错误:" + openIdResult.errmsg);
}
string sp_billno = Request["order_no"];
if (string.IsNullOrEmpty(sp_billno))
{
//生成订单10位序列号,此处用时间和随机数生成,商户根据自己调整,保证唯一
sp_billno = string.Format("{0}{1}{2}",TenPayV3Info.MchId,DateTime.Now.ToString("yyyyMMdd"),TenPayV3Util.BuildRandomStr(10));
}
else
{
sp_billno = Request["order_no"];
}
var timeStamp = TenPayV3Util.GetTimestamp();
var nonceStr = TenPayV3Util.GetNoncestr();
var body = product == null ? "test" : product.Name;
var price = product == null ? 100 : product.Price * 100;
var xmlDataInfo = new TenPayV3UnifiedorderRequestData(TenPayV3Info.AppId,body,sp_billno,price,Request.UserHostAddress,TenPayV3Info.TenPayV3Notify,TenPayV3Type.JSAPI,openIdResult.openid,TenPayV3Info.Key,nonceStr);
var result = TenPayV3.Unifiedorder(xmlDataInfo);//调用统一订单接口
//JsSdkUiPackage jsPackage = new JsSdkUiPackage(TenPayV3Info.AppId,timeStamp,nonceStr,);
var package = string.Format("prepay_id={0}",result.prepay_id);
ViewData["appId"] = TenPayV3Info.AppId;
ViewData["timeStamp"] = timeStamp;
ViewData["nonceStr"] = nonceStr;
ViewData["package"] = package;
ViewData["paySign"] = TenPayV3.GetJsPaySign(TenPayV3Info.AppId,package,TenPayV3Info.Key);
return View();
}
catch (Exception ex)
{
var msg = ex.Message;
msg += "
" + ex.StackTrace;
msg += "
==Source==
" + ex.Source;
if (ex.InnerException != null)
{
msg += "<br>===InnerException===<br>" + ex.InnerException.Message;
}
return Content(msg);
}
}
先在微信服务后台生成预支付交易单,获得预支付订单号。
先说说在统一下单这里遇到的坑。
1.在统一下单的时候解析返回结果,一直出现以下问题:您没有JSAPI支付权限
1)先看看你的公众号微信支付设置是否正确。
2)检查你的授权目录是否正确,格式要这样,后面记得别漏了一个/ 例如:
3)检查需要传过去的账户参数,上公众号还有商户号检查你的账户参数是否正确。我在开发当中就出现,微信公众号商户号,appid 是分别不同两个公众号的,坑啊,找了好久,觉得不对劲,原来是给的配置参数密钥不对。 这里详细说一下对应的参数: MCHID:商户号(必须配置,开户邮件中可查看),商户申请微信支付后,由微信支付分配的商户收款账号。
APPID:微信开放平台审核通过的应用APPID,appid是微信公众账号或开放平台APP的唯一标识,在公众平台申请公众账号或者在开放平台申请APP账号后,微信会自动分配对应的appid用于标识该应用。可在微信公众平台-->开发者中心查看,商户的微信支付审核通过邮件中也会包含该字段值. KEY:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置),交易过程生成签名的密钥,仅保留在商户系统和微信支付后台,不会在网络中传播。商户妥善保管该Key,切勿在网络中传输,不能在其他客户端中存储,保证key不会被泄漏。商户可根据邮件提示登录微信商户平台进行设置。也可按一下路径设置:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置.
APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置, 登录公众平台,进入开发者中心可设置) 2.在统一下单,解析返回来的结果我出现了商户号mch_id与appid不匹配这个问题 原因是我拿到的商户号不是这个公众号的。一定要检查是不是这个公众号的商户号。 3.在统一下单,解析返回来的结果出现 appid and openid not match,appid和openid不匹配。 原因是我这个用户的openid 不是这个公众号的 4.在统一下单,解析返回来的结果出现 CDATA[openid is invalid],openid无效 原因是,传过去不是有效的opendid。不小心看错了,把用户id 当做openid传过去了。 当统一下单成功,会返回以下格式的参数 解析获得预支付单号: 获取预支付订单号 给页面对应地参数 } else { }
//支付失败
// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
}
});