Search code examples
javascriptphppaypal

Paypal advanced checkout integration: how to pass amount and other data to create an order?


I'm trying to migrate the PayPal form with IPN notification to the advanced checkout using PHP and JS. I've got many doubts. The major is this:

In PHP I've got a MyOrder example class. I report only a crucial part of the createOrder() method:

// Create order
public function createOrder()
{
    $this->generateAccessToken();
    $data = [
        "intent" => "CAPTURE",
        "purchase_units" => [[
            "amount" => [
                "currency_code" => "EUR",
                "value" => "100",
            ],
            "description" => "my product",
            "soft_descriptor" => "my prod",
        ]],
        "application_context" => [
            "shipping_preference" => "NO_SHIPPING"
        ]
    ];

    $paypal_button = [
        "payment_source" => [
            "paypal" => [
                // billing address
                "address" => [
                    "address_line_1" => "aaa",
                    "address_line_2" => "aNews",
                    "admin_area_2" => "Springfield",
                    "postal_code" => "34343",
                    "admin_area_1" => "33",
                    "country_code" => "IT"
                ],
            ]
        ],
    ];

    /* We merge the two arrays above only if the order is created through the PayPal Button */
    if (isset($_GET['task']) && $_GET['task'] == 'button') $data = array_merge($data, $paypal_button);
    $requestid = "new-order-" . date("Y-m-d-h-i-s");
    $json = json_encode($data);
    $curl = curl_init();
    curl_setopt_array(
        $curl,
        array(
            CURLOPT_URL => "https://api.sandbox.paypal.com/v2/checkout/orders/",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_CUSTOMREQUEST => "POST",
            CURLOPT_HEADER => false,
            CURLOPT_HTTPHEADER => array(
                "Content-Type: application/json",
                "Authorization: Bearer " . $this->accessToken,
                "PayPal-Request-Id: " . $requestid,
                "Prefer: return=representation"
            ),
            CURLOPT_POSTFIELDS => $json,
        )
    );
    $response = curl_exec($curl);
    curl_close($curl);
    print_r($response);
}

And I also have to app.js from the same example code. When I push the button to pay, it calls the createOrder() method:

paypal
  .Buttons({
    // When a payment button is clicked, an order is created on the server and the order ID is returned
    createOrder: function (data, actions) {
      return fetch('backend.php?task=button', {
        method: "post",
        // use the "body" param to optionally pass
        // additional order information like product ids or amount. 
      })
        .then((response) => response.json())
        .then((order) => order.id);
    },

    // Finalize the transaction after payer approval
    onApprove: function (data, actions) {
         .....
    },
  }).render("#paypal-button-container");

The question is about the comment on the app.js:

// use the "body" param to optionally pass
// additional order information like product ids or amount. 

I think that I need to add to the "body" param the $data structure that I have in PHP. Do I have to modify the app.js and add the $data with a stringify? Or do I have to change it in PHP?

Do someone have an example where amount and description are parametrized?


Solution

  • Add a body parameter to the fetch. Its value should be a JSON.stringify() of a cart object or similar. Here is an example:

                  return fetch("/api/paypal/create-order", {
                    method: "POST",
                    headers: {
                      "Content-Type": "application/json",
                    },
                    body: JSON.stringify({
                      cart: [
                        {
                          sku: "1blwyeo8",
                          quantity: 2,
                        },
                        {
                          sku: "i5b1g92y",
                          quantity: 1,
                        }
                      ],
                    }),
                  })
                    .then((response) => response.json())
                    .then((orderData) => {
                      if (orderData?.id) {
                        return orderData.id;
                      } else {
    

    (from: https://github.com/paypal-examples/paypal-sdk-server-side-integration/blob/main/public/buttons.html#L51 )

    The PHP will receive the JSON as a post data string, which it can then decode into a PHP array and utilize the cart object it receives. (Look up a guide on how to read JSON input with PHP if you need it, because it is not $_POST like form data.)

    The contents of the object/array should essentially reflect the user's cart contents: a list of item IDs (sku i.e. stock keeping unit is the parameter name used by the PayPal v2 Orders API) and their quantities.

    The backend should iterate over the cart array to calculate a total, and it can also include an amount with breakdown and items array which will show in the PayPal transaction details. The amount breakdown object is required if including an items array. See the create order API reference for details.