转自:http://www.kwstu.com/ArticleView/netmvc_201511132005431321

最近开发手机app需要实现移动支付功能,由于考虑支付安全将支付宝生成签名写到了服务器端,官网给的demo是在客户端的,纠结了几天终于实现了。

注本教程不对支付宝申请,移动开发配置做解释,核心需要注意的地方就是在官方下载的demo中有生成私钥跟公钥的工具,公钥需要在商家管理后台跟支付宝做交换,这个很关键,笔者在调试的时候出现错误了,最后问支付宝官方客服要了这几个信息。

开发思路:下载支付宝移动支付demo,根据demo的代码重新写服务器端,然后将生成的签名信息替换demo里面参数测试服务器端的代码是否成功,然后在写服务器端的返回成功处理程序。

废话不多说了直接上代码吧

1、C#生成支付签名代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//第一步去支付宝付款,根据支付宝返回结果进行处理,如果成功需要生成会员记录、充值记录、广告位记录
                    //第一步开始
                    //支付类型
                    string payment_type = "1";
                    //必填,不能修改
                    //服务器异步通知页面路径
                    //string notify_url = "http://" + HttpContext.Request.Url.Host.ToString() + "/ZwOnLine/notifyUrl";
                    string notify_url = "http://api.kwstu.com/Pay/NotifyUrl";
                    //需http://格式的完整路径,不能加?id=123这类自定义参数
                    //页面跳转同步通知页面路径
                    //需http://格式的完整路径,不能加?id=123这类自定义参数,不能写成http://localhost/
                    //卖家支付宝帐户
                    string seller_id = "***";
                    //必填
                    //商户订单号
                    string out_trade_no = checkId;
                    //商户网站订单系统中唯一订单号,必填
                    //订单名称
                    string subject = unitBase.NAME + "[" + zphBase.ZPHNAME + "(" + zphZwService.ZWID + ")]";
                    //必填
                    //付款金额
                    //string total_fee = "0.1";
                    string total_fee = price;
                    //必填
                    //订单描述
                    string body = unitBase.NAME + "于" + DateTime.Now.ToString("yyyy-MM-dd") + "在线预订“" + zphBase.ZPHNAME + "”的" + zphZwService.ZWID + "号展位,缴费" + price + "元。";
                    //防钓鱼时间戳
                    //string anti_phishing_key = "";
                    //若要使用请调用类文件submit中的query_timestamp函数
                    //超时时间需要动态计算,并且减去2,如果超时时间小于2是否让继续支付。
                    TimeSpan time = DateTime.Now - Convert.ToDateTime(zphZwService.LOCKDATE);
                    int minTmp = 10 - ((int)time.TotalMinutes);
                    string minStr = "";
                    if (minTmp >= 2)
                        minStr = (minTmp - 1) + "m";
                    else if (minTmp <= 1)
                        return ClassesLib.ToJson(new
                        {
                            success = false,
                            msg = "操作失败,剩余支付时间不足,请重新选择展位!",
                            error_code = "400"
                        });
                    ////////////////////////////////////////////////////////////////////////////////////////////////
                    string signStr = "partner=\"" + Config.Partner + "\"&seller_id=\"****\"&out_trade_no=\"" + out_trade_no + "\"&subject=\"" + subject + "\"&body=\"" + body + "\"&total_fee=\"0.01\"&notify_url=\"" + notify_url + "\"&service=\"mobile.securitypay.pay\"&payment_type=\"1\"&_input_charset=\"utf-8\"&it_b_pay=\"30m\"&return_url=\"m.alipay.com\"";
                    string retrnStr = "partner=\"" + Config.Partner + "\"&seller_id=\"****\"&out_trade_no=\"" + out_trade_no + "\"&subject=\"" + subject + "\"&body=\"" + body + "\"&total_fee=\"0.01\"&notify_url=\"" + notify_url + "\"&service=\"mobile.securitypay.pay\"&payment_type=\"1\"&_input_charset=\"utf-8\"&it_b_pay=\"30m\"&return_url=\"m.alipay.com\"&sign=\"" + HttpUtility.UrlEncode(RSAFromPkcs8.sign(signStr, Config.Private_key, Config.Input_charset), System.Text.Encoding.UTF8) + "\"&sign_type=\"RSA\"";
客户端将returnStr直接提交的支付宝即可,修改demo中的如下代码进行调试,客户端可以不做账号信息配置,包名要注意
1
2
3
// 完整的符合支付宝参数规范的订单信息
        //final String payInfo= orderInfo + "&sign=\"" + sign + "\"&" + getSignType();
        final String payInfo="partner=\"*****\"&seller_id=\"*****\"&out_trade_no=\"ZFB_201511111751182080\"&subject=\"酷网网络工作室[2015-11-21(周六)综合人才招聘会(A012)]\"&body=\"酷网网络工作室于2015-11-11在线预订“2015-11-21(周六)综合人才招聘会”的A012号展位,缴费200元。\"&total_fee=\"0.01\"&notify_url=\"http://api.kwstu.com/Pay/NotifyUrl\"&service=\"mobile.securitypay.pay\"&payment_type=\"1\"&_input_charset=\"utf-8\"&it_b_pay=\"30m\"&return_url=\"m.alipay.com\"&sign=\"KbCV%2bHvHhGHuE%2fSxFjaXQJ9BP%2bY5m7bR9IxGKL7nk%2bz%2fxI%2fNALY21XEgAFOhGbzCTwer02FSKI2oadw9ChHYIhyC7f6o3vWl18k01o34hyrCexXfSP36ZkZ4k2V0ABaHGbrBLOPD73SewPtfxEfiJj88JJIDEbYI9CU%2bFhJWEHo%3d\"&sign_type=\"RSA\"";

将final String payInfo= orderInfo + "&sign=\"" + sign + "\"&" + getSignType();代码注释直接赋值returnStr的值即可

服务端支付成功处理代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/// <summary>
        /// 功能:服务器异步通知页面
        /// 版本:3.3
        /// 日期:2012-07-10
        /// 说明:
        /// 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
        /// 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
        ///
        /// ///////////////////页面功能说明///////////////////
        /// 创建该页面文件时,请留心该页面文件中无任何HTML代码及空格。
        /// 该页面不能在本机电脑测试,请到服务器上做测试。请确保外部可以访问该页面。
        /// 该页面调试工具请使用写文本函数logResult。
        /// 如果没有收到该页面返回的 success 信息,支付宝会在24小时内按一定的时间策略重发通知
        /// </summary>
        public ActionResult NotifyUrl()
        {
            SortedDictionary<string, string> sPara = GetRequestPost();
            ClassesLib.InsertLog("1(notifyUrl)");
            if (sPara.Count > 0)//判断是否有带返回参数
            {
                ClassesLib.InsertLog("2(notifyUrl)");
                Notify aliNotify = new Notify();
                bool verifyResult = aliNotify.Verify(sPara, Request.Form["notify_id"], Request.Form["sign"]);
                ClassesLib.InsertLog("--" + "notify_id:" + Request.Form["notify_id"] + "--" + "sign:" + Request.Form["sign"]);
                //——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
                //获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表
                //商户订单号                string out_trade_no = Request.Form["out_trade_no"];
                string out_trade_no = Request.Form["out_trade_no"];
                ClassesLib.InsertLog("--" + "out_trade_no:" + Request.Form["out_trade_no"]);
                //支付宝交易号                string trade_no = Request.Form["trade_no"];
                string trade_no = Request.Form["trade_no"];
                ClassesLib.InsertLog("--" + "trade_no:" + Request.Form["trade_no"]);
                //交易状态
                string trade_status = Request.Form["trade_status"];
                ClassesLib.InsertLog("--" + "trade_status:" + Request.Form["trade_status"]);
                if (verifyResult)//验证成功
                {
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //请在这里加上商户的业务逻辑程序代码
                    if (Request.Form["trade_status"] == "TRADE_FINISHED")
                    {
                        ClassesLib.InsertLog(out_trade_no + "订单状态正常(notifyUrl)");
                        //判断该笔订单是否在商户网站中已经做过处理
                        //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                        //如果有做过处理,不执行商户的业务程序
                        //注意:
                        //该种交易状态只在两种情况下出现
                        //1、开通了普通即时到账,买家付款成功后。
                        //2、开通了高级即时到账,从该笔交易成功时间算起,过了签约时的可退款时限(如:三个月以内可退款、一年以内可退款等)后。
                        
                    }
                    else if (Request.Form["trade_status"] == "TRADE_SUCCESS")
                    {
                        ClassesLib.InsertLog(out_trade_no + "订单状态正常(notifyUrl)");
                        //判断该笔订单是否在商户网站中已经做过处理
                        //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                        //如果有做过处理,不执行商户的业务程序
                        //注意:
                        //该种交易状态只在一种情况下出现——开通了高级即时到账,买家付款成功后。
                         
                             
                    }
                    else
                    {
                        ClassesLib.InsertLog(out_trade_no + "状态错误(notifyUrl)");
                        return Content("trade_status=" + Request.QueryString["trade_status"]);
                    }
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                }
                else//验证失败
                {
                    ClassesLib.InsertLog(out_trade_no + "验证失败(notifyUrl)");
                    return Content("验证失败");
                }
            }
            else
            {
                ClassesLib.InsertLog("无返回参数(notifyUrl)");
                return Content("无返回参数");
            }
        }

开发资料获取地址:https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-8489738063.2.VrK9RN&id=524269482340

支付宝移动支付开发详细教程服务端采用.net mvc webapi(C#)的更多相关文章

  1. 微信移动支付V3开发详细教程服务端采用.net mvc webapi(C#)

    转自:http://www.kwstu.com/ArticleView/netmvc_201511132050268716 最近开发手机app需要实现移动支付功能,由于考虑支付安全将微信支付生成签名写 ...

  2. 适合新手:从零开发一个IM服务端(基于Netty,有完整源码)

    本文由“yuanrw”分享,博客:juejin.im/user/5cefab8451882510eb758606,收录时内容有改动和修订. 0.引言 站长提示:本文适合IM新手阅读,但最好有一定的网络 ...

  3. ubuntu下安装 gSOAP 用于C/C++开发web service服务端与客户端

    昨天在ubuntu下进行安装gSOAP,费了很多时间,没成功,今天又来找了大量教程资料,终于一次成功,这里写下自己的安装步骤和方法,供大家参考. 首先下载gsoap,我下载的是gsoap-2.8.1. ...

  4. 转: 基于netty+ protobuf +spring + hibernate + jgroups开发的游戏服务端

    from: http://ybak.iteye.com/blog/1853335 基于netty+ protobuf +spring + hibernate + jgroups开发的游戏服务端 游戏服 ...

  5. 网络编程之TCP客户端开发和TCP服务端开发

    开发 TCP 客户端程序开发步骤 创建客户端套接字对象 和服务端套接字建立连接 发送数据 接收数据 关闭客户端套接字 import socket if __name__ == '__main__': ...

  6. 移动APP 支付宝快捷支付开发流程

    [代码] [Java]代码 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ...

  7. 二、网络编程-socket之TCP协议开发客户端和服务端通信

    知识点:之前讲的udp协议传输数据是不安全的,不可靠不稳定的,tcp协议传输数据安全可靠,因为它们的通讯机制是不一样的.udp是用户数据报传输,也就是直接丢一个数据包给另外一个程序,就好比寄信给别人, ...

  8. Linux下用gSOAP开发Web Service服务端和客户端程序

    网上本有一篇流传甚广的C版本的,我参考来实现,发现有不少问题,现在根据自己的开发经验将其修改,使用无误:另外,补充同样功能的C++版本,我想这个应该更有用,因为能用C++,当然好过受限于C. 1.gS ...

  9. Linux下用gSOAP开发Web Service服务端和客户端程序(一)

    1.功能说明: 要开发的Web Service功能非常简单,就是一个add函数,将两个参数相加,返回其和. 2.C版本的程序: (1)头文件:SmsWBS.h,注释部分不可少,url部分的IP必须填写 ...

随机推荐

  1. .net设计模式之装饰模式

    概述: 装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象. 装饰模式的特点: (1) 装饰对象和真实对象有相同的接口.这样 ...

  2. 【百度地图API】如何激发手机的高分辨率

    原文:[百度地图API]如何激发手机的高分辨率 摘要:不少用户使用百度地图API开发在移动浏览器上的应用时发现,明明自己的手机是高分辨率的,但是显示出来的地图却比较模糊,甚至“看不清楚”.接下来,我们 ...

  3. 编程算法 - 切割排序 代码(C)

    切割排序 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 排序切割, 把一个数组分为, 大于k\小于k\等于k的三个部分. 能够使用高速排序的Parti ...

  4. JS开发调试

    开发调试工具   页面制作之开发调试工具(1) 开发工具介绍 开发工具一般分为两种类型:文本编辑器和集成开发环境(IDE) 常用的文本编辑器:Sublime Text.Notepad++.EditPl ...

  5. ar命令提取.a时刻,一个错误 is a fat file (use libtool(1) or lipo(1) and ar(1) on it)

    在减压.a当文件,据报一个类别似 xxx.a is a fat file (use libtool(1) or lipo(1) and ar(1) on it)的错误,经过查找资料,原来是由于该.a文 ...

  6. easyui 小知识

    默认为今天 $(document).ready(function () {        $(function () {            var curr_time = new Date();  ...

  7. easyui datagrid load 封装 参数问题 js 作用域

    var temp = { LoginAccount: $('#LoginAccount').val(), ShopName: $('#ShopName').val() }; function doSe ...

  8. kprobe 内核模块

    代码来自于linux内核sample/kprobe kprobe_example.c /* * NOTE: This example is works on x86 and powerpc. * He ...

  9. Android SDK 2.2 离线安装

    android的普通安装方法非常easy,不必多说. 因为普通安装方法速度非常慢,对一般的用户要数小时的时间等待. 为更高速安装,能够採取离线安装方法.即,先分别下载所需包,再安装. 一,首先下载SD ...

  10. PHP程序猿必备的七种武器

    作为一个程序猿(又或者是程序媛),出来闯荡江湖,没有几种必杀技在手,那是肯定无法赢得江湖名声的,除了必杀技之外,武器也是很重要的,但是一把青钢剑,肯定是无法赢得万千少男少女的欢心的.就连小李飞刀,人家 ...