开篇先给大家讲段历史故事,博主是湖北襄阳人。襄阳物华天宝,人杰地灵,曾用名襄樊。在2800多年的历史文化中出现了一代名相诸葛亮(卧龙),三国名士庞统(凤雏),魏晋隐士司马徽(水镜先生),唐代大诗人孟浩然(孟襄阳),张继、杜审言,文学家皮日休,北宋著名书画家米芾(米襄阳),“允冠百王”的光武帝刘秀,东方圣人释道安等一大批历史文化名人。小说《三国演义》120回故事中有30多回提到襄阳。

相传诸葛亮的老婆黄月英黄头发黑皮肤,但知识广博。诸葛亮发明木牛流马,就是从黄月英的传授的技巧上发展出来。不仅如此黄月英还有一大很重要的发明,就是大头菜,传承多年到现在已经成为湖北襄阳的一道特产,也是一项重要的饮食文化,早几年有关部门根据诸葛孔明的赫赫大名为大头菜取了个比较国际化的名字:孔明菜(广告语:吃孔明菜,谋天下事!)。

正是因为孔明菜响亮的声誉美名,近几年家乡的孔明菜事业繁荣发展,畅销五大洲,海内外。为了更好的打造国外市场,博主有幸得令,成为襄阳市孔明菜国际互联网电子商务平台打造任务的一分子,负责对接国际支付接口Paypal。

以上故事只为引题,部分虚构,如有雷同,不胜荣幸。如果你正在或将来打算赚赚老外的钱,那就跟着博主的节奏一起来国际化吧!

怎么对接Paypal支付呢?博主选择了其中的一种对接方式即(快速结账),也是当前的主流对接方式,具体步骤和详细参见官方介绍:https://www.paypal-biz.com/developer/internet/ec/,博主友情提示,操作步骤需要遵循,至于每个步骤的文档可以粗略的看看。

因为博主一出道就从MVC干起,传统的webForm先天性驾驭不了,也没那闲时间去回头学习,官方提供的源码下载下来一直未调通(如有大神调通,望不吝赐教!)。所以博主潜心研究,取其技术精髓,整合出了一个MVC3版本下的demo供各位看官参考。

MVC对接Paypal怎么做呢?我们需要如下准备材料:

  1. 在Paypal官方注册个高级帐号:https://www.paypal.com/c2/webapps/mpp/get-started然后在开发者中心里面去创建至少一个卖家和一个买家帐号(供您在上线之前做测试用,官方称之为Sandbox帐号,同可以理解为测试环境帐号):https://developer.paypal.com/webapps/developer/applications/accounts,如下图,红色代表卖家帐号,绿色代表买家帐号
  2. 在项目中加入官方dll文件,引用Paypal类库paypal_base.dll和log4net.dll,已在源码中附加。
  3. 获取卖家帐号API配置项,(配置项的关键需要从您创建的某个卖家帐号中获取,获取方式如下图):
  4. 配置卖家帐号API到您的网站:
    1. <!--Paypal支付账号配置-->
    2. <add key="APIUserName" value="wen_api1.shipfinder.cn"/>
    3. <add key="APIPassword" value=""/>
    4. <add key="APISinature" value="An5ns1Kso7MWUdW4ErQKJJJ4qi4-AKqBVNoNVjFOrjJUxaTCiRAvn7V4"/>
    5. <add key="Environment" value="sandbox"/>
    6. <!--测试环境:https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token= -->
    7. <!--真实环境:https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token= -->
    8. <add key="RedirectURL" value="https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&amp;token="/>
  5. SetExpressCheckout (向paypal提交订单,自己的网站做订单入库操作)核心代码如下:
    1. public ActionResult SetExpressCheckout() {
    2. string currency = Request.Form["currencyCodeType"];
    3. string name = Request.Form["NAME"];
    4. string SHIPTOSTREET = Request.Form["SHIPTOSTREET"];
    5. string SHIPTOCITY = Request.Form["SHIPTOCITY"];
    6. string SHIPTOSTATE = Request.Form["SHIPTOSTATE"];
    7. string SHIPTOCOUNTRYCODE = Request.Form["SHIPTOCOUNTRYCODE"];
    8. string SHIPTOZIP = Request.Form["SHIPTOZIP"];
    9. string L_NAME1 = Request.Form["L_NAME1"];
    10. string L_AMT1 = Request.Form["L_AMT1"];
    11. string L_QTY1 = Request.Form["L_QTY1"];
    12. string L_NAME0 = Request.Form["L_NAME0"];
    13. string L_AMT0 = Request.Form["L_AMT0"];
    14. string L_QTY0 = Request.Form["L_QTY0"];
    15.  
    16. string hots = Request.Url.Scheme + "://" + Request.Url.Host + ":" + Request.Url.Port + "/";
    17.  
    18. NVPCodec encoder = new NVPCodec();
    19. encoder.Add("PAYMENTACTION", "Sale");
    20.  
    21. //不允许客户改地址
    22. encoder.Add("ADDROVERRIDE", "");
    23. encoder.Add("CANCELURL", hots + "/Pay/Index");
    24. encoder.Add("CURRENCYCODE", currency);
    25. encoder.Add("SHIPTONAME", name);
    26. encoder.Add("SHIPTOSTREET", SHIPTOSTREET);
    27. encoder.Add("SHIPTOCITY", SHIPTOCITY);
    28. encoder.Add("SHIPTOSTATE", SHIPTOSTATE);
    29. encoder.Add("SHIPTOCOUNTRYCODE", SHIPTOCOUNTRYCODE);
    30. encoder.Add("SHIPTOZIP", SHIPTOZIP);
    31. encoder.Add("L_NAME0", L_NAME0);
    32. encoder.Add("L_NUMBER0", "");
    33. encoder.Add("L_DESC0", "Size: 8.8-oz");
    34. encoder.Add("L_AMT0", L_AMT0);
    35. encoder.Add("L_QTY0", L_QTY0);
    36. encoder.Add("L_NAME1", L_NAME1);
    37. encoder.Add("L_NUMBER1", "");
    38. encoder.Add("L_DESC1", "Size: Two 24-piece boxes");
    39. encoder.Add("L_AMT1", L_AMT1);
    40. encoder.Add("L_QTY1", L_QTY1);
    41. encoder.Add("L_ITEMWEIGHTVALUE1", "0.5");
    42. encoder.Add("L_ITEMWEIGHTUNIT1", "lbs");
    43.  
    44. double ft = double.Parse(L_QTY0) * double.Parse(L_AMT0) + double.Parse(L_QTY1) * double.Parse(L_AMT1);
    45. encoder.Add("ITEMAMT", ft.ToString());
    46. encoder.Add("TAXAMT", "2.00");
    47.  
    48. double amt = System.Math.Round(ft + 5.00f + 2.00f + 1.00f, );
    49. double maxamt = System.Math.Round(amt + 25.00f, );
    50.  
    51. encoder.Add("SHIPDISCAMT","-3.00");
    52. encoder.Add("AMT",amt.ToString());
    53.  
    54. string returnURL = hots + "/Pay/GetExpressCheckoutDetails?amount="+amt.ToString();//获取订单详情的地址,也是此步骤之后的地址
    55.  
    56. encoder.Add("RETURNURL",returnURL);
    57. encoder.Add("SHIPPINGAMT", "8.00");
    58. encoder.Add("MAXAMT", maxamt.ToString());
    59.  
    60. encoder.Add("INSURANCEOPTIONOFFERED", "true");
    61. encoder.Add("INSURANCEAMT", "1.00");
    62.  
    63. encoder.Add("LOCALECODE", "US");
    64.  
    65. encoder.Add("NOSHIPPING", "");
    66.  
    67. encoder.Add("L_SHIPPINGOPTIONISDEFAULT0", "false");
    68. encoder.Add("L_SHIPPINGOPTIONNAME0", "Ground");
    69. encoder.Add("L_SHIPPINGOPTIONLABEL0", "UPS Ground 7 Days");
    70. encoder.Add("L_SHIPPINGOPTIONAMOUNT0", "3.00");
    71. encoder.Add("L_SHIPPINGOPTIONISDEFAULT1", "true");
    72. encoder.Add("L_SHIPPINGOPTIONNAME1", "UPS Air");
    73. encoder.Add("L_SHIPPINGOPTIONlABEL1", "UPS Next Day Air");
    74. encoder.Add("L_SHIPPINGOPTIONAMOUNT1", "8.00");
    75.  
    76. encoder.Add("CALLBACKTIMEOUT", "");
    77.  
    78. NVPCodec decoder = PaypalProvider.SetExpressCheckout(encoder);
    79.  
    80. string ack = decoder["ACK"];
    81. string L_ERRORCODE0 = decoder["L_ERRORCODE0"];
    82. string L_SHORTMESSAGE0 = decoder["L_SHORTMESSAGE0"];
    83. string L_LONGMESSAGE0 = decoder["L_LONGMESSAGE0"];
    84. string L_SEVERITYCODE0 = decoder["L_SEVERITYCODE0"];
    85.  
    86. if (!string.IsNullOrEmpty(ack) &&
    87. (ack.Equals("Success", System.StringComparison.OrdinalIgnoreCase) || ack.Equals("SuccessWithWarning", System.StringComparison.OrdinalIgnoreCase))
    88. )
    89. {
    90. // 发送电子邮件
    91. //new MailManager(email, "订单", "订单信息").Send();
    92. Session["TOKEN"] = decoder["token"];
    93. return Redirect(ConfigurationManager.AppSettings["RedirectURL"] + decoder["token"]);
    94.  
    95. }
    96. else
    97. {
    98. return Redirect("/Pay/Index");
    99. }
    100. }
  6. GetExpressCheckoutDetails (根据提交订单后返回的Token,获取当前订单详情 ),核心代码如下:
    1. //得到支付详细信息
    2. string token = Session["TOKEN"].ToString();
    3. NVPCodec nvp = new NVPCodec();
    4. nvp.Add("TOKEN", token);
    5. nvp.Add("CURRENCYCODE", "USD");
    6.  
    7. NVPCodec responsenvp = PaypalProvider.GetExpressCheckoutDetails(nvp);
    8. string ack = responsenvp["ACK"];
    9.  
    10. if (string.IsNullOrEmpty(ack) ||
    11. (
    12. !ack.Equals("Success", System.StringComparison.OrdinalIgnoreCase) &&
    13. !ack.Equals("SuccessWithWarning", System.StringComparison.OrdinalIgnoreCase))
    14. )
    15. {
    16.  
    17. return Redirect("/Pay/Index");
    18. }
    19. string payerstatus = responsenvp["PAYERSTATUS"];
    20. string email = responsenvp["EMAIL"];
    21. string payerid = responsenvp["PAYERID"];
    22. string firstname = responsenvp["FIRSTNAME"];
    23. string lastname = responsenvp["LASTNAME"];
  7. DoExpressCheckoutPayment(根据订单详情进行验证并支付,然后自己的网站更新支付状态,订单状态),核心代码如下:
    1. //开始支付
    2.  
    3. NVPCodec donvp = new NVPCodec();
    4. donvp.Add("TOKEN", token);
    5. donvp.Add("AMT", amount);
    6. donvp.Add("PAYERID", payerid);
    7. donvp.Add("PAYMENTACTION", "Sale");
    8. donvp.Add("CURRENCYCODE", "USD");
    9.  
    10. NVPCodec response_do = PaypalProvider.DoExpressCheckoutPayment(donvp);
    11. string do_ack = response_do["ACK"];
    12.  
    13. string L_ERRORCODE0 = response_do["L_ERRORCODE0"];
    14. string L_SHORTMESSAGE0 = response_do["L_SHORTMESSAGE0"];
    15. string L_LONGMESSAGE0 = response_do["L_LONGMESSAGE0"];
    16. string L_SEVERITYCODE0 = response_do["L_SEVERITYCODE0"];
    17. if (string.IsNullOrEmpty(do_ack) ||
    18. (
    19. !do_ack.Equals("Success", System.StringComparison.OrdinalIgnoreCase) &&
    20. !do_ack.Equals("SuccessWithWarning", System.StringComparison.OrdinalIgnoreCase))
    21. )
    22. {
    23. return Redirect("/Pay/Index");
    24. }
    25. else {
    26.  
    27. string paymenttype = response_do["PAYMENTTYPE"];
    28. string transactionID = response_do["TRANSACTIONID"];
    29. string note = response_do["NOTE"];
    30. string ordertime = response_do["ORDERTIME"];
    31. string paymentstatus = response_do["PAYMENTSTATUS"];
    32. string reason=response_do["PENDINGREASON"];
    33. double feeamt = double.Parse(response_do["FEEAMT"]);
    34. return Content("恭喜您支付成功!");
    35. }
  8. 真正的核心就是5、6、7步骤,用Paypal技术人员熟练的口气说就是Set,Get,Do,最后一步成功后就是处理我们网站业务逻辑的过程。博主这里提供个买家帐号供大家测试(帐号:a@bc.cn,密码:11111111),下面附上demo运行效果:




源码下载地址

感谢阅读,如果您觉得此文对你有用,不要吝啬右边的推荐哦,大家的支持是我分享智慧的动力,后面的文章打算聊聊如何对接支付宝,有兴趣可以通过关注本博客或我的微博动态!

正在看本人博客的这位童鞋,我看你气度不凡,谈吐间隐隐有王者之气,日后必有一番作为!旁边有“推荐”二字,你就顺手把它点了吧,相得准,我分文不收;相不准,你也好回来找我!

【网站国际化必备】Asp.Net MVC 集成Paypal(贝宝)快速结账 支付接口 ,附源码demo的更多相关文章

  1. Python3+Django2集成PayPal(贝宝)跨境支付三方接口以及订单查询和退款业务

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_157 如果您所在的公司涉及外贸或者跨境支付业务,那一定听说过大名鼎鼎的PayPal,总的来说,PayPal在跨国贸易里的优势还是比 ...

  2. asp.net mvc 之旅 —— 第六站 ActionFilter的应用及源码分析

    这篇文章我们开始看一下ActionFilter,从名字上其实就大概知道ActionFilter就是Action上的Filter,对吧,那么Action上的Filter大概有几个呢??? 这个问题其实还 ...

  3. arcgis api 4.x for js 集成 Echarts4 实现模拟迁徙图效果(附源码下载)

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 4.x for js:esri 官网 api,里面详细的介绍 arcgis api 4.x 各个类 ...

  4. SpringBoot 集成 FreeMarker 导出 Word 模板文件(底部附源码)

    思路解说 word 模板文件(doc 或 docx 文件)另存为 xml 文件 将后缀 xml 改成 html:大部分文档会改成 ftl(FreeMarker 的后缀名),因为 word 文件另存为 ...

  5. PayPal贝宝集成

    今天在集成PayPal贝宝在线支付功能时,遇到了一些小挫折,费了不少功夫才最终解决(贝宝的技术支持确实让我很想吐槽).现在记录下来,供后来者参考.根据集成说明文档,我们写的测试demo如下: < ...

  6. Asp.net MVC集成Google Calendar API(附Demo源码)

    Asp.net MVC集成Google Calendar API(附Demo源码) Google Calendar是非常方便的日程管理应用,很多人都非常熟悉.Google的应用在国内不稳定,但是在国外 ...

  7. ASP.NET MVC Filters 4种默认过滤器的使用【附示例】 数据库常见死锁原因及处理 .NET源码中的链表 多线程下C#如何保证线程安全? .net实现支付宝在线支付 彻头彻尾理解单例模式与多线程 App.Config详解及读写操作 判断客户端是iOS还是Android,判断是不是在微信浏览器打开

    ASP.NET MVC Filters 4种默认过滤器的使用[附示例]   过滤器(Filters)的出现使得我们可以在ASP.NET MVC程序里更好的控制浏览器请求过来的URL,不是每个请求都会响 ...

  8. [转]ASP.NET MVC 5 学习教程:快速入门

    本教程将使用Visual Studio 2013手把手教你构建一个入门的ASP.NET MVC5 Web应用程序.本教程配套的C#源码工程可通过如下网址下载:C#版本源码链接.同时,请查阅 Build ...

  9. C#/ASP.NET MVC微信公众号接口开发之从零开发(三)回复消息 (附源码)

    C#/ASP.NET MVC微信接口开发文章目录: 1.C#/ASP.NET MVC微信公众号接口开发之从零开发(一) 接入微信公众平台 2.C#/ASP.NET MVC微信公众号接口开发之从零开发( ...

随机推荐

  1. TCP/IP协议和HTTP协议 浩哥指教

    TCP和IP在HTTP协议的上层,HTTP算是应用层,IP协议建立的是电脑跟电脑之间的联系,具体过程是,物理上,通过网线,解析MAC地址,到达路由,路由告诉数据将要去哪里,对方电脑通过NDS解析,解析 ...

  2. 一个暂时无法理解的bug

    BUG bug的存在是不可避免的 一个静态变量,改成绝对地址之后可以生成静态页面.但是主页有一个用了静态变量的超链接就不能用, 最后我加了一个相对地址的静态变量,可以解决这个问题.

  3. vi

    e! 放弃所有修改,从上次保存文件开始再编辑 shift+g 最后一行 gg 第一行 u 恢复上一次操作 如果查找下一个,按"n"即可. set nu 显示行号 编辑模式下111g ...

  4. 新版Xcode无法新建iOS空项目解决方案

    --感谢同学分享-- 操作说明: 拷贝Empty Application.xctemplate文件夹至   /Contents/Developer/Platforms/iPhoneOS.platfor ...

  5. jsp:软件包 javax.servlet 不存在

    jdk里面有javax.servlet和javax.servlet.http这两个包吗? JavaServlet程序运行还需要安装JDK以外的包吗...? why?我运行JavaServlet程序的时 ...

  6. 闲来无事——第一弹 Java基础 基本数据类型

    一个优秀的Java类一定要去优质的名称,类的命名主要有字母和数字,并且必须以字母开头:虽然说没有明确规定类名首字母要大写,但是实际上如果出现首字母小写的类名,那就呵呵了,坐等挨骂吧!类名首字母大写是业 ...

  7. noip2010-t3

    [题目描述] S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来 ...

  8. px4flow通过iic读取具体寄存器数据程序

    底层通信用了昨天写好的iic,今天结合官方资料成功读出所有指定寄存器的数据附上源码 include.h主要包括了一些stm32 IO控制的宏定义,具体参考正点原子所有例程中都有的sys.h头文件 in ...

  9. 编译器工具 Flex Bison for Windows 简单入门例子

    最近从事一个系统仿真软件的开发,里面定义了自己的描述性语言MSL, MSL语言经FlexBison转换成C语言,然后用C编译器来编译并计算仿真. 现在领域驱动开发比较热门,有机会定义自己的语言对程序员 ...

  10. Scrum - BB项目日志

    这是第三个Scrum团队开发,也是我首次担任Scrum Master一职.所以需要掌握的流程还是很多,也会碰到各种问题,在此记录一下,希望对以后有所帮助. Day1: 开了一次kick-off mee ...