PayPal отвечает CANNOT_MIX_CURRENCIES при изменении валюты единицы покупки

Я продаю товар, цена и валюта которого зависят от адреса доставки.

Если у пользователя два адреса, один в США, а другой в Великобритании, он сможет изменить адрес доставки через PayPal. Когда пользователь меняет регион с США на Великобританию, PayPal сообщает моему сайту, что произошло изменение региона, и он отвечает с новой валютой и ценой, изменяющейся с 345 долларов на 305 фунтов стерлингов.

Когда PayPal получает это обновление, PayPal отображает ошибку для покупателя. Во вкладке сети есть больше информации, и можно найти следующую ошибку: CANNOT_MIX_CURRENCIES. Однако и цены на товары, и общие цены конвертируются в желаемую валюту, поэтому нет смешивания валют. Ниже приведен запрос и соответствующий ответ, в котором возникает ошибка.

Запрос: PATCH - ›www.sandbox.paypal.com/smart/api / order / 890595684S747592L / patch

{
    "data":{
        "patch":[
            {
                "op":"replace",
                "path":"/purchase_units/@reference_id=='xxx'",
                "value":{
                    "reference_id":"xxx",
                    "invoice_id":"xxx",
                    "custom_id":1,
                    "description":"xxx",
                    "amount":{
                        "currency_code":"GBP",
                        "value":"305.00",
                        "breakdown":{
                            "item_total":{
                                "currency_code":"GBP",
                                "value":"305.00"
                            },
                            "shipping":{
                                "currency_code":"GBP",
                                "value":"0.00"
                            },
                            "tax_total":{
                                "currency_code":"GBP",
                                "value":"0.00"
                            },
                            "discount":{
                                "currency_code":"GBP",
                                "value":"0.00"
                            }
                        }
                    },
                    "items":[
                        {
                            "name":"xxx",
                            "sku":"xxx",
                            "currency":"GBP",
                            "quantity":1,
                            "category":"PHYSICAL_GOODS",
                            "unit_amount":{
                                "currency_code":"GBP",
                                "value":"305.00"
                            }
                        }
                    ]
                }
            }
        ]
    }

}

Ответ:

{
  "ack":"contingency",
  "contingency":"UNPROCESSABLE_ENTITY",
  "data": {
    "name":"UNPROCESSABLE_ENTITY",
    "details":[{ 
      "location":"body",
      "issue":"CANNOT_MIX_CURRENCIES",
      "description":"CANNOT_MIX_CURRENCIES"
    }],
    "message":"The requested action could not be performed, semantically incorrect, or failed business validation.",
    "debug_id":"xxx",
    "links":[{
      "href":"https://developer.paypal.com/docs/api/orders/v2/#error-CANNOT_MIX_CURRENCIES",
      "rel":"information_link",
      "method":"GET"
    }]
  },
  "meta":{"calc":"xxx","rlog":"xxx"},
  "server":"xxx"
}

Ниже приведен запрос (и ответ) на создание единицы покупки выше.

Запрос: POST - ›POST -› www.sandbox.paypal.com/v2/checkout/ заказы

{
    "intent":"CAPTURE",
    "purchase_units":[
        {
            "reference_id":"xxx",
            "invoice_id":"xxx",
            "custom_id":1,
            "description":"xxx",
            "amount":{
                "currency_code":"USD",
                "value":"345.00",
                "breakdown":{
                    "item_total":{
                        "currency_code":"USD",
                        "value":"345.00"
                    },
                    "shipping":{
                        "currency_code":"USD",
                        "value":"0.00"
                    },
                    "tax_total":{
                        "currency_code":"USD",
                        "value":"0.00"
                    },
                    "discount":{
                        "currency_code":"USD",
                        "value":"0.00"
                    }
                }
            },
            "items":[
                {
                    "name":"xxx",
                    "sku":"xxx",
                    "currency":"USD",
                    "quantity":1,
                    "category":"PHYSICAL_GOODS",
                    "unit_amount":{
                        "currency_code":"USD",
                        "value":"345.00"
                    }
                }
            ]
        }
    ],
    "application_context":{
        "shipping_preference":"GET_FROM_FILE"
    }
}

Ответ:

{
    "id":"xxx",
    "status":"CREATED",
    "links":[
        {
            "href":"https://api.sandbox.paypal.com/v2/checkout/orders/xxx",
            "rel":"self",
            "method":"GET"
        },
        {
            "href":"https://www.sandbox.paypal.com/checkoutnow?token=xxx",
            "rel":"approve",
            "method":"GET"
        },
        {
            "href":"https://api.sandbox.paypal.com/v2/checkout/orders/xxx",
            "rel":"update",
            "method":"PATCH"
        },
        {
            "href":"https://api.sandbox.paypal.com/v2/checkout/orders/xxx/capture",
            "rel":"capture",
            "method":"POST"
        }
    ]
}

Я использую PayPal Orders API v2 через response-paypal-button-v2 пакет npm.

В документации для CANNOT_MIX_CURRENCIES упоминается, что все валюты в покупной единице должны быть одинаковыми, но не упоминается, что изменение валюты покупной единицы невозможно. Что-то сбивает с толку то, что я смог найти упоминание об этой ошибке (CANNOT_MIX_CURRENCIES) только в Billing Agreement API v1.

CANNOT_MIX_CURRENCIES

Код валюты недействителен. Все коды валют очень совпадают. Используйте один и тот же код валюты для всех объектов суммы.


person higab85    schedule 16.09.2020    source источник


Ответы (1)


В строке <script>, где вы загружаете SDK, по умолчанию используется валюта в долларах США, и валюта этой строки SDK имеет значение, поскольку она используется для определения того, какие кнопки могут отображаться до вызова объекта orders v2.

Если вам нужно изменить валюту после загрузки страницы, вы можете перезагрузить SDK асинхронно.

function loadAsync(url, callback) {
    var s = document.createElement('script');
    s.setAttribute('src', url); s.onload = callback;
    document.head.insertBefore(s, document.head.firstElementChild);
}

// Usage:

loadAsync('https://www.paypal.com/sdk/js?client-id=sb&currency=USD', function() {
  paypal.Buttons({
    createOrder: function(data, actions) {
        //your code here
    },
    onApprove: function(data, actions) {
        //your code here
    }
  }).render('body');  // Replace with selector to render in
});

В качестве альтернативы есть пакет узлов, если вам нравятся зависимости более трех строковых функций :) https://github.com/paypal/paypal-js

person Preston PHX    schedule 16.09.2020
comment
Спасибо за быстрый ответ. Единственная проблема с этим заключается в том, что каждый раз, когда меняется валюта, сеанс с PayPal перезагружается, что заставляет пользователя снова нажимать Pay на нашем сайте. Валюта меняется во время сеанса с PayPal. - person higab85; 21.09.2020
comment
Перед отправкой пользователя в PayPal вы должны разобраться в этой детали. - person Preston PHX; 22.09.2020
comment
Извините, предыдущее сообщение было не очень ясным. Пользователь может изменить свой адрес (и, следовательно, валюту для внесения оплаты) в PayPal, поэтому эту деталь нельзя разобрать раньше. Я мог бы пометить изменения адресов за пределами предварительно выбранной области как недопустимые, но я хотел бы разрешить пользователю вносить изменения, если это возможно. - person higab85; 22.09.2020
comment
Почему смена адреса требует смены валюты? В любом случае, валюта должна быть известна, прежде чем можно будет отобразить кнопки. - person Preston PHX; 22.09.2020
comment
спасибо, я думаю, это сэкономило мне несколько часов на отладку - person Jamie Mason; 13.01.2021