发布补丁订单金额与细分- Paypal Checkout.NET SDK



我遇到了一个障碍,试图用更新的总数修补PayPal订单。我正在使用他们在GitHub上提供的PayPal checkout - net sdk,但他们为补丁订单样本提供的示例文档有点过于简单:https://github.com/paypal/Checkout-NET-SDK/blob/develop/Samples/PatchOrderSample.cs

我正在尝试更新以下路径:/purchase_units/@reference_id = =‘默认’/amount"

我试过将值设置为:

  • 表示AmountWithBreakdown对象的JSON字符串
  • 一个AmountWithBreakdown对象

当调用API时,分配一个AmountWithBreakdown对象作为值,我遇到了一个。net异常:

PayPalCheckoutSdk.Orders类型"。不期望数据合约名称为"AmountWithBreakdown:http://schemas.datacontract.org/2004/07/PayPalCheckoutSdk.Orders"的AmountWithBreakdown。如果您正在使用DataContractSerializer或将任何未知类型静态地添加到已知类型列表中,请考虑使用DataContractResolver—例如,通过使用KnownTypeAttribute属性或将它们添加到传递给序列化器的已知类型列表中。

构建PATCH请求的样例函数:
Private Function BuildPatchRequest() As List(Of Patch(Of Object))
Dim patches = New List(Of Patch(Of Object)) From {
New Patch(Of Object) With {
.Op = "replace",
.Path = "/intent",
.Value = "CAPTURE"
},
New Patch(Of Object) With {
.Op = "replace",
.Path = "/purchase_units/@reference_id=='default'/amount",
.Value = New AmountWithBreakdown With {
.CurrencyCode = Me.Order.CurrencyCode,
.Value = Me.Order.Total.ToString("N2"),
.AmountBreakdown = New AmountBreakdown With {
.ItemTotal = New PayPalCheckoutSdk.Orders.Money With {.CurrencyCode = Me.Order.CurrencyCode, .Value = Me.Order.SubTotal.ToString("N2")},
.TaxTotal = New PayPalCheckoutSdk.Orders.Money With {.CurrencyCode = Me.Order.CurrencyCode, .Value = Me.Order.TaxTotal.ToString("N2")},
.Shipping = New PayPalCheckoutSdk.Orders.Money With {.CurrencyCode = Me.Order.CurrencyCode, .Value = Me.Order.ShippingTotal.ToString("N2")},
.Discount = New PayPalCheckoutSdk.Orders.Money With {.CurrencyCode = Me.Order.CurrencyCode, .Value = Me.Order.DiscountTotal.ToString("N2")},
.Handling = New PayPalCheckoutSdk.Orders.Money With {.CurrencyCode = Me.Order.CurrencyCode, .Value = Me.Order.HandlingFeeTotal.ToString("N2")},
.Insurance = New PayPalCheckoutSdk.Orders.Money With {.CurrencyCode = Me.Order.CurrencyCode, .Value = "0.00"},
.ShippingDiscount = New PayPalCheckoutSdk.Orders.Money With {.CurrencyCode = Me.Order.CurrencyCode, .Value = "0.00"}
}
}
}
}
Return patches
End Function

所有将JSON手工构造为字符串并将其分配给值的尝试都会遇到通用的INVALID_PARAMETER_SYNTAX错误响应,尽管输出传递JSON验证工具。

是否有人使用此SDK与PayPal成功更新此数据点?我的实现是在VB中,但我已经得到了实现所有其他功能的要点,SDK是在c#中采购的。

我也遇到了同样的问题。

System.Runtime.Serialization。SerializationException:类型为PayPalCheckoutSdk.Orders。不期望数据合约名称为"AmountWithBreakdown:http://schemas.datacontract.org/2004/07/PayPalCheckoutSdk.Orders"的AmountWithBreakdown。如果您正在使用DataContractSerializer或将任何未知类型静态地添加到已知类型列表中,请考虑使用DataContractResolver——例如,通过使用KnownTypeAttribute属性或将它们添加到传递给序列化器的已知类型列表中。

调用永远不会向PayPal请求响应,因为它无法序列化请求。我能够让它工作的唯一方法是在没有SDK的情况下生成我自己的请求。这不是可用于生产的代码。我只是测试一下,如果我自己制作请求,它是否会工作,它确实可以。

var ppe = PayPalClient.environment(productLine);
var accessTokenClient = new HttpClient(ppe);
var accessTokenRequest = new AccessTokenRequest(ppe, null);
var accessTokenResponse = Task.Run(async () =>
{
var httpResponse = await accessTokenClient.Execute(accessTokenRequest);
return httpResponse;
}).Result;
if (accessTokenResponse.StatusCode != HttpStatusCode.OK)
{
Logger.Error("[PayPalRestService] Unable to get access token.");
return null;
}

var accessToken = accessTokenResponse.Result<AccessToken>();
var client = new RestClient(ppe.BaseUrl());
client.AddDefaultHeader("Authorization", $"Bearer {accessToken.Token}");

var body = BuildUpdateTaxPatchRequest(cart, paypalOrder);
var request = new RestRequest($"/v2/checkout/orders/{paypalOrder.Id}")
.AddJsonBody(JsonConvert.SerializeObject(body));
var response = client.Patch(request);
if (response.StatusCode == HttpStatusCode.NoContent)
{
return GetOrder(paypalOrder.Id, productLine);
}


private static List<Patch<object>> BuildUpdateTaxPatchRequest(ICart cart, Order paypalOrder)
{
//Doc: https://developer.paypal.com/docs/api/orders/v2/#orders_patch
var subtotal = $"{cart.GetSubTotal():N2}";
var shipping = $"{cart.GetShippingTotal():N2}";
var discount = $"{cart.GetOrderDiscountTotal():N2}";
var tax = $"{cart.GetTaxTotal():N2}";
var total = double.Parse(tax, CultureInfo.GetCultureInfo("en-US")) + double.Parse(shipping, CultureInfo.GetCultureInfo("en-US")) + double.Parse(subtotal, CultureInfo.GetCultureInfo("en-US")) - double.Parse(discount, CultureInfo.GetCultureInfo("en-US"));
var strTotal = total.ToString("0.00", CultureInfo.GetCultureInfo("en-US"));

var updates = new AmountWithBreakdown()
{
CurrencyCode = paypalOrder.PurchaseUnits.First().AmountWithBreakdown.CurrencyCode,
Value = strTotal,
AmountBreakdown = new AmountBreakdown
{
ItemTotal = new Money
{
CurrencyCode = cart.Currency.CurrencyCode,
Value = subtotal
},
Shipping = new Money
{
CurrencyCode = cart.Currency.CurrencyCode,
Value = shipping
},
TaxTotal = new Money
{
CurrencyCode = cart.Currency.CurrencyCode,
Value = tax
},
}
};
var patches = new List<Patch<object>>
{
new Patch<object>
{
Op= "replace",
Path= "/purchase_units/@reference_id=='default'/amount",
Value = updates
}
};
return patches;
}
}

我也有这个问题,我看了PayPalHttp。HttpClient源代码,并找到了解决方案,为我工作。也许这对你会有帮助。

public async Task<UpdatePayPalV2CheckoutPaymentResponse> UpdatePayment(string orderId, decimal amount)
{
try
{
var request = new OrdersPatchRequest<object>(orderId);
// This doesn't work because DataContractSerializer.
// request.RequestBody(BuildPatchRequest(amount));
var json = JsonConvert.SerializeObject(BuildPatchRequest(amount));
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
await CreatePayPalClient().Execute(request);
}
catch (Exception e)
{
return new UpdatePayPalV2CheckoutPaymentResponse
{
Success = false,
Message = e.Message
};
}
return new UpdatePayPalV2CheckoutPaymentResponse
{
Success = true
};
}
private static List<Patch<object>> BuildPatchRequest(decimal amount)
{
var patches = new List<Patch<object>>
{
new Patch<object>
{
Op = "replace",
Path = "/purchase_units/@reference_id=='default'/amount",
Value = new AmountWithBreakdown
{
CurrencyCode = "USD",
Value = amount.ToString("F")
}
}
};
return patches;
}
private PayPalEnvironment CreatePayPalEnvironment()
{
PayPalEnvironment environment;
if (_orderProcessingConfiguration.PayPalCheckoutConfiguration.Sandbox)
{
environment = new SandboxEnvironment(
_orderProcessingConfiguration.PayPalCheckoutConfiguration.ClientId,
_orderProcessingConfiguration.PayPalCheckoutConfiguration.ClientSecret
);
}
else
{
environment = new LiveEnvironment(
_orderProcessingConfiguration.PayPalCheckoutConfiguration.ClientId,
_orderProcessingConfiguration.PayPalCheckoutConfiguration.ClientSecret
);
}
return environment;
}
private PayPalHttp.HttpClient CreatePayPalClient()
{
return new PayPalHttpClient(CreatePayPalEnvironment());
}

最新更新