If checkout is allowed for anonymous users, the AuthorizeNet::doCreatePaymentMethod() fails because the user email address is empty.

  protected function doCreatePaymentMethod(PaymentMethodInterface $payment_method, array $payment_details) {
     ...
      if ($owner->isAuthenticated()) {
        $profile = new Profile([
          // @todo how to allow altering.
          'merchantCustomerId' => $owner->id(),
          'email' => $owner->getEmail(),
        ]);
      }
      else {
        $profile = new Profile([
          // @todo how to allow altering.
          'merchantCustomerId' => $owner->id() . '_' . REQUEST_TIME,
          'email' => $owner->getEmail(),  // <<<<<<<<<<<<<<<< This is empty for anonymous users
        ]);
   ...
  }

AuthNet doesn't allow for an empty email to be passed in. If this property is removed (I just commented it out), AuthNet does accept it. A quick fix is to remove email from the anonymous users. A better long term fix would be to pull their email info in from their billing profile.

CommentFileSizeAuthor
#3 anonymous_checkout-2892467-3.patch684 bytesmglaman

Comments

onedotover created an issue. See original summary.

mglaman’s picture

Hm, the billing profile does not have an email. And the order's email should be set from the account information pane, where they have to enter an email address. So instead of $owner we need to do $order

mglaman’s picture

Status: Active » Needs review
StatusFileSize
new684 bytes

We don't have access to the order in that method. So just omitting.

mglaman’s picture

Hm, but from the API page http://developer.authorize.net/api/reference/#customer-profiles-create-c...

Required only when you use a European payment processor.

That patch is a quickfix. The method should probably be revisited. It's borrowed from the first gateway we wrote, Braintree, which supported tokenization much more easily.

mglaman’s picture

Title: Anonymous checkout fails due to missing email » Does not support anonymous checkout
Priority: Normal » Major

The module just cannot support anonymous checkout at the moment. When I applied this fix, I then had errors with the customer profile ID.

    $transactionRequest->addDataType(new Profile([
      'customerProfileId' => $customer_id,
      'paymentProfile' => [
        'paymentProfileId' => $payment_method->getRemoteId(),
      ],
    ]));

It is null here, leading to

The 'AnetApi/xml/v1/schema/AnetApiSchema.xsd:customerProfileId' element is invalid - The value '' is invalid according to its datatype 'AnetApi/xml/v1/schema/AnetApiSchema.xsd:numericString' - The 
               Pattern constraint failed. 

Since the 2.x architecture is built around tokenized payment methods.. I don't think there is anyway to solve this until we implement Accept.js.

mglaman’s picture

Status: Needs review » Needs work
bojanz’s picture

adrian83’s picture

So is this blocked by the lack of Accept.js

bradjones1’s picture

And to clarify, using Accept.js means this bug doesn't apply.

czigor’s picture

Using the access.js patch in #2813401-15: Use Accept.js to ease PCI requirements. I can make anonymous checkouts.

mglaman’s picture

We need to add a test for this.

nikathone’s picture

Status: Needs work » Needs review

A fix for this at http://cgit.drupalcode.org/commerce_authnet/tree/src/Plugin/Commerce/Pay... is already implemented. I guess we should find a better way of collecting the anonymous user email than the one in http://cgit.drupalcode.org/commerce_authnet/tree/src/PluginForm/Authoriz... then close this issue. Switched it to need review for the latest beta not the patch.

mglaman’s picture

Okay, so this is _working_ but is fragile and really needs a core API improvement (still)

mglaman’s picture

Status: Needs review » Fixed

I'm marking this fixed. It's working, albeit we need a core API improvement to get order email for payment method.

mglaman’s picture

Fixing credits. Credits all around. Credits for debugging this thing.,

Status: Fixed » Closed (fixed)

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