I've got a patch which enhances the Payflow gateway by adding additional order details to the Payflow requests, as well as cleaning up a few code styling and variable naming issues along the way. I'm splitting that out from a larger patch and will post it here shortly.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

bmcclure created an issue. See original summary.

replicaobscura’s picture

Adding related issue for the issue these changes originally came from (the patch in comment #10 there)

replicaobscura’s picture

Status: Active » Needs review
StatusFileSize
new8.67 KB

Here are the changes split out into a separate patch.

bojanz’s picture

+    if ($order->hasField('shipping_profile') && !$order->get('shipping_profile')->isEmpty()) {
+      $shipping_profile = $order->get('shipping_profile')->entity;

This is odd.
Commerce Shipping doesn't add such a field. Why would we add integration for a non-Shipping-provided field?
Sounds like we need an alter mechanism (== event) instead.

replicaobscura’s picture

Hm, I don't know why it works for me if commerce_shipping doesn't add that field, I guess another patch I was using may have introduced it or something. That should be changed to some standard way to access the shipping profile in that case.

I think even if it's the wrong field name or mechanism for accessing the shipping profile, it seems like it still makes sense to support commerce_shipping within commerce_paypal if it's enabled (using a better mechanism to access the profile). Otherwise, commerce_shipping would need to support commerce_paypal and that doesn't seem right to me as shipping is a much broader module than a particular payment processor. A higher percentage of commerce_paypal users will be using commerce_shipping than the percentage of commerce_shipping users using commerce_paypal.

Unless you're suggesting the event model in order to separate the logic into a submodule of commerce_paypal (though I don't think there's enough code for that to be necessary), or simply to split the logic out of that file into a class dedicated to shipping, which I could understand. Or, the other reason I could see for that to be handled in an event would be to require users to add support for commerce_shipping on their own rather than supporting shipping within commerce_paypal, but that seems unnecessarily burdensome when a significant portion of users will likely be using shipping.

I'm not opposed to using an event for it in general, to allow other modifications to it besides for just supporting shipping, but I still feel that the shipping use case should be supported by default if the order has shipping information (obviously using a more standard way to access the profile since you indicated this isn't normal).

Unless there's some reason not to support shipping by default?

mglaman’s picture

  1. +++ b/src/Plugin/Commerce/PaymentGateway/Payflow.php
    @@ -210,15 +212,124 @@ class Payflow extends OnsitePaymentGatewayBase implements PayflowInterface {
    +      'invnum' => $order->getOrderNumber(),
    

    The order number isn't populated until the order is placed, so this will be empty.

  2. +++ b/src/Plugin/Commerce/PaymentGateway/Payflow.php
    @@ -210,15 +212,124 @@ class Payflow extends OnsitePaymentGatewayBase implements PayflowInterface {
    +    if ($order->hasField('shipping_profile') && !$order->get('shipping_profile')->isEmpty()) {
    +      $shipping_profile = $order->get('shipping_profile')->entity;
    +      if ($shipping_profile instanceof ProfileInterface) {
    +        $parameters = $this->populateShippingProfileParameters($parameters, $shipping_profile);
    +      }
    +    }
    

    I think we should just remove this, for now. Or check if shipping module is enabled.

  3. +++ b/src/Plugin/Commerce/PaymentGateway/Payflow.php
    @@ -210,15 +212,124 @@ class Payflow extends OnsitePaymentGatewayBase implements PayflowInterface {
    +  protected function populateBillingProfileParameters(array $parameters, ProfileInterface $profile) {
    

    Why should this be split out of the main function?

replicaobscura’s picture

I do think it could be useful to submit shipping information to PayFlow, but I agree that it should at least check if commerce_shipping is enabled first. Or this could be abstracted into an event with a submodule used for commerce_shipping, but that seems kind of heavy for such a simple bit of code.

The main reason to split out the function is that mapping profile parameters seems like it should be a separate concern to me. All the main function should care about is that the profile parameters get populated, but which fields map where, and how they're retrieved, seems like a prime candidate for abstraction.

I would be fine with combining the functions if preferred, I just tend to prefer keeping functions small and focused to a single concern if possible.

shaunole made their first commit to this issue’s fork.

shaunole’s picture

I'm attempting to tackle this from another direction - similar to how the CheckoutSdk.php handles modifying the PayPal request params. Perhaps, we should allow the parameters to be specified via an Event Subscriber when the payment is created via Payflow. I've incorporated a few changes that create a new Event for Payflow payment creation, and that dispatch said event within the createPayment() method.

Custom modules should be able to subscribe to the PayPalEvents::PAYFLOW_CREATE_PAYMENT event and modify the request parameters as needed.

shaunole’s picture

It appears that the latest test failure is due to a previously existing "Symmetric array destructuring" assignment - this feature was introduced in PHP 7.1 (I'm assuming that the test runner is using PHP 7.0?). This is the offending code block from line 296 of src/Plugin/Commerce/PaymentGateway/Payflow.php.

[$key, $value] = explode('=', $bodyPart, 2);

Otherwise, it appears the tests were successful.

jimmynash’s picture

@shaunole thanks for doing this work. I've found myself needing to conditionally set the paypal comment1 field for a project and having an event subscriber to modify the values before going to paypal would be extremely helpful.

shaunole’s picture

Status: Needs review » Reviewed & tested by the community
shaunole’s picture

Resolved remaining test failures. We should be good to merge this into the next release.

shaunole’s picture

Status: Reviewed & tested by the community » Needs review
rszrama’s picture

+1 from me on the approach - we should have request / response events for every API integration. This just needs the docblock at https://git.drupalcode.org/project/commerce_paypal/-/merge_requests/8/di... fixed and it's ready to commit.

shaunole’s picture

Thanks @rszrama. The Dockblocks have been updated. Thanks for the feedback.

The PHP7 test failure is unrelated as its being caused by the void return type being specified in commerce_paypal/tests/src/Kernel/IPNHandlerTest.php::setUp() function declaration. Including the return type was intentionally introduced in commit https://git.drupalcode.org/project/commerce_paypal/-/commit/0741a59b3203... and released in 8.x-1.0-rc4.

  • rszrama committed 6862ef9 on 8.x-1.x authored by shaunole
    Issue #2932200 by shaunole, bmcclure, rszrama: Include additional order...
rszrama’s picture

Title: Include additional order details in Payflow payments » Include additional order details in Payflow payments via a custom event
Status: Needs review » Fixed

Thanks for the updates. Merging this in via the CLI ... I still don't know how to use GitLab to squash / retitle merges. 🤷🏼‍♂️

shaunole’s picture

Great! Thank you @szrama. I appreciate the review and feedback.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.