简介
Senparc.Weixin SDK 是由盛派网络(Senparc)团队自主研发的针对微信各模块的 开发套(C#SDK),
已全面支持微信公众号、微信支付、企业号、开放平台、JSSDK、摇一摇周边等模块。 快使用 Senparc.Weixin SDK 轻松打造微信各平台的扩展应用吧!
开发步骤
模式介绍
模式一
商户后台系统根据微信支付规则链接生成二维码,链接中带固定参数productid(可定义为产品标识或订单号)。用户扫码后,微信支付系统将productid和用户唯一标识(openid)回调商户后台系统(需要设置支付回调URL),商户后台系统根据productid生成支付交易,最后微信支付系统发起用户支付流程。
商户支付回调URL设置指引:进入公众平台–>微信支付–>开发配置–>扫码支付–>修改
模式二
户后台系统调用微信支付【统一下单API】生成预付交易,将接口返回的链接生成二维码,用户扫码后输入密码完成支付交易。注意:该模式的预付单有效期为2小时,过期后无法支付。
业务流程说明:
(1)商户后台系统根据用户选购的商品生成订单。
(2)用户确认支付后调用微信支付【统一下单API】生成预支付交易;
(3)微信支付系统收到请求后生成预支付交易单,并返回交易会话的二维码链接code_url。
(4)商户后台系统根据返回的code_url生成二维码。
(5)用户打开微信“扫一扫”扫描二维码,微信客户端将扫码内容发送到微信支付系统。
(6)微信支付系统收到客户端请求,验证链接有效性后发起用户支付,要求用户授权。
(7)用户在微信客户端输入密码,确认支付后,微信客户端提交授权。
(8)微信支付系统根据用户授权完成支付交易。
(9)微信支付系统完成支付交易后给微信客户端返回交易结果,并将交易结果通过短信、微信消息提示用户。微信客户端展示支付交易结果页面。
(10)微信支付系统通过发送异步消息通知商户后台系统支付结果。商户后台系统需回复接收情况,通知微信后台系统不再发送该单的支付通知。
(11)未收到支付通知的情况,商户后台系统调用【查询订单API】。
(12)商户确认订单已支付后给用户发货。
生成二维码规则
对应链接格式:weixin://wxpay/bizpayurl?sr=XXXXX。请商户调用第三方库将code_url生成二维码图片。该模式链接较短,生成的二维码打印到结账小票上的识别率较高。
代码实现(使用模式二)
前端代码
<div class="ZhiFu_All">
<div class="ZhiFu_Money">请填入预付金额:<input type="number" id="money" name="money" />元<span>当前余额:@ViewBag.Money元</span><span id="error"></span></div>
<div class="ZhiFu_Fangshi">请选择支付方式:</div>
<ul class="ZhiFu_UL">
<li>
<div class="Div_css">
<label>
<input name="WXbank" checked="checked" type="radio" />
<img src="/Content/state/img/WePayLogo.png" />
<img class="TUIjian" src="/Content/state/img/tuijian.png" />
</label>
</div>
</li>
<li>
<div class="Div_css">
<label>
<input name="WXbank" type="radio" />
<img src="/Content/state/img/bank1.png" />
</label>
</div>
<div class="Div_css">
<label>
<input name="WXbank" type="radio" />
<img src="/Content/state/img/bank2.png" />
</label>
</div>
</li>
<li>
<div class="Div_css">
<label>
<input name="WXbank" type="radio" />
<img src="/Content/state/img/bank3.png" />
</label>
</div>
<div class="Div_css">
<label>
<input name="WXbank" type="radio" />
<img src="/Content/state/img/bank4.png" />
</label>
</div>
</li>
<li>
<div class="Div_css">
<label>
<input name="WXbank" type="radio" />
<img src="/Content/state/img/bank5.png" />
</label>
</div>
<div class="Div_css">
<label>
<input name="WXbank" type="radio" />
<img src="/Content/state/img/bank6.png" />
</label>
</div>
</li>
<li>
<div class="Div_css">
<label>
<input name="WXbank" type="radio" />
<img src="/Content/state/img/bank7.png" />
</label>
</div>
<div class="Div_css">
<label>
<input name="WXbank" type="radio" />
<img src="/Content/state/img/bank8.png" />
</label>
</div>
</li>
</ul>
<div class="ZhiFu_sum">
<input type="submit" id="WX_zhifu" value="继续下一步" />
</div>
</div>
//保存生成的订单
<input type="hidden" value="0" id="OrderNo" />
<!-- 隐藏层 当用户点击继续下一步(相当于充值)时显示此层-->
<div id="WX_All" class="WX_zhifu">
<div class="WX_left">
<div class="WX_title">
<img src="/Content/state/img/tuijian.png" />
<span>使用微信支付</span>
<label class="WX_Close">x</label>
</div>
<div class="WX_All">
<div class="WX_imgLogo">
<img src="/Content/state/img/WePayLogo.png" />
</div>
<div>
<div class="WX_jinE">
<ul>
<li id="OrderNum">订单编号:</li>
</ul>
</div>
<span class="WX_Money">应付金额:<label class="WX_Moneys" id="trueMoney">33</label></span>
</div>
<div class="WX_ewma">
<div class="WX_ewmaL">
<img src="/Content/state/img/gongzhonghao.jpg" id="code_url" />
<img src="/Content/state/img/shuoming.png" />
</div>
<div class="WX_shifan">
<img src="/Content/state/img/shouj.png" />
</div>
<div class="clear"></div>
</div>
</div>
</div>
</div>
<script type="text/javascript" language="javascript">
//用来循环检测订单是否支付完成 然后页面进行跳转
$(document).ready(function () {
setInterval("ajaxstatus()", 3000);
});
function ajaxstatus() {
//如果OrderNo不等于0时 说明用户已经生成订单 就开始轮询检查用户支付成功没
//微信的回调
if ($("#OrderNo").val() != "0") {
$.ajax({
url: "/Member/MemWeixinPay/Search",
type: "post",
dataType: "text",
data: { OutID: $("#OrderNo").val() },
success: function (data) {
// alert(data);
if (data == "1") { //订单状态为1表示支付成功
window.location.href = "/Member/MemAccount/Index"; //页面跳转
}
},
error: function () {
console.log("请求订单状态出错");
}
});
}
}
$("#WX_zhifu").click(function () {
var r = /^\+?[1-9][0-9]*$/; //正整数
var Money = $("#money").val();
var flag = r.test(Money);
if (flag == false) {
$("#error").html("请输入整数");
return false;
}
//支付金额
$("#trueMoney").html("" + Money);
//获取订单编号
var num = generateMixed(15);
$("#OrderNum").html("订单编号:" + num);
//订单编号保存到隐藏域名里面
$("#OrderNo").val(num);
//获取返回的二维码
$("#code_url").attr("src", "/Member/MemWeixinPay/WeixinPayErweima?price=" + Money + "&outTradeNo=" + num + "");
//显示出二维码支付的一个层 层里面放一个微信返回的支付二维码和订单编号 订单金额
$("#WX_All").show();
});
$(".WX_Close").click(function () {
$("#WX_All").hide();
});
//生成订单编号
function generateMixed(n) {
var chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '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'];
var res = "";
for(var i = 0; i < n ; i ++) {
var id = parseInt(10 * Math.random());
res += chars[id]+"";
}
return res;
}
</script>
后端代码
private static TenPayV3Info _tenPayV3Info;
public static TenPayV3Info TenPayV3Info
{
get
{
if (_tenPayV3Info == null)
{
_tenPayV3Info = new TenPayV3Info("appid", "AppSecret", "商户ID", "密码", "回调接口");
TenPayV3InfoCollection.Register(_tenPayV3Info);
}
return _tenPayV3Info;
}
}
/// <summary>
/// 返回二维码
/// </summary>
/// <returns></returns>
public string WeixinPayErweima(int price,string outTradeNo)
{
UserBasic user = userBasicBll.GetUser(LoginUserID);
if (user == null)
{
return "";
}
var body = "充值";
var timeStamp = TenPayV3Util.GetTimestamp();
var nonceStr = TenPayV3Util.GetNoncestr();
//这个商户订单号可以通过前端传入 也可以通过后台生成。 现在我们是前端传入的
string sp_billno = outTradeNo;
if (string.IsNullOrEmpty(sp_billno))
{
//生成订单10位序列号,此处用时间和随机数生成,商户根据自己调整,保证唯一
sp_billno = string.Format("{0}{1}{2}", TenPayV3Info.MchId/*10位*/, DateTime.Now.ToString("yyyyMMddHHmmss"),
TenPayV3Util.BuildRandomStr(6));
}
// 添加一个交易记录 放在本地服务器里面
//等会儿前端轮询就好判断用户订单是否支付成功
TenPayV3UnifiedorderRequestData od = new TenPayV3UnifiedorderRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, body, sp_billno, price*100, Request.UserHostAddress, TenPayV3Info.TenPayV3Notify, TenPayV3Type.NATIVE, "", TenPayV3Info.Key, nonceStr);
var order = TenPayV3.Unifiedorder(od);
var erweima = order.code_url;
String data = erweima;
//生成二维码
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
qrCodeEncoder.QRCodeScale = 4;
qrCodeEncoder.QRCodeVersion = 8;
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
System.Drawing.Bitmap image = qrCodeEncoder.Encode(data);
System.IO.MemoryStream MStream = new System.IO.MemoryStream();
image.Save(MStream, System.Drawing.Imaging.ImageFormat.Png);
Response.ClearContent();
Response.ContentType = "image/Png";
Response.BinaryWrite(MStream.ToArray());
return "";
}
//支付成功回调接口
public string Success()
{
//获取微信返回的数据
string resultFromWx = getPostStr();
//转换成xml文档
var ress = XDocument.Parse(resultFromWx);
//返回给微信接口 提示微信处理成功
string data = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
//通信成功
if (ress.Element("xml").Element("return_code").Value == "SUCCESS")
{
if (ress.Element("xml").Element("result_code").Value == "SUCCESS")
{
//商户订单号<><!
string outNos = ress.Element("xml").Element("out_trade_no").Value;
//微信订单号
string tranId = ress.Element("xml").Element("transaction_id").Value;
if (outNos == "")
{
return data;
}
//这里可以不用再次查询了 但是我还是查询了一个次 为了更好的验证
string norcestr = TenPayV3Util.GetNoncestr();
var xmlDataInfo = new TenPayV3OrderQueryRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, tranId, norcestr, outNos, TenPayV3Info.Key);
var result = TenPayV3.OrderQuery(xmlDataInfo);
if (result == null)
{
return data;
}
if (result.trade_state != "SUCCESS")
{
return data;
}
//微信端返回充值成功 跟据商户订单号获取交易记录 修改交易状态
//充值完成
}
else
{
}
}
return data;
}
public string getPostStr()
{
Int32 intLen = Convert.ToInt32(Request.InputStream.Length);
byte[] b = new byte[intLen];
Request.InputStream.Read(b, 0, intLen);
return System.Text.Encoding.UTF8.GetString(b);
}