result.GetValue("prepay_id").ToString() == "")
{
Log.Error(this.GetType().ToString(), "UnifiedOrder response error!"); throw new WxPayException("UnifiedOrder response error!");
}
unifiedOrderResult = result; return result;
} /**
*
* 从统一下单成功返回的数据中获取微信浏览器调起jsapi支付所需的参数,
* 微信浏览器调起JSAPI时的输入参数格式如下:
* {
* "appId" : "wx2421b1c4370ec43b", //公众号名称,由商户传入
* "timeStamp":" 1395712654", //时间戳,自1970年以来的秒数
* "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串
* "package" : "prepay_id=u802345jgfjsdfgsdg888",
* "signType" : "MD5", //微信签名方式:
* "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名
* }
* @return string 微信浏览器调起JSAPI时的输入参数,json格式可以直接做参数用
* 更详细的说明请参考网页端调起支付API:http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7
*
*/
public string GetJsApiParameters()
{
Log.Debug(this.GetType().ToString(), "JsApiPay::GetJsApiParam is processing...");
WxPayData jsApiParam = new WxPayData();
jsApiParam.SetValue("appId", unifiedOrderResult.GetValue("appid"));
jsApiParam.SetValue("timeStamp", WxPayApi.GenerateTimeStamp());
jsApiParam.SetValue("nonceStr", WxPayApi.GenerateNonceStr());
jsApiParam.SetValue("package", "prepay_id=" + unifiedOrderResult.GetValue("prepay_id"));
jsApiParam.SetValue("signType", "MD5");
jsApiParam.SetValue("paySign", jsApiParam.MakeSign()); string parameters = jsApiParam.ToJson();
Log.Debug(this.GetType().ToString(), "Get jsApiParam : " + parameters); return parameters;
} /**
*
* 获取收货地址js函数入口参数,详情请参考收货地址共享接口:http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_9
* @return string 共享收货地址js函数需要的参数,json格式可以直接做参数使用 */
public string GetEditAddressParameters()
{ string parameter = ""; try
{ string host = context.Request.Url.Host; string path = context.Request.Path; string queryString = context.Request.Url.Query; //这个地方要注意,参与签名的是网页授权获取用户信息时微信后台回传的完整url
string url = "http://" + host + path + queryString; //构造需要用SHA1算法加密的数据
WxPayData signData = new WxPayData();
signData.SetValue("appid",WxPayConfig.APPID);
signData.SetValue("url", url);
signData.SetValue("timestamp",WxPayApi.GenerateTimeStamp());
signData.SetValue("noncestr",WxPayApi.GenerateNonceStr());
signData.SetValue("accesstoken",access_token); string param = signData.ToUrl();
Log.Debug(this.GetType().ToString(), "SHA1 encrypt param : " + param); //SHA1加密
string addrSign = FormsAuthentication.HashPasswordForStoringInConfigFile(param, "SHA1");
Log.Debug(this.GetType().ToString(), "SHA1 encrypt result : " + addrSign); //获取收货地址js函数入口参数
WxPayData afterData = new WxPayData();
afterData.SetValue("appId",WxPayConfig.APPID);
afterData.SetValue("scope","jsapi_address");
afterData.SetValue("signType","sha1");
afterData.SetValue("addrSign",addrSign);
afterData.SetValue("timeStamp",signData.GetValue("timestamp"));
afterData.SetValue("nonceStr",signData.GetValue("noncestr")); //转为json格式
parameter = afterData.ToJson();
Log.Debug(this.GetType().ToString(), "Get EditAddressParam : " + parameter);
} catch (Exception ex)
{
Log.Error(this.GetType().ToString(), ex.ToString()); throw new WxPayException(ex.ToString());
} return parameter;
}
}
}
View Code
这个页面可以在本地调试,可以比较方便的确认参数是否ok。
唤起支付
官方页面的示例如下:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6 但主要的参数(mark部分)是由后台生成的,也就是上一个步骤的ViewBag.wxJsApiParam
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,但并不保证它绝对可靠。
}
);
}所以在MVC中要这样写:
@{
ViewBag.Title = "微信支付";
Layout = "~/Views/Shared/_Layout.cshtml";
}<p class="page" id="Wxpayment">
<p class="content">
<p>订单详情:@Html.Raw(ViewBag.unifiedOrder)</p>
<button id="h5pay" onclick="callpay()">支付</button>
</p>
<input type="hidden" value="@ViewBag.OrderNumber" id="ordernum"/></p>
<script type="text/javascript">
//调用微信JS api 支付
function jsApiCall() {
WeixinJSBridge.invoke( 'getBrandWCPayRequest', @Html.Raw(ViewBag.wxJsApiParam),//josn串
function (res)
{
WeixinJSBridge.log(res.err_msg); //alert(res.err_code + res.err_desc + res.err_msg);
if (res.err_msg == "get_brand_wcpay_request:ok") { var num = $("#ordernum").val();
$.post("/payment/WeiXinPaySuccess", { ordernumber: num }, function(data) { if (data.IsSuccess === true) {
alert("支付成功");
location.href = document.referrer;
} else {
}
});
}
if (res.err_msg == 'get_brand_wcpay_request:cancel') {
$('.button').removeAttr('submitting');
alert('取消支付');
}
}
);
} function callpay()
{ if (typeof WeixinJSBridge == "undefined")
{
alert("WeixinJSBridge ="); if (document.addEventListener)
{
document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
} else if (document.attachEvent)
{
document.attachEvent('WeixinJSBridgeReady', jsApiCall);
document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
}
} else
{
jsApiCall();
}
}</script>必须要用Html.Raw,不然json解析不对,无法支付。这个时候点击页面,会出现微信的加载效果,但别高兴的太早,还是会出错,出现一个“3当前的URL未注册”

原因就在于,需要在公众号中设置支付目录。而这个支付目录是大小写敏感的,所以你得多试几次。直到弹出输入密码的窗口才是真的流程正确了。然后支付成功之后马上就可以收到js中的回调,这个时候你可以去处理你的订单和业务逻辑。
小结
如果是生产环境,我们需要再多个地方调用,需要再封装一下。
function jsApiCall(json, success, fail) {
WeixinJSBridge.invoke( 'getBrandWCPayRequest',
json,//josn串
function (res)
{
WeixinJSBridge.log(res.err_msg); //alert(res.err_code + res.err_desc + res.err_msg);
if (res.err_msg == "get_brand_wcpay_request:ok") { //充值进去 要区分是出题充值 还是购买悬赏 前者冲到他的钱包
//后者直接冲到系统账户
if (success) success();
}
if (res.err_msg == 'get_brand_wcpay_request:cancel') { // alert('取消支付');
if (fail)fail();
}
}
);
}function callpay(json,success,fail)
{ if (typeof WeixinJSBridge == "undefined")
{
alert("请在微信中打开!"); if (document.addEventListener)
{
document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
} else if (document.attachEvent)
{
document.attachEvent('WeixinJSBridgeReady', jsApiCall);
document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
}
} else
{
jsApiCall(json, success, fail);
}
}View Code
[LoginValid] public ActionResult H5PayJson(string orederId)
{ var user = _workContext.CurrentUser; var order = _paymentService.GetOrderByOrderNumber(orederId); //判断订单是否存在 //订单是否已经支付了
var openid = user.OpenId; var jsApipay = new JsApiPayMvc(ControllerContext.HttpContext)
{
openid = openid,
total_fee = (int) order.Amount*100
}; try
{
jsApipay.GetUnifiedOrderResult(); return Json(jsApipay.GetJsApiParameters());//实际还是字符串
} catch (Exception e)
{ //统一下单失败
return Json(new PortalResult(false, e.Message));
}
}调用的时候这样直接唤起支付了。 但如果传入的json不是json对象,微信加载动画会一直卡在哪儿。
$.post("/Checkout/H5PayJson", { orederId: orderId }, function (jsondata) { var jdata = JSON.parse(jsondata); if (jdata.appId) {
callpay(jdata, function () {
$.post("/payment/WeiXinPaySuccess", { ordernumber: orderId }, function (paymentdata) { if (paymentdata.IsSuccess === true) {
submitQuestion();
} else {
$.alert(paymentdata.Message);
}
});
}, function () {
$.alert("你已取消支付!");
});
} else {
alert("统一下单失败!");
}
});相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
webpack自动刷新与解析的使用
webpack的模块热替换详解
JS事件先发布后订阅的方法
以上就是公众号支付接口的开发的详细内容,更多请关注php中文网其它相关文章!
微信提供公众平台、朋友圈、消息推送等功能,用户可以通过“摇一摇”、“搜索号码”、“附近的人”、扫二维码方式添加好友和关注公众平台,同时微信将内容分享给好友以及将用户看到的精彩内容分享到微信朋友圈。
关键词:公众号支付接口的开发