如何将 asp.net mvc 5 与最新的 Paypal checkout .net sdk v2 集成?
Posted
技术标签:
【中文标题】如何将 asp.net mvc 5 与最新的 Paypal checkout .net sdk v2 集成?【英文标题】:how to integrate asp.net mvc 5 with latest Paypal checkout .net sdk v2? 【发布时间】:2021-02-19 03:42:14 【问题描述】:我尝试在我的 Asp.Net MVC 5 项目中使用 Paypal Checkout SDK V2 和 .Net Framework 4.7.2,但这似乎是我的缺失或错误。
我只是想集成 Paypal Checkout sdk 并想创建一个订单,以便我的付款将由一些 paypal 用户进行,我只想显示一个“立即付款”按钮。
SDK 链接在这里:
https://github.com/paypal/Checkout-NET-SDK
并点击这些链接
https://developer.paypal.com/docs/checkout/reference/server-integration/get-transaction/#on-the-client https://developer.paypal.com/demo/checkout/#/pattern/server
这是我尝试的代码
C# Code
public class CheckoutController : Controller
public ActionResult Index()
ViewBag.ClientId = PayPalClient.ClientId;
ViewBag.CurrencyCode = "GBP"; // Get from a data store
ViewBag.CurrencySign = "£"; // Get from a data store
return View();
//[Route("api/paypal/checkout/order/create")]
public async static Task<HttpResponse> createOrder()
HttpResponse response;
// Construct a request object and set desired parameters
// Here, OrdersCreateRequest() creates a POST request to /v2/checkout/orders
var order = new OrderRequest()
CheckoutPaymentIntent = "CAPTURE",
PurchaseUnits = new List<PurchaseUnitRequest>()
new PurchaseUnitRequest()
AmountWithBreakdown = new AmountWithBreakdown()
CurrencyCode = "USD",
Value = "100.00"
,
ApplicationContext = new ApplicationContext()
ReturnUrl = "https://www.example.com",
CancelUrl = "https://www.example.com"
;
// Call API with your client and get a response for your call
var request = new OrdersCreateRequest();
request.Prefer("return=representation");
request.RequestBody(order);
response = await PayPalClient.Client().Execute(request);
var statusCode = response.StatusCode;
Order result = response.Result<Order>();
Console.WriteLine("Status: 0", result.Status);
Console.WriteLine("Order Id: 0", result.Id);
Console.WriteLine("Intent: 0", result.CheckoutPaymentIntent);
Console.WriteLine("Links:");
foreach (LinkDescription link in result.Links)
Console.WriteLine("\t0: 1\tCall Type: 2", link.Rel, link.Href, link.Method);
return response;
public async static Task<HttpResponse> captureOrder()
// Construct a request object and set desired parameters
// Replace ORDER-ID with the approved order id from create order
var request = new OrdersCaptureRequest("APPROVED-ORDER-ID");
request.RequestBody(new OrderActionRequest());
HttpResponse response = await PayPalClient.Client().Execute(request);
var statusCode = response.StatusCode;
Order result = response.Result<Order>();
Console.WriteLine("Status: 0", result.Status);
Console.WriteLine("Capture Id: 0", result.Id);
return response;
/// <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<SmartButtonHttpResponse> Create()
var request = new PayPalCheckoutSdk.Orders.OrdersCreateRequest();
request.Prefer("return=representation");
request.RequestBody(OrderBuilder.Build());
// Call PayPal to set up a transaction
var response = await PayPalClient.Client().Execute(request);
// Create a response, with an order id.
var result = response.Result<PayPalCheckoutSdk.Orders.Order>();
var payPalHttpResponse = new 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 ActionResult Approved(string orderId)
return Json("Sucess", JsonRequestBehavior.AllowGet);
/// <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 ActionResult Complete(string orderId)
// 1. Update the database.
// 2. Complete the order process. Create and send invoices etc.
// 3. Complete the shipping process.
return Json("Completed", JsonRequestBehavior.AllowGet);
/// <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 ActionResult Cancel(string orderId)
// 1. Remove the orderId from the database.
return Json("Cancel", JsonRequestBehavior.AllowGet);
/// <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 ActionResult Error(string orderId,
string error)
// Log the error.
// Notify the user.
string temp = System.Web.HttpUtility.UrlDecode(error);
return Json(temp, JsonRequestBehavior.AllowGet);
public static class OrderBuilder
/// <summary>
/// Use classes from the PayPalCheckoutSdk to build an OrderRequest
/// </summary>
/// <returns></returns>
public static OrderRequest Build()
// Construct a request object and set desired parameters
// Here, OrdersCreateRequest() creates a POST request to /v2/checkout/orders
OrderRequest order = new OrderRequest()
CheckoutPaymentIntent = "CAPTURE",
PurchaseUnits = new List<PurchaseUnitRequest>()
new PurchaseUnitRequest()
AmountWithBreakdown = new AmountWithBreakdown()
CurrencyCode = "USD",
Value = "100.00"
,
ApplicationContext = new ApplicationContext()
ReturnUrl = "https://www.example.com",
CancelUrl = "https://www.example.com"
;
// Call API with your client and get a response for your call
var request = new OrdersCreateRequest();
request.Prefer("return=representation");
request.RequestBody(order);
return order;
public class PayPalClient
public static string ClientId = " your client id";
public static string Secrets = "your client secret";
public static string SandboxClientId get; set; =
"<alert>SandboxClientId</alert>";
public static string SandboxClientSecret get; set; =
"<alert>SandboxClientSecret</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>";
public static PayPalEnvironment Environment()
//return new SandboxEnvironment("<alert>SandboxClientId</alert>",
// "<alert>SandboxClientSecret</alert>");
return new SandboxEnvironment(ClientId, Secrets);
public static PayPalCheckoutSdk.Core.PayPalHttpClient Client()
return new PayPalHttpClient(Environment());
public static PayPalCheckoutSdk.Core.PayPalHttpClient Client(string refreshToken)
return new PayPalHttpClient(Environment(), refreshToken);
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();
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;
View html is
<!-- Set up a container element for the PayPal smart button -->
<div id="paypal-button-container"></div>
@section scripts
<script src="https://www.paypal.com/sdk/js?client-id=@ViewBag.ClientId"></script>
<script type="text/javascript">
var orderId;
function httpGet(url)
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", url, false);
xmlHttp.send(null);
return xmlHttp.responseText;
paypal.Buttons(
// Set up the transaction
enableStandardCardFields: true,
createOrder: function (data, actions)
orderId = data.orderID;
console.log("Start");
console.log(data);
console.log(actions);
console.log("End");
return fetch(
'/PaypalPayments/create/',
method: 'post'
).then(function (res)
return res.json();
).then(function (data)
return data.orderID;
);
,
// Finalise the transaction
onApprove: function (data, actions)
return fetch('/PaypalPayments/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('/PaypalPayments/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('/PaypalPayments/cancel/' + data.orderID);
,
// An error occurred during the transaction
onError: function (err)
debugger;
fetch(
'/PaypalPayments/error/',
method: 'post',
headers: 'Content-type': 'application/json' ,
body: JSON.stringify( orderId: orderId, error: encodeURIComponent(err))
).then(function (res)
return res.json();
).then(function (data)
return data.orderID;
);
).render('#paypal-button-container');
</script>
我必须收到的错误如下: 我的创建帖子请求成功,返回 200 状态。
在这个请求之后,控件立即进入错误函数并抛出这个错误。
错误:JSON 中位置 0 处的意外标记 P"
下面提到了完整的错误细节
SyntaxError: Unexpected token P in JSON at position 0
Error: Unexpected token P in JSON at position 0
at Qt.error (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:60544)
at Object.<anonymous> (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:68311)
at JSON.parse (<anonymous>)
at o (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:68170)
at dr (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:68323)
at u.on (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:72994)
at br (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:73131)
at https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:79250
at Function.n.try (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:14118)
at https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:79047
Error: Unexpected token P in JSON at position 0
at Qt.error (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:60544)
at Array.<anonymous> (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:68311)
at JSON.parse (<anonymous>)
at o (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:68170)
at dr (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:68323)
at u.on (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:72994)
at br (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:73131)
at https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:79250
at Function.n.try (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:14118)
at https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:79047
有人可以正确指导我吗?我尝试了不同的文章,但仍然收到这些错误。
【问题讨论】:
如果您正在寻找 ASP.NET(Web 表单或核心 MVC)中 PayPal 结账的最新解决方案(使用带有 PayPal JavaScript SDK、服务器端集成的 Orders v2 REST API),请查看演示 > >>techtolia.com/PayPal 【参考方案1】:当您从服务器获取/PaypalPayments/create/
时,您会返回什么?
显然您没有返回有效的 JSON,但您的代码正在尝试将其解析为 JSON。
更改您的服务器代码以仅返回有效的 JSON。代码实际上看起来没问题,所以客户端代码中硬编码的 /PayPalPayments/create/
路由可能有问题。
更改客户端代码以遵循https://developer.paypal.com/demo/checkout/#/pattern/server 上的最佳示例也是明智之举,该示例演示了如何正确处理捕获错误
(刚刚注意到您的示例中的代码使用actions.order.capture()
与此服务器端集成相结合,这相当糟糕——似乎服务器端 captureOrder 任务甚至从未被调用,这正是使用服务器的重点-side APIs,如果你不从服务器捕获,你将得不到任何好处)
【讨论】:
谢谢普雷斯顿 PHX。我还在想它会怎么样?你能看看吗?我已删除 actions.order.capture() 并从 createOrder 返回 res/*.json()*/。但仍有问题。查看新错误。 1)。 create_order_error err:“错误:postMessage createOrder() i 2) 没有 ack。click_initiate_payment_reject err:“错误:htt 中 postMessage createOrder() 没有 ack…47fPl3cl 3).unhandled_error err:“错误:postMessage 没有 ack kn() in www.…47fPl3cligEbl Prestob PHX,你在吗?我们可以做一个远程桌面吗?我想展示。在服务器端的代码中,我在 payPalHttpResponse 对象中添加了 orderId 和 OrderResult。但是当响应来自针对 createOrder 的 fetch 函数时,两者都丢失了 修复了 PrestobPHX 的问题。你的解决方案奏效了。我的服务器端调用不正确。谢谢以上是关于如何将 asp.net mvc 5 与最新的 Paypal checkout .net sdk v2 集成?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Web API 添加到现有的 ASP.NET MVC (5) Web 应用程序项目中?
使用 ASP.NET 5 MVC 6 Web API 进行 Cookie 身份验证
ASP.Net MVC 5 身份验证与另一个 MVC 5 身份网站
如何只显示数据库中最近的 5 条记录 - ASP.NET MVC