目录
学习成果
先决条件
创建具有以下行标题的电子表格
创建PayPal商业帐户
获取API凭据——即客户端ID和密码
获取实时的API凭证
什么字段添加到您的数据存储
服务器端代码
- 从GitHub存储库下载源代码
- 如何设置PayPal业务帐户
- 如何获取沙箱的API凭据——即客户端ID和密码
- 如何获取实时的API凭据——即客户端ID和密码
- 数据存储中包括哪些字段
- 服务器端代码
- 您已经为电子商务网站注册了URL,例如www.delaneys.space。
- 该网站已通过SSL证书保护。
- 您的客户可以使用OAuth或某些安全的方式以安全的方式注册并登录到您的网站。
- 您的网站有一个后端数据存储,您知道如何维护它。
- 您熟悉Visual Studio。
1
Dashboard URL
https://www.paypal.com/mep/dashboard
2
开发人员Dashboard URL
https://developer.paypal.com/developer/applications
3
沙盒详细信息
4
网址
www.sandbox.paypal.com/
5
应用名称
6
商业
7
用户名
…@business.example.com
8
密码
9
客户编号
10
密码
11
个人(客户)
12
用户名
... @ personal.example.com
13
密码
14
实时细节
15
用户名
info@...
16
密码
17
应用名称
18岁
客户编号
19
密码
创建PayPal商业帐户
要创建PayPal商业帐户,您不必拥有商业或拥有商业银行帐户。话虽如此,您应该采取措施将个人财务交易与电子商务网站的交易区分开。因此,我建议使用一个单独的个人银行帐户来链接到您的PayPal“商业”帐户。
1、浏览至www.PayPal.com。
2、即使您已经有一个个人PayPal帐户,也请单击“注册”。切记切勿将生意与娱乐混为一谈。
3、选择商业帐户,然后单击下一步。
4、完成简短的问卷。
- 选择“在我的网站上”作为“我主要要接受付款:”问题。
- 选择问题“5月的年产量为: ”的答案。
5、提供一个电子邮件地址,然后单击继续。
这可以是任何有效的电子邮件地址,但您可能需要使用“info @ your e-commerce.com ”。
6、提供密码,然后单击继续。
确认电子邮件将发送到提供的地址。
更新您的电子表格。
15
用户名
info@...
16
密码
7、完成业务联系详细信息页面,然后单击同意并创建帐户。
他们将要求您提供联系人姓名,公司名称,电话号码和公司地址。
8、选择一种业务类型。
从“个人”,“唯一所有者”,“合伙商业”,“私人公司”,“公众公司”,“非营利组织”,“政府实体”,“信托–投资和家庭”列表中选择。
9、添加个人详细信息。
这包括您的姓名,出生日期和地址。
10、点击提交。
现在,您已经设置了PayPal商业帐户。您应该看到仪表板显示。
获取API凭据——即客户端ID和密码1、转到开发人员仪表板:
2
开发人员仪表板URL
https://developer.paypal.com/developer/applications
沙箱选项将被预先选择。因此,让我们先进行设置。
2、点击创建应用。
3、创建一个沙箱应用名称,并将其存储在电子表格中。
17
应用名称
4、再次单击创建应用程序。
在电子表格上更新以下内容:
6
商业
7
用户名
…@business.example.com
9
客户编号
10
密码
现在,让我们获取密码。
5、单击“沙盒” | 帐户按钮或(developer.paypal.com/developer/accounts/)。
您应该看到两个代表商业和个人帐户的电子邮件地址。
6、点击公司帐户的…按钮,然后选择查看/编辑帐户。
- 在电子表格中记录系统生成的密码。
8
密码
8、单击关闭。
9、单击个人帐户的…按钮,然后选择查看/编辑帐户。
在电子表格中记录用户名和密码。
11
个人(客户)
12
用户名
... @ personal.example.com
13
密码
获取实时的API凭证
1、点击我的应用和凭据(developer.paypal.com/developer/applications/)。
2、单击实时按钮。
3、点击创建应用。
在电子表格中记录应用名称。
17
应用名称
4、再次单击创建应用。
在电子表格中记录客户端ID和密码。
18岁
客户编号
19
密码
什么字段添加到您的数据存储
- 选择一个数据存储,例如SQL Server。
- 您将需要一个Basket,Item和Invoice型号/核心类。将以下蓝色突出显示的字段添加到发票表中。这些字段将由PayPal使用。
请注意FirstName,LastName和Email存储在User表中,但在Invoice表中也重复。这是因为来自客户的PayPal帐户的数据可能与User表格上的数据不同。
由您决定如何在数据存储中包括蓝色字段。
服务器端代码1、使用Visual Studio创建一个ASP.NET Core 3.x MVC应用程序。
2、转到NuGet程序包管理器并添加以下程序包:
- PayPalCheckoutSdk,软件包版本1.0.3。在撰写本文时,我使用的是最新版本。
PayPalCheckoutSdk仅仅是一个类库。库中没有逻辑。这些类用属性修饰,以帮助序列化为JSON。
- PayPalHttp v1.0.0。
- Microsoft.AspNetCore.Mvc.NewtonsoftJson。随着ASP.NET Core 3.0的发布,Microsoft中断了其JSON序列化的实现。搜索“ASP.NET Core:Blank Json {}升级到3.0后返回 ”,以查找要添加到Startup.ConfigureServices的内容或从下一步中选择一个选项。
3、更新Startup.ConfigureServices以调用AddNewtonsoftJson。
services.AddMvc()
.AddNewtonsoftJson();
或者:
services.AddMvc()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver());
4、在ASP.NET Core项目中创建一个名为PayPal的文件夹。
5、使用以下代码在文件夹中创建一个PayPalClient类。记住要使用沙盒和实时客户端ID和密码来填充突出显示的字符串内容。
using System;
using PayPalCheckoutSdk.Core;
using System.IO;
using System.Text;
using System.Runtime.Serialization.Json;
namespace PayPal
{
public class PayPalClient
{
// Place these static properties into a settings area.
public static string SandboxClientId { get; set; } =
"{PayPal SANDBOX Client Id}";
public static string SandboxClientSecret { get; set; } =
"{PayPal SANDBOX Client Secret}";
public static string LiveClientId { get; set; } =
"{PayPal LIVE Client Id}";
public static string LiveClientSecret { get; set; } =
"{PayPal LIVE Client Secret}";
///
/// Set up PayPal environment with sandbox credentials.
/// In production, use LiveEnvironment.
///
public static PayPalEnvironment Environment()
{
#if DEBUG
// You may want to create a UAT (user exceptance tester)
// role and check for this:
// "if(_unitOfWork.IsUATTester(GetUserId())" instead of fcomiler directives.
return new SandboxEnvironment(SandboxClientId,
SandboxClientSecret);
#else
return new LiveEnvironment(LiveClientId,
LiveClientSecret);
#endif
}
///
/// Returns PayPalHttpClient instance to invoke PayPal APIs.
///
public static PayPalCheckoutSdk.Core.PayPalHttpClient Client()
{
return new PayPalHttpClient(Environment());
}
public static PayPalCheckoutSdk.Core.PayPalHttpClient Client(string refreshToken)
{
return new PayPalHttpClient(Environment(), refreshToken);
}
///
/// Use this method to serialize Object to a JSON string.
///
public static String ObjectToJSONString(Object serializableObject)
{
MemoryStream memoryStream = new MemoryStream();
var writer = JsonReaderWriterFactory.CreateJsonWriter(memoryStream,
Encoding.UTF8,
true,
true,
" ");
var ser = new DataContractJsonSerializer(serializableObject.GetType(),
new DataContractJsonSerializerSettings
{
UseSimpleDictionaryFormat = true
});
ser.WriteObject(writer,
serializableObject);
memoryStream.Position = 0;
StreamReader sr = new StreamReader(memoryStream);
return sr.ReadToEnd();
}
}
}
6、使用代码在文件夹中创建一个SmartButtonHttpResponse类。
using System.Net;
using System.Net.Http.Headers;
namespace PayPal
{
public class SmartButtonHttpResponse
{
readonly PayPalCheckoutSdk.Orders.Order _result;
public SmartButtonHttpResponse(PayPalHttp.HttpResponse httpResponse)
{
Headers = httpResponse.Headers;
StatusCode = httpResponse.StatusCode;
_result = httpResponse.Result();
}
public HttpHeaders Headers { get; }
public HttpStatusCode StatusCode { get; }
public PayPalCheckoutSdk.Orders.Order Result()
{
return _result;
}
public string orderID { get; set; }
}
}
7、使用代码在文件夹中创建一个OrderBuilder类。
using PayPalCheckoutSdk.Orders;
using System.Collections.Generic;
namespace PayPal
{
public static class OrderBuilder
{
///
/// Use classes from the PayPalCheckoutSdk to build an OrderRequest
///
///
public static OrderRequest Build()
{
OrderRequest orderRequest = new OrderRequest();
// Add code to fill out the order request properties
// See the attached source code for a more detailed example.
return orderRequest;
}
}
}
8、在名为Controllers的文件夹中创建一个控制器类CheckoutController。添加以下代码:
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using PayPalCheckoutSdk.Orders;
namespace Test.Controllers
{
public class CheckoutController : Controller
{
///
/// Action to display the cart form for the SERVER side integration
///
///
public IActionResult Index()
{
#if DEBUG
// You may want to create a UAT (user exceptance tester) role
// and check for this:
// "if(_unitOfWork.IsUATTester(GetUserId())"
// Company SANDBOX Client Id. To go live replace this with the live ID.
ViewBag.ClientId =
PayPal.PayPalClient.SandboxClientId; // Get from a
// data store or stettings
#else
// Company LIVE Client Id. To go live replace this with the live ID.
ViewBag.ClientId =
PayPal.PayPalClient.LiveClientId; // Get from a
// data store or stettings
#endif
ViewBag.CurrencyCode = "GBP"; // Get from a data store
ViewBag.CurrencySign = "£"; // Get from a data store
return View();
}
///
/// This action is called when the user clicks on the PayPal button.
///
///
[Route("api/paypal/checkout/order/create")]
public async Task Create()
{
var request = new PayPalCheckoutSdk.Orders.OrdersCreateRequest();
request.Prefer("return=representation");
request.RequestBody(PayPal.OrderBuilder.Build());
// Call PayPal to set up a transaction
var response = await PayPal.PayPalClient.Client().Execute(request);
// Create a response, with an order id.
var result = response.Result();
var payPalHttpResponse = new PayPal.SmartButtonHttpResponse(response)
{
orderID = result.Id
};
return payPalHttpResponse;
}
///
/// This action is called once the PayPal transaction is approved
///
///
///
[Route("api/paypal/checkout/order/approved/{orderId}")]
public IActionResult Approved(string orderId)
{
return Ok();
}
///
/// This action is called once the PayPal transaction is complete
///
///
///
[Route("api/paypal/checkout/order/complete/{orderId}")]
public IActionResult Complete(string orderId)
{
// 1. Update the database.
// 2. Complete the order process. Create and send invoices etc.
// 3. Complete the shipping process.
return Ok();
}
///
/// This action is called once the PayPal transaction is complete
///
///
///
[Route("api/paypal/checkout/order/cancel/{orderId}")]
public IActionResult Cancel(string orderId)
{
// 1. Remove the orderId from the database.
return Ok();
}
///
/// This action is called once the PayPal transaction is complete
///
///
///
[Route("api/paypal/checkout/order/error/{orderId}/{error}")]
public IActionResult Error(string orderId,
string error)
{
// Log the error.
// Notify the user.
return NoContent();
}
}
}
9、在“视图”文件夹中创建一个Checkout文件夹,然后添加一个名为index.cshtml的视图。
添加以下代码以在视图中创建PayPal智能按钮。
// This is stored just in case the user cancels the other
// or there is an error in the other process.
var orderId;
// Render the PayPal smart button into #paypal-button-container
paypal.Buttons({
// Set up the transaction
createOrder: function (data, actions) {
orderId = data.orderID;
return fetch('/api/paypal/checkout/order/create/', {
method: 'post'
}).then(function (res) {
return res.json();
}).then(function (data) {
return data.orderID;
});
},
// Finalise the transaction
onApprove: function (data, actions) {
return fetch('/api/paypal/checkout/order/approved/' + data.orderID, {
method: 'post'
}).then(function (res) {
return actions.order.capture();
}).then(function (details) {
// (Preferred) Notify the server that the transaction id complete
// and have an option to display an order completed screen.
window.location.replace('/api/paypal/checkout/order/complete/' +
data.orderID + '/@ViewBag.CurrencyCode');
// OR
// Notify the server that the transaction id complete
//httpGet('/api/paypal/checkout/order/complete/' + data.orderID);
// Show a success message to the buyer
alert('Transaction completed by ' + details.payer.name.given_name + '!');
});
},
// Buyer cancelled the payment
onCancel: function (data, actions) {
httpGet('/api/paypal/checkout/order/cancel/' + data.orderID);
},
// An error occurred during the transaction
onError: function (err) {
httpGet('/api/paypal/checkout/order/error/' + orderId + '/' +
encodeURIComponent(err));
}
}).render('#paypal-button-container');
除了URL,此代码对于所有解决方案都是相同的。
10、添加以下JavaScript函数:
function httpGet(url) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", url, false);
xmlHttp.send(null);
return xmlHttp.responseText;
}
11、在PayPal文件夹中创建一个名为Values的文件夹。
12、在Values文件夹中添加一个名为CheckoutPaymentIntent.cs的类。 添加以下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace PayPal.Values
{
///
/// The intent to either capture payment immediately or
/// authorize a payment for an order after order creation.
///
public static class CheckoutPaymentIntent
{
///
/// The merchant intends to capture payment immediately after
/// the customer makes a payment.
///
public static string CAPTURE { get; private set; } = "CAPTURE";
///
/// The merchant intends to authorize a payment and
/// place funds on hold after the customer makes a payment.
/// Authorized payments are guaranteed for up to three days but
/// are available to capture for up to 29 days.
/// After the three-day honor period, the original authorized payment expires
/// and you must re-authorize the payment.
/// You must make a separate request to capture payments on demand.
/// This intent is not supported when you have more than one `purchase_unit`
/// within your order.
///
public static string AUTHORIZE { get; private set; } = "AUTHORIZE";
}
}
13、在Values文件夹中添加一个名为CurrencyCode.cs的类。 添加以下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace PayPal.Values
{
public static class CurrencyCode
{
///
/// Great British Pounds
///
public static string GBP { get; private set; } = "GBP";
///
/// US Dolars
///
public static string USD { get; private set; } = "USD";
///
/// Euros
///
public static string EUR { get; private set; } = "EUR";
}
}
根据需要添加其他货币。
14、在Values文件夹中添加一个名为LandingPage.cs的类。 添加以下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace PayPal.Values
{
///
/// The type of landing page to show on the PayPal site for customer checkout.
/// Default: NO_PREFERENCE.
/// Source: https://developer.paypal.com/docs/api/orders/v2/
///
public class LandingPage
{
///
/// When the customer clicks PayPal Checkout,
/// the customer is redirected to a page to log in to PayPal
/// and approve the payment.
///
public static string LOGIN { get; private set; } = "LOGIN";
///
/// When the customer clicks PayPal Checkout,
/// the customer is redirected to a page to enter credit or
/// debit card and other relevant billing information required to
/// complete the purchase.
///
public static string BILLING { get; private set; } = "BILLING";
///
/// When the customer clicks PayPal Checkout,
/// the customer is redirected to either a page to log in to PayPal and
/// approve the payment or to a page to enter credit or
/// debit card and other relevant billing information
/// required to complete the purchase, depending on their
/// previous interaction with PayPal.
///
public static string NO_PREFERENCE { get; private set; } = "NO_PREFERENCE";
}
}
15、在Values文件夹中添加一个称为ShippingPreference.cs的类。 添加以下代码:
namespace PayPal.Values
{
///
/// The shipping preference:
///
/// * Displays the shipping address to the customer.
/// * Enables the customer to choose an address on the PayPal site.
/// * Restricts the customer from changing the address
/// during the payment-approval process.
///
/// Default: GET_FROM_FILE.
/// Source: https://developer.paypal.com/docs/api/orders/v2/
///
public static class ShippingPreference
{
///
/// Use the customer-provided shipping address on the PayPal site.
///
public static string GET_FROM_FILE { get; private set; } = "GET_FROM_FILE";
///
/// Redact the shipping address from the PayPal site.
/// Recommended for digital goods.
///
public static string NO_SHIPPING { get; private set; } = "NO_SHIPPING";
///
/// Use the merchant-provided address.
/// The customer cannot change this address on the PayPal site.
///
public static string SET_PROVIDED_ADDRESS { get; private set; } =
"SET_PROVIDED_ADDRESS";
}
}
16、在Values文件夹中添加一个名为UserAction.cs的类。 添加以下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace PayPal.Values
{
///
/// Configures a Continue or Pay Now checkout flow.
/// Source: https://developer.paypal.com/docs/api/orders/v2/
///
public static class UserAction
{
///
/// After you redirect the customer to the PayPal payment page,
/// a Continue button appears. Use this option when the final amount is not known
/// when the checkout flow is initiated and you want to redirect
/// the customer to the merchant page without processing the payment.
///
public static string CONTINUE { get; private set; } = "CONTINUE";
///
/// After you redirect the customer to the PayPal payment page,
/// a Pay Now button appears.
/// Use this option when the final amount is known when the checkout is initiated
/// and you want to process the payment immediately
/// when the customer clicks Pay Now.
///
public static string PAY_NOW { get; private set; } = "PAY_NOW";
}
}
17、在PayPal\Values文件夹中创建一个名为Item的文件夹。
18、在Values文件夹中添加一个名为Category.cs的类。 添加以下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace PayPal.Values.Item
{
///
/// The item category type.
///
public static class Category
{
///
/// Goods that are stored, delivered, and
/// used in their electronic format.
/// This value is not currently supported for API callers that leverage the
/// [PayPal for Commerce Platform]
/// (https://www.paypal.com/us/webapps/mpp/commerce-platform) product.
///
public static string DIGITAL_GOODS { get; private set; } = "DIGITAL_GOODS";
///
/// A tangible item that can be shipped with proof of delivery.
///
public static string PHYSICAL_GOODS { get; private set; } = "PHYSICAL_GOODS";
}
}
19、最后一步是编写代码来处理调用以下代码时发生的情况:
- api/paypal/checkout/order/create
- api/paypal/checkout/order/approved/{orderId}
- api/paypal/checkout/order/complete/{orderId}
- api/paypal/checkout/order/cancel/{orderId}
- api/paypal/checkout/order/error/{orderId}/{error}
20、祝好运!