In the application of WeChat, WeChat payment is a more useful part, but it is also a relatively complicated technical point. In the era when WeChat business is very popular, it seems unreasonable that your own store does not add WeChat payment. WeChat payment is designed to serve the majority of people. WeChat users and merchants are provided with better payment services. WeChat’s payment and security system is supported by Tencent Tenpay. This article mainly introduces how to implement WeChat payment access, WeChat payment API encapsulation, and API calls on WeChat official accounts to realize some of our common business calls.
WeChat payment is the basis for authentication of WeChat public accounts, that is, it is only open to certified public accounts. WeChat authentication requires signing of relevant information and conducting For reconciliation and verification, you will usually be contacted by phone to confirm the relevant information.
Before we start using the WeChat payment API, we generally need to perform certain configurations in the background. For example, we need to configure the authorization directory for official account payment, test whitelist and other information. And the callback processing address supported by QR code scanning (this implementation will be discussed later), as shown below.
Before using the API, we need to know that some key operations on WeChat, such as refunds, order cancellations, etc., require certificates, and for regular payment operations, we also We need information such as merchant number, merchant payment key, etc. These certificates and key information are obtained from the merchant platform of WeChat Pay. After WeChat Pay is activated and approved, we can log in to the merchant platform to perform related operations. .
First we need to install the certificate on the development computer.
Then you need to set the API secret key
Finally download the certificate on the [API Security] project for our development environmental use.
WeChat payment configuration related parameters, and obtain certificates, API keys, merchants After receiving the number and other information, we can start to understand the specific use of the WeChat payment API. We need to first encapsulate the API into a C# class library for use, so that it can be easily called in various applications.
WeChat payment is divided into many methods, such as scan code payment, official account payment, JSAPI payment, APP payment, etc. However, the core APIs are similar and basically cover the APIs in the screenshot below. , there are only some interface differences.
We can start to understand from the scan code payment. This is the scenario of scanning the QR code to pay, which is divided into two methods: mode one and mode two.
# Scan code payment can be divided into two modes. Merchants can choose the corresponding mode according to the payment scenario.
[Mode 1]: The merchant's backend system generates a QR code based on the WeChat payment rule link, with a fixed parameter productid (can be defined as a product ID or order number) in the link. After the user scans the code, the WeChat payment system calls the productid and user's unique identifier (openid) back to the merchant's backend system (the payment callback URL needs to be set). The merchant's backend system generates a payment transaction based on the productid, and finally the WeChat payment system initiates the user payment process.
[Mode 2]: The merchant's backend system calls WeChat Pay [Unified Order API] to generate a prepaid transaction, and generates a QR code from the link returned by the interface. The user scans the code and enters the password to complete the payment transaction. Note: The prepaid order in this mode is valid for 2 hours, and payment cannot be made after expiration.
According to the API description of scan code payment, we can encapsulate these interfaces (such as unified order placement, order inquiry, order closing, refund application, refund inquiry, statement download, etc.) one by one to It is convenient for our development and use.
Both mode one and mode two need to use the unified ordering interface, and then generate the corresponding QR code for customers to scan and pay.
Then we. Let’s first take a look at the unified ordering interface description to understand its specific use
##Except for the scanned payment scenario, the merchant system first calls this interface to generate a prepayment transaction order in the WeChat payment service background, returns the correct prepayment transaction reply ID, and then scans Code, JSAPI, APP and other different scenarios generate transaction strings to initiate payment.
2) Interface link
URL address: https ://api.mch.weixin.qq.com/pay/unifiedorder
3) Do you need a certificate
Not required
4) Request parameters
The fixed parameters required by the system are as follows.
Part of it is the business parameters. The business parameters are as follows, which mainly record the relevant product ID, description, cost, etc. of the order
The invocation of the WeChat payment interface is different from the invocation of other interfaces of the public account. All exchanges here are done using XML, which does not feel as convenient and flexible as JSON. The following is the unified order interface to submit data.
The returned data is also in XML, as shown in the example code below, and the field contents are not yet certain, so as recommended by the official website, use a dictionary collection. Store the returned data object.
3. WeChat Payment APIC# Encapsulation and Calling
For example, we can define the API interface definition of WeChat payment as shown below.
/// <summary> /// 微信支付接口 /// </summary> public interface ITenPayApi { /// <summary> /// 生成扫描支付模式一URL /// </summary> /// <param>商品ID /// <returns></returns> string GetPrePayUrl(string productId); /// <summary> /// 生成直接支付url,支付url有效期为2小时,模式二 /// </summary> /// <param>商品订单数据 /// <returns></returns> string GetPayUrl(WxPayOrderData info); /// <summary> /// 统一下单。(不需要证书,默认不需要) /// 除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单, /// 返回正确的预支付交易回话标识后再按扫码、JSAPI、APP等不同场景生成交易串调起支付。 /// </summary> /// <param>商品订单数据 WxPayData UnifiedOrder(WxPayOrderData info); .............
For the input parameters of the interface method, we define an entity class
WxPayOrderData to store some business parameters, These parameters are defined according to the interface description in point 2. The code is as follows
/// <summary> /// 统一下单的商品订单信息 /// </summary> public class WxPayOrderData { /// <summary> /// 商品ID, trade_type=NATIVE,此参数必传 /// </summary> public string product_id { get; set; } /// <summary> /// 商品或支付单简要描述 /// </summary> public string body { get; set; } /// <summary> /// 订单总金额,单位为分 /// </summary> public int total_fee { get; set; } /// <summary> /// 商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠 /// </summary> public string goods_tag { get; set; } /// <summary> /// 交易类型,默认为:NATIVE。 /// JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付 /// </summary> public string trade_type { get; set; } /// <summary> /// 商品名称明细列表 /// </summary> public string detail { get; set; } /// <summary> /// 附加数据 /// 在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据 /// </summary> public string attach { get; set; } /// <summary> /// 用户标识 /// trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识。 /// </summary> public string openid { get; set; } public WxPayOrderData() { this.trade_type = "NATIVE"; } }
Then we define a class WxPayData returned by the interface, which is used to store the returned For object information, this class is explained in the official website example. It has a sorted dictionary object built in to store data. Part of the code is as follows. I have made relevant modifications to it to facilitate initialization in the constructor. Required parameters (fixed parameters).
public class WxPayData { //采用排序的Dictionary的好处是方便对数据包进行签名,不用再签名之前再做一次排序 private SortedDictionary<string> m_values = new SortedDictionary<string>(); /// <summary> /// 默认构造函数 /// 如果initDefault为true,则自动填入字段(appid,mch_id,time_stamp,nonce_str,out_trade_no,) /// </summary> public WxPayData(bool initDefault = false) { if(initDefault) { Init(); } } /// <summary> /// 对象初始化后,自动填入字段(appid,mch_id,time_stamp,nonce_str,out_trade_no,) /// </summary> public void Init() { //初始化几个参数 this.SetValue("appid", WxPayConfig.APPID);//公众帐号id this.SetValue("mch_id", WxPayConfig.MCHID);//商户号 this.SetValue("nonce_str", GenerateNonceStr());//随机字符串 this.SetValue("out_trade_no", GenerateOutTradeNo(WxPayConfig.MCHID));//随机字符串 }</string></string>
Then based on the above data definition, we can realize the unified order function content, mainly converting the input parameters into the dictionary parameter set we need, As shown in the following code.
/// <summary> /// 统一下单。(不需要证书,默认不需要) /// 除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单, /// 返回正确的预支付交易回话标识后再按扫码、JSAPI、APP等不同场景生成交易串调起支付。 /// </summary> /// <param>商品订单数据 public WxPayData UnifiedOrder(WxPayOrderData info) { WxPayData data = new WxPayData(true); data.SetValue("product_id", info.product_id);//商品ID data.SetValue("openid", info.openid);//商品ID //其他信息 data.SetValue("body", info.body);//商品描述 data.SetValue("attach", info.attach);//附加数据 data.SetValue("total_fee", info.total_fee);//总金额 data.SetValue("goods_tag", info.goods_tag);//商品标记 data.SetValue("trade_type", info.trade_type);//交易类型 //默认构建 data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));//交易起始时间 data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));//交易结束时间 ..............
For the final data exchange logic, we can submit XML data to it by POSTing the URL to get the return result, as shown below.
string url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; return GetPostResult(data, url);
其中上面的函数的代码逻辑如下所示,主要是把返回的结果再还原为XML对象类WxPayData。
/// <summary> /// 通用的获取结果函数 /// </summary> private WxPayData GetPostResult(WxPayData data, string url) { string xml = data.ToXml(); string response = helper.GetHtml(url, xml, true); WxPayData result = new WxPayData(); result.FromXml(response); return result; }
对于扫码操作的模式二,直接生成一种二维码,不需要后台进行回调的,那么它的实现逻辑只需要对上面代码进行封装就可以了,如先构建二维码的函数代码如下所示。
/// <summary> /// 生成直接支付url,支付url有效期为2小时,模式二 /// </summary> /// <param>商品订单数据 /// <returns></returns> public string GetPayUrl(WxPayOrderData info) { WxPayData result = UnifiedOrder(info);//调用统一下单接口 return result.GetString("code_url");//获得统一下单接口返回的二维码链接 }
如在Winform界面里面,调用生成二维码的代码如下所示,主要逻辑就是构建好二维码,然后显示在界面上。
private void btnGetPayUrl_Click(object sender, EventArgs e) { //测试扫码模式二的生成二维码方式 WxPayOrderData data = new WxPayOrderData() { product_id = "123456789", body = "测试支付-模式二", attach = "爱奇迪技术支持", detail = "测试扫码支付-模式二", total_fee = 1, goods_tag = "test1" }; var url = api.GetPayUrl(data); var image = api.GenerateQRImage(url); this.imgGetPayUrl.Image = image; this.imgGetPayUrl.SizeMode = PictureBoxSizeMode.StretchImage; }
另外对于模式一,它在前端传入一个简单的产品ID,生成二维码,当用户扫码的时候,微信后台会调用商户平台(我们服务器)的回调处理方法,这个回调方法会调用统一下单的API进行生成支付交易,过程有点复杂,我们来看看,我们的实现代码如下所示。
/// <summary> /// 生成扫描支付模式一URL /// </summary> /// <param>商品ID /// <returns></returns> public string GetPrePayUrl(string productId) { WxPayData data = new WxPayData(true); data.SetValue("product_id", productId);//商品ID data.SetValue("time_stamp", data.GenerateTimeStamp());//随机字符串 data.SetValue("sign", data.MakeSign());//签名 string str = data.ToUrlParams();//转换为URL串 string url = "weixin://wxpay/bizpayurl?" + str; return url; }
它的调用代码生成二维码操作如下所示。
private void btnGetPrePayUrl_Click(object sender, EventArgs e) { var productId = "12345678"; var url = api.GetPrePayUrl(productId); var image = api.GenerateQRImage(url); this.imgGetPrePayUrl.Image = image; this.imgGetPayUrl.SizeMode = PictureBoxSizeMode.StretchImage; }
我们在第一小节里面介绍了,需要在微信后台配置扫码的回调函数,如下所示。
这样我们还需要添加一个页面aspx、或者一般处理程序ashx的方式来实现扫码的回调过程。具体的逻辑也就是在这个页面里面获取到提交过来的参数,然后调用统一下单处理后,进行数据返回即可,代码逻辑如下所示。
前面的例子,我介绍了Winfrom的扫码例子,很多时候,我们的应用可能是基于Web的,那么它的实现是如何的呢,下面我继续介绍一下。
首先我们在自己的业务Web后台系统里面,添加两个页面,主要是用来生成二维码在页面上进行展示的,如下所示。
最终我们在NativePayPage.aspx页面上展示我们的二维码,方便用户进行扫码支付处理,页面的代码很简单,我们只需要在前端页面放置两个图片控件,图片内容通过MakeQRCode.aspx页面进行生成就可以了。
nbsp;html> <meta> <meta> <title>微信支付样例-扫码支付</title> <div>扫码支付模式一</div><br> <image></image> <br><br><br> <div>扫码支付模式二</div><br> <image></image>
页面后台的代码就是绑定二维码的过程,代码如下所示,和Winform的代码类似操作。
protected void Page_Load(object sender, EventArgs e) { TenPayApi api = new TenPayApi(); var productId = "123456789"; //生成扫码支付模式一url string url1 = api.GetPrePayUrl(productId); //生成扫码支付模式二url WxPayOrderData info = new WxPayOrderData() { product_id = "123456789", body = "测试支付-模式二", attach = "爱奇迪技术支持", detail = "测试扫码支付-模式二", total_fee = 1, goods_tag = "test1" }; string url2 = api.GetPayUrl(info); //将url生成二维码图片 Image1.ImageUrl = "MakeQRCode.aspx?data=" + HttpUtility.UrlEncode(url1); Image2.ImageUrl = "MakeQRCode.aspx?data=" + HttpUtility.UrlEncode(url2); }
实现后的页面效果如下所示。
实现并预览效果,确定是我们所需的页面后,我们可以发布在公众号的菜单连接上进行测试使用了。
打开微信公众号-广州爱奇迪,我们可以看到对应的菜单发生改变,并且看到进入微信支付的菜单可以进行支付了。
The above is an implementation of the QR code scanning process of WeChat Pay. WeChat Pay also includes many other API interfaces, as follows Opportunities can continue to be introduced. Although the interface implementation of WeChat payment is more complicated than other WeChat interfaces, once we complete a few cases, the rest will be relatively easy because its calling method is basically consistent and similar.
For more C# development WeChat portal and application WeChat payment access and API encapsulation and related articles, please pay attention to the PHP Chinese website!