使用C#和ASP.NET Core的PayPal智能按钮的客户端/服务器实现

目录

学习成果

先决条件

创建具有以下行标题的电子表格

创建PayPal商业帐户

获取API凭据——即客户端ID和密码

获取实时的API凭证

什么字段添加到您的数据存储

服务器端代码


学习成果

  • 如何设置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、完成简短的问卷。

  1. 选择在我的网站上作为我主要要接受付款:问题。
  2. 选择问题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、点击公司帐户的按钮,然后选择查看/编辑帐户

  1. 在电子表格中记录系统生成的密码。

8

密码

 

8、单击关闭

9、单击个人帐户的按钮,然后选择查看/编辑帐户

在电子表格中记录用户名和密码。

11

个人(客户)

 

12

用户名

... @ personal.example.com

13

密码

 

获取实时的API凭证

1、点击我的应用和凭据(developer.paypal.com/developer/applications/)。

2、单击实时按钮。

3、点击创建应用。

在电子表格中记录应用名称。

17

应用名称

 

4、再次单击创建应用。

在电子表格中记录客户端ID和密码。

18

客户编号

 

19

密码

 

什么字段添加到您的数据存储

  1. 选择一个数据存储,例如SQL Server
  2. 您将需要一个BasketItemInvoice型号/核心类。将以下蓝色突出显示的字段添加到发票表中。这些字段将由PayPal使用。

请注意FirstNameLastNameEmail存储在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 CoreBlank 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; } = 
                             "<alert>{PayPal SANDBOX Client Id}</alert>";
        public static string SandboxClientSecret { get; set; } = 
                             "<alert>{PayPal SANDBOX Client Secret}</alert>";

        public static string LiveClientId { get; set; } = 
                      "<alert>{PayPal LIVE Client Id}</alert>";
        public static string LiveClientSecret { get; set; } = 
                      "<alert>{PayPal LIVE Client Secret}</alert>";

        ///<summary>
        /// Set up PayPal environment with sandbox credentials.
        /// In production, use LiveEnvironment.
        ///</summary>
        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(<alert>SandboxClientId</alert>,
                                          <alert>SandboxClientSecret</alert>);
#else
            return new LiveEnvironment(<alert>LiveClientId</alert>, 
                                       <alert>LiveClientSecret</alert>);
#endif
        }

        ///<summary>
        /// Returns PayPalHttpClient instance to invoke PayPal APIs.
        ///</summary>
        public static PayPalCheckoutSdk.Core.PayPalHttpClient Client()
        {
            return new PayPalHttpClient(Environment());
        }

        public static PayPalCheckoutSdk.Core.PayPalHttpClient Client(string refreshToken)
        {
            return new PayPalHttpClient(Environment(), refreshToken);
        }
        
        ///<summary>
        /// Use this method to serialize Object to a JSON string.
        ///</summary>
        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<PayPalCheckoutSdk.Orders.Order>();
        }

        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
    {
        /// <summary>
        /// Use classes from the PayPalCheckoutSdk to build an OrderRequest
        /// </summary>
        /// <returns></returns>
        public static OrderRequest Build()
        {
            OrderRequest orderRequest = new OrderRequest();
            
            // Add code to fill out the order request properties
            <alert>// See the attached source code for a more detailed example.</alert> 

            return orderRequest;
        }
    }
}

8、在名为Controllers文件夹中创建一个控制器类CheckoutController。添加以下代码:

using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;

using PayPalCheckoutSdk.Orders;

namespace Test.Controllers
{
    public class CheckoutController : Controller
    {
        /// <summary>
        /// Action to display the cart form for the SERVER side integration
        /// </summary>
        /// <returns></returns>
        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 = 
            <alert>PayPal.PayPalClient.SandboxClientId</alert>; // Get from a 
                                                       // data store or stettings
#else
            // Company LIVE Client Id. To go live replace this with the live ID.
            ViewBag.ClientId = 
            <alert>PayPal.PayPalClient.LiveClientId</alert>; // 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();
        }

        /// <summary>
        /// This action is called when the user clicks on the PayPal button.
        /// </summary>
        /// <returns></returns>
        [Route("api/paypal/checkout/order/create")]
        public async Task<PayPal.SmartButtonHttpResponse> 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<PayPalCheckoutSdk.Orders.Order>();
            var payPalHttpResponse = new PayPal.SmartButtonHttpResponse(response)
            {
                orderID = result.Id
            };
            return payPalHttpResponse;
        }

        /// <summary>
        /// This action is called once the PayPal transaction is approved
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        [Route("api/paypal/checkout/order/approved/{orderId}")]
        public IActionResult Approved(string orderId)
        {
            return Ok();
        }

        /// <summary>
        /// This action is called once the PayPal transaction is complete
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        [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();
        }

        /// <summary>
        /// This action is called once the PayPal transaction is complete
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        [Route("api/paypal/checkout/order/cancel/{orderId}")]
        public IActionResult Cancel(string orderId)
        {
            // 1. Remove the orderId from the database.
            return Ok();
        }

        /// <summary>
        /// This action is called once the PayPal transaction is complete
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        [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智能按钮。

<!-- Set up a container element for the PayPal smart button -->
<div id="paypal-button-container"></div>

<!-- Include the PayPal JavaScript SDK -->
<script src="https://www.paypal.com/sdk/js?client-id=@ViewBag.ClientId&
 currency=@ViewBag.CurrencyCode"></script>

<script>

    // 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');
</script>

除了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
{
    /// <summary>
    /// The intent to either capture payment immediately or
    /// authorize a payment for an order after order creation.
    /// </summary>
    public static class CheckoutPaymentIntent
    {
        /// <summary>
        /// The merchant intends to capture payment immediately after 
        /// the customer makes a payment.
        /// </summary>
        public static string CAPTURE { get; private set; } = "CAPTURE";

        /// <summary>
        /// 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.
        /// </summary>
        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
    {
        /// <summary>
        /// Great British Pounds
        /// </summary>
        public static string GBP { get; private set; } = "GBP";

        /// <summary>
        /// US Dolars
        /// </summary>
        public static string USD { get; private set; } = "USD";

        /// <summary>
        /// Euros
        /// </summary>
        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
{
    /// <summary>
    /// 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/
    /// </summary>
    public class LandingPage
    {
        /// <summary>
        /// When the customer clicks PayPal Checkout, 
        /// the customer is redirected to a page to log in to PayPal 
        /// and approve the payment.
        /// </summary>
        public static string LOGIN { get; private set; } = "LOGIN";

        /// <summary>
        /// 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.
        /// </summary>
        public static string BILLING { get; private set; } = "BILLING";

        /// <summary>
        /// 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.
        /// </summary>
        public static string NO_PREFERENCE { get; private set; } = "NO_PREFERENCE";
    }
}

15、在Values文件夹中添加一个称为ShippingPreference.cs的类。 添加以下代码:

namespace PayPal.Values
{
    /// <summary>
    /// 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/
    /// </summary>
    public static class ShippingPreference
    {
        /// <summary>
        /// Use the customer-provided shipping address on the PayPal site.
        /// </summary>
        public static string GET_FROM_FILE { get; private set; } = "GET_FROM_FILE";

        /// <summary>
        /// Redact the shipping address from the PayPal site. 
        /// Recommended for digital goods.
        /// </summary>
        public static string NO_SHIPPING { get; private set; } = "NO_SHIPPING";

        /// <summary>
        /// Use the merchant-provided address. 
        /// The customer cannot change this address on the PayPal site.
        /// </summary>
        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
{
    /// <summary>
    /// Configures a Continue or Pay Now checkout flow.
    /// Source: https://developer.paypal.com/docs/api/orders/v2/
    /// </summary>
    public static class UserAction
    {
        /// <summary>
        /// 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.
        /// </summary>
        public static string CONTINUE { get; private set; } = "CONTINUE";

        /// <summary>
        /// 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.
        /// </summary>
        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
{
    /// <summary>
    /// The item category type.
    /// </summary>
    public static class Category
    {
        /// <summary>
        /// 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.
        /// </summary>
        public static string DIGITAL_GOODS { get; private set; } = "DIGITAL_GOODS";

        /// <summary>
        /// A tangible item that can be shipped with proof of delivery.
        /// </summary>
        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、祝好运!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值