【问题标题】:how to prevent to customer to add same credit card如何防止客户添加同一张信用卡
【发布时间】:2015-05-25 08:47:26
【问题描述】:

我使用 stripe 作为我的支付提供商,并将加密的信用卡 ID 存储在我从 stripe 返回的数据库中。

我的问题是 GUI 客户可以再次添加同一张卡。我看到条纹不会阻止为同一客户多次添加同一张卡。由于条带总是为同一张卡生成不同的加密卡 ID,所以我不能用它来验证是否再次添加了同一张卡。

如何阻止客户再次添加同一张卡。

【问题讨论】:

  • 客户为自己添加同一张卡两次或多次除了不优雅之外,还会带来哪些问题?

标签: stripe-payments


【解决方案1】:

看起来我明白了。我可以使用 json 响应中返回的指纹。我看到了条纹仪表板,发现我再次添加的同一张卡的指纹总是相同的。

这是确认的json请求和响应

请求

{
  "source": {
    "number": "378282246310005",
    "cvc": "123",
    "address_line2": "4th Floor",
    "address_line1": "140 2nd Street",
    "address_country": "USA",
    "name": "VIAY KUMAR",
    "address_state": "CA",
    "exp_month": 12,
    "exp_year": 2015,
    "address_zip": "94105",
    "address_city": "San Francisco",
    "object": "card"
  }
}

回应

 {
      "id": "card_166H9rC8Y8JrMFgBh9GVsmNG",
      "object": "card",
      "status": null,
      "exp_month": 12,
      "exp_year": 2015,
      "last4": "0005",
      "country": "US",
      "type": null,
      "name": "VIAY KUMAR",
      "customer": "cus_6IrxhfwXNyD1Uw",
      "recipient": null,
      "address_line1": "140 2nd Street",
      "address_line2": "4th Floor",
      "address_zip": "94105",
      "address_city": "San Francisco",
      "address_state": "CA",
      "address_country": "USA",
      "address_zip_check": "pass",
      "address_line1_check": "pass",
      "cvc_check": "pass",
      "fingerprint": "TwjSA2KqPDhSMUvQ",
      "brand": "American Express",
      "funding": "credit"
    }

再次添加同一张卡并获得不同的卡号但相同的指纹:-)

请求

{
  "source": {
    "number": "378282246310005",
    "cvc": "123",
    "address_line2": "4th Floor",
    "address_line1": "140 2nd Street",
    "address_country": "USA",
    "name": "VIAY KUMAR",
    "address_state": "CA",
    "exp_month": 12,
    "exp_year": 2015,
    "address_zip": "94105",
    "address_city": "San Francisco",
    "object": "card"
  }
}

回应

{
  "id": "card_166HKVC8Y8JrMFgBfvbHPgk2",
  "object": "card",
  "status": null,
  "exp_month": 12,
  "exp_year": 2015,
  "last4": "0005",
  "country": "US",
  "type": null,
  "name": "VIAY KUMAR",
  "customer": "cus_6IrxhfwXNyD1Uw",
  "recipient": null,
  "address_line1": "140 2nd Street",
  "address_line2": "4th Floor",
  "address_zip": "94105",
  "address_city": "San Francisco",
  "address_state": "CA",
  "address_country": "USA",
  "address_zip_check": "pass",
  "address_line1_check": "pass",
  "cvc_check": "pass",
  "fingerprint": "TwjSA2KqPDhSMUvQ",
  "brand": "American Express",
  "funding": "credit"
}

【讨论】:

    【解决方案2】:

    感谢 Vijay 的上述回答。

    我在我的 Rails 应用程序中编写了以下 Ruby 代码来检查这一点。

    将相关的@user.stripe_customer_id 变量替换为您自己的。

    # Retrieve the customer we're adding this token to
    customer = Stripe::Customer.retrieve(@user.stripe_customer_id)
    
    # Retrieve the token 
    token = Stripe::Token.retrieve(params[:stripeToken])
    
    # The fingerprint of the card is stored in `card.fingerprint`
    card_fingerprint = token.card.fingerprint
    
    # Check if the card fingerprint submitted matches one of the customer's current sources
    fingerprint_already_exists = customer.sources.any? {|source| source[:fingerprint] == card_fingerprint}
    
    if fingerprint_already_exists
      # You can do whatever you want here. I've personally set a flash message to let the user know this card is already on their account
      flash[:warning] = "That card already exists on your account."
      redirect_to user_path(@user) and return
    end
    
    # Continue adding the source as normal
    customer.sources.create(source: params[:stripeToken])
    
    # Anything else you want to do...
    flash[:success] = "Your account has been updated."
    redirect_to user_path(@user) and return
    

    【讨论】:

      【解决方案3】:

      Stripe 生成的fingerprint 对于每张卡都是唯一的。取自文档:

      指纹字符串

      唯一标识此特定卡号。例如,您可以使用此属性检查与您注册的两个客户是否使用相同的卡号。

      假设此时您已经有一个 customer 对象(新的或要更新的),这将允许您添加一张卡片并将其设为默认值,而不会重复:

          // $customer = \Stripe\Customer::retrieve( $clicker->customer );
      
          /**
           * Add the card, but only if it does not exist. Make it default in any case.
           **/
          $token = \Stripe\Token::retrieve( $_POST['stripeToken'] );
          $card = null;
      
          /** Does this customer already have this card? If so, find it. **/
          foreach ( $customer->sources['data'] as $source ) {
              if ( $source['fingerprint'] == $token['card']->fingerprint ) {
                  $card = $source;
              }
          }
      
          /** If not, add the new card to the customer **/
          if ( is_null( $card ) ) {
              $card = $customer->sources->create( array( 'source' => $_POST['stripeToken'] ) );
          }
      
          $customer->default_source = $card->id;
          $customer->save();
      

      您可以将它包含在通常的 try/catch 中,如文档所示。


      话虽如此,从用户的角度来看,如果可能的话,最好向他们展示他们的卡列表(last4 + 到期日期)并让他们选择他们想要收费的卡– 而不是不必要地询问他们的信息。

      【讨论】:

        猜你喜欢
        • 2017-02-08
        • 2012-02-26
        • 1970-01-01
        • 2016-09-04
        • 2018-03-04
        • 2021-01-25
        • 1970-01-01
        • 2021-01-31
        • 1970-01-01
        相关资源
        最近更新 更多