【问题标题】:createTokenWithCard with tipsi-stripe does not return an error when expiration is incorrect?当过期不正确时,带有tipsi-stripe的createTokenWithCard不会返回错误?
【发布时间】:2018-11-25 02:35:06
【问题描述】:

也发布在https://github.com/tipsi/tipsi-stripe/issues/312

"firebase": "^4.12.0",
"react": "^16.2.0",
"react-native": "^0.53.3",
"react-native-firebase": "^3.2.7",
"react-stripe-elements": "^1.6.0",
"tipsi-stripe": "^5.2.1"

问题

我使用不正确的到期日期调用 createTokenWithCard,它似乎没有返回错误,而是返回了一个令牌。 然后,当我尝试将此令牌写入 Firebase 时,我看到一个错误:“您的卡已被拒绝。” tipsi-stripe 是否返回错误而我没有正确检查?

代码如下:

addCard = async ({
    number, expMonth, expYear, cvc,
  }) => {
    this.setState({ addingCardInProcess: true });
    try {
      const tokenObject = await stripe.createTokenWithCard({
        number, expMonth, expYear, cvc
      });
      firebase
        .database()
        .ref(`/stripe_customers/${uid()}/sources`)
        .push({ token: tokenObject.tokenId })
        .then(() => {
          this.setState({ addingCardInProcess: false });
          this.cardAlert(true);
        })
        .catch((err) => {
          this.setState({ addingCardInProcess: false });
          this.cardAlert(false, err.message);
        });
    } catch(err) {
      this.cardAlert(false, err.message);
      this.setState({ addingCardInProcess: false })
    }
  };

【问题讨论】:

    标签: react-native stripe-payments


    【解决方案1】:

    当您说“不正确的到期日期”时,您是指有效日期(即不是过去),而不是与卡本身匹配的日期吗?假设你这样做:

    当您调用stripe.createTokenWithCard 时,Stripe 仅检查这些值在一般意义上是否有效,例如卡号通过了 luhn 检查并且到期日期在未来。标记化时没有针对实际卡进行实时验证。所以即使过期不匹配真卡也可以创建token。

    稍后,当您将卡附加到客户时(我假设当您调用 /stripe_customers/${uid()}/sources 端点时),Stripe 将对真实卡执行 $0/$1 授权,此时您将获得如果到期日期错误,则拒绝 - 这就是您所看到的。

    [0] - https://en.wikipedia.org/wiki/Luhn_algorithm

    [1] - https://stripe.com/docs/saving-cards#saving-credit-card-details-for-later

    【讨论】:

    • 哇,太棒了,谢谢。如果是这种情况,我不应该从 firebase.push 收到错误吗?
    • 我不确定,不是很熟悉firebase,只有Stripe :) 如果您将其用作基础,我认为错误将来自这里。 github.com/firebase/functions-samples/blob/master/stripe/…
    • 非常感谢。我会查的。如果我找到任何东西,我会在这里发布。
    【解决方案2】:

    添加到@karllekko 答案:

    • 因此,stripe 不会检查过期和 CVC,即使它们不正确也会返回一个令牌
    • 但是,Firebase 在获得要写入的条带令牌时,会执行以下操作:
      • 写它
      • 验证它(包括过期和 CVC)
      • 如果详细信息正确,它会将之前写入的令牌替换为卡详细信息(最后 4 位数字、品牌、国家等)
      • 如果到期或 CVC 不正确,它将令牌留在数据库中并添加错误消息(key='error'。“卡被拒绝”或其他消息,如果到期正常且 CVC 不正确)。

    所以,如果我们想知道卡片验证的真实状态是什么,我们需要等到 firebase 用最终的详细信息替换初始令牌。这可能需要几秒钟。

    仅用于测试目的,这是修改后的代码(最终代码可能会在之后检查状态,或者休眠一小段时间,然后检查数据库中的值等,直到最终值设置):

    try {
          const tokenObject = await stripe.createTokenWithCard({
            number, expMonth, expYear, cvc
          });
    
          const id = firebase.database().ref().push().key;
          const body = { token: tokenObject.tokenId };
          firebase
            .database()
            .ref(`/stripe_customers/${uid()}/sources`).child(id)
            .set(body)
            .then(() => {
              console.log("sleeping for a while");
              this.sleep(15000); // delay, waiting for firebase to update
              firebase
                .database()
                .ref(`/stripe_customers/${uid()}/sources/${id}`).once('value')
                .then((snapshot) => {
    
                  const dataAfterValidation = snapshot.val();
    
                  if (dataAfterValidation) {  // not null
                    if (dataAfterValidation.hasOwnProperty('error')) {
                      // card invalid
                      console.log("Card declined. Check expiration date and CVC.");
                    } else if (dataAfterValidation.hasOwnProperty('brand')) {
                      console.log("Card added to the database.");
                    } else {
                      // still not updated
                      console.log("Card is being validated.");
                    }
                  } else {
                    console.log("Hmmm... Should not reach here...");
                  }
                });
    
              this.setState({ addingCardInProcess: false });
            })
    
            .catch((err) => {
              this.setState({ addingCardInProcess: false });
              console.log("FAILURE", err.message);
            });
        } catch(err) {
          console.log("FAILURE", err.message);
          this.setState({ addingCardInProcess: false })
        }
      };
    

    【讨论】:

      猜你喜欢
      • 2015-01-07
      • 1970-01-01
      • 2020-03-18
      • 1970-01-01
      • 2011-03-23
      • 1970-01-01
      • 1970-01-01
      • 2018-08-11
      • 1970-01-01
      相关资源
      最近更新 更多