银联支付服务之公众号支付业务(二)

上一节已经介绍了银联的公众号支付业务,以及如何注册成为开发者,这一节将创建一个控制台应用程序调启微信支付并成功付款。

一、请求协议

HTTP(S)

HTTP方法:GET

二、接口地址

测试环境:http://58.247.0.18:29015/v1/netpay/webpay/pay

生产环境:https://api-mop.chinaums.com/v1/netpay/webpay/pay

三、参数

3.1URL参数

参数名称参数说明参数类型长度是否必须备注
authorization认证方式string 值为OPEN-FORM-PARAM
appIdAppIdstring<=32 
timestamp时间戳string14yyyyMMddHHmmss
nonce随机数string<=128 
content业务内容string  
signature签名string 

Base64_Encode(HmacSHA256

(appId + timestamp + nonce +

SHA256_HEX(content), AppKey))

3.2业务内容主体(只列出必填与部分主要参数,详细参数请参考官方文档)

格式:JSON

参数名称参数说明参数类型长度是否必须备注
msgId消息IDstring<=64原样返回
requestTimestamp报文请求时 间string 格式yyyy-MM-dd HH:mm:ss
merOrderId商户订单号string 商户自行生成(下面详细介绍)
mid商户号string15 
tid终端号string8 
instMid业务类型string YUEDANDEFAULT
totalAmount支付总金额 1..100000000 
notifyUrl支付结果通知地址string(url)  
returnUrl网页跳转地址string(url)  

四、参数准备

4.1appId、商户号、终端号、来源编码获取

注册成为开发者后可以获取到这几个参数,注册开发者请回顾上一节

4.2订单号规则与生成

以银商分配的4位来源编号作为账单号的前4位,且在商户系统中此账单号保证唯一。总长 度需大于6位,小于28位。银商的推荐规则为(无特殊情况下,建议遵守此规则):{来源编号(4位)}{时间(yyyyMMddmmHHssSSS)(17位)}{7位随机数}

public static string getMerOrderId(string number)//number即来源编号,一般为1017
        {
            string time = DateTime.Now.ToString("yyyyMMddHHmmssSSS");
            System.Random Random = new System.Random();
            int Result = Random.Next(1000000, 9999999);//7位随机数

            return number += time += Result;
        }

4.3 生成签名

Base64_Encode(HmacSHA256(appId + timestamp + nonce + SHA256_HEX(content), AppKey))

private static string createSignature(string appid, string timestamp, string nonce, string body, string appkey)
        {
            string signature = "";
            SHA256 sha256 = new SHA256CryptoServiceProvider();
            byte[] retVal = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(body));
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < retVal.Length; i++)
            {
                sb.Append(retVal[i].ToString("x2"));
            }
            Console.WriteLine("SHA256:" + sb.ToString());
            var encoding = new System.Text.UTF8Encoding();
            byte[] keyByte = encoding.GetBytes(appkey);
            byte[] messageBytes = encoding.GetBytes(appid + timestamp + nonce + sb.ToString());
            using (var hmacsha256 = new HMACSHA256(keyByte))
            {
                byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
                signature = Convert.ToBase64String(hashmessage);
            }
            return signature;
        }

4.4业务内容主体

业务主体格式为JSON字符串,示例代码为C#,我们通过引入Newtonsoft库来构建一个JSON对象,后面再转成字符串即可。

JObject jobject = new JObject();
            jobject.Add("requestTimestamp", timestamp);    // 报文请求时间
            jobject.Add("merOrderId", merOrderId); // 商户订单号
            jobject.Add("srcReserve", "qqyl"); // 请求系统预留字段
            jobject.Add("mid", "898340149000005"); // 商户号
            jobject.Add("tid", "88880001");    // 终端号
            jobject.Add("instMid", "YUEDANDEFAULT"); // 业务类型
            jobject.Add("attachedData", "fjsj"); //商户附加数据
            jobject.Add("orderDesc", "zdms");  // 账单描述
            jobject.Add("totalAmount", 1);      // 支付总金额
            jobject.Add("notifyUrl", "https://www.sina.com.cn");  // 支付结果通知地址
            jobject.Add("returnUrl", "http://www.baidu.com");  // 网页跳转地址
            string body = jobject.ToString();

一切准备就绪,下面是完整代码

        /// <summary>
        /// 前台支付
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            string payUrl = "http://58.247.0.18:29015/v1/netpay/webpay/pay";//测试地址
            string appid = "10037e6f66f2d0f901672aa27d69XXXX";
            string appkey = "47ace12ae3b348fe93ab46cee97cXXXX";
            string timestamp = DateTime.Now.ToString("yyyyMMddHHmmss");
            string merOrderId = getMerOrderId("1017");
            string nonce = Guid.NewGuid().ToString().Replace("-","");
            JObject jobject = new JObject();
            jobject.Add("requestTimestamp", timestamp);    // 报文请求时间
            jobject.Add("merOrderId", merOrderId); // 商户订单号
            jobject.Add("srcReserve", "qqyl"); // 请求系统预留字段
            jobject.Add("mid", "898340149000005"); // 商户号
            jobject.Add("tid", "88880001");    // 终端号
            jobject.Add("instMid", "YUEDANDEFAULT"); // 业务类型
            jobject.Add("attachedData", "fjsj"); //商户附加数据
            jobject.Add("orderDesc", "zdms");  // 账单描述
            jobject.Add("totalAmount", 1);      // 支付总金额,单位:分,也就是支付0.01元
            jobject.Add("notifyUrl", "https://www.sina.com.cn");  // 支付结果通知地址
            jobject.Add("returnUrl", "http://www.baidu.com");  // 网页跳转地址
            string body = jobject.ToString();
            string signature = createSignature(appid, timestamp, nonce, body, appkey);
            string connection = "Data Source=.;Initial Catalog=JwsoftBsFrame_20200606;Integrated Security=True;";
            using (SqlConnection conn = new SqlConnection(connection))
            {
                conn.Open();
                string sql = $"INSERT INTO A0_TestPay(requestTimestamp,appid,merOrderId ) VALUES ({timestamp},'{appid}',{merOrderId})";
                using (SqlCommand cmd = new SqlCommand(sql, conn))
                {
                    cmd.ExecuteNonQuery();
                }
            }
            //url即我们需要的最终结果,复制url到微信打开就能调起微信支付
            string url = payUrl + "?authorization=OPEN-FORM-PARAM&appId=" + appid
                + "&timestamp=" + timestamp
                + "&nonce=" + nonce
                + "&content=" + HttpUtility.UrlEncode(body, Encoding.UTF8) + "&signature=" + HttpUtility.UrlEncode(signature, Encoding.UTF8);
            Console.WriteLine(url);
            Console.ReadKey();
        }
        /// <summary>
        /// 生成订单号
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static string getMerOrderId(string number)
        {
            string time = DateTime.Now.ToString("yyyyMMddHHmmss");
            System.Random Random = new System.Random();
            int Result = Random.Next(1000000, 9999999);

            return number += time += Result;
        }
        /// <summary>
        /// 生成签名
        /// </summary>
        /// <param name="appid"></param>
        /// <param name="timestamp"></param>
        /// <param name="nonce"></param>
        /// <param name="body"></param>
        /// <param name="appkey"></param>
        /// <returns></returns>
        private static string createSignature(string appid, string timestamp, string nonce, string body, string appkey)
        {
            string signature = "";
            //先计算出 body 的 sha256加密
            SHA256 sha256 = new SHA256CryptoServiceProvider();
            byte[] retVal = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(body));
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < retVal.Length; i++)
            {
                sb.Append(retVal[i].ToString("x2"));
            }
            Console.WriteLine("SHA256:" + sb.ToString());

            //在结合起来
            var encoding = new System.Text.UTF8Encoding();
            byte[] keyByte = encoding.GetBytes(appkey);
            byte[] messageBytes = encoding.GetBytes(appid + timestamp + nonce + sb.ToString());
            using (var hmacsha256 = new HMACSHA256(keyByte))
            {
                byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
                signature = Convert.ToBase64String(hashmessage);
            }
            return signature;
        }

 

string url = payUrl + "?authorization=OPEN-FORM-PARAM&appId=" + appid
                + "&timestamp=" + timestamp
                + "&nonce=" + nonce
                + "&content=" + HttpUtility.UrlEncode(body, Encoding.UTF8) + "&signature=" + HttpUtility.UrlEncode(signature, Encoding.UTF8);

示例:

http://58.247.0.18:29015/v1/netpay/webpay/pay?authorization=OPEN-FORM-PARAM&appId=10037e6f66f2d0f901672aa27d690006&timestamp=20200831215653&nonce=c31e0e0e47bf49f3968dd73e510be52e&content=%7b%0d%0a++%22requestTimestamp%22%3a+%2220200831215653%22%2c%0d%0a++%22merOrderId%22%3a+%221017202008312156533441158%22%2c%0d%0a++%22srcReserve%22%3a+%22qqyl%22%2c%0d%0a++%22mid%22%3a+%22898340149000005%22%2c%0d%0a++%22tid%22%3a+%2288880001%22%2c%0d%0a++%22instMid%22%3a+%22YUEDANDEFAULT%22%2c%0d%0a++%22attachedData%22%3a+%22fjsj%22%2c%0d%0a++%22orderDesc%22%3a+%22zdms%22%2c%0d%0a++%22totalAmount%22%3a+1%2c%0d%0a++%22notifyUrl%22%3a+%22https%3a%2f%2fwww.sina.com.cn%22%2c%0d%0a++%22returnUrl%22%3a+%22http%3a%2f%2fwww.baidu.com%22%0d%0a%7d&signature=pghTBBzie2qMewmy4FvZuvsLJV%2bqdC%2bhZhTm6T53r%2bE%3d

url即我们需要的最终结果,复制url到微信打开就能调起微信支付。实际业务中,我们只需要构建好好这个url微信中跳转就好。

五、调起微信支付

 

  1. 将程序构建好的url复制到微信中打开,点击访问
  2. 成功调起微信支付后,就是熟悉的付款操作了
  3. jobject.Add("totalAmount", 1);      // 支付总金额,单位:分,也就是支付0.01元
  4. jobject.Add("returnUrl", "http://www.baidu.com");  // 支付成功后网页跳转地址
  5. 如果检查程序没问题,但是点击链接,没有响应的话,可能是测试接口不稳定造成了,请在工作时间内进行测试调用。不是上班时间,估计银联那边把所有访问都拒绝了。

下一节,我们将继续讲解支付结果查询和退款查询的接口调用,我们测试支付的钱可以通过退款接口进行退回的。 

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值