在Braintree中,是否可以仅为一个客户而不是整个金库验证重复的付款方式?

时间:2015-12-23 01:03:32

标签: php braintree

对于Braintree_PaymentMethod::create()功能,其中一个选项是:

  

'failOnDuplicatePaymentMethod', bool

     

如果传递此选项并且付款方式已添加到Vault,则请求将失败。此选项不适用于PayPal付款方式。

这似乎是一次全球比较。即如果保险箱中存在信用卡信息,无论客户ID如何,都将失败。

有没有办法检查特定客户的重复项?

5 个答案:

答案 0 :(得分:8)

完全披露:我在Braintree工作。如果您有任何其他问题,请随时联系support

您和Evan是正确的:无论客户创建,这是唯一预先构建的重复创建方式。但是,您可以实现自己尝试使用自己的自动化。

为此,只需从credit card unique ids收集已存在的the customer object即可。然后当您create the new payment method时,将其与现有卡片进行比较:

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";
    }
} 

根据您的目的,您可以删除新的付款方式或其他任何需要的方法。

答案 1 :(得分:1)

使用Braintree支持进行检查 - 仍未开箱即用:

  

如果您使用failOnDuplicatePaymentMethod,任何将重复的付款方式信息添加到Vault中的请求都将失败。

     

我们目前没有防止客户在其个人资料中添加重复卡的功能,同时允许在多个配置文件下添加重复的卡。如果这是你感兴趣的东西,你必须建立自己的逻辑。

答案 2 :(得分:1)

@Raymond Berg,我对你的代码进行了更改,这是更新后的代码:
1.使用foreach而不是in_array
2.同时删除添加的卡如果发现重复

$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";
    }

}

答案 3 :(得分:1)

  

这是.NET版本。并非100%完成,但对于处于相同情况的人来说是一个很好的入门者。如果您发现任何问题或建议,请编辑此答案。

        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's 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's unique
            return token;
        }
        catch (BraintreeException ex)
        {
            throw;  
        }
        catch (Exception ex)
        {
            throw;
        }

答案 4 :(得分:-1)

//  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);