In Braintree, can I check the duplicate payment method for only one client, and not for the entire store?

For the Braintree_PaymentMethod :: create () function, one of the options:

'failOnDuplicatePaymentMethod' bool If this option is passed and the payment method has already been added to the Vault, the request will fail. This option will not work with PayPal payment methods. 

This is like a global comparison. that is, if credit card information exists in the repository, regardless of customer ID, this will not be done.

Is there a way to check for duplicates for a specific client?

+7
source share
5 answers

Full disclosure: I work at Braintree. If you have further questions, feel free to contact support .

You and Evan are true: this is the only pre-created way to fail duplication, created independently of the creation of the client. However, you can achieve what you are trying to do with your own automation.

To do this, simply collect the unique credit card identifiers that already exist from the customerโ€™s object . Then, when you create a new payment method , compare it with existing cards:

 function extractUniqueId($creditCard){ return $creditCard->uniqueNumberIdentifier; } $customer = Braintree_Customer::find('your_customer'); $unique_ids = array_map(extractUniqueId,$customer->creditCards); $result = Braintree_PaymentMethod::create(array( 'customerId' => 'your_customer', 'paymentMethodNonce' => 'fake-valid-discover-nonce', )); if ($result->success) { if(in_array(extractUniqueId($result->paymentMethod), $unique_ids)) { echo "Do your duplicate logic"; } else { echo "Continue with your unique logic"; } } 

Depending on what you want to do, you can remove the new payment method or whatever you need.

+8
source

Tested with Braintree support - still not available out of the box:

If you use failOnDuplicatePaymentMethod, any request to add duplicate payment method information to the repository will not be executed.

We currently do not have features that allow customers to add a duplicate card to their profile, while allowing duplicate cards to continue to be added to multiple profiles. If this is what interests you, you will have to build your own logic.

+1
source

@ Raymond Berg, I made changes to your code, here is the updated code:
1. Used by foreach instead of in_array
2. Also delete the added card. If duplicate is found

 $customer = Braintree_Customer::find('your_customer'); $unique_ids = array_map(extractUniqueId,$customer->creditCards); $result = Braintree_PaymentMethod::create(array( 'customerId' => 'your_customer', 'paymentMethodNonce' => 'fake-valid-discover-nonce', )); if ($result->success) { $cardAlreadyExist = false; $currentPaymentMethod = $this->extractUniqueId($result->paymentMethod); //The in_array function was not working so I used foreach to check if card identifier exist or not foreach ($unique_ids as $key => $uid) { if( $currentPaymentMethod == $uid->uniqueNumberIdentifier) { $cardAlreadyExist = true; //Here you have to delete the currently added card $payment_token = $result->paymentMethod->token; Braintree_PaymentMethod::delete($payment_token); } } if($cardAlreadyExist) { echo "Do your duplicate logic"; } else { echo "Continue with your unique logic"; } } 
+1
source

Here is the .NET version. Not 100% complete, but a good starter for a person with the same situation. If you find any problems or suggestions, just edit this answer.

  try { // final token value (unique across merchant account) string token; // PaymentCreate request var request = new PaymentMethodRequest { CustomerId = braintreeID, PaymentMethodNonce = nonce, Options = new PaymentMethodOptionsRequest() }; // try to create the payment without allowing duplicates request.Options.FailOnDuplicatePaymentMethod = true; var result = await gateway.PaymentMethod.CreateAsync(request); // handle duplicate credit card (assume CC type in this block) if (result.Errors.DeepAll().Any(x => x.Code == ValidationErrorCode.CREDIT_CARD_DUPLICATE_CARD_EXISTS)) { // duplicate card - so try again (could be in another vault - ffs) // get all customer existing payment methods (BEFORE adding new one) // don't waste time doing this unless we know we have a dupe var vault = await gateway.Customer.FindAsync(braintreeID); // fortunately we can use the same nonce if it fails request.Options.FailOnDuplicatePaymentMethod = false; result = await gateway.PaymentMethod.CreateAsync(request); var newCard = (result.Target as CreditCard); // consider a card a duplicate if the expiration date is the same + unique identifier is the same // add on billing address fields here too if needed var existing = vault.CreditCards.Where(x => x.UniqueNumberIdentifier == newCard.UniqueNumberIdentifier).ToArray(); var existingWithSameExpiration = existing.Where(x => x.ExpirationDate == newCard.ExpirationDate); if (existingWithSameExpiration.Count() > 1) { throw new Exception("Something went wrong! Need to decide how to handle this!"); } else { // delete the NEW card await gateway.PaymentMethod.DeleteAsync(newCard.Token); // use token from existing card token = existingWithSameExpiration.Single().Token; } } else { // use token (could be any payment method) token = result.Target.Token; } // added successfully, and we know it unique return token; } catch (BraintreeException ex) { throw; } catch (Exception ex) { throw; } 
0
source
 // Search for customer in Braintree Vault try $braintree_result_find = Braintree_Customer::find($cust_id); // prepare Braintree sale, but do not execute (yet) $sale_array = array( 'amount' => $amt, // other braintree Parameters 'options' => array( 'submitForSettlement' => true, 'storeInVaultOnSuccess' => $save_cc_chk_bool ) ); // customer does not yet exist in Braintree Vault if (!isset($braintree_result_find) || !$braintree_result_find) $sale_array["customer"]['id'] = $cust_id; // customer does exist in Braintree Vault else $sale_array['customerId'] = $cust_id; $braintree_result_sale = Braintree_Transaction::sale($sale_array); 
-1
source

All Articles