对于Braintree_PaymentMethod::create()功能,其中一个选项是:
'failOnDuplicatePaymentMethod', bool
如果传递此选项并且付款方式已添加到Vault,则请求将失败。此选项不适用于PayPal付款方式。
这似乎是一次全球比较。即如果保险箱中存在信用卡信息,无论客户ID如何,都将失败。
有没有办法检查特定客户的重复项?
答案 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);