当前位置: 首页 > 知识库问答 >
问题:

发布带细分的修补订单金额-Paypal Checkout NET SDK

孙子民
2023-03-14

我在尝试用更新的总数修补PayPal订单时遇到了障碍。我使用的是他们在GitHub上提供的PayPal Checkout NET SDK,但他们为Patch Order示例提供的示例文档有点过于简单:https://github.com/paypal/Checkout-NET-SDK/blob/develop/Samples/PatchOrderSample.cs

我正在尝试更新以下路径:/purchase\u units/@reference\u id=='default'/amount'

我尝试使用以下组合设置值:

  • 一个JSON字符串,用于表示AmountBackBrodown对象
  • 一个AmountBackSubdown对象

当使用指定为值的AmountWithBreakdown对象调用API时,我遇到了一个错误。净例外:

输入PayPalCheckoutSdk。命令。不期望数据合同名称为Amount天击穿:http://schemas.datacontract.org/2004/07/PayPalCheckoutSdk.Orders的Amount天击穿。如果您正在使用数据契约序列化器,或者将静态未知的任何类型添加到已知类型列表中,请考虑使用数据契约解析程序——例如,通过使用已知类型属性或将它们添加到传递给序列化器的已知类型列表中。

生成修补程序请求的示例函数:

 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验证工具,但所有手动构建JSON作为字符串并将其分配给值的尝试都会遇到通用INVALID_PARAMETER_SYNTAX错误响应。

是否有人使用此SDK使用PayPal成功更新此数据点?我的实现是用VB实现的,但我已经掌握了用C#实现SDK的所有其他功能的要点。

共有2个答案

傅丁雷
2023-03-14

我也有这个问题,我期待着支付。HttpClient源代码并找到了适合我的解决方案。也许这对你有帮助。

public async Task<UpdatePayPalV2CheckoutPaymentResponse> UpdatePayment(string orderId, decimal amount)
{
    try
    {
        var request = new OrdersPatchRequest<object>(orderId);

        // This doesn't work bacause 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());
}
朱兴安
2023-03-14

我遇到了同样的问题。

系统运行时。序列化。序列化异常:键入“PayPalCheckoutSdk”。命令。数据合同名称为“AmountWithBreakdown”的AmountWithBreakdown:http://schemas.datacontract.org/2004/07/PayPalCheckoutSdk.Orders”他说。如果您正在使用DATACONTROTSCORALIZER或将未知类型的任何类型添加到已知类型的列表中,请考虑使用DATACONTracTracver,例如,使用NoNyType属性或将它们添加到传递给序列化程序的已知类型的列表中。

该调用从未向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;
    }
}
 类似资料:
  • 测试工程使用node发布 有些朋友在配置环境的时候cesium编程入门(三)开始使用cesium开发,在发布这个步骤出现了问题,这里补充一下使用node发布的步骤,毕竟,cesium源码下载下来也是使用node来发布,这个环境机器上应该都配置好了。 如果觉得写得不明白,也可以自己搜索一下相关资料 这里以Cesium-test为例 首先添加server.js文件,内容: var http = req

  • 问题内容: 我如何对帖子进行排序,以便最近的活动排在最前面? 我想按最新顺序对帖子进行排序,其中新帖子显然比以前发布的帖子要新,但是具有最新评论的旧帖子也可以视为最新帖子。 第一次尝试 这不起作用,因为新帖子在带有评论的旧帖子之后排序。 第二次尝试 不起作用,因为如果帖子中有多个评论,则 新近度 将匹配第一行的 创建 值,这是最早的评论。 有没有一种方法可以 按p.id分组(因此,每个帖子仅选择一

  • 问题内容: Pypubsub为您的Python应用程序提供了一种解耦其组件的简单方法:应用程序的某些部分可以发布消息(带有或不带有数据),其他部分可以订阅/接收它们。这允许消息“发件人”和消息“侦听器”彼此不知道: 一个不需要导入另一个 发件人不需要知道 “谁”得到消息, 监听者将如何处理数据, 甚至任何侦听器都将获取消息数据。 同样,听众也不必担心消息的来源。 这是用于实现模型-视图-控制器体系

  • 我目前加入了5个表来选择20个对象显示给用户,不幸的是,如果我使用和,它会变得非常慢。 查询的解释显示如下: 所以看起来它没有为表使用键,分析说明它使用2.7s复制到tmp表。 没有使用或,我尝试使用,但不幸的是,这没有改善。 我想我错过了一些基本的概念在这里和任何帮助将是感激的。 由于很可能是我弄错了表,下面是对表的描述: Objekte laender,regionen,subregionen

  • 简介 Redis 的列表类型键可以用来实现队列,并且支持阻塞式读取,所以 Redis 能够非常容易的实现一个高性能的优先队列。同时在更高层面上,Redis 还支持“发布/订阅”的消息模式,可以基于此构建一个聊天系统。 发布示例 发布(Publish)即将消息发布到频道中。示例代码: // 发送消息 Redis::publish('chan-1', 'Hello, World!'); // 发送消息

  • 请求地址 http://api.dc78.cn/Api/do_get_order 请求方式 GET 请求参数 参数 参数名称 描述 id 订单号 订单号,取自上一协议返回值 getpay=1 获取订单支付信息 获取订单支付信息 ,用于订单有支付时,一次性获取订单信息和支付信息 invoice=1 是否单独推送发票信息 设置该参数备注(memo字段)与发票信息(invoice字段)分别单独显示,不设