代码:
Stripe::setApiKey($stripe_secret_key);
Stripe::setApiVersion('2017-02-14');
// Either create a new customer object or retrieve the existing customer object
$db->query(" SELECT StripeCustomerToken FROM stripe_ids WHERE UPPER(UserEmail) = UPPER(:email) ");
$db->bind(':email', $user_email);
$db->execute();
$customer_token = $db->fetchSingleColumn();
if(!$customer_token)
{
$customer = Stripe_Customer::create(
[
'card' => $stripe_card_token,
'description' => $user_email,
'email'=>$user_email
],
$stripe_access_token
);
$customer_token = $customer->id;
$db->query(" INSERT INTO stripe_ids (UserEmail, StripeCustomerToken) VALUES (:e, :custID) ");
$db->bind(':e', $user_email);
$db->bind(':custID', $customer_token);
$db->execute();
}
if(!$customer_token)
throw new Exception('No Stripe Customer Token detected. The payment could not be processed.');
$customer = Stripe_Customer::retrieve($customer_token);
// Using the token ID, retrieve the full token object and retrieve the fingerprint from the `card.fingerprint` attribute
$current_card = Stripe_Token::retrieve($stripe_card_token);
$current_card_fingerprint = $current_card->card->fingerprint;
$current_card_id = $current_card->card->id;
// Iterate through the list of the customer's saved sources and check if any has the same value for its `fingerprint`
$source_exists = false;
foreach($customer->sources->data as $i => $fingerprint)
{
if($current_card_fingerprint === $fingerprint)
$source_exists = true;
}
// If not, add the card to the customer object
if(!$source_exists)
$customer->sources->create(['source' => $stripe_card_token]);
$customer->default_source = $current_card_id;
$customer->save();
// Create the charge using the customer ID and the card ID
$charge = [
'customer' => $customer->id,
'source' => $current_card_id,
'amount' => $total_gross_received_cents,
'currency' => 'EUR',
'description' => $transaction_description_str,
'application_fee' => $databiz_fee
];
$charge_obj = Stripe_Charge::create($charge, $stripe_access_token);
if(empty($charge_obj))
throw new Exception('No Stripe Charge Object detected. The payment could not be processed.');
$charge_token = $charge_obj->id;
问题:
每次客户使用该应用程序时,他们都必须输入其CC细节。因此我想:
我遇到了麻烦,即返回的客户的默认卡没有更新到当前使用的卡(导致资金来自默认值),所以我将卡ID添加到收费对象,并且将当前卡保存为客户的默认值。
现在的问题是,在实时交易中,我收到InvalidRequest异常 - 我不能多次使用令牌。
有人能指出我哪里出错了吗?
答案 0 :(得分:1)
将卡添加到客户($customer->sources->create(...)
)时提供的令牌可能已被其他API请求使用。您应该检查您的集成,以确保$stripe_card_token
包含由Checkout或Elements创建的“新鲜”令牌。
我注意到的其他一些事情:
您正在Connect使用direct charges。这意味着客户对象必须存在于已连接的帐户上,而不是平台的帐户上。当您检索客户时,您没有指定已连接帐户的API密钥,因此该请求将在您平台的帐户上发出并且将失败(因为该平台的帐户中不存在该客户ID)
您正在使用Stripe's PHP library的旧版本(1.x)。您应该考虑升级到更新版本。这需要将代码更新为新语法(Stripe_Class
- > \Stripe\Class
)
当查看客户卡上是否已存在时,您会迭代$customer->sources->data
。请注意,在检索客户对象时,此属性最多包含10个源。如果客户拥有10个以上的来源,则需要使用pagination来检索完整列表。
请注意,如果您使用最新版本的Stripe的PHP库,则可以使用auto-pagination功能轻松处理此问题。