如何将 asp.net mvc 5 与最新的 Paypal checkout .net sdk v2 集成?
how to integrate asp.net mvc 5 with latest Paypal checkout .net sdk v2?
我尝试在带有 .Net Framework 4.7.2 的 Asp.Net MVC 5 项目中使用 Paypal Checkout SDK V2,但这似乎是我这边遗漏或错误的地方。
我只是想集成 Paypal Checkout sdk 并想创建一个订单,以便我的付款将由某个 paypal 用户进行,我只想显示一个“立即付款”按钮。
SDK link 在这里:
https://github.com/paypal/Checkout-NET-SDK
并关注了这些 links
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("\t{0}: {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>
}
我必须收到的错误如下:
我的创建 post 请求成功返回 200 状态。
此请求后,控件立即转到 Error 函数并抛出此错误。
错误: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
谁能正确指导我?我尝试了不同的文章,但仍然遇到这些错误。
当您从服务器获取 /PaypalPayments/create/
时,您会返回什么?
显然您没有返回有效 JSON,但您的代码正试图将其解析为 JSON。
更改您的服务器代码以仅返回有效 JSON。代码实际上看起来没问题,所以也许硬编码在 client-side 代码中的 /PayPalPayments/create/
路由有问题。
更改您的 client-side 代码以遵循可用的最佳示例也是明智的,该示例位于 https://developer.paypal.com/demo/checkout/#/pattern/server 并演示了如何正确处理捕获的错误
(刚刚注意到您的示例中的代码使用 actions.order.capture()
与此 server-side 集成相结合,这相当糟糕 - 似乎 server-side captureOrder 任务甚至从未被调用,这而是首先使用 server-side API 的全部意义,如果您不从服务器捕获,您将获得 none 的好处)
我尝试在带有 .Net Framework 4.7.2 的 Asp.Net MVC 5 项目中使用 Paypal Checkout SDK V2,但这似乎是我这边遗漏或错误的地方。
我只是想集成 Paypal Checkout sdk 并想创建一个订单,以便我的付款将由某个 paypal 用户进行,我只想显示一个“立即付款”按钮。
SDK link 在这里:
https://github.com/paypal/Checkout-NET-SDK
并关注了这些 links
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("\t{0}: {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>
}
我必须收到的错误如下: 我的创建 post 请求成功返回 200 状态。
此请求后,控件立即转到 Error 函数并抛出此错误。
错误: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
谁能正确指导我?我尝试了不同的文章,但仍然遇到这些错误。
当您从服务器获取 /PaypalPayments/create/
时,您会返回什么?
显然您没有返回有效 JSON,但您的代码正试图将其解析为 JSON。
更改您的服务器代码以仅返回有效 JSON。代码实际上看起来没问题,所以也许硬编码在 client-side 代码中的 /PayPalPayments/create/
路由有问题。
更改您的 client-side 代码以遵循可用的最佳示例也是明智的,该示例位于 https://developer.paypal.com/demo/checkout/#/pattern/server 并演示了如何正确处理捕获的错误
(刚刚注意到您的示例中的代码使用 actions.order.capture()
与此 server-side 集成相结合,这相当糟糕 - 似乎 server-side captureOrder 任务甚至从未被调用,这而是首先使用 server-side API 的全部意义,如果您不从服务器捕获,您将获得 none 的好处)