微信H5支付三步轻松搞定(C#)
目前,从商城网站、餐厅、商场、超市到菜市、小卖部、路边摊,移动支付无处不在,极大地方便了我们的生活。特别是微信支付,应用极广,很受大众欢迎。然而,对于拥有H5移动商城的商家来说,微信支付只能在微信客户端内实现,而在微信中又无法使用支付宝,这是令人非常蛋疼的事。
现在,好消息来了!微信已全面开放了H5支付功能,它将实现在微信客户端之外的H5商城网页场景完成支付,极大地满足了商家的收款需求和买家便捷支付的要求。
好东西当然不能错过,但如何快速将H5支付功能嵌入到您的H5商城中呢?微信并没有提供官方Demo可以参考。没关系,按照本文的方法,您不需要再花精力做额外的开发,只需三步就能轻松搞定。
【我的思路】既然H5支付也是通过调用统一下单接口来实现,那么直接用官方提供的公众号支付SDK(WxPayAPI_CS_v3)进行扩展和修改不就行了吗?省时省力(本人比较懒,能不折腾就尽量不折腾,哈哈)。
【准备工作】一、您已经调通了WxPayAPI_CS_v3(可以正常实现公众号支付),二、您已经开通了H5支付功能(需要去微信商户平台上申请开通)。对这方面不清楚的朋友请查阅相关文档,它不是本文所要讨论的话题。
现在,就让我们开始吧!
第一步
在WxPayAPI/ business文件夹下添加一个类,将其命名为H5Pay(可从JsApiPay.cs中复制相关代码进行修改,重点是将交易类型trade_type设置为MWEB,另外还要传递终端IP),H5Pay.cs的完整代码如下:
using System.Web;
namespace WxPayAPI
{
public class H5Pay
{
public string GetPayUrl(string thip)
{
Log.Info(this.GetType().ToString(), "H5 pay url is producing...");
WxPayData data = new WxPayData();
data.SetValue("body",”商品描述”); //这里替换成你的数据
data.SetValue("attach", "详见我的订单");//这里替换成你的数据
data.SetValue("out_trade_no",”商户订单号”); //这里替换成你的数据
data.SetValue("total_fee",”总金额”); //这里替换成你的数据
data.SetValue("spbill_create_ip", thip);// 终端IP
data.SetValue("trade_type", "MWEB");//交易类型
data.SetValue("scene_info", "{'h5_info':{'type':'Wap','wap_url':'你的H5域名','wap_name':'你的商城名称'}}");//场景信息
WxPayData result = WxPayApi.UnifiedOrder(data);//调用统一下单接口
string url = result.GetValue("mweb_url").ToString();//获得统一下单接口返回的链接
Log.Info(this.GetType().ToString(), "Get H5 pay url : " + url);
return url;
}
}
}
说明:GetPayUrl方法将返回微信支付中间页的跳转URL(即统一下单接口返回的mweb_url参数)。
第二步
在example文件夹下添加一个Web窗体,将其命名为H5PayPage,前台H5PayPage.aspx里不需要添加任何东西,在H5PayPage.aspx.cs中添加相关代码,其完整代码如下:
using System;
using System.Web;
namespace WxPayAPI
{
public partial class H5PayPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Log.Info(this.GetType().ToString(), "page load");
H5Pay h5Pay = new H5Pay();
string scip = GetIP();//获取客户端真实IP
string url = h5Pay.GetPayUrl(scip);//通过统一下单接口进行H5支付
Response.Redirect(url); //跳转到微信支付中间页
}
//因H5支付要求商户在统一下单接口中上传用户真实ip地址“spbill_create_ip”,故需要调用以下方法。
public string GetIP()
{
HttpRequest request = HttpContext.Current.Request;
string result = request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (string.IsNullOrEmpty(result))
{
result = request.ServerVariables["REMOTE_ADDR"];
}
if (string.IsNullOrEmpty(result))
{
result = request.UserHostAddress;
}
if (string.IsNullOrEmpty(result))
{
result = "0.0.0.0";
}
return result;
}
}
}
第三步
打开WxPayAPI/lib/WxPayApi.cs文件,找到UnifiedOrder方法,再找到如下4行原代码:
inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID
inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号
inputObj.SetValue("spbill_create_ip", WxPayConfig.IP);//终端ip
inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串
将其修改为:
//若终端IP未设置,则使用配置文件中的终端IP
if (!inputObj.IsSet("spbill_create_ip"))
{
inputObj.SetValue("spbill_create_ip", WxPayConfig.IP);//终端IP
}
inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID
inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号
inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串
说明:因为原代码传递给调用统一下单接口的终端IP是配置文件Config.cs中的默认值(8.8.8.8),这样肯定会出错(H5支付要求上传用户真实IP),因此需要加上一个判断,即如果已经设置了终端IP则不使用默认值。
OK,这样就行了,是不是非常简单?
【最后要说的】其它平台(如PHP、java等)照此思路操作也是一件很轻松的事儿。H5支付结果异步回调通知与公众号支付(JSAPI支付)和扫码支付都是统一的接口,如果你之前已做好了更新订单的逻辑处理,那现在就不需要做重复劳动了,是不是很爽?