braintree / braintree_php

Braintree PHP library
https://developer.paypal.com/braintree/docs/start/overview
MIT License
545 stars 224 forks source link

Creating a duplicate payment method does not fail as expected. #227

Closed ShaunDychko closed 6 years ago

ShaunDychko commented 6 years ago

General information

Issue description

When creating a new payment method using the same credit card number, expiry, cvv, and postal code as an already vaulted card for a different customer, the request does not fail despite passing the 'failOnDuplicatePaymentMethod' => TRUE option. In other words, the code snippet in the Braintree API reference

$result = $gateway->paymentMethod()->create([
    'customerId' => '12345',
    'paymentMethodNonce' => nonceFromTheClient,
    'options' => [
      'failOnDuplicatePaymentMethod' => true
    ]
]);

does not work as expected. This is despite failing as expected when creating a new customer with an already vaulted credit card.

Steps to reproduce

  1. Create two customers using different test cards submitted using the Braintree Drop-in UI, with options similar to the following
    $result = $this->braintreeApiService->getGateway()->customer()->create([
      'firstName' => $user->getAccountName(),
      'email' => $user->getEmail(),
      'paymentMethodNonce' => $nonce,
      'creditCard' => [
        'options' => [
          'verifyCard' => TRUE,
          'failOnDuplicatePaymentMethod' => TRUE,
        ],
      ],
    ]);

    If you use a duplicate card for one of the customers, it will fail as expected.

  2. Create a new payment method for one of the customers using the same card number, expiry, cvv, and postal code as for the other already vaulted customer, using options similar to
    $payload = [
      'customerId' => $customer->id,
      'paymentMethodNonce' => $nonce,
      'options' => [
        'makeDefault' => TRUE,
        'failOnDuplicatePaymentMethod' => TRUE,
        'verifyCard' => TRUE,
      ],
    ];
    $result = $this->braintreeApiService->getGateway()->paymentMethod()->create($payload);

    The $result will be successful, even though expected behavior is for it to fail.

ShaunDychko commented 6 years ago

It turns out that the failOnDuplicatePaymentMethod option needs to be passed to the token generator in order to take effect. See https://developers.braintreepayments.com/reference/request/client-token/generate/php#options.