Brille24 / SyliusCustomOptionsPlugin

A Sylius plugin that adds customer options
MIT License
46 stars 34 forks source link

Paypal Checkout Amount mismatch #143

Open bellu opened 1 year ago

bellu commented 1 year ago

Hi,

i'm using a fixed amount price for some of my product's customization, but the paypal checkout it's not working anymore. I think it's because of the price on the custom option, i'm having an amount mismatch. I'm using the version 2.16.1.

Attached the paypal log:

{
  "additional_properties": "xxxxxx",
  "body": {
    "application_context": {
      "shipping_preference": "SET_PROVIDED_ADDRESS"
    },
    "intent": "CAPTURE",
    "purchase_units": [
      {
        "amount": {
          "breakdown": {
            "discount": {
              "currency_code": "EUR",
              "value": "0.00"
            },
            "item_total": {
              "currency_code": "EUR",
              "value": "68.00"
            },
            "shipping": {
              "currency_code": "EUR",
              "value": "10.00"
            },
            "tax_total": {
              "currency_code": "EUR",
              "value": "0.00"
            }
          },
          "currency_code": "EUR",
          "value": "88.00"
        },
        "invoice_number": "xxxxxx",
        "items": [
          {
            "name": "Agenda Giornaliera Classic in pelle 2024 - 11x16 cm",
            "quantity": 1,
            "tax": {
              "currency_code": "EUR",
              "value": "0.00"
            },
            "unit_amount": {
              "currency_code": "EUR",
              "value": "68.00"
            }
          }
        ],
        "payee": {
          "merchant_id": "XXXXXXXXXX"
        },
        "reference_id": "XXXXXXXXXX",
        "shipping": {
          "address": {
            "address_line_1": "*****",
            "admin_area_2": "Empoli",
            "country_code": "IT",
            "postal_code": "50053"
          },
          "name": {
            "full_name": "*****"
          }
        },
        "soft_descriptor": "Sylius PayPal Payment"
      }
    ]
  },
  "header": {
    "accept": "application/json",
    "akamai-x-forwarded-for-7": "xxxxxx",
    "authorization": "xxxxx",
    "client-auth": "xxxxx",
    "client_info": "xxxxxx",
    "content-length": "921",
    "content-type": "application/json",
    "correlation-id": "0b18c0fae5797",
    "edge-locator": "xxxxxx",
    "host": "api.paypal.com",
    "paypal-partner-attribution-id": "Sylius_MP_PPCP",
    "paypal-request-id": "XXXXXXXXX",
    "paypal-routing-metadata": "xxxxxx",
    "pp_client_ssl_cipher": "XXXXXXXX",
    "pp_client_ssl_protocol": "TLSv1.3",
    "pp_geo_loc": "DE",
    "pp_remote_addr": "XXXXXXX",
    "pp_vip": "XXXXXXXX",
    "traceparent": "xxxxxx",
    "user-agent": "GuzzleHttp/6.5.5 curl/7.68.0 PHP/7.4.3-4ubuntu2.19",
    "x-b3-spanid": "xxxxxx",
    "x-forwarded-for": "XXXXXX",
    "x-forwarded-proto": "xxxxxx",
    "x-paypal-correlation-id": "XXXXXXXX",
    "x-pp-corrid": "XXXXXXXX",
    "x-pp-idempotencyid": "XXXXXX",
    "x-pp-slingshot-targetapp": "apiplatformproxyserv",
    "x-sigsci-agentresponse": "xxxxxx",
    "x-sigsci-mac": "xxxxxx",
    "x-sigsci-requestid": "xxxxxx",
    "x-slr-orig-script_uri": "https://api.paypal.com/v2/checkout/orders"
  },
  "method": "POST"
}

{
  "additional_properties": "xxxxxx",
  "body": {
    "debug_id": "XXXXXXX",
    "details": [
      {
        "description": "Should equal item_total + tax_total + shipping + handling + insurance - shipping_discount - discount.",
        "field": "/purchase_units/@reference_id=='XXXXXXXXX'/amount/value",
        "issue": "AMOUNT_MISMATCH",
        "value": "xxxxxx"
      }
    ],
    "links": [
      {
        "href": "https://developer.paypal.com/docs/api/orders/v2/#error-AMOUNT_MISMATCH",
        "method": "GET",
        "rel": "information_link"
      }
    ],
    "message": "The requested action could not be performed, semantically incorrect, or failed business validation.",
    "name": "UNPROCESSABLE_ENTITY"
  },
  "duration_time": 84,
  "header": {
    "APPLICATION_ID": "APP-XXXXXXXX",
    "Access-Control-Expose-Headers": "xxxxxx",
    "BORDER-IP": "xxxxxx",
    "CALLER_ACCT_NUM": "XXXXXXXX",
    "Date": "Thu, 14 Sep 2023 09:49:38 GMT",
    "Keep-Alive": "xxxxxx",
    "PROCESSING-IP": "xxxxxx",
    "SERVER_INFO": "xxxxxx",
    "Server-Timing": "xxxxxx",
    "paypal-debug-id": "XXXXXXXXX"
  },
  "status": 422
}
mamazu commented 1 year ago

Hey thanks for reporting this bug. Currently we haven't looked into supporting the paypal plugin of Sylius explicitly and I have no idea where Sylius is taking the individual prices from. We are using the adjustment mechanic of Sylius, which means that it should just add the customer option prices to the total before submitting them to paypal.

From the response debug output I take is that Sylius is trying to add all of those

            "discount": "0.00"
            "item_total": "68.00"
            "shipping": "10.00"
            "tax_total": "0.00"

Which is not the same as

{
          "currency_code": "EUR",
          "value": "88.00"
}

It looks like the item total of the order is missing the customer options. As I said I don't know how the paypal plugin works.

However it looks like you might need to add a functions to your OrderItem class:

    /**
     * Overriding sylius' total calculation to also take customer options into account.
     */
    public function getSubtotal(): int
    {
        return parent::getSubtotal() + $this->getAdjustmentsTotalRecursively(CustomerOptionRecalculator::CUSTOMER_OPTION_ADJUSTMENT);
    }

I hope this helps other than that, you'd have to see if there is anything you can do to fix the prices when exporting them to paypal.