You are here

public function ExpressCheckout::setExpressCheckout in Commerce PayPal 8

SetExpressCheckout API Operation (NVP) request.

Builds the data for the request and make the request.

Parameters

\Drupal\commerce_payment\Entity\PaymentInterface $payment: The payment.

array $extra: Extra data needed for this request.

Return value

array PayPal response data.

Overrides ExpressCheckoutInterface::setExpressCheckout

See also

https://developer.paypal.com/docs/classic/api/merchant/SetExpressCheckou...

File

src/Plugin/Commerce/PaymentGateway/ExpressCheckout.php, line 458

Class

ExpressCheckout
Provides the Paypal Express Checkout payment gateway.

Namespace

Drupal\commerce_paypal\Plugin\Commerce\PaymentGateway

Code

public function setExpressCheckout(PaymentInterface $payment, array $extra) {
  $order = $payment
    ->getOrder();
  $amount = $this->rounder
    ->round($payment
    ->getAmount());
  $configuration = $this
    ->getConfiguration();
  if ($extra['capture']) {
    $payment_action = 'Sale';
  }
  else {
    $payment_action = 'Authorization';
  }

  // Build a name-value pair array for this transaction.
  $nvp_data = [
    'METHOD' => 'SetExpressCheckout',
    // Default the Express Checkout landing page to the Mark solution.
    'SOLUTIONTYPE' => 'Mark',
    'LANDINGPAGE' => 'Login',
    // Disable entering notes in PayPal, we don't have any way to accommodate
    // them right now.
    'ALLOWNOTE' => '0',
    'PAYMENTREQUEST_0_PAYMENTACTION' => $payment_action,
    'PAYMENTREQUEST_0_AMT' => $amount
      ->getNumber(),
    'PAYMENTREQUEST_0_CURRENCYCODE' => $amount
      ->getCurrencyCode(),
    'PAYMENTREQUEST_0_INVNUM' => $order
      ->id() . '-' . $this->time
      ->getCurrentTime(),
    // Set the return and cancel URLs.
    'RETURNURL' => $extra['return_url'],
    'CANCELURL' => $extra['cancel_url'],
  ];

  // Check if there is a reference transaction, and also see if a billing
  // agreement was supplied.
  if (!empty($configuration['reference_transactions']) && !empty($configuration['ba_desc'])) {
    $nvp_data['BILLINGTYPE'] = 'MerchantInitiatedBillingSingleAgreement';
    $nvp_data['L_BILLINGTYPE0'] = 'MerchantInitiatedBillingSingleAgreement';
    $nvp_data['L_BILLINGAGREEMENTDESCRIPTION0'] = $configuration['ba_desc'];
  }

  // If Express Checkout Account Optional is enabled...
  if ($configuration['solution_type'] != 'Mark') {

    // Update the solution type and landing page parameters accordingly.
    $nvp_data['SOLUTIONTYPE'] = 'Sole';
    if ($configuration['solution_type'] == 'SoleBilling') {
      $nvp_data['LANDINGPAGE'] = 'Billing';
    }
  }

  // Add itemized information to the API request.
  $nvp_data += $this
    ->itemizeOrder($order, $amount
    ->getCurrencyCode());

  // If the shipping module is not enabled, or if
  // "Shipping address collection" is configured to not send the address to
  // PayPal, set the NOSHIPPING parameter to 1.
  if ($configuration['shipping_prompt'] == self::SHIPPING_SKIP || !$this->moduleHandler
    ->moduleExists('commerce_shipping')) {
    $nvp_data['NOSHIPPING'] = '1';
  }
  else {

    // Check if the order references shipments.
    if ($order
      ->hasField('shipments') && !$order
      ->get('shipments')
      ->isEmpty()) {

      // Gather the shipping profiles and only send shipping information if
      // there's only one shipping profile referenced by the shipments.
      $shipping_profiles = [];

      // Loop over the shipments to collect shipping profiles.
      foreach ($order
        ->get('shipments')
        ->referencedEntities() as $shipment) {
        if ($shipment
          ->get('shipping_profile')
          ->isEmpty()) {
          continue;
        }
        $shipping_profile = $shipment
          ->getShippingProfile();
        $shipping_profiles[$shipping_profile
          ->id()] = $shipping_profile;
      }

      // Don't send the shipping profile if we found more than one.
      if ($shipping_profiles && count($shipping_profiles) === 1) {
        $shipping_profile = reset($shipping_profiles);

        /** @var \Drupal\address\AddressInterface $address */
        $address = $shipping_profile->address
          ->first();
        $name = $address
          ->getGivenName() . ' ' . $address
          ->getFamilyName();
        $shipping_info = [
          'PAYMENTREQUEST_0_SHIPTONAME' => substr($name, 0, 32),
          'PAYMENTREQUEST_0_SHIPTOSTREET' => substr($address
            ->getAddressLine1(), 0, 100),
          'PAYMENTREQUEST_0_SHIPTOSTREET2' => substr($address
            ->getAddressLine2(), 0, 100),
          'PAYMENTREQUEST_0_SHIPTOCITY' => substr($address
            ->getLocality(), 0, 40),
          'PAYMENTREQUEST_0_SHIPTOSTATE' => substr($address
            ->getAdministrativeArea(), 0, 40),
          'PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE' => $address
            ->getCountryCode(),
          'PAYMENTREQUEST_0_SHIPTOZIP' => substr($address
            ->getPostalCode(), 0, 20),
        ];

        // Filter out empty values.
        $nvp_data += array_filter($shipping_info);

        // Do not prompt for an Address at Paypal.
        if ($configuration['shipping_prompt'] != self::SHIPPING_ASK_ALWAYS) {
          $nvp_data += [
            'NOSHIPPING' => '1',
            'ADDROVERRIDE' => '1',
          ];
        }
        else {
          $nvp_data += [
            'NOSHIPPING' => '0',
            'ADDROVERRIDE' => '0',
          ];
        }
      }
      else {
        $nvp_data['NOSHIPPING'] = '0';
      }
    }
  }

  // Send the order's email if not empty.
  if (!empty($order
    ->getEmail())) {
    $nvp_data['PAYMENTREQUEST_0_EMAIL'] = $order
      ->getEmail();
  }

  // Make the PayPal NVP API request.
  return $this
    ->doRequest($nvp_data, $order);
}