C# - ASP.NET 开发者 PayPal 入门
针对C#开发者,概述所有PayPal集成选项。
目录
注意事项,2017年更新
我大约8年前写了这篇文章。请注意,许多事情已经发生了变化。虽然这里描述的集成在大多数情况下仍然有效,但PayPal的技术和开发支持在过去几年中一直在稳步下降。最重要的是——PayPal的客户支持现在比以往任何时候都差。基本上,PayPal的问题在于您的资金可能在没有任何充分理由的情况下随时被冻结。当这种情况发生时,没有人可以沟通。我个人在几个项目中经历过这种情况,我提供建议的资金充足、合法初创公司的PayPal账户被冻结了。
几年前(2012年之前),您至少可以与决策者沟通,并使用常识解冻账户。现在看来,大多数理智的人都离开了PayPal,当您的账户被冻结时,没有人会花时间与您公开交谈。这里有一些记录完好的恐怖故事,人们因最奇怪的原因被冻结了大量资金
现在,我完全支持公司保护自己。如果PayPal正在处理您网站上的信用卡购买,并且流量突然增加,他们就会面临风险。如果人们开始要求退款,他们需要有能力退还这笔钱。如果您从PayPal提款到银行而不合作,他们就会处于弱势。
但我不知道PayPal运营团队是如何从这一点跳到我们完全关闭您的账户——自己处理吧。我的意思是,他们基本上是在给企业判死刑。如果公司账户上有定期付款怎么办?如果公司需要向客户退款怎么办?如果您不仅使用PayPal收款,还用于汇款和支付承包商费用怎么办?
现在,对于我合作的每个客户,如果他们要求我进行PayPal集成,我都会要求他们签署弃权书。我强烈建议您也这样做。如果您对这个话题有任何疑问,请随时留言,我会尽力帮助您。
开始使用 PayPal
对于那些真正想深入了解 PayPal 并且愿意花钱的人,我推荐 Pro PayPal E-Commerce 这本书——我最终通过它理解了 PayPal 集成的概念。对于那些不太愿意付费的人——别担心,这就是为什么有这篇文章……我将涵盖这本书中的大部分内容,但以更简洁明了的方式。
首先,理解 PayPal 提供的集成类型,我敢说,是成功开始您的开发之旅最重要的事。一个常见的错误(我也犯过)是立即开始使用 PayPal API 和 Express Checkout。我的意思是这很自然——我们是开发者,当他们告诉我们与某个东西集成时,我们首先寻找的是 SDK 和 API……PayPal API 就会出现……我们对自己说“就是它了”……然后开始工作。问题是——大多数支付场景可以通过一种更简单的方法处理——作为网站支付标准的一部分的 HTML 表单。
所以,事不宜迟,这是 PayPal 集成的分类
- 网站标准支付 (HTML)
- 支付后处理
- 自动返回
- 支付数据传输(PDT)
- 即时支付通知 (IPN)
- PayPal API
- 快捷结账
- 直接支付 (网站支付专业版)
- Payflow Gateway
分类中的项目也按照我建议大家遵循的方式进行排序。所以,如果您是 PayPal 新手——首先学习网站支付标准 (HTML) 中的所有选项。然后,如果您需要添加一些基本的支付后处理,看看自动返回或 PDT 是否能解决您的问题……如果不能,IPN 是您可用的更可靠的选项。
下一个级别将涉及 PayPal API 和实现 Express Checkout,这是最灵活的 PayPal 集成解决方案。最后,如果您渴望能够在您的网站上直接处理信用卡,您将向 PayPal 支付月费并实现直接支付(实际上是获得所谓的网站支付专业版)。
另一方面,我们分类中的最后一项——Payflow Gateway,是一个不同的东西。它不像前面提到的技术那样“更新堆栈”。它是一个专门针对那些拥有/想要互联网商家账户 (IMA) 并且只需要支付网关的企业而设计的解决方案。为了保持文章的一致性,我将跳过解释 Payflow Gateway 的细节。但是,如果您有任何相关问题,请随时在评论区留言,我会尽力回答。
话虽如此,让我们开始设置一个测试 PayPal 账户,然后我们将深入探讨上述集成。
设置测试账户
请注意——即使您已经拥有一个真实的 PayPal 账户,您也需要遵循此步骤。使用测试账户有两个原因
- 你不想用真钱测试和玩耍
- 您想访问不同类型的PayPal账户
- 个人账户 – 大多数人拥有此类账户;一个允许您在线支付时使用 PayPal 的账户。理论上,您可以使用个人账户收款;但请注意,您将受到严格限制 – 每月收款限额为500美元,并且只能使用网站支付标准 (HTML) 接受一次性付款。个人账户的最大优点是收款时无需支付任何交易费用。但是请注意,如果您在一个月内收款超过500美元,系统将提示您升级到高级账户/商业账户或拒绝付款。
- 高级账户 – 个人账户的升级版;适用于任何想经营个人在线业务的人。此类账户拥有所有集成选项(接受信用卡、定期付款、PayPal API)。然而,大多数人直接从个人账户跳到商业账户,因为高级账户的交易费用相同(大多数情况下,每笔交易2.9% + 0.30美元),但缺少商业账户的报告、多用户访问和其他高级商家服务。
- 企业账户 – 拥有高级账户的所有功能,外加一些(例如,能够以您的企业名称运营)。如果您正在开发一个需要接受付款的网站,99% 的情况下您会选择此类型账户。
首先,访问 PayPal 沙盒并注册一个新账户。过程很简单,大多数开发者应该都能轻松完成。但是,这里有一些图片可以帮助您完成整个过程
完成沙盒账户详细信息输入后,您需要检查您提供的电子邮件以完成注册。之后,您将能够登录并开始创建沙盒 PayPal 账户。点击 **测试账户** (左侧菜单),然后点击创建账户:**预配置** - 您将获得如下所示的表单
账户类型单选按钮的说明:选择买家将创建个人账户,选择卖家将创建企业账户。为了测试大多数集成场景,您需要两个账户,所以请务必创建它们。点击 **测试账户** 后,您的屏幕上最终应该会显示以下内容
勾选列表中任意账户旁的单选按钮,然后点击“进入沙盒测试网站”应会显示沙盒 PayPal 网站,该网站允许您像普通 PayPal 账户一样登录和管理您的账户。唯一的区别是您会看到一个巨大的 PayPal 沙盒标题和显示您开发者账户电子邮件地址的文本。要了解我在说什么,请查看下图
最后但并非最不重要的一点是——为了使用您的沙盒账户进行测试,您需要登录您的开发者账户。如果您未登录并点击某个支付链接,您将看到以下屏幕
网站支付标准 (HTML)
在本节中,我将为您提供一些示例,演示如何创建自己的 HTML 表单以通过 PayPal 收款。您将了解如何使用不同的变量来影响支付详情。在我们深入了解细节之前,让我们先看看两个最基本的变量
- 表单的 `action` 属性 - 大多数情况下,它应该是 `https://www.paypal.com/cgi-bin/webscr`。如果您正在使用 Sandbox 测试支付,您将把它改为 **https://www.sandbox.paypal.com/cgi-bin/webscr** - 实际上,您只需在 URL 中插入单词 **sandbox** (这对于其他一些集成也适用;例如,PayPal API)。对于即将到来的示例,我将不使用 Sandbox URL,因为你们中的大多数人只会看到“登录以使用 PayPal Sandbox 功能”屏幕(请查看图片)。
- 表单的业务子项 - 大多数示例中我将使用 *youremailaddress@yourdomain.com*;如果您复制粘贴代码,您需要将其替换为您的 PayPal 账户电子邮件。
基本支付
好的,假设您已经开通了 PayPal 账户,并且只想为通过您的网站销售的一幅画作接受 10 美元的付款。只需将以下 HTML 插入您的页面,您就可以开始了
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick" />
<input type="hidden" name="business" value="youremailaddress@yourdomain.com" />
<input type="hidden" name="item_name" value="My painting" />
<input type="hidden" name="amount" value="10.00" />
<input type="submit" value="Buy!" />
</form>
运费和手续费
接下来想到的事情是,您希望在表单中添加运费和/或手续费。这很容易——只需添加更多参数
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick" />
<input type="hidden" name="business" value="youremailaddress@yourdomain.com" />
<input type="hidden" name="item_name" value="My painting" />
<input type="hidden" name="amount" value="10.00" />
<input type="hidden" name="shipping" value="3.00" />
<input type="hidden" name="handling" value="2.00" />
<input type="submit" value="Buy with additional parameters!" />
</form>
捐赠和文本链接
如果您不销售任何商品,而是为某个事业接受捐赠——您只需将 `cmd` 变量的值更改为 `_donations`。如果我们将此与常见的将超链接而不是按钮的要求结合起来——我们将得到以下 URL(当然,您可以将此 URL 创建方法用于其他 PayPal 支付类型)
- https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=youremailaddress@yourdomain.com&item_name=拯救北极熊!&amount=10.00
结果
购物车系统
如果您有大量不同的产品可供选择,并且您只想要一个简单的购物车系统而无需实现任何功能,PayPal 可以满足您的需求。基本上,您只需使用 `cmd` 变量,同时保持表单的其余部分与基本支付相同。让我们看看如何为两个产品执行此操作;一个产品定价为 10 美元,不含运费,另一个产品定价为 5 美元,含 1 美元运费。我们还需要一个“查看购物车”按钮
My Cart Item 1:
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="paypal">
<input type="hidden" name="cmd" value="_cart">
<input type="hidden" name="add" value="1">
<input type="hidden" name="business" value="youremailaddress@yourdomain.com">
<input type="hidden" name="item_name" value="My Cart Item 1">
<input type="hidden" name="amount" value="10.00">
<input type="hidden" name="shopping_url"
value="http://www.yourwebsite.com/shoppingpage.html">
<input type="hidden" name="return" value="http://www.yourwebsite.com/success.html">
<input type="hidden" name="cancel_return" value="http://www.yourwebsite.com/cancel.html">
<input type="hidden" name="bn" value="PP-ShopCartBF:x-click-but22.gif:NonHosted">
<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but22.gif" border="0"
name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1"
height="1">
</form>
My Cart Item 2:
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="paypal">
<input type="hidden" name="cmd" value="_cart">
<input type="hidden" name="add" value="1">
<input type="hidden" name="business" value="youremailaddress@yourdomain.com">
<input type="hidden" name="item_name" value="My Cart Item 2">
<input type="hidden" name="amount" value="5.00">
<input type="hidden" name="shipping" value="1.00">
<input type="hidden" name="shopping_url"
value="http://www.yourwebsite.com/shoppingpage.html">
<input type="hidden" name="return" value="http://www.yourwebsite.com/success.html">
<input type="hidden" name="cancel_return" value="http://www.yourwebsite.com/cancel.html">
<input type="hidden" name="bn" value="PP-ShopCartBF:x-click-but22.gif:NonHosted">
<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but22.gif" border="0"
name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1"
height="1">
</form>
View Cart:
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="paypal">
<input type="hidden" name="cmd" value="_cart">
<input type="hidden" name="display" value="1">
<input type="hidden" name="business" value="youremailaddress@yourdomain.com">
<input type="hidden" name="shopping_url"
value="http://www.yourwebsite.com/shoppingpage.html">
<input type="image" src="https://www.paypal.com/en_US/i/btn/view_cart_02.gif"
name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form>
定期付款
如果您销售的是月度服务而非产品,您会对 PayPal 提供的定期付款选项感兴趣。同样,这是在玩弄具有不同含义的不同变量。假设您希望设置 3 天的免费试用期,之后用户每月需要支付 10.00 美元才能继续使用该服务。以下 HTML 表单应该可以解决问题
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick-subscriptions"/>
<input type="hidden" name="business" value="youremailaddress@yourdomain.com"/>
<input type="hidden" name="item_name" value="Something"/>
<input type="submit" value="Subscribe!" />
<input type="hidden" name="a1" value="0"/>
<input type="hidden" name="p1" value="3"/>
<input type="hidden" name="t1" value="D"/>
<input type="hidden" name="a3" value="10.00"/>
<input type="hidden" name="p3" value="1"/>
<input type="hidden" name="t3" value="M"/>
<input type="hidden" name="src" value="1"/>
<input type="hidden" name="srt" value="0"/>
<input type="hidden" name="sra" value="1"/>
</form>
HTML变量和资源
阅读完前面的例子后,您可能想知道某些变量是做什么的 (a1? p1? srt?)。幸运的是,PayPal 提供了一个“网站支付标准 HTML 变量”页面,您可以在其中阅读任何您感兴趣的变量。
此外,另一个很棒的资源(我希望在我第一次开始 PP 集成时有人向我推荐它)是“滑雪者的 PayPal 示例”。您会找到几乎所有你能想到的支付场景的示例——因此,我不会用更多示例来使本文变得混乱,而是鼓励您访问该页面,如果您希望实现更高级的 PayPal HTML 表单。
支付后处理
当您设置 PayPal HTML 表单时,您可能会问的第一个问题是——用户支付后,我能否有一些支付后处理逻辑?这并非没有道理;我们可以想到许多支付后场景——从发送简单的“谢谢”电子邮件到更新网站数据库并允许用户访问他已付费的受限资源。根据您的知识和支付后处理逻辑所需的健壮性级别,有三种方法可以选择;好消息是您可以将它们结合使用。
自动返回
自动返回是您拥有的最简单的支付后处理解决方案——用户支付后,他将**自动***重定向到您网站上的指定页面,您可以在该页面上显示一些确认文本。如果您仔细阅读了“网站支付标准 HTML 变量”,您就知道可以使用 **return** 变量在 HTML 表单中指定自动返回 URL。如果您希望使用默认的自动返回 URL,请遵循以下步骤
- 登录您的高级或企业账户
- 点击“个人资料”子选项卡
- 在“销售偏好”列中点击“网站支付偏好”
- 点击“自动返回”标签旁边的“开启”单选按钮
- 在标记为“返回 URL”的文本框中输入您希望用户返回的 URL
- 点击页面底部的“保存”按钮
请注意,如果您在个人资料中同时设置了自动返回 URL 并在 HTML 表单中提供了 **return** 变量,则 **return** 变量将覆盖个人资料中的 URL 值。
现在,当您的返回页面被访问时,您将收到允许您自定义页面显示和记录支付的变量
tx
- 交易IDst
- 付款状态amt
- 付款金额cc
- 货币代码
在本节结束前,还有一件事。我在第一句话中将“自动”这个词斜体显示的原因是:如果用户使用信用卡支付,他将不会自动重定向到您的返回 URL;他需要点击“返回商家”按钮。如果这听起来很奇怪,请知道您并不孤单;然而,由于法律问题,PayPal 过去和现在都拒绝更改使用 AutoReturn 处理信用卡支付的方式。
支付数据传输(PDT)
查看了自动返回提供的变量列表后,您可能想知道——我能否获得更多关于已发生交易的详细信息?这正是 PDT 的用武之地——它建立在自动返回功能之上。因此,您需要在您的个人资料中同时启用自动返回和 PDT;以下是操作方法
- 登录您的高级或企业账户
- 点击“个人资料”子选项卡
- 在“销售偏好”列中点击“网站支付偏好”
- 点击“自动返回”标签旁边的“开启”单选按钮
- 输入将处理从PayPal发送的PDT HTTP请求的脚本URL
- 在“支付数据传输”下,点击“开启”单选按钮
- 单击“保存”。
完成这些步骤后,您应该会获得一个 PDT 身份令牌,该令牌是查询 PayPal 所必需的。如果您在点击“保存”后没有复制粘贴该令牌,请注意,您始终可以在“网站支付偏好”中查看它
现在您有了身份令牌,您可以在您的返回 URL 被访问后查询 PayPal 获取更多详细信息。以下是利用 PDT 时流程的运作方式
SUCCESS
first_name=Firstname
last_name=Lastname
payment_status=Completed
payer_email=firstname%40lastname.com
payment_gross=50.00
mc_currency=USD
custom=Custom+value+you+passed+with+your+HTML+form
etc.
- 用户付款并被重定向到您的自动返回页面,例如:http://www.yourdomain.com/Thanks.aspx?tx=[TransactionID]。
- 在 Thanks.aspx 的代码后台,您将解析 `tx` 值并向 https://www.paypal.com/cgi-bin/webscr 发送一个 HTTP POST 请求,其中包含以下参数:cmd=_notify-synch&tx=[TransactionID]&at=[PDTIdentityToken]。(如果您正在使用沙盒,您当然会向 https://www.sandbox.paypal.com/cgi-bin/webscr 发送 HTTP POST 请求。)
- PayPal将以以下格式响应您的HTTP POST
- 随心所欲地处理这些数据。
以下是前面几行所述内容在C#代码中的体现
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
authToken = WebConfigurationManager.AppSettings["PDTToken"];
//read in txn token from querystring
txToken = Request.QueryString.Get("tx");
query = string.Format("cmd=_notify-synch&tx={0}&at={1}",
txToken, authToken);
// Create the request back
string url = WebConfigurationManager.AppSettings["PayPalSubmitUrl"];
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
// Set values for the request back
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = query.Length;
// Write the request back IPN strings
StreamWriter stOut = new StreamWriter(req.GetRequestStream(),
System.Text.Encoding.ASCII);
stOut.Write(query);
stOut.Close();
// Do the request to PayPal and get the response
StreamReader stIn = new StreamReader(req.GetResponse().GetResponseStream());
strResponse = stIn.ReadToEnd();
stIn.Close();
// sanity check
Label2.Text = strResponse;
// If response was SUCCESS, parse response string and output details
if (strResponse.StartsWith("SUCCESS"))
{
PDTHolder pdt = PDTHolder.Parse(strResponse);
Label1.Text =
string.Format("Thank you {0} {1} [{2}] for your payment of {3} {4}!",
pdt.PayerFirstName, pdt.PayerLastName,
pdt.PayerEmail, pdt.GrossTotal, pdt.Currency);
}
else
{
Label1.Text = "Oooops, something went wrong...";
}
}
}
在本文附带的代码中,在 *PDT* 目录下,您会看到更多类,这些类将帮助您遵循前面提到的流程。
而且,与自动返回一样,在结束本主题之前,请注意 PayPal 响应您的 HTTP POST 中的 `custom` 变量。您可能希望利用此变量,因为它允许您将一些信息从您的支付页面传递到您的后处理页面,而无需向用户显示。举个例子,在我的某些 PayPal 实现中,我用它来跟踪用户——他何时开始支付过程,以及何时/是否完成支付。
即时支付通知(IPN)
PDT 的一个主要缺点是它是一个用户驱动的过程,这意味着——如果用户在完成支付后、但在重定向到您的网站之前关闭了浏览器,您将失去运行支付后处理逻辑的机会。这就是为什么建议您将 PDT 与 IPN 结合用于任何与 PayPal 的严肃集成。
IPN是一种后端机制,它向您的页面发送HTTP POST请求,通知您重要的事件。它不仅用于支付后处理,还用于处理后续事件,例如用户取消定期支付。
作为一种后端技术,它比 PDT 更难实现和调试。在开始实现 IPN 之前,您应该注意以下几点
- IPN消息有时可能会延迟。我知道,我知道……这与IPN中的“即时”一词相悖,但事实就是如此。
- IPN 服务存在已知的历史问题;最近两次事件发生在2009年10月2日(延迟2小时)和2009年9月6日(延迟6小时)。
- 每当您遇到 IPN 问题时,请务必查看 **实时状态** 页面,看看是否有事件通知,然后再深入调试和更改您的脚本。还有一个类似的 **沙盒状态** 页面。
在能够接收 IPN 消息之前,您需要激活此服务;请遵循以下步骤
- 登录您的高级或企业账户
- 点击“个人资料”子选项卡
- 在“销售偏好”列中点击“即时付款通知”
- 点击“编辑 IPN 设置”按钮以更新您的设置
- 选择“接收IPN消息”(已启用)并输入您的IPN处理程序URL
- 点击“保存”,您应该会收到一条消息,表明您已成功激活 IPN
与自动返回一样,您可以通过添加 `notify_url` 变量来覆盖个人资料中设置的 IPN 处理程序 URL(请参阅 HTML 变量参考)。请注意,这将不仅影响初始 IPN 消息,还会影响与该交易相关的所有未来消息(它们都将发送到 `notify_url`)。
要处理 IPN 消息,您需要在网站上的某个位置创建一个 HTTP 处理程序。当发生重要事件(例如,用户完成付款)时,将发生以下流程
- PayPal将向您的IPN处理程序发送一个包含多个变量的HTTP POST。
- 收到 HTTP POST 并解析后,您需要将完整的消息正文提交回 https://www.paypal.com/cgi-bin/webscr(或沙盒账户的 https://www.sandbox.paypal.com/cgi-bin/webscr)。在执行此操作时,请务必以您收到的精确格式发送消息;您唯一允许做的事情是添加 **cmd=_notify-validate**。这样做是为了验证 HTTP POST 是真实的,并且是由 PayPal 发送的。
- PayPal 将以 VERIFIED 或 INVALID 响应。收到此响应后,请务必发送 200 OK,以防止 PayPal 再次尝试发送 IPN。如果您不以 200 OK 结束循环,PayPal 将开始重新发送 IPN(从 4 秒开始,然后加倍——8 秒、16 秒、32 秒……最长可达 4 天)。
这是一个通用的 C# IPN 处理程序(更多代码请查看文章附带的 zip 文件)
protected void Page_Load(object sender, EventArgs e)
{
string postUrl = ConfigurationManager.AppSettings["PayPalSubmitUrl"];
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(postUrl);
//Set values for the request back
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
byte[] param = Request.BinaryRead(HttpContext.Current.Request.ContentLength);
string strRequest = Encoding.ASCII.GetString(param);
string ipnPost = strRequest;
strRequest += "&cmd=_notify-validate";
req.ContentLength = strRequest.Length;
//for proxy
//WebProxy proxy = new WebProxy(new Uri("http://url:port#"));
//req.Proxy = proxy;
//Send the request to PayPal and get the response
StreamWriter streamOut = new StreamWriter(req.GetRequestStream(),
System.Text.Encoding.ASCII);
streamOut.Write(strRequest);
streamOut.Close();
StreamReader streamIn = new StreamReader(req.GetResponse().GetResponseStream());
string strResponse = streamIn.ReadToEnd();
streamIn.Close();
// logging ipn messages... be sure that you give write
// permission to process executing this code
string logPathDir = ResolveUrl("Messages");
string logPath = string.Format("{0}\\{1}.txt",
Server.MapPath(logPathDir), DateTime.Now.Ticks);
File.WriteAllText(logPath, ipnPost);
//
if (strResponse == "VERIFIED")
{
//check the payment_status is Completed
//check that txn_id has not been previously processed
//check that receiver_email is your Primary PayPal email
//check that payment_amount/payment_currency are correct
//process payment
}
else if (strResponse == "INVALID")
{
//log for manual investigation
}
else
{
//log response/ipn data for manual investigation
}
}
如果您收到 INVALID 响应,这可能意味着两件事
- 有人试图向您的IPN处理程序发送恶意消息。
- 您的实施并不完美。
如果是恶意消息,您需要自行处理(记录 IP,采取适当措施),但对于不完善的实现,请访问 PayPal 开发者论坛上的IPN 故障排除主题;它充满了有用的提示,应该能帮助您解决 INVALID 响应。
另外,在您的 IPN 处理程序上线之前,请务必使用即时支付通知 (IPN) 模拟器对其进行彻底测试。由于 IPN 处理程序将在后台运行,您需要在上线并依赖其处理之前尽可能多地对其进行测试。
如果您正在实现 IPN,您还需要访问 ScriptGenerator2 页面……它可以用您选择的语言快速生成一个 IPN 处理程序。有趣的是——他们缺少一个 ASP.NET/C# 的生成器;为此,请查看本文附带的代码存档中的 IPN 目录和这些代码示例。
最后,在 PayPal 开发者中心,有一个很好的页面列出了大多数 IPN 和 PDT 变量。我说“大多数”是因为上面缺少一些变量(请查看此页面上的评论),但该列表绝不是无用的。
PayPal API
正如引言中所述,大多数开发者,即使他们以前没有使用 PayPal 的经验,也会直接从 API 开始。Google 搜索会显示API 参考或SDK 和下载页面,然后开始浏览文档。我并不是说使用 PayPal API 进行支付有什么问题;我想说的是,在大多数情况下,没有必要走那条路。
PayPal API 远不止是一种支付机制——如果您查看提供的API 参考页面,您会发现有很多方法与“用户执行支付”没有直接关系。您可以使用 API 浏览您的交易历史记录、退款或更新定期支付档案。那么,您如何开始使用它呢?
首先,您需要启用您账户的 API 访问权限;请按照以下步骤操作
- 登录您的高级或企业账户
- 点击“个人资料”子选项卡
- 点击“账户信息”标题下的“API 访问”链接
- 点击“请求API凭据/查看API证书”链接
- 选择 API 签名或 API 证书
我建议您选择 API 签名,接下来的示例将假定您做出了此选择。选择 API 证书没有任何问题;我只是觉得从设置角度来看它更麻烦。
现在您有了进行 API 调用的凭据,如何执行它们呢?适用于所有平台的通用方法是下载 SDK,针对适当的 API 端点,然后使用名称-值对或 SOAP 开始进行 HTTP 调用。
然而,对于 .NET 开发者,我推荐一种不同的方法。考虑到 Visual Studio 拥有出色的 WSDL 解析器,我强烈建议您只需向 https://www.paypal.com/wsdl/PayPalSvc.wsdl 添加一个 Web 服务引用。稍后,您将拥有一个最新的类,可以为您提供强类型的所有优势——无需构建 HTTP 请求,无需复制粘贴字段名称,也无需繁琐地解析响应。您也可以在沙盒环境中获得同样的功能,地址是:https://www.sandbox.paypal.com/wsdl/PayPalSvc.wsdl。
快捷结账
Express Checkout 是最灵活的 PayPal 集成解决方案。用户被重定向到 PayPal 只是为了进行身份验证和确认他希望为您的服务付款,之后所有操作都在您的网站上完成;您将在后台调用 PayPal API。下图描述了该过程(摘自此页面)
- 您将添加一个 PayPal 结账按钮,点击后它会调用 PayPal API 的 `SetExpressCheckout` 方法。
- 如果您为一次性付款调用此方法,则只需包含必填字段即可。如果您销售在线服务,将 `NOSHIPPING` 变量设置为 1 很重要(它将帮助您跳过发货信息页面)。
- 如果您正在调用此方法以设置定期付款,请务必将 `L_BILLINGTYPE0` 设置为 `RecurringPayments`,并将 `L_BILLINGAGREEMENTDESCRIPTION0` 设置为您的服务的有效描述。
- `SetExpressCheckout` 将返回一个 20 字符的令牌,该令牌将唯一标识您的交易。此令牌有效期为 3 小时。收到令牌后,将用户重定向到 https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=[TOKEN](您能猜到沙盒的 URL 是什么,对吗?)。
- 用户将审查支付信息,如果一切正常,则输入登录凭据。之后,PayPal 会将他重定向到您在调用 `SetExpressCheckout` 时使用 `RETURNURL` 指定的 URL。
- 当您的 `RETURNURL` 被访问时,您需要调用 `GetExpressCheckoutDetails` 方法并查看实际交易的详细信息;验证一切是否正常。
- 现在,剩下的就是提交交易了。根据您在步骤1中所做的操作,可以完成两件事。
- 对于一次性付款,您只需调用 `DoExpressCheckoutPayment` 并转发相应的变量。
- 对于定期付款,您将调用 `CreateRecurringPayments` 方法。您必须包含 DESC 字段,并使其与您在调用 `SetExpressCheckout` 时输入的 L_BILLINGAGREEMENTDESCRIPTION0 值匹配。
简而言之——就是这样。再次强调,我已在本文附带的存档(API 目录下)中提供了遵循上述流程的代码示例。如果您愿意,也可以使用 PayPal 快捷结账集成向导来生成参考代码。
直接支付(网站支付专业版)
大多数开发人员没有意识到 PayPal 平台可以仅用于信用卡处理。PayPal API 的这一部分称为直接支付,当与 Express Checkout(仅服务于拥有 PayPal 账户的客户)结合使用时,您将获得在 PayPal 开发者中心被称为 网站支付专业版 的服务。
要能够调用属于直接支付的方法(`DoDirectPayment` 和 `CreateRecurringPayments`),您首先需要满足一些条件
- 拥有一个在美国、英国或加拿大注册的商业账户
- 承诺在您的网站上同时实施 Express Checkout 和 Direct Payment
- 通过您的 PayPal 账户提交 Website Payments Pro 申请并获得批准
- 支付月费(目前每月 30 美元)
在您拥有 Website Payments Pro 账户后,调用 Direct Payment 方法非常简单——如有疑问,请访问 API 参考页面,或查看本文附带的代码。请注意,如果您尝试在未启用 Pro 的账户上调用任何 Direct Payment 方法,您将收到错误代码 10501(这是 Sandbox 论坛中报告的最常见问题之一)。
最后,一旦您开始处理信用卡,您就需要处理 PCI 合规性;这里有一个不错的论坛帖子提供了更多相关信息。
结论
我希望本文能为您提供 PayPal 集成选项的良好概述。如果做到了,我将心安理得——因为一旦您理解了本文中阐述的概念,您将轻松地从提供的链接中获取所需的详细信息。当然,有些主题我们没有涉及,例如加密网站支付、PayPal API 证书或Payflow Gateway,但我认为一旦您完全理解了这里写的所有内容,即使这些您也能自行解决。
如果您遇到任何问题,我建议您首先访问 PayPal 开发者社区并在相应的论坛中提问。许多优秀、知识渊博的开发者会关注这些论坛,您很可能在不到一小时内得到几乎所有 PayPal 问题的答案。我也有一个该网站的账户 (lepipele),只要有时间就会尝试回答问题;所以如果您路过或遇到麻烦,请随时给我发私信。
历史
- 2009年11月5日 - 因PayPal X重组更新链接
- 2009年10月1日 - 文章初始版本。