您当前的位置: 首页 >  服务器

寒冰屋

暂无认证

  • 0浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

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

寒冰屋 发布时间:2020-08-25 22:40:36 ,浏览量:0

目录

学习成果

先决条件

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

创建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、完成简短的问卷。

  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. 您将需要一个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、祝好运!

关注
打赏
1665926880
查看更多评论
立即登录/注册

微信扫码登录

0.2371s