转自: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. java_tomcat_Server at localhost was unable to start within 45 seconds 小喵咪死活启动报错-二

    错误:Server Tomcat v6.0 Server at localhost was unable to start within 45 seconds 错误提示就是我们限定了部署的时间导致的错 ...

  2. Java数据库编程、XML解析技术

    数据库编程 JDBC概述 是Java Database Connecive,即数据库连接技术的简称,它提供了连接各种常用数据库的能力. 是一种用于执行SQL语句的Java API,可以为多种关系数据库 ...

  3. mysql很全的和完整的总结

    (1)数据类型 类型 备注 tinyint/smallint/mediumint/int/bigint 1B/2B/3B/4B/8B float/double 单精度/双精度浮点型 decimal 不 ...

  4. PHP实例——输出安全的HTML代码

    原文:PHP实例--输出安全的HTML代码 //输出安全的htmlfunction h($text, $tags = null){ $text = trim($text); //完全过滤注释 $tex ...

  5. android 使用asm.jar将android手机屏幕投射到电脑

    使用asm.jar将Android手机到电脑屏幕投影 有时候可能须要将手机上的一些操作投影出来,比方一些App Demo的展示等.事实上,有专门的硬件设备能干这件事儿.但不是必需专门为展示个Demo去 ...

  6. ResultSet取结果集多少条记录方法及分页概要

    allst=toconn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); allsql = ...

  7. js对象字面量

    在编程语言中,字面量是一种表示值的记法.例如,"Hello, World!" 在许多语言中都表示一个字符串字面量(string literal ),JavaScript也不例外.以 ...

  8. leetcode 第41题 Trapping Rain Water

    题目: Given n non-negative integers representing an elevation map where the width of each bar is 1, co ...

  9. &lt;图形图像,动画,多媒体&gt; 读书笔记 --- 力学行为特性

    UIKit力学行为包括了:重力(UIGravityBehavior),碰撞(UICollisionBehavior),吸附(UIAttachmentBehavior),推(UIPushBehavior ...

  10. 屏幕录制H.264视频,AAC音频,MP4复,LibRTMP现场活动

    上周完成了一个屏幕录制节目,实时屏幕捕获.记录,视频H.264压缩,音频应用AAC压缩,复用MP4格公式,这使得计算机和ios设备上直接播放.支持HTML5的播放器都能够放,这是标准格式的优点.抓屏也 ...